appfw/apparchitecture/apserv/apsnnappupdates.h
author William Roberts <williamr@symbian.org>
Fri, 23 Apr 2010 14:37:17 +0100
branchRCL_3
changeset 22 c82a39b81a38
parent 0 2e3d3ce01487
permissions -rw-r--r--
Rework addition of Symbian splash screen to reduce the source impact (uses SVG from Bug 2414) Notes: by using the OPTION SOURCEDIR parameter in the mifconv extension instructions, I can arrange to use the same source file name in sfimage, without having to export over the original Nokia file. This means that the name inside splashscreen.mbg is the same, which removes the need for the conditional compilation in SplashScreen.cpp, and gets rid of sf_splashscreen.mmp.

// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// apsnnappupdates.h
//

#ifndef APSNNAPPUPDATES_H
#define APSNNAPPUPDATES_H

#include <e32base.h>
#include <f32file.h>
	


// classes referenced
class CApaAppData;
class CApaAppArcServer;
class RApsUpdateLog;
class RWriteStream;

/**
This class keeps track of a resource file or icon file, 
whether it is in its final location or a temporary directory.

The NonNativeApps updates system makes heavy use of moving files
between temporary and final locations, in an attempt to provide
atomicity of update lists.

@internalComponent
*/
NONSHARABLE_CLASS(TFileDetails)
	{
public:
	TFileDetails();
	const TDesC& Path();
	void SetPath(const TDesC& aPath);
	TBool Exists() const;
	void CloseHandle();
	
	void OpenL(RFs& aFs, const TFileName& aFileName);
	void CreateTemporaryL(RFs& aFs, const TFileName& aDir);
	void GetDuplicateHandleL(RFile& aFile);

	void RenameToRealL(RFs& aFs);
	void RenameToTemporaryL(RFs& aFs, const TFileName& aDir);
	TInt Delete(RFs& aFs);
	TInt DeleteTemporary(RFs& aFs);
	TInt RestoreReal(RFs& aFs);

	void ExternalizeL(RWriteStream& aStream);
	void ExternalizeContinuationL(RWriteStream& aStream, TInt aTag);
	TInt ExternalizeContinuation(RWriteStream& aStream, TInt aTag);
	void InternalizeL(RReadStream& aStream, TInt& aPosition);
	void PostInternalizeL(RFs& aFs);

private:
	TInt RenameToReal(RFs& aFs);

private:
	enum TState
		{
		EStateInvalid = 0,
		EStateNull,
		EStateTemporary,
		EStateReal
		};
	TState iState;
	TFileName iPath;
	TFileName iTempPath;
	RFile iHandle;
	};

/**
Abstract base class for objects that represent updates to the non-native applications
registry. Subclasses must implement the DoPerformUpdateL and DoRollbackUpdate methods.

- DoPerformUpdateL will only ever be called once or not at all
- DoPerformUpdateL will be called first, if at all
- DoRollbackUpdate will not be called before DoPerformUpdateL
- DoRollbackUpdate will be called if DoPerformUpdateL fails on this update or any subsequent one
- DoRollbackUpdate will not be called twice
- The object may be deleted at any time.

If the device is turned off / crashes partway through performing updates, 
the following will be called upon reboot:

- The subclass' NewL, with dummy values instead of class-specific data (if any)
- InternalizePerformLogL() will be called immediately afterwards
- InternalizeRollbackLogL() iff a rollback action for this update is in the log
- PostInternalizeL() will be called after the log has been read in entirely
- DoRollbackUpdaetL() may then be called if, after replaying the log, the class' state is
                      EPerforming, EPerformed or ERollingBack

@internalComponent
*/
NONSHARABLE_CLASS(CApsNonNativeApplicationsUpdate) : public CBase
	{
public: // Types
	enum TState
		{
		ENew,
		ENeedsInternalizing,
		EPerforming,
		EPerformed,
		ERollingBack,
		ERolledBack
		};
	
	enum TLogActionType
		{
		EInvalidAction = 0,
		ENewUpdate,				// Indicates the record of an update's initial state
		EPerformUpdate,			// Indicates the start of a Perform-update log
		ERollbackUpdate,        // Indicates the start of a Rollback-update log
		EContinuationOfUpdate,  // Specifies that the current update's log has not finished
		EChangeOfUpdateState,   // Similar to EContinuationOfUpdate, but used by this superclass
		EEndOfUpdate            // Specifies that the current update's log has finished
		};

	enum TLogUpdateType
		{
		EInvalidUpdate = 0,
		ERegisterApplication,   // Indicates the start of a RegisterApplication update
		EDeregisterApplication, // Indicates the start of a DeregisterApplication update
#ifdef _DEBUG
		EFail,                  // Indicates the start of a Forced-Fail update
		EPanic,                 // Indicates the start of a Forced-Panic update
		ERollbackPanic          // Indicates the start of a Forced-Panic-On-Rollback update
#endif
		};

public:
	~CApsNonNativeApplicationsUpdate();

protected:
	CApsNonNativeApplicationsUpdate(RFs& aFs, TUid aUid, TState aState, TLogUpdateType aType);

public: 
	CApsNonNativeApplicationsUpdate* Previous() const;
	CApsNonNativeApplicationsUpdate* Next() const;
	TUid Uid();
	void PerformUpdateL(RApsUpdateLog& aUpdateLog);
	void RollbackUpdateL(RApsUpdateLog& aUpdateLog);
	void InternalizeStateChangeL(RReadStream& aStream, TInt& aPosition);

	void InternalizeNewUpdateL(RReadStream& aStream, TInt& aPosition);
	void InternalizePerformUpdateL(RReadStream& aStream, TInt& aPosition);
	void InternalizeRollbackUpdateL(RReadStream& aStream, TInt& aPosition);

protected:
	TFileName TemporaryFilePathL(TDriveName& aDrive);
	void StateChangeL(TState aState, RWriteStream& aStream);

private:
	void SharedInternalizeLoopL(RReadStream& aStream, TInt& aPosition);

	virtual void DoPerformUpdateL(RApsUpdateLog& aUpdateLog) = 0;
	virtual void DoRollbackUpdate(RApsUpdateLog& aUpdateLog) = 0;

	virtual void ExternalizeL(RWriteStream& aStream);
	virtual void InternalizeL(RReadStream& aStream, TInt& aPosition);
	virtual void InternalizeUpdateContinuationL(RReadStream& aStream, TInt& aPosition);
	virtual void PostInternalizeL();


protected:
	TState iState;
	RFs& iFs;

private:
	friend class CApsNonNativeApplicationsUpdateList; // so it can link up iPrevious/iNext
	const TLogUpdateType iType;
	CApsNonNativeApplicationsUpdate* iPrevious;
	CApsNonNativeApplicationsUpdate* iNext;
	const TUid iUid;
	};

/**
Implementation of CApsNonNativeApplicationsUpdate that performs the registration of a
non-native application.

The Write/Copy methods of this class should be used to prepare the update,
they will write resource and icon files to a temporary directory.

When this update is executed, the files will be moved to the locations set with the
Set*FileTargetLocation functions.

@internalComponent
*/
NONSHARABLE_CLASS(CApsRegisterNonNativeApplication) : public CApsNonNativeApplicationsUpdate
	{
public:
	static CApsRegisterNonNativeApplication* NewL(RFs& aFs, TUid aUid, const TDriveName& aDrive, TState aState = ENew);
	~CApsRegisterNonNativeApplication();

private:
	CApsRegisterNonNativeApplication(RFs& aFs, TUid aUid, const TDriveName& aDrive, TState aState);

public:
	void SetResourceFileTargetLocation(const TDesC& aLocation);
	void WriteResourceFileL(const TDesC8& aData, const TDesC8* aDataPrefix);

	void SetLocalisableResourceFileTargetLocation(const TDesC& aLocation);
	void WriteLocalisableResourceFileL( const TDesC8& aData, const TDesC8* aDataPrefix);

	void SetIconFileTargetLocation(const TDesC& aLocation);
	void CopyIconFileL(RFile& aSourceFile);

private:	
	void NewTemporaryFileL(TFileDetails& aFile);
	void WriteResourceFileL(TFileDetails& aFile, const TDesC8& aData, const TDesC8* aDataPrefix);

	// from CApsNonNativeApplicationsUpdate
	void DoPerformUpdateL(RApsUpdateLog& aUpdateLog);
	void DoRollbackUpdate(RApsUpdateLog& aUpdateLog);
	void ExternalizeL(RWriteStream& aStream);
	void InternalizeL(RReadStream& aStream, TInt& aPosition);
	void InternalizeUpdateContinuationL(RReadStream& aStream, TInt& aPosition);
	void PostInternalizeL();


private:
	enum TLogContinuationType 
		{
		EInvalidContinuation = 0,
		EResourceFileUpdate,
		ELocalisableResourceFileUpdate,
		EIconFileUpdate
		};
	TDriveName iDrive;
	TFileDetails iResourceFile;
	TFileDetails iLocalisableResourceFile;
	TFileDetails iIconFile;
	};

/**
Implementation of CApsNonNativeApplicationsUpdate that performs the deregistration of a
non-native application.

@internalComponent
*/
NONSHARABLE_CLASS(CApsDeregisterNonNativeApplication) : public CApsNonNativeApplicationsUpdate
	{
public:
	static CApsDeregisterNonNativeApplication* NewL(RFs& aFs, CApaAppArcServer& aServ, TUid aUid, TState aState = ENew);
	~CApsDeregisterNonNativeApplication();

private:
	CApsDeregisterNonNativeApplication(RFs& aFs, CApaAppArcServer& aServ, TUid aUid, TState aState);

private:
	void RenameToTemporaryL(TFileDetails& aFile, RApsUpdateLog& aUpdateLog);
	CApaAppData* FindAppDataLC(RApsUpdateLog& aUpdateLog);

	// from CApsNonNativeApplicationsUpdate
	void DoPerformUpdateL(RApsUpdateLog& aUpdateLog);
	void DoRollbackUpdate(RApsUpdateLog& aUpdateLog);
	void ExternalizeL(RWriteStream& aStream);
	void InternalizeL(RReadStream& aStream, TInt& aPosition);
	void InternalizeUpdateContinuationL(RReadStream& aStream, TInt& aPosition);
	void PostInternalizeL();

private:
	enum TLogContinuationType 
		{
		EInvalidContinuation = 0,
		EResourceFileUpdate,
		ELocalisableResourceFileUpdate,
		EIconFileUpdate
		};
	CApaAppArcServer& iServ;
	TFileDetails iResourceFile;
	TFileDetails iLocalisableResourceFile;
	TFileDetails iIconFile;
	};


#ifdef _DEBUG
/**
CApsAlwaysFailUpdate

A dummy CNonNativeApplicationsUpdate for testing purpouses.
Always fails with KErrGeneral when performed

@internalComponent
*/
NONSHARABLE_CLASS(CApsAlwaysFailUpdate) : public CApsNonNativeApplicationsUpdate
	{
public:
	CApsAlwaysFailUpdate(RFs& aFs, TState aState = ENew);
private:
	// from CApsNonNativeApplicationsUpdate
	void DoPerformUpdateL(RApsUpdateLog& aUpdateLog);
	void DoRollbackUpdate(RApsUpdateLog&) {}
	};


/**
CApsAlwaysPanicUpdate

A dummy CNonNativeApplicationsUpdate for testing purpouses.
Always panics when performed

@internalComponent
*/
NONSHARABLE_CLASS(CApsAlwaysPanicUpdate) : public CApsNonNativeApplicationsUpdate
	{
public:
	CApsAlwaysPanicUpdate(RFs& aFs, TState aState = ENew);
private:
	// from CApsNonNativeApplicationsUpdate
	void DoPerformUpdateL(RApsUpdateLog& aUpdateLog);
	void DoRollbackUpdate(RApsUpdateLog&) {}
	};


/**
CApsAlwaysPanicOnRollbackUpdate

A dummy CNonNativeApplicationsUpdate for testing purpouses.
Always panics upon rollback

@internalComponent
*/
NONSHARABLE_CLASS(CApsAlwaysPanicOnRollbackUpdate) : public CApsNonNativeApplicationsUpdate
	{
public:
	CApsAlwaysPanicOnRollbackUpdate(RFs& aFs, TState aState = ENew);
private:
	// from CApsNonNativeApplicationsUpdate
	void DoPerformUpdateL(RApsUpdateLog&) {}
	void DoRollbackUpdate(RApsUpdateLog& aUpdateLog);
	};
#endif // _DEBUG


#endif // APSNNAPPUPDATES_H