emailservices/emailservermonitor/src/emailshutter.cpp
changeset 4 e7aa27f58ae1
parent 1 12c456ceeff2
child 8 e1b6206813b4
--- 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 <e32property.h>                // RProperty
 #include <apgtask.h>                    // TApaTaskList
 #include <w32std.h>                     // RWsSession
+#include <s32mem.h>                     // RDesRead/WriteStream
 
 #include <AlwaysOnlineManagerClient.h>  // RAlwaysOnlineClientSession
 #include <CPsRequestHandler.h>          // CPSRequestHandler
 #include <centralrepository.h>          // CRepository
+#include <platform/mw/aisystemuids.hrh> // 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; i<count; i++ )
         {
@@ -284,7 +324,19 @@
             task.EndTask();
             }
         }
+    
+    // Then end applications that are registered in P&S as platform API users
+    for( TInt i = 0; i<iPlatformApiAppsToClose.Count(); i++ )
+        {
+        TApaTask task = taskList.FindApp( iPlatformApiAppsToClose[i] );
+        if ( task.Exists() )
+            {
+            INFO_1( "Closing API UI app with UID: %d", iPlatformApiAppsToClose[i].iUid );
 
+            task.EndTask();
+            }
+        }
+    
     CleanupStack::PopAndDestroy( &session );
     }
 
@@ -440,6 +492,12 @@
             {
             return ETrue;
             }
+
+        // Check also clients registered as platform API users
+        if( iPlatformApiAppsToClose.Find( aSid ) != KErrNotFound )
+            {
+            return ETrue;
+            }
         }
 
     if( aMode == EKillingModePlugins ||
@@ -531,7 +589,10 @@
         {
         iMonitor->Cancel();
         }
-    
+
+    // 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 );
+    }