common/tools/ats/smoketest/localisation/apparchitecture/apserv/apsnnapps.cpp
changeset 793 0c32c669a39d
child 872 17498133d9ad
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/tools/ats/smoketest/localisation/apparchitecture/apserv/apsnnapps.cpp	Fri Nov 27 12:22:12 2009 +0000
@@ -0,0 +1,733 @@
+// 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 the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Non-Native application registration functionality for the AppArc server session
+// 
+//
+
+
+#include "apsnnapps.h"
+
+#include <bautils.h>
+#include <f32file.h>
+#include <s32file.h>
+
+#include "APSCLSV.H"
+#include "APSSERV.H"
+#include "APSSTD.H"
+#include "../apgrfx/apprivate.h"
+#include "apsnnappupdates.h"
+
+/**
+KNonNativeApplicationsUpdateLog
+@internalComponent
+*/
+_LIT(KNonNativeApplicationsUpdateLog, ":\\private\\10003a3f\\UpdatedAppsList.bin");
+
+/**************************************************************************************************************
+ * CApsNonNativeApplicationsUpdateList
+ **************************************************************************************************************/
+
+CApsNonNativeApplicationsUpdateList* CApsNonNativeApplicationsUpdateList::NewL(RFs& aFs)
+	{
+	CApsNonNativeApplicationsUpdateList* self = new(ELeave) CApsNonNativeApplicationsUpdateList(aFs);
+	return self;
+	}
+
+void CApsNonNativeApplicationsUpdateList::RecoverFromUpdateLogL(RFs& aFs, RFile& aFile)
+	{
+	CleanupClosePushL(aFile);
+	CApsNonNativeApplicationsUpdateList* self = new(ELeave) CApsNonNativeApplicationsUpdateList(aFs);
+	CleanupStack::PushL(self);
+	self->RecoverFromUpdateLogL(aFile); // consumes aFile
+	CleanupStack::PopAndDestroy(self);
+	CleanupStack::Pop(&aFile);
+	}
+
+
+CApsNonNativeApplicationsUpdateList::CApsNonNativeApplicationsUpdateList(RFs& aFs) :
+		iFs(aFs)
+	{
+	}
+
+CApsNonNativeApplicationsUpdateList::~CApsNonNativeApplicationsUpdateList()
+	{
+	CApsNonNativeApplicationsUpdate* update = iUpdateListHead;
+	while(update != NULL)
+		{
+		CApsNonNativeApplicationsUpdate* next = update->Next();
+		delete update;
+		update = next;
+		}
+	}
+
+void CApsNonNativeApplicationsUpdateList::RecoverFromUpdateLogL(RFile& aFile)
+	{
+	RFileReadStream readStream;
+	CleanupClosePushL(readStream);
+	RFile logFileDupe;
+	User::LeaveIfError(logFileDupe.Duplicate(aFile));
+	readStream.Attach(logFileDupe); // Attach takes ownership of & Nulls the handle passed to it
+	TInt pos = 0;
+	InternalizeL(readStream,pos);
+	CleanupStack::PopAndDestroy(&readStream);
+
+	/* Great, we've read in all our performed updates and deleted all the ones that were fully
+	   rolled back.
+	   The next step is to roll back the rest of the updates. We'll need to create an
+	   update log as it was before the reboot, so that further rollbacks we successfully perform
+	   can also be logged in it */
+	
+	// pos should point to the end of the last compelte action recorded in the file
+	// remove any invalid or half-written actions by truncating to pos
+	User::LeaveIfError(aFile.SetSize(pos));
+	RApsUpdateLog updateLog(iFs);
+	updateLog.Open(aFile,pos); // consumes aFile
+	CleanupClosePushL(updateLog);
+
+	if(iEEndOfUpdateRequiredToFixLog)
+		{
+		updateLog.LogWriteStream().WriteInt8L(CApsNonNativeApplicationsUpdate::EEndOfUpdate);
+		updateLog.LogWriteStream().CommitL(); // puts us back to an alpha stopping point
+		}
+
+	if(iLogReplayCurrentUpdate != NULL)
+		{
+		switch(iLogReplayCurrentUpdate->iState)
+			{
+		case CApsNonNativeApplicationsUpdate::ENew:
+			/* current update was never performed. Start rollback at the previous one,
+			   which will be in EPerformed */
+			iLogReplayCurrentUpdate = iLogReplayCurrentUpdate->Previous();
+			ASSERT(iLogReplayCurrentUpdate == NULL || iLogReplayCurrentUpdate->iState == CApsNonNativeApplicationsUpdate::EPerformed);
+			break;
+		case CApsNonNativeApplicationsUpdate::EPerforming:
+		case CApsNonNativeApplicationsUpdate::EPerformed:
+		case CApsNonNativeApplicationsUpdate::ERollingBack:
+			break;
+		case CApsNonNativeApplicationsUpdate::ERolledBack:
+			User::Leave(KErrCorrupt);
+			break;
+			}
+		Rollback(iLogReplayCurrentUpdate, updateLog);
+		}
+	CleanupStack::PopAndDestroy(&updateLog);
+	}
+
+void CApsNonNativeApplicationsUpdateList::InternalizeL(RReadStream& aStream, TInt& aPosition)
+	{
+	TInt err = KErrNone;
+	while(err == KErrNone)
+		{
+		TRAP(err,InternalizeActionL(aStream,aPosition));
+		if(err == KErrNone || err == KErrCorrupt || err == KErrEof)
+			{
+			// We anticipate that the last update we try to read may be incomplete or corrupt.
+			// if we get either of these, jsut stop reading in the list of updates.
+			}
+		else
+			{
+			// something really unexpected, e.g. KErrNoMemory
+			User::Leave(err);
+			}
+		}
+	CApsNonNativeApplicationsUpdate* update = iUpdateListHead;
+	while(update) 
+		{
+		update->PostInternalizeL();
+		update = update->Next();
+		}
+	}
+
+void CApsNonNativeApplicationsUpdateList::InternalizeActionL(RReadStream& aStream, TInt& aPosition)
+	{
+	TInt pos = aPosition;
+
+	CApsNonNativeApplicationsUpdate::TLogActionType action =
+		static_cast<CApsNonNativeApplicationsUpdate::TLogActionType>(aStream.ReadInt8L());
+	CApsNonNativeApplicationsUpdate::TLogUpdateType type =
+		static_cast<CApsNonNativeApplicationsUpdate::TLogUpdateType>(aStream.ReadInt8L());
+	TUid appUid;
+	appUid.iUid = aStream.ReadInt32L();
+	pos += sizeof(TInt8) + sizeof(TInt8) + sizeof(TUint32);
+
+	switch(action)
+		{
+	case CApsNonNativeApplicationsUpdate::ENewUpdate:
+		// for ENewUpdate, this is not a valid stopping point,
+		// so we don't want to change aPosition unless it completes successfully.
+		InternalizeNewUpdateL(aStream, pos, type, appUid);
+		aPosition = pos;
+		break;
+	case CApsNonNativeApplicationsUpdate::EPerformUpdate:
+		// for EPerformUpdate, this is a beta stopping point, and
+		// InternalizePerformUpdateL will only ever update aPosition to
+		// another stopping point, so we can give it the real aPosition.
+		// Since it's a beta stopping point, we need to set iEEndofUpdateRequiredToFixLog
+		iEEndOfUpdateRequiredToFixLog = ETrue;
+		aPosition = pos;
+		InternalizePerformUpdateL(aStream, aPosition, type, appUid);
+		iEEndOfUpdateRequiredToFixLog = EFalse;
+		break;
+	case CApsNonNativeApplicationsUpdate::ERollbackUpdate:
+		// this action has the same behaviour as EPerformUpdate
+		iEEndOfUpdateRequiredToFixLog = ETrue;
+		aPosition = pos;
+		InternalizeRollbackUpdateL(aStream, aPosition, type, appUid);
+		iEEndOfUpdateRequiredToFixLog = EFalse;
+		break;
+	default:
+		User::Leave(KErrCorrupt);
+		break;
+		}
+	}
+
+void CApsNonNativeApplicationsUpdateList::InternalizeNewUpdateL(RReadStream& aStream, TInt& aPosition, CApsNonNativeApplicationsUpdate::TLogUpdateType aType, TUid aUid)
+	{
+	// check that this is the first update or the previous update was performed completely
+	if(iLogReplayCurrentUpdate !=  NULL && (iLogReplayCurrentUpdate->iState != CApsNonNativeApplicationsUpdate::EPerformed || iLogReplayCurrentUpdate->Next() != NULL))
+		{
+		User::Leave(KErrCorrupt);
+		}
+
+	/*
+	 create the update object, depending on type
+	 */
+	CApsNonNativeApplicationsUpdate* update = NULL;
+	switch(aType) 
+		{
+	case CApsNonNativeApplicationsUpdate::ERegisterApplication:
+		update = CApsRegisterNonNativeApplication::NewL(iFs, aUid, TDriveName(), CApsNonNativeApplicationsUpdate::ENeedsInternalizing);
+		break;
+	case CApsNonNativeApplicationsUpdate::EDeregisterApplication:
+		update = CApsDeregisterNonNativeApplication::NewL(iFs, *CApaAppListServer::Self(), aUid, CApsNonNativeApplicationsUpdate::ENeedsInternalizing);
+		break;
+#ifdef _DEBUG
+	case CApsNonNativeApplicationsUpdate::EFail:
+		update = new(ELeave) CApsAlwaysFailUpdate(iFs, CApsNonNativeApplicationsUpdate::ENeedsInternalizing);
+		break;
+	case CApsNonNativeApplicationsUpdate::EPanic:
+		update = new(ELeave) CApsAlwaysPanicUpdate(iFs, CApsNonNativeApplicationsUpdate::ENeedsInternalizing);
+		break;
+	case CApsNonNativeApplicationsUpdate::ERollbackPanic:
+		update = new(ELeave) CApsAlwaysPanicOnRollbackUpdate(iFs, CApsNonNativeApplicationsUpdate::ENeedsInternalizing);
+		break;
+#endif
+	default:
+		User::Leave(KErrCorrupt);
+		break;
+		}
+	CleanupStack::PushL(update);
+	update->InternalizeNewUpdateL(aStream, aPosition);
+	CleanupStack::Pop(update);
+	/* alpha stopping point.
+	   update->iState should be ENew now.
+	 */
+	Append(update);
+	iLogReplayCurrentUpdate = update;
+	}
+
+void CApsNonNativeApplicationsUpdateList::InternalizePerformUpdateL(RReadStream& aStream, TInt& aPosition, CApsNonNativeApplicationsUpdate::TLogUpdateType aType, TUid aUid)
+	{
+	if(iLogReplayCurrentUpdate == NULL || iLogReplayCurrentUpdate->iState != CApsNonNativeApplicationsUpdate::ENew)
+		{
+		User::Leave(KErrCorrupt);
+		}
+	if(iLogReplayCurrentUpdate->Uid() != aUid || iLogReplayCurrentUpdate->iType != aType)
+		{
+		User::Leave(KErrCorrupt);
+		}
+	/*
+	 tell the update to read in its log
+	 */
+	iLogReplayCurrentUpdate->InternalizePerformUpdateL(aStream, aPosition);
+	// the function above will return iff EEndOfUpdate is reached
+	}
+
+
+void CApsNonNativeApplicationsUpdateList::InternalizeRollbackUpdateL(RReadStream& aStream, TInt& aPosition, CApsNonNativeApplicationsUpdate::TLogUpdateType aType, TUid aUid)
+	{
+	if(iLogReplayCurrentUpdate == NULL)
+		{
+		User::Leave(KErrCorrupt);
+		}
+	if( iLogReplayCurrentUpdate->iState != CApsNonNativeApplicationsUpdate::EPerforming
+	 && iLogReplayCurrentUpdate->iState != CApsNonNativeApplicationsUpdate::EPerformed
+	 && iLogReplayCurrentUpdate->iState != CApsNonNativeApplicationsUpdate::ERollingBack)
+		{
+		User::Leave(KErrCorrupt);
+		}
+	if(iLogReplayCurrentUpdate->iType != aType || iLogReplayCurrentUpdate->Uid() != aUid)
+		{
+		User::Leave(KErrCorrupt);
+		}
+	
+	iLogReplayCurrentUpdate->InternalizeRollbackUpdateL(aStream, aPosition);
+	// the function above will return iff EEndOfUpdate is reached
+
+	if(iLogReplayCurrentUpdate->iState == CApsNonNativeApplicationsUpdate::ERolledBack)
+		{
+		iLogReplayCurrentUpdate = iLogReplayCurrentUpdate->Previous();
+		}
+	}
+
+void CApsNonNativeApplicationsUpdateList::Append(CApsNonNativeApplicationsUpdate* aUpdate)
+	{
+	if(iUpdateListHead == NULL)
+		{
+		iUpdateListHead = aUpdate;
+		return;
+		}
+
+	CApsNonNativeApplicationsUpdate* update = iUpdateListHead;
+	while(update->iNext != NULL)
+		{
+		update = update->iNext;
+		}
+	update->iNext = aUpdate;
+	aUpdate->iPrevious = update;
+	}
+
+void CApsNonNativeApplicationsUpdateList::ExecuteL()
+	{
+	RApsUpdateLog updateLog(iFs);
+	updateLog.OpenL();
+	CleanupClosePushL(updateLog);
+	CApsNonNativeApplicationsUpdate* update = iUpdateListHead;
+	while(update != NULL)
+		{
+		TRAPD(err,update->PerformUpdateL(updateLog));
+		if(err == KErrNone)
+			{
+			update = update->Next();
+			}
+		else
+			{
+			// call rollback on everything, including the one that failed
+			// since it may have to clean up half-finished stuff
+			Rollback(update, updateLog);
+			User::Leave(err);
+			}
+		}
+	CleanupStack::PopAndDestroy(&updateLog);
+	}
+
+void CApsNonNativeApplicationsUpdateList::Rollback(CApsNonNativeApplicationsUpdate* aStartPoint, RApsUpdateLog& aUpdateLog)
+	{
+	CApsNonNativeApplicationsUpdate* update = aStartPoint;
+
+	while(update != NULL)
+		{
+		TRAP_IGNORE(update->RollbackUpdateL(aUpdateLog));
+		update = update->Previous();
+		}
+	}
+
+/**
+@internalComponent
+*/
+RApsUpdateLog::RApsUpdateLog(RFs& aFs) :
+		iFs(aFs)
+	{
+	TChar drive = RFs::GetSystemDriveChar();
+	iLogFileName.Append(drive);
+	iLogFileName.Append(KNonNativeApplicationsUpdateLog);
+	}
+
+/**
+RApsUpdateLog::OpenL
+
+Opens a write stream to a log file that keeps track of what updates have been performed.
+
+@internalComponent
+*/
+void RApsUpdateLog::OpenL()
+	{
+	User::LeaveIfError(iLogWriteStream.Replace(iFs,iLogFileName,EFileShareExclusive|EFileStream|EFileWrite));
+	}
+
+/**
+RApsUpdateLog::Open
+
+Opens a write stream to a log file that keeps track of what updates have been performed.
+
+@internalComponent
+*/
+void RApsUpdateLog::Open(RFile& aFile, TUint aSeekPos)
+	{
+	iLogWriteStream.Attach(aFile, aSeekPos);
+	}
+
+/**
+RApsUpdateLog::Close
+
+Cleans up the list of new Registration files created during this set of updates
+and deletes the log files created.
+
+@internalComponent
+*/
+void RApsUpdateLog::Close()
+	{
+	_LIT(KLitPathForTemporaryFiles, "\\private\\10003a3f\\temp\\");
+	const TInt count = iDrivesAffected.Count();
+	CFileMan* fileman = NULL;
+	TRAPD(err, fileman = CFileMan::NewL(iFs));
+	if (err == KErrNone) 
+		{
+		for(TInt i = 0; i < count; ++i)
+			{
+			TFileName dir(*(iDrivesAffected[i]));
+			dir.Append(KLitPathForTemporaryNonNativeResourceAndIconFiles);
+			fileman->RmDir(dir); // recursive
+			iFs.RmDir(KLitPathForTemporaryFiles); // non-recursive
+			}
+		delete fileman;
+		}
+	
+	iFilesRegistered.ResetAndDestroy();
+	iDrivesAffected.ResetAndDestroy();
+	iLogWriteStream.Close();
+	iFs.Delete(iLogFileName);
+	}
+
+
+/**
+CApsNonNativeApplicationsUpdateList::RApsUpdateLog holds a list of registration files that have
+been written during this transaction. This list is used by the Deregistration
+command as the forced-updates list.
+
+This stops them from being incorrectly hidden from the scan performed to find
+the registration file to delete.
+
+@internalComponent
+*/
+RPointerArray<HBufC>& RApsUpdateLog::NewRegistrationFiles()
+	{
+	return iFilesRegistered;
+	}
+
+
+/**
+CApsNonNativeApplicationsUpdateList::RApsUpdateLog holds a list of drives that have been used
+in the transaction. This is then used to clean up the temporary file directories
+
+@internalComponent
+*/
+RPointerArray<HBufC>& RApsUpdateLog::DrivesAffected()
+	{
+	return iDrivesAffected;
+	}
+
+/**
+Returns the stream that updates should write their recovery log data to
+@internalComponent
+*/
+RWriteStream& RApsUpdateLog::LogWriteStream()
+	{
+	return iLogWriteStream;
+	}
+
+/**************************************************************************************************************
+ * CApsNonNativeApplicationsManager
+ **************************************************************************************************************/
+
+void CApsNonNativeApplicationsManager::NotifyScanComplete()
+	{
+	//See if the session is intrested in scan complete notification.
+	if (!iNotifyOnScanCompleteMsg.IsNull())
+		{
+		iNotifyOnScanCompleteMsg.Complete(KErrNone);
+		}
+	} //lint !e1762 Suppress member function could be made const
+
+
+CApsNonNativeApplicationsManager* CApsNonNativeApplicationsManager::NewL(CApaAppListServer& aServ, RFs& aFs)
+	{
+	CApsNonNativeApplicationsManager* self = new(ELeave)CApsNonNativeApplicationsManager(aServ, aFs);
+	return self;
+	}
+
+CApsNonNativeApplicationsManager::~CApsNonNativeApplicationsManager()
+	{
+	delete iUpdateList;
+	}
+
+CApsNonNativeApplicationsManager::CApsNonNativeApplicationsManager(CApaAppListServer& aServ, RFs& aFs) :
+		iServ(aServ),
+		iFs(aFs)
+	{
+	}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void CApsNonNativeApplicationsManager::PrepareNonNativeApplicationsUpdatesL()
+	{
+	if (iServ.AppList().AppScanInProgress())
+		{
+		iServ.AppList().StopScan(ETrue); //Stop updating applist now, we anyways have to update it when we are commiting these changes
+		}
+	if (iNonNativeApplicationsUpdateAppsLock) 
+		{
+		User::Leave(KErrInUse);
+		}
+
+	ASSERT(iUpdateList == NULL);
+	
+	iUpdateList = CApsNonNativeApplicationsUpdateList::NewL(iFs);
+	iNonNativeApplicationsUpdateAppsLock = ETrue;
+	}
+
+
+void CApsNonNativeApplicationsManager::CheckForUpdateAppsLockL()
+	{
+	if (!iNonNativeApplicationsUpdateAppsLock)
+		{
+		// PrepareNonNativeApplicationsUpdatesL hasn't been called successfully
+		User::Leave(KErrNotReady);
+		}	
+	}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ 
+ void CApsNonNativeApplicationsManager::RegisterNonNativeApplicationL(const RMessage2& aMessage)
+	{
+	CheckForUpdateAppsLockL();
+	CleanupStack::PushL(TCleanupItem(&StaticAbortNonNativeApplicationsUpdates,this));
+	DoRegisterNonNativeApplicationL(aMessage);
+	CleanupStack::Pop(this);
+	}
+
+
+void CApsNonNativeApplicationsManager::DoRegisterNonNativeApplicationL(const RMessage2& aMessage)
+	{
+	// an RBuf for creating the file names in.
+	// create it here so it's below ipcParameter0 on the cleanup stack
+	RBuf target;
+	CleanupClosePushL(target);
+
+	// read in the resource file from aMessage
+	RBuf8 ipcParameter0(HBufC8::NewL(aMessage.GetDesLengthL(0)));
+	CleanupClosePushL(ipcParameter0);
+	aMessage.ReadL(0, ipcParameter0);
+	if (ipcParameter0.Length()<=sizeof(SNonNativeApplicationInfo)+sizeof(TCheckedUid))
+		{
+		User::Leave(KErrArgument);
+		}
+
+	// get drivename
+	const SNonNativeApplicationInfo nonNativeApplicationInfo = *reinterpret_cast<const SNonNativeApplicationInfo*>(ipcParameter0.Ptr());
+	TDriveName driveName = TDriveUnit(nonNativeApplicationInfo.iDrive).Name();
+
+	// get uid
+	const TUid applicationUid(TCheckedUid(ipcParameter0.Mid(sizeof(SNonNativeApplicationInfo), sizeof(TCheckedUid))).UidType()[2]);
+	if (applicationUid==TUid::Null())
+		{
+		User::Leave(KErrArgument);
+		}
+
+	// construct resource file name
+	target.CreateL(driveName, KMaxFileName);
+	target.Append(KLitPathForNonNativeResourceAndIconFiles);
+	const TInt startOfFileName=target.Length(); // take note of this so we can chop off the file name later
+	target.AppendFormat(KLitFormatForRegistrationResourceFile, applicationUid.iUid);
+
+	// prepare registrationResourceFileDataPrefix
+	const TUidType uidPrefix(TUid::Uid(KUidPrefixedNonNativeRegistrationResourceFile), nonNativeApplicationInfo.iApplicationType, applicationUid);
+	const TBufC8<sizeof(TCheckedUid)> registrationResourceFileDataPrefix(TCheckedUid(uidPrefix).Des());
+
+	// create the object that will actually perform the update
+	CApsRegisterNonNativeApplication* updateObject = CApsRegisterNonNativeApplication::NewL(iFs, applicationUid, driveName);
+	CleanupStack::PushL(updateObject);
+
+	// write resource file to temp location
+	updateObject->SetResourceFileTargetLocation(target);
+	updateObject->WriteResourceFileL(ipcParameter0.Mid(sizeof(SNonNativeApplicationInfo)), &registrationResourceFileDataPrefix);
+	
+	if (aMessage.Int1()!=0) // if there is a localisable resource-file
+		{
+		RBuf8 ipcParameter1(HBufC8::NewL(User::LeaveIfError(aMessage.GetDesLength(1))));
+		CleanupClosePushL(ipcParameter1);
+		aMessage.ReadL(1, ipcParameter1);
+		
+		// construct localisable resoure file name
+		target.SetLength(startOfFileName);
+		target.AppendFormat(KLitFormatForLocalisableResourceFile, applicationUid.iUid);
+
+		updateObject->SetLocalisableResourceFileTargetLocation(target);
+		// write localisable resource file to temp location
+		updateObject->WriteLocalisableResourceFileL(ipcParameter1, NULL);
+		CleanupStack::PopAndDestroy(&ipcParameter1);
+
+		if (aMessage.Int2()!=0) // if there is an icon-file
+			{
+			RFile iconFile;
+			CleanupClosePushL(iconFile);
+			User::LeaveIfError(iconFile.AdoptFromClient(aMessage, 2, 3));
+			RBuf iconFileName;
+			CleanupClosePushL(iconFileName);
+			iconFileName.CreateL(KMaxFileName);
+			User::LeaveIfError(iconFile.Name(iconFileName));
+
+			if (startOfFileName+iconFileName.Length()>KMaxFileName)
+				{
+				User::Leave(KErrArgument);
+				}
+			target.SetLength(startOfFileName);
+			target.Append(iconFileName);
+			updateObject->SetIconFileTargetLocation(target);
+			updateObject->CopyIconFileL(iconFile);
+
+			CleanupStack::PopAndDestroy(2, &iconFile); // iconFileName, iconFile
+			}
+		}
+
+	CleanupStack::Pop(updateObject);
+	iUpdateList->Append(updateObject);
+
+	CleanupStack::PopAndDestroy(2, &target); // ipcParameter0, target
+	}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ 
+void CApsNonNativeApplicationsManager::DeregisterNonNativeApplicationL(const RMessage2& aMessage)
+	{
+	CheckForUpdateAppsLockL();
+	CleanupStack::PushL(TCleanupItem(&StaticAbortNonNativeApplicationsUpdates,this));
+	const TUid applicationUid(TUid::Uid(aMessage.Int0()));
+	iUpdateList->Append(CApsDeregisterNonNativeApplication::NewL(iFs, iServ, applicationUid));
+	CleanupStack::Pop(this);
+	}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef _DEBUG
+void CApsNonNativeApplicationsManager::ForceFailInNonNativeApplicationsUpdatesL()
+	{
+	CheckForUpdateAppsLockL();
+	CleanupStack::PushL(TCleanupItem(&StaticAbortNonNativeApplicationsUpdates,this));
+	iUpdateList->Append(new(ELeave) CApsAlwaysFailUpdate(iFs));
+	CleanupStack::Pop(this);
+	}
+
+void CApsNonNativeApplicationsManager::ForcePanicInNonNativeApplicationsUpdatesL()
+	{
+	CheckForUpdateAppsLockL();
+	CleanupStack::PushL(TCleanupItem(&StaticAbortNonNativeApplicationsUpdates,this));
+	iUpdateList->Append(new(ELeave) CApsAlwaysPanicUpdate(iFs));
+	CleanupStack::Pop(this);
+	}
+
+void CApsNonNativeApplicationsManager::ForcePanicInNonNativeApplicationsRollbackL()
+	{
+	CheckForUpdateAppsLockL();
+	CleanupStack::PushL(TCleanupItem(&StaticAbortNonNativeApplicationsUpdates,this));
+	iUpdateList->Append(new(ELeave) CApsAlwaysPanicOnRollbackUpdate(iFs));
+	CleanupStack::Pop(this);
+	}
+
+#endif // _DEBUG
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void CApsNonNativeApplicationsManager::CommitNonNativeApplicationsUpdatesL(const RMessage2& aMessage)
+	{
+	CheckForUpdateAppsLockL();
+
+	TRAPD(err,iUpdateList->ExecuteL());
+
+	// Failure or success, we can't be hanging on to the lock after this function completes
+	delete iUpdateList;
+	iUpdateList = NULL;
+	iNonNativeApplicationsUpdateAppsLock = EFalse;
+	
+	if (KErrNone != err)
+		{
+		if(iServ.AppList().AppListUpdatePending())
+			{
+			// Trigger a rescan
+			iServ.UpdateApps();	
+			}
+		User::Leave(err); // bail out at this point if things didn't go to plan
+		}
+	
+	if(aMessage.Int0()==(TInt) ETrue)	
+		//The request is completed without waiting till completion application list preparation. 
+		aMessage.Complete(KErrNone); 
+	else	
+		//The request is not completed till completion application list preparation.		
+		iNotifyOnScanCompleteMsg=aMessage;
+	
+	// Trigger a rescan
+	iServ.UpdateApps();
+	}
+
+/**
+This function has the word "Rollback" in it because it used to actually roll back the
+updates that had been preformed but whose effects were hidden from the public APIs until commit.
+
+The real updates no longer happen until commit-time, so there's no real rolling back to be done here.
+The real rolling back is done automatically by iUpdateList, during the commit call, if neccessary.
+*/
+void CApsNonNativeApplicationsManager::RollbackNonNativeApplicationsUpdates()
+	{
+	AbortNonNativeApplicationsUpdates();
+	}
+
+void CApsNonNativeApplicationsManager::AbortNonNativeApplicationsUpdates()
+	{
+	if (!iNonNativeApplicationsUpdateAppsLock)
+		{
+		// It is always ok to call this function but if we haven't called PrepareNonNativeApplicationsUpdatesL()
+		// there isn't anything to do
+		return;
+		}
+	if(iServ.AppList().AppListUpdatePending())
+		{
+		// Trigger a rescan
+		iServ.UpdateApps();	
+		}
+	delete iUpdateList;
+	iUpdateList = NULL;
+	iNonNativeApplicationsUpdateAppsLock = EFalse;
+	}
+
+void CApsNonNativeApplicationsManager::StaticAbortNonNativeApplicationsUpdates(TAny* aSelf)
+	{
+	static_cast<CApsNonNativeApplicationsManager*>(aSelf)->AbortNonNativeApplicationsUpdates();
+	}
+
+void CApsNonNativeApplicationsManager::RecoverFromUpdateLogL(RFs& aFs)
+	{
+	TChar drive = RFs::GetSystemDriveChar();
+	TFileName logPath;
+	logPath.Append(drive);
+	logPath.Append(KNonNativeApplicationsUpdateLog);
+	RFile logFile;
+	TInt err = logFile.Open(aFs,logPath,EFileShareExclusive|EFileStream|EFileWrite);
+	if(err == KErrNotFound || err == KErrPathNotFound)
+		{
+		// no log file, nothing to do.
+		return;
+		}
+	User::LeaveIfError(err);
+	// this function takes over ownership of logFile
+	TRAP(err,CApsNonNativeApplicationsUpdateList::RecoverFromUpdateLogL(aFs, logFile));
+	if(err != KErrNone)
+		{
+		// there's nothing we can do, just delete it and move on
+		aFs.Delete(logPath);
+		}
+	
+	}