diff -r 491b3ed49290 -r 65326cf895ed filemanager/bkupchecker/src/filemanagerbkupchecker.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/filemanager/bkupchecker/src/filemanagerbkupchecker.cpp Wed Sep 01 12:31:07 2010 +0100 @@ -0,0 +1,460 @@ +/* +* Copyright (c) 2006-2008 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: Rule based application launch during backup and restore. +* +*/ + + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FileManagerDebug.h" +#include "filemanagerprivatepskeys.h" +#include "FileManagerUID.h" +#include "filemanagerbkupchecker.h" + +// CONSTANTS +_LIT(KMsengRscFilePath,"filemanagerbkupchecker.rsc"); +_LIT(KThreadName,"BkupCheckerThread"); + +#ifdef __SKIP_PS_IN_TEST_ +// Controlling of KUidBackupRestoreKey only possible with SID 0x10202D56 +// That is why we have to variate running of test code using testVariable +extern TInt testVariable; +#endif + +// Define the interface UIDs. +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY( 0x1020508A, CFileManagerBkupChecker::NewL ) + }; + + +// ======== LOCAL FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// ProcessExists +// --------------------------------------------------------------------------- +// +static TBool ProcessExists( const TSecureId& aSecureId ) + { + _LIT( KFindPattern, "*" ); + TFindProcess finder(KFindPattern); + TFullName processName; + while( finder.Next( processName ) == KErrNone ) + { + RProcess process; + if ( process.Open( processName ) == KErrNone ) + { + TSecureId processId( process.SecureId() ); + process.Close(); + if( processId == aSecureId ) + { + return ETrue; + } + } + } + return EFalse; + } + +// --------------------------------------------------------------------------- +// GetFileManagerBurStatus +// --------------------------------------------------------------------------- +// +static TInt GetFileManagerBurStatus() + { + TInt status( EFileManagerBkupStatusUnset ); + TInt err( RProperty::Get( + KPSUidFileManagerStatus, KFileManagerBkupStatus, status ) ); + if ( err != KErrNone ) + { + status = EFileManagerBkupStatusUnset; + } + else if( status == EFileManagerBkupStatusBackup || + status == EFileManagerBkupStatusRestore ) + { + const TSecureId KFileManagerUid(KFileManagerUID3); + // Check file manager process just if bur state detected + if( !ProcessExists( KFileManagerUid ) ) + { + status = EFileManagerBkupStatusUnset; + } + } + + INFO_LOG2( "GetFileManagerBurStatus, status %d, err %d", status, err ) + + return status; + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// ----------------------------------------------------------------------------- +// ImplementationGroupProxy. +// +// ----------------------------------------------------------------------------- +// +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount ) + { + aTableCount = sizeof( ImplementationTable ) / sizeof( TImplementationProxy ); + return ImplementationTable; + } + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CFileManagerBkupChecker::CFileManagerBkupChecker +// +// --------------------------------------------------------------------------- +// +CFileManagerBkupChecker::CFileManagerBkupChecker() + { + } + +// --------------------------------------------------------------------------- +// CFileManagerBkupChecker::NewL +// +// --------------------------------------------------------------------------- +// +CFileManagerBkupChecker* CFileManagerBkupChecker::NewL() + { + CFileManagerBkupChecker* self = new (ELeave) CFileManagerBkupChecker(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// CFileManagerBkupChecker::ConstructL +// +// --------------------------------------------------------------------------- +// +void CFileManagerBkupChecker::ConstructL() + { + FUNC_LOG + RFs fsSession; + + // Connect to File Server + User::LeaveIfError(fsSession.Connect()); + CleanupClosePushL(fsSession); + + // Get resource drive from dll location + TFileName dllFileName; + Dll::FileName( dllFileName ); + TParsePtrC dllParse( dllFileName ); + TFileName fileName; +#ifdef __SKIP_PS_IN_TEST_ + _LIT(KDriveZ,"Z:"); + fileName.Copy( KDriveZ ); +#else + // Drive is parsed normally from dll-location in order to support + // installing/patching of component. + fileName.Copy( dllParse.Drive() ); +#endif + fileName.Append( KDC_RESOURCE_FILES_DIR ); + fileName.Append( KMsengRscFilePath ); + BaflUtils::NearestLanguageFile( fsSession, fileName ); + // + TEntry entry; + User::LeaveIfError( fsSession.Entry( fileName, entry ) ); + // if file does not exist, leaves with KErrNotFound + + CResourceFile *resFile; + resFile = CResourceFile::NewLC( fsSession, fileName, 0, entry.iSize ); + + resFile->ConfirmSignatureL(); + + ///////////////////////////////////////////////////////// + //Initialize white-list of applications from resource file + + RResourceReader theReader; + theReader.OpenLC( resFile, ALLOWEDUIDS ); + + //the first WORD contains the number of elements in the resource + TInt numberOfUIDs = theReader.ReadInt16L(); + + for( TInt i = 0; i < numberOfUIDs; i++) + { + TUint32 uid = theReader.ReadInt32L(); + iUids.Append(uid); + INFO_LOG1( "CFileManagerBkupChecker::ConstructL, Application 0x%x added in white-list", iUids[i] ) + } + CleanupStack::PopAndDestroy( &theReader ); + + //Initialize information note texts from resource file + theReader.OpenLC( resFile, R_QTN_FMGR_BACKUP_APPLAUNCH_PREVENTED ); + iBackupNote = theReader.ReadHBufCL(); + CleanupStack::PopAndDestroy( &theReader ); + + theReader.OpenLC( resFile, R_QTN_FMGR_RESTORE_APPLAUNCH_PREVENTED ); + iRestoreNote = theReader.ReadHBufCL(); + CleanupStack::PopAndDestroy( &theReader ); + + CleanupStack::PopAndDestroy( resFile ); + CleanupStack::PopAndDestroy( &fsSession ); + } + + +// --------------------------------------------------------------------------- +// CFileManagerBkupChecker::~CFileManagerBkupChecker +// +// --------------------------------------------------------------------------- +// +CFileManagerBkupChecker::~CFileManagerBkupChecker() + { + delete iBackupNote; + delete iRestoreNote; + iUids.Close(); + } + +// --------------------------------------------------------------------------- +// CFileManagerBkupChecker::OkayToLaunchL +// +// --------------------------------------------------------------------------- +// +CAppLaunchChecker::TAppLaunchCode CFileManagerBkupChecker::OkayToLaunchL(const TUid aAppToLaunch, + TApaTaskList& /* aTaskList */) + { + FUNC_LOG + CAppLaunchChecker::TAppLaunchCode launch = CAppLaunchChecker::EAppLaunchIndifferent; + + TInt burState( 0 ); + TInt burErr = RProperty::Get( KUidSystemCategory, KUidBackupRestoreKey, burState ); + + if(burErr == KErrNone) + { + INFO_LOG2 + ( + "CFileManagerBkupChecker::OkayToLaunchL, Application 0x%x, KUidBackupRestoreKey status %d", + aAppToLaunch.iUid, burState + ) + + TBURPartType burType = static_cast< TBURPartType >( burState & KBURPartTypeMask ); + TInt fmBurStatus( GetFileManagerBurStatus() ); + + // We can't rely on just p&s value. Additional check is carried out in ValidateBUROngoing. +#ifdef __SKIP_PS_IN_TEST_ + // Run additional validation check in test mode just to cover all use cases + ValidateBUROngoing(); +#else + if( fmBurStatus == EFileManagerBkupStatusBackup || + fmBurStatus == EFileManagerBkupStatusRestore || + ( ( burType == EBURBackupPartial || burType == EBURBackupFull || + burType == EBURRestorePartial || burType == EBURRestoreFull ) && + ValidateBUROngoing() ) ) +#endif + { + launch = CAppLaunchChecker::EAppLaunchDecline; + + TInt count( iUids.Count() ); + + for( TInt i = 0; i < count; i++ ) + { + if(iUids[i] == aAppToLaunch.iUid) + { + INFO_LOG1 + ( + "CFileManagerBkupChecker::OkayToLaunchL, Application 0x%x in white-list", + iUids[i] + ) + launch = CAppLaunchChecker::EAppLaunchIndifferent; + break; + } + } + + if( launch == CAppLaunchChecker::EAppLaunchDecline ) + { + INFO_LOG1 + ( + "CFileManagerBkupChecker::OkayToLaunchL, Application 0x%x launch prevented", + aAppToLaunch.iUid + ) + + iIsBackup = ( fmBurStatus == EFileManagerBkupStatusBackup || + burType == EBURBackupPartial || + burType == EBURBackupFull ); + + RThread thread; + + TInt err = thread.Create( + KThreadName, ThreadFunction, KDefaultStackSize, NULL, this ); + + INFO_LOG1("CFileManagerBkupChecker::OkayToLaunchL, thread err %d", err) + + if ( err == KErrNone ) + { + TRequestStatus status; + + thread.Rendezvous( status ); + thread.Resume(); + + // Wait until thread has copy of note text. + User::WaitForRequest( status ); + + INFO_LOG1("CFileManagerBkupChecker::OkayToLaunchL, thread exit %d", status.Int()) + } + + thread.Close(); + } + } + } + + return launch; + } + +// --------------------------------------------------------------------------- +// CFileManagerBkupChecker::ValidateBUROngoing +// +// --------------------------------------------------------------------------- +// +TBool CFileManagerBkupChecker::ValidateBUROngoing() + { + TBool err(EFalse); + _LIT( KFindPattern, "*" ); + const TSecureId KSBEUid(0x10202D56); + const TSecureId KFileManagerUid(KFileManagerUID3); + const TSecureId KPCConnectivityUid(0x101F99F6); + TBool serverRunning(EFalse); + TBool client1Running(EFalse); + TBool client2Running(EFalse); + + // If SBE panics, File Manager and PC-connectivity server are supposed to + // re-establish connection to server and set BUR-mode back to normal. + // If SBE client panics, server is supposed to set BUR-mode back to normal. + // However, it might be reasonable to validate also that BUR client is + // up and running. E.g. if both server and client panic in sequence, BUR + // state might stay as backup or restore and we never let application run. + // We have to search by UID, because process can have localized name + TFindProcess finder( KFindPattern ); + TFullName processName; + + while( finder.Next( processName ) == KErrNone ) + { + RProcess process; + const TInt r = process.Open( processName ); + if ( r == KErrNone ) + { + const TSecureId processId = process.SecureId(); + process.Close(); + + if( processId == KSBEUid ) + { + serverRunning = ETrue; + } + else if( processId == KFileManagerUid ) + { + client1Running = ETrue; + } + else if( processId == KPCConnectivityUid ) + { + client2Running = ETrue; + } + } + } + + INFO_LOG2("CFileManagerBkupChecker::ValidateBUROngoing, %x status %d", + KSBEUid.iId, serverRunning); + INFO_LOG2("CFileManagerBkupChecker::ValidateBUROngoing, %x status %d", + KFileManagerUid.iId, client1Running); + INFO_LOG2("CFileManagerBkupChecker::ValidateBUROngoing, %x status %d", + KPCConnectivityUid.iId, client2Running); + + if( serverRunning && (client1Running || client2Running) ) + { + err = ETrue; + } + + return err; + } + +// ---------------------------------------------------------------------------- +// CFileManagerBkupChecker::ThreadFunction() +// +// ---------------------------------------------------------------------------- +TInt CFileManagerBkupChecker::ThreadFunction( TAny* ptr ) + { + FUNC_LOG + + CFileManagerBkupChecker* self = + static_cast< CFileManagerBkupChecker* >( ptr ); + + CTrapCleanup* cleanupStack = CTrapCleanup::New(); + if ( !cleanupStack ) + { + return KErrNoMemory; + } + + TRAPD( err, self->ThreadFunctionL() ); + + INFO_LOG1("CFileManagerBkupChecker::ThreadFunction, ThreadFunctionL err %d", err) + + delete cleanupStack; + + return err; + } + +// ---------------------------------------------------------------------------- +// CFileManagerBkupChecker::ThreadFunctionL() +// +// ---------------------------------------------------------------------------- +void CFileManagerBkupChecker::ThreadFunctionL( ) + { + FUNC_LOG + + HBufC* note = NULL; + +#ifdef __SKIP_PS_IN_TEST_ + if(!testVariable) + { + note = iBackupNote->AllocLC(); + } + else + { + note = iRestoreNote->AllocLC(); + } +#else + if( iIsBackup ) + { + note = iBackupNote->AllocLC(); + } + else + { + note = iRestoreNote->AllocLC(); + } +#endif + + // Once we have locally allocated note string, we can signal main thread. + RThread::Rendezvous( KErrNone ); + + RAknUiServer aknSrv; + TInt err( aknSrv.Connect() ); + INFO_LOG1("CFileManagerBkupChecker::ThreadFunctionL, connect err %d", err) + User::LeaveIfError( err ); + CleanupClosePushL( aknSrv ); + + aknSrv.ShowGlobalNoteL( *note, EAknGlobalInformationNote ); + + CleanupStack::PopAndDestroy( &aknSrv ); + CleanupStack::PopAndDestroy( note ); + } +