diff -r 5cc91383ab1e -r 7333d7932ef7 installationservices/swi/source/daemon/daemonbehaviour.cpp --- a/installationservices/swi/source/daemon/daemonbehaviour.cpp Thu Aug 19 10:02:49 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,435 +0,0 @@ -/* -* Copyright (c) 2004-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 "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: -* -*/ - - -#include "daemonbehaviour.h" -#include "swispubsubdefs.h" -#include "recsisx.h" -#include "sisregistrywritablesession.h" -#include "sisregistryentry.h" -#include "filesisdataprovider.h" -#include "swi/sisparser.h" -#include "swi/siscontents.h" -#include "swi/siscontroller.h" -#include "sisinfo.h" -#include "cleanuputils.h" -#include "sisregistrypackage.h" -#include "log.h" - -void ScanDirectoryL(TInt aDrive); - -using namespace Swi; - -CDaemonBehaviour* CDaemonBehaviour::NewL() - { - CDaemonBehaviour* self = NewLC(); - CleanupStack::Pop(self); - return self; - } - -CDaemonBehaviour* CDaemonBehaviour::NewLC() - { - CDaemonBehaviour* self = new (ELeave) CDaemonBehaviour; - CleanupStack::PushL(self); - self->ConstructL(); - return self; - } - -void CDaemonBehaviour::ConstructL() - { - User::LeaveIfError(iFs.Connect()); - User::LeaveIfError(iFs.ShareProtected()); - User::LeaveIfError(iApaSession.Connect()); - iSisInstaller = CSisInstaller::NewL(this); - TRAP_IGNORE(iSwiDaemonPlugin = CSwiDaemonPlugin::NewL()); - } - -CDaemonBehaviour::~CDaemonBehaviour() - { - if(iSwiDaemonPlugin) - { - delete iSwiDaemonPlugin; - REComSession::FinalClose(); - } - delete iSisInstaller; - iFs.Close(); - iApaSession.Close(); - } - - // from MDaemonBehaviour -TBool CDaemonBehaviour::StartupL() - { - // Return state of Startup - return ETrue; - } - -void CDaemonBehaviour::MediaChangeL(TInt aDrive, TChangeType aChangeType) - { - DEBUG_PRINTF3(_L8("SWI Daemon - Media change detected. Drive: %d, Change Type: %d."), - aDrive, aChangeType); - - RSisRegistryWritableSession registrySession; - - User::LeaveIfError(registrySession.Connect()); - CleanupClosePushL(registrySession); - - if (aChangeType==EMediaInserted) - { - // notify IAR - registrySession.AddDriveL(aDrive); - - // Scan directory on the card and run pre-installed through SWIS - // nb. will leave if no SIS files to install. - ProcessPreinstalledFilesL(aDrive); - } - else if (aChangeType==EMediaRemoved) - { - // Cancel all requests for install - iSisInstaller->Reset(); - - // Notify plugin - if(iSwiDaemonPlugin) - { - iSwiDaemonPlugin->MediaRemoved(aDrive); - } - -#ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK - // notify IAR - registrySession.RemoveDriveL(aDrive); -#endif - } - CleanupStack::PopAndDestroy(®istrySession); - } - -void CDaemonBehaviour::ProcessPreinstalledFilesL(TInt aDrive) - { - _LIT(KDaemonPrivatePath,":\\private\\10202dce\\"); - - iSisInstaller->Reset(); - ProcessPreinstalledFilesL(aDrive, KDaemonPrivatePath); - iStartNotified = EFalse; - iDrive = aDrive; - iSisInstaller->StartInstallingL(); - } - -void CDaemonBehaviour::ProcessPreinstalledFilesL(TInt aDrive, const TDesC& aDirectory) - { - TPath preInstalledPath; - TChar drive; - RFs::DriveToChar(aDrive, drive); - preInstalledPath.Append(drive); - preInstalledPath.Append(aDirectory); - - CDir* dir = NULL; - TInt err = iFs.GetDir(preInstalledPath, KEntryAttNormal, ESortByName, dir); - if (err != KErrNone && err != KErrPathNotFound) - { - User::Leave(err); - } - if(dir) - { - // dir will only exist if GetDir succeeded - CleanupStack::PushL(dir); - for(TInt i = 0; i < dir->Count(); i++) - { - const TEntry &entry = (*dir)[i]; - if(!entry.IsDir()) - { - TFileName fileName(preInstalledPath); - fileName.Append(entry.iName); - iSisInstaller->AddFileToInstallL(fileName); - } - } - CleanupStack::PopAndDestroy(dir); - } - } - - -// From MDaemonInstallBehaviour - -MDaemonInstallBehaviour::TSisInstallState CDaemonBehaviour::VerifyAppCacheListL() - { - MDaemonInstallBehaviour::TSisInstallState returnState = MDaemonInstallBehaviour::EStateVerifyAppCacheList; - - // What is really desired is notification that the Application Architecture cached List - // is valid, but as this cannot be done simply. - // Is is simulated by a call to two member functions. - - TApaAppInfo appInfo; - User::LeaveIfError(iApaSession.GetAllApps()); - TInt err(iApaSession.GetNextApp(appInfo)); // Call member function that can report an EAppListInvalid - - if (err == RApaLsSession::EAppListInvalid) - { - returnState = MDaemonInstallBehaviour::EStateVerifyAppCacheList; - } - else if (err == KErrNone) // cached list of apps is ready - { - returnState = MDaemonInstallBehaviour::EStateVerifySwisProperty; - } - else - { - User::Leave(err); - } - return returnState; - } - -MDaemonInstallBehaviour::TSisInstallState CDaemonBehaviour::VerifySwisPropertyL() - { - MDaemonInstallBehaviour::TSisInstallState returnState = MDaemonInstallBehaviour::EStateVerifySwisProperty; - TInt swisState; - TInt err(RProperty::Get(KUidSystemCategory,KUidSoftwareInstallKey,swisState)); - - if (err == KErrNotFound) - { - returnState = (MDaemonInstallBehaviour::EStateInstall); - } - else if (err == KErrNone) - { - if (swisState == ESwisNone) - { - // SWIS is idle - returnState = (MDaemonInstallBehaviour::EStateInstall); - } - else - { - // SWIS is performing an operation - returnState = (MDaemonInstallBehaviour::EStateVerifySwisIdle); - } - } - else - { - User::Leave(err); - } - return returnState; - } - -MDaemonInstallBehaviour::TSisInstallState CDaemonBehaviour::VerifySwisIdleL() - { - MDaemonInstallBehaviour::TSisInstallState returnState = MDaemonInstallBehaviour::EStateVerifySwisIdle; - TInt swisState; - - // Obtain the state of the software installer - User::LeaveIfError(RProperty::Get(KUidSystemCategory,KUidSoftwareInstallKey,swisState)); - - if (swisState == ESwisNone) // Swis is idle - { - returnState = (MDaemonInstallBehaviour::EStateInstall); - } - else // Software installer is currently installing/uinstalling - { - returnState = (MDaemonInstallBehaviour::EStateVerifySwisIdle); - } - return returnState; - } - -void CDaemonBehaviour::ReadSymbianHeaderL(RFile& aFile, TUid& aUid1, TUid& aUid2, TUid& aUid3) - { - - TInt uidLen = sizeof(TInt32); - - TPckg uid1(aUid1.iUid); - User::LeaveIfError(aFile.Read(uid1, uidLen)); - if (uid1.Length() != uidLen) - { - User::Leave(KErrUnderflow); - } - - TPckg uid2(aUid2.iUid); - User::LeaveIfError(aFile.Read(uid2, uidLen)); - if (uid1.Length() != uidLen) - { - User::Leave(KErrUnderflow); - } - - TPckg uid3(aUid3.iUid); - User::LeaveIfError(aFile.Read(uid3, uidLen)); - if (uid1.Length() != uidLen) - { - User::Leave(KErrUnderflow); - } - - } - -void CDaemonBehaviour::DoInstallRequestL(const TDesC& aFileName) - { - DEBUG_PRINTF2(_L("SWI Daemon - Processing presinstalled SIS file '%S'"), - &aFileName); - - TUid appUid; - TDataType dataType; - - User::LeaveIfError(iFs.ShareProtected()); - - // have to pass the file using the file handle - // otherwise SisHelper won't be able to read the - // daemon private directory - RFile file; - User::LeaveIfError(file.Open(iFs, aFileName, EFileRead | EFileStream | EFileShareReadersOnly)); - CleanupClosePushL(file); - User::LeaveIfError(iApaSession.AppForDocument(file,appUid,dataType)); - - // Start installing the file only if it is a sisx file - if (dataType.Des8() == KDataTypeSisx) - { - - // Check if this is already installed, by extracting the package UID and - // asking the registry. - - TUid uid1, uid2, uid3; - ReadSymbianHeaderL(file, uid1, uid2, uid3); - - - // UID 3 will be the package UID, query the registry about it. - RSisRegistrySession session; - User::LeaveIfError(session.Connect()); - CleanupClosePushL(session); - - // temporary work around while we decide what IsInstalled should be policed by. - - RSisRegistryEntry entry; - TInt entryOpenResult = entry.Open(session, uid3); - CleanupClosePushL(entry); - - // Get the types and other details from the stub - CFileSisDataProvider* fileProvider = CFileSisDataProvider::NewLC(iFs, aFileName, EFileRead | EFileShareReadersOnly); - TInt64 pos( 0 ); - fileProvider->Seek( ESeekStart, pos ); - Swi::Sis::CContents* content = Swi::Sis::Parser::ContentsL(*fileProvider); - CleanupStack::PushL( content ); - HBufC8* controllerdata = content->ReadControllerL(); - CleanupStack::PushL( controllerdata ); - TPtrProvider provider(controllerdata->Des()); - Sis::CController *siscontroller = Swi::Sis::CController::NewLC(provider); - - switch(siscontroller->Info().InstallType()) - { - /* For SA/PA, If UID is found in registry, Don't install otherwise Install */ - case EInstInstallation: - case EInstPreInstalledApp: - { - if(entryOpenResult != KErrNone) - { - DoInstallL(file,appUid); - } - - break; - } - /* - For PP/SP, If patch name is found already in registry, Don't install - otherwise Install - */ - case EInstPreInstalledPatch: - case EInstAugmentation: - { - TBool shouldInstall = ETrue; - const RPointerArray& names = siscontroller->Info().Names(); - RPointerArray augmentations; - - // If Base package is not available then don't do anything and break the case. - if (entryOpenResult != KErrNone) - { - break; - } - - //Get the Augmentation and Install if augmentation doesn't match - CleanupResetAndDestroy >::PushL(augmentations); - entry.AugmentationsL(augmentations); - for (TInt i = 0; i < augmentations.Count(); ++i) - { - for (TInt j =0; j < names.Count(); ++j) - { - if ((uid3 == augmentations[i]->Uid()) && - (augmentations[i]->Name() == names[j]->Data())) - { - shouldInstall=EFalse; - break; - } - } - } - - if(shouldInstall) - { - DoInstallL(file,appUid); - } - - CleanupStack::PopAndDestroy(&augmentations); - break; - } - - default: - /* - If SA/PA/SP/PP is not the case we can't handle because - PU has never been supported for SwiDaemon according to FS. - */ - ASSERT(EFalse); - - } - - CleanupStack::PopAndDestroy(6, &session); - - } // End of SISX file condition - - CleanupStack::PopAndDestroy(&file); // close - } - -void CDaemonBehaviour::DoNotifyMediaProcessingComplete() - { - if(iSwiDaemonPlugin && iStartNotified) - { - iSwiDaemonPlugin->MediaProcessingComplete(); - } - } - -void CDaemonBehaviour::DoInstallL(RFile &file, const TUid &appUid) - { - - // Rewind file - TInt pos = 0; - file.Seek(ESeekStart, pos); - - if(iSwiDaemonPlugin) - { - DEBUG_PRINTF(_L8("SWI Daemon - Using external plugin to process install")); - - if(!iStartNotified) - { - iSwiDaemonPlugin->MediaProcessingStart(iDrive); - iStartNotified = ETrue; - } - iSwiDaemonPlugin->RequestInstall(file); - } - - else - { - DEBUG_PRINTF(_L8("SWI Daemon - Using internal logic to process install")); - - TThreadId threadId; - User::LeaveIfError(iApaSession.StartDocument(file,appUid,threadId)); - - RThread thread; - User::LeaveIfError(thread.Open(threadId)); - CleanupClosePushL(thread); - - // Wait for the installer to terminate before launching another install. - - TRequestStatus status; - thread.Logon(status); - User::WaitForRequest(status); - CleanupStack::PopAndDestroy(&thread); - } - }