diff -r a4d6f1ea0416 -r e7aa27f58ae1 emailservices/emailservermonitor/src/emailshutter.cpp --- a/emailservices/emailservermonitor/src/emailshutter.cpp Tue Jan 26 11:45:42 2010 +0200 +++ b/emailservices/emailservermonitor/src/emailshutter.cpp Tue Feb 02 00:02:40 2010 +0200 @@ -24,10 +24,12 @@ #include // RProperty #include // TApaTaskList #include // RWsSession +#include // RDesRead/WriteStream #include // RAlwaysOnlineClientSession #include // CPSRequestHandler #include // CRepository +#include // HomeScreen UIDs #include "FreestyleEmailUiConstants.h" // FS Email UI UID #include "fsmtmsconstants.h" // MCE, Phonebook & Calendar UIDs @@ -51,6 +53,14 @@ { KCalendarAppUid1 } // Calendar }; +// Applications that should not be closed. Should include only system +// applications that free the email resources by some other means. +const TUid KApplicationsNotToBeClosed[] = + { + { AI_SID_AIFW_EXE }, // HomeScreen + { AI_UID3_AIFW_COMMON }, // HomeScreen + }; + // Non-UI clients that need to be closed const TUid KOtherClientsToClose[] = { @@ -78,6 +88,7 @@ { KUidEmailStorePreInstallExe } // MessageStorePreInstallExe }; +const TInt KEmailUidExtraBuffer = 2 * KEmailPlatformApiUidItemSize; // ======== MEMBER FUNCTION DEFINITIONS ======== @@ -123,6 +134,8 @@ CEmailShutter::~CEmailShutter() { FUNC_LOG; + iInstStatusProperty.Close(); + iPlatformApiAppsToClose.Close(); } // --------------------------------------------------------------------------- @@ -140,7 +153,8 @@ KPowerMgmtPolicy ); if( error != KErrNone && error != KErrAlreadyExists ) { - ERROR_1( error, "RProperty::Define failed, error code: ", error ); + ERROR( error, "RProperty::Define (EEmailPsKeyInstallationStatus) failed!" ); + ERROR_1( error, " error code: ", error ); User::Leave( error ); } @@ -148,9 +162,34 @@ EEmailPsKeyInstallationStatus ); if( error != KErrNone ) { - ERROR_1( error, "RProperty::Attach failed, error code: ", error ); + ERROR( error, "RProperty::Attach (EEmailPsKeyInstallationStatus) failed!" ); + ERROR_1( error, " error code: ", error ); User::Leave( error ); } + + // Define P&S key used to register platform API applications + error = RProperty::Define( EEmailPsKeyPlatformApiAppsToCloseLength, + RProperty::EInt, + KAllowAllPolicy, + KWriteDeviceDataPolicy ); + + if( error != KErrNone && error != KErrAlreadyExists ) + { + ERROR( error, "RProperty::Define (EEmailPsKeyPlatformApiAppsToCloseLength) failed!" ); + ERROR_1( error, " error code: ", error ); + } + + // Define P&S key used to register platform API applications + error = RProperty::Define( EEmailPsKeyPlatformApiAppsToClose, + RProperty::EByteArray, + KAllowAllPolicy, + KWriteDeviceDataPolicy ); + + if( error != KErrNone && error != KErrAlreadyExists ) + { + ERROR( error, "RProperty::Define (EEmailPsKeyPlatformApiAppsToClose) failed!" ); + ERROR_1( error, " error code: ", error ); + } CActiveScheduler::Add(this); } @@ -273,6 +312,7 @@ TApaTaskList taskList( session ); + // First end our own applications that are defined in hard coded list TInt count = sizeof(KApplicationsToClose) / sizeof(TUid); for( TInt i = 0; iCancel(); } - + + // First read the platform API UIDs from P&S, those are needed later + TRAP_IGNORE( ReadPlatformApiUidsL() ); + // End all clients EndClients(); // Wait some time to give the clients some time to shut down themselves @@ -587,3 +648,51 @@ // there are some process(es) to wait for } while ( ( totalWaitTime < aMaxWaitTime ) && KillEmAll( aMode, ETrue ) ); } + +// --------------------------------------------------------------------------- +// Reads platform API process UIDs from Publish and Subscribe key +// --------------------------------------------------------------------------- +// +void CEmailShutter::ReadPlatformApiUidsL() + { + FUNC_LOG; + + iPlatformApiAppsToClose.Reset(); + + // Read buffer length + TInt bufLength( 0 ); + User::LeaveIfError( RProperty::Get( KEmailShutdownPsCategory, + EEmailPsKeyPlatformApiAppsToCloseLength, + bufLength ) ); + + // Allocate buffer for reading and then read the list of UIDs from P&S. + // Adding some extra buffer just in case the size key and actual list + // are out of sync. This shouldn't happen, but you never know. + HBufC8* readBuf = HBufC8::NewLC( bufLength + KEmailUidExtraBuffer ); + TPtr8 readPtr = readBuf->Des(); + + User::LeaveIfError( RProperty::Get( KEmailShutdownPsCategory, + EEmailPsKeyPlatformApiAppsToClose, + readPtr ) ); + + RDesReadStream readStream( readPtr ); + CleanupClosePushL( readStream ); + + // Get items count from the actual buffer + TInt itemsCount = readPtr.Length() / KEmailPlatformApiUidItemSize; + + for ( TInt ii = 0;ii < itemsCount; ++ii ) + { + // Read next UID from the stream + TUid item = TUid::Uid( readStream.ReadInt32L() ); + + // Append only UIDs of such applications that should be closed + TInt count = sizeof(KApplicationsNotToBeClosed) / sizeof(TUid); + if( !FindFromArray( item, KApplicationsNotToBeClosed, count ) ) + { + iPlatformApiAppsToClose.AppendL( item ); + } + } + + CleanupStack::PopAndDestroy( 2, readBuf ); + }