smartinstaller/adm/src/ADMInstallManager.cpp
branchADM
changeset 48 364021cecc90
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smartinstaller/adm/src/ADMInstallManager.cpp	Wed Jun 30 11:01:26 2010 +0530
@@ -0,0 +1,392 @@
+/*
+* Copyright (c) 2009-2010 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: 
+*     CInstallManager implementation
+*
+*
+*/
+
+
+#include <swi/swispubsubdefs.h>
+#include <swi/sisregistrysession.h>
+#include <swi/sisregistryentry.h>
+#include <swi/sisregistrypackage.h>
+#include <e32base.h>
+#include "ADMAppUi.h"
+#include "ADMInstallManager.h"
+
+#include "macros.h"
+#include "debug.h"
+
+class TSisInfo
+	{
+public:
+	TVersion iVersion;
+	TChar iInstalledDrive;
+	RArray<TUid> iSids;
+	};
+
+_LIT8(KMIME,"x-epoc/x-sisx-app");
+
+#ifdef USE_LOGFILE
+CInstallManager* CInstallManager::NewLC(MInstallClient* aInstallClient, RFileLogger& aLogger)
+	{
+	CInstallManager* object = new ( ELeave ) CInstallManager(aInstallClient, aLogger);
+	CleanupStack::PushL( object );
+	object->ConstructL();
+	return object;
+	}
+
+CInstallManager* CInstallManager::NewL(MInstallClient* aInstallClient, RFileLogger& aLogger)
+	{
+	CInstallManager* object = CInstallManager::NewLC(aInstallClient, aLogger);
+	CleanupStack::Pop();
+	return object;
+	}
+
+CInstallManager::CInstallManager(MInstallClient* aInstallClient, RFileLogger& aLogger) :
+	CActive(EPriorityStandard),
+	iLog(aLogger),
+	iInstallClient(aInstallClient)
+	{
+	CActiveScheduler::Add(this);
+	}
+#else
+CInstallManager* CInstallManager::NewLC(MInstallClient* aInstallClient)
+	{
+	CInstallManager* object = new ( ELeave ) CInstallManager(aInstallClient);
+	CleanupStack::PushL( object );
+	object->ConstructL();
+	return object;
+	}
+
+CInstallManager* CInstallManager::NewL(MInstallClient* aInstallClient)
+	{
+	CInstallManager* object = CInstallManager::NewLC(aInstallClient);
+	CleanupStack::Pop();
+	return object;
+	}
+
+CInstallManager::CInstallManager(MInstallClient* aInstallClient) :
+	CActive(EPriorityStandard),
+	iInstallClient(aInstallClient)
+	{
+	CActiveScheduler::Add(this);
+	}
+#endif
+
+CInstallManager::~CInstallManager()
+	{
+	Cancel();
+	iLauncher.Close();
+	DELETE_IF_NONNULL( iInstallFilename );
+	}
+
+void CInstallManager::RunL()
+	{
+	if ( ((iStatus.Int() == SwiUI::KSWInstErrBusy )||(iStatus.Int() == KErrInUse) || (iStatus.Int() == KErrServerBusy) ) &&
+			((++iInstallAttempt) <= KAttemptsToAccessInstaller) )
+		{
+		LOG( "CInstallManager: Installer busy, waiting" );
+		User::After( KIterationTimer );
+		// Start asynchronous silent installation again
+		if( !IsActive() )
+			{
+			SetActive();
+			}
+
+		iStatus = KRequestPending;
+
+		iLauncher.SilentInstall( iStatus, *iInstallFilename, iOptionsPckg );
+		}
+	else
+		{
+		LOG2( "CInstallManager: Install completed (%d)", iInstallAttempt );
+		iInstallClient->HandleInstallCompletedL( iStatus.Int() );
+		}
+	}
+
+void CInstallManager::DoCancel()
+	{
+	CancelInstallation();
+	CancelUninstallation();
+	}
+
+void CInstallManager::ConstructL()
+	{
+	User::LeaveIfError(iLauncher.Connect());
+	}
+
+TBool CInstallManager::IsPackagePresentL( const TUid& aUid )
+	{
+	TSisInfo sisInfo;
+	TBool isInstalled;
+
+	sisInfo = GetPackageInfoL(aUid, isInstalled);
+
+	return isInstalled;
+	}
+
+TBool CInstallManager::GetPackageSidsL(const TUid& aUid, RArray<TUid>& aSids)
+	{
+	TSisInfo sisInfo;
+	TBool isInstalled;
+
+	sisInfo = GetPackageInfoL(aUid, isInstalled);
+
+	if (isInstalled)
+		{
+		aSids = sisInfo.iSids;
+		}
+
+	return isInstalled;
+	}
+
+TBool CInstallManager::GetPackageInstalledDriveL(const TUid& aUid, TChar& aWrapperDrive)
+	{
+	TSisInfo sisInfo;
+	TBool isInstalled;
+
+	sisInfo = GetPackageInfoL(aUid, isInstalled);
+
+	if (isInstalled)
+		{
+		aWrapperDrive = sisInfo.iInstalledDrive;
+		}
+
+	return isInstalled;
+	}
+
+TBool CInstallManager::GetPackageVersionInfoL(const TUid& aUid, TVersion& aVersion)
+	{
+	TSisInfo sisInfo;
+	TBool isInstalled;
+
+	sisInfo = GetPackageInfoL(aUid, isInstalled);
+
+	if (isInstalled)
+		{
+		aVersion = sisInfo.iVersion;
+		}
+
+	return isInstalled;
+	}
+
+TSisInfo CInstallManager::GetPackageInfoL(const TUid& aUid, TBool& aIsPkgInstalled)
+	{
+	TSisInfo sisInfo;
+	// Connect to SisRegistry to fetch Package info
+	Swi::RSisRegistrySession registrySession;
+
+	User::LeaveIfError( registrySession.Connect() );
+	CleanupClosePushL(registrySession);
+
+	aIsPkgInstalled = registrySession.IsInstalledL( aUid );
+
+	if ( aIsPkgInstalled )
+		{
+		Swi::RSisRegistryEntry entry;
+
+		// Open registry entry to get version information.
+		User::LeaveIfError(entry.Open(registrySession, aUid));
+		CleanupClosePushL(entry);
+
+		// Get the data
+		sisInfo.iVersion = entry.VersionL();
+		sisInfo.iInstalledDrive = entry.SelectedDriveL();
+		entry.SidsL(sisInfo.iSids);
+
+		CleanupStack::PopAndDestroy(&entry);
+		}
+
+	CleanupStack::PopAndDestroy(&registrySession);
+
+	return sisInfo;
+	}
+
+void CInstallManager::SilentInstallPackageL(const TDesC& aInstallFilename, const TChar aInstallDrive)
+	{
+	LOG2( "+ SilentInstallPackage(): '%S'", &aInstallFilename );
+
+	DELETE_IF_NONNULL( iInstallFilename );
+	iInstallFilename = aInstallFilename.AllocL();
+	iInstallAttempt = 0;
+
+	SwiUI::TInstallOptions Options;
+
+	Options.iUpgrade = SwiUI::EPolicyAllowed;
+	Options.iOCSP    = SwiUI::EPolicyNotAllowed;
+	RFs::DriveToChar(aInstallDrive, Options.iDrive);
+	Options.iUntrusted = SwiUI::EPolicyNotAllowed;
+	Options.iCapabilities = SwiUI::EPolicyAllowed;
+	Options.iOverwrite = SwiUI::EPolicyAllowed;
+
+	iOptionsPckg = Options;
+
+	// We have to cancel any pending async request, because we might
+	// get called during installation (user cancel, for instance)
+	if (IsActive())
+		{
+		Cancel();
+		}
+
+	// Start asynchronous silent installation
+	iStatus = KRequestPending;
+	SetActive();
+	iLauncher.SilentInstall( iStatus, *iInstallFilename, iOptionsPckg);
+	}
+
+TInt CInstallManager::SilentUnInstallPackage(const TUid& aPkgUid)
+	{
+	TInt ret;
+
+	SwiUI::TUninstallOptions Options;
+	SwiUI::TUninstallOptionsPckg OptionsPckg;
+
+	// TODO: Missing iBreakDependency: Allowed or not?
+	Options.iBreakDependency = SwiUI::EPolicyAllowed;
+	Options.iKillApp = SwiUI::EPolicyAllowed;
+	OptionsPckg = Options;
+
+	// Start silent uninstallation
+	// If connection to Install server fails,
+	// make KAttemptsToAccessInstaller connection attempts
+	for (TInt i = 0; i < KAttemptsToAccessInstaller; i++)
+		{
+		// Silent Uninstallation
+		ret = iLauncher.SilentUninstall( aPkgUid, OptionsPckg, KMIME );
+
+		// SWI returns KErrInUse & KErrServerBusy as well.
+		// SwiUI errors are returned as is
+		if ( ret == SwiUI::KSWInstErrBusy ||
+			 ret == KErrInUse ||
+			 ret == KErrServerBusy)
+			{
+			LOG3( "Installer busy, retrying (%d: %d)", i, ret );
+			// Wait a while and then retry the uninstallation again
+			User::After( KIterationTimer );
+			}
+		else
+			{
+			break;
+			}
+		}
+
+	return ret;
+	}
+
+void CInstallManager::SilentUninstallPackageAsync(const TUid& aPkgUid)
+	{
+	SwiUI::TUninstallOptions options;
+
+	// TODO: Missing iBreakDependency: Allowed or not?
+	options.iBreakDependency = SwiUI::EPolicyAllowed;
+	options.iKillApp = SwiUI::EPolicyAllowed;
+	iUninstallOptionsPckg = options;
+
+	// We have to cancel any pending async request, because we might
+	// get called during uninstallation (user cancel, for instance)
+	if (IsActive())
+		{
+		Cancel();
+		}
+
+	// Start asynchronous silent uninstallation
+	iStatus = KRequestPending;
+	SetActive();
+	iLauncher.SilentUninstall( iStatus, aPkgUid, iUninstallOptionsPckg, KMIME );
+	}
+
+void CInstallManager::CancelAll()
+	{
+	Cancel();
+	CancelInstallation();
+	CancelUninstallation();
+	}
+
+TInt CInstallManager::CancelInstallation()
+	{
+	return iLauncher.CancelAsyncRequest(SwiUI::ERequestSilentInstall);
+	}
+
+TInt CInstallManager::CancelUninstallation()
+	{
+	return iLauncher.CancelAsyncRequest(SwiUI::ERequestSilentUninstall);
+	}
+
+TInt CInstallManager::InstallPackage(const TDesC& aInstallFilename)
+	{
+	LOG2( "+ InstallPackage(): '%S'", &aInstallFilename );
+
+	DELETE_IF_NONNULL( iInstallFilename );
+	iInstallFilename = aInstallFilename.AllocL();
+
+	TInt ret;
+	SwiUI::RSWInstLauncher Launcher;
+
+	ret = Launcher.Connect();
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+
+	// Start Installation
+	// If connection to Install server fails,
+	// make KAttemptsToAccessInstaller connection attempts
+	for (TInt i = 0; i < KAttemptsToAccessInstaller; i++)
+		{
+		// Normal installation
+		ret = Launcher.Install(*iInstallFilename);
+
+		// SWI returns KErrInUse & KErrServerBusy as well.
+		// SwiUI errors are returned as is
+		if ( ret == SwiUI::KSWInstErrBusy ||
+			 ret == KErrInUse ||
+			 ret == KErrServerBusy)
+			{
+			LOG3( "Installer busy, retrying (%d: %d)", i, ret );
+			// Wait a while and then retry the uninstallation again
+			User::After( KIterationTimer );
+			}
+		else
+			{
+			break;
+			}
+		}
+	Launcher.Close();
+	return ret;
+	}
+
+TUid CInstallManager::GetPackageUidL(const TUid& aSid)
+	{
+	// Connect to SisRegistry to fetch Package info
+	Swi::RSisRegistrySession registrySession;
+	User::LeaveIfError(registrySession.Connect());
+	CleanupClosePushL(registrySession);
+
+	Swi::CSisRegistryPackage* pkg = NULL;
+	pkg = registrySession.SidToPackageL(aSid);
+
+	CleanupStack::PopAndDestroy(&registrySession);
+
+	TUid uid = TUid::Uid(0);
+	if ( pkg )
+		{
+		uid = pkg->Uid();
+		}
+
+	delete pkg;
+
+	return uid;
+	}