emailservices/emailservermonitor/src/emailshutter.cpp
branchRCL_3
changeset 64 3533d4323edc
equal deleted inserted replaced
63:d189ee25cf9d 64:3533d4323edc
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 * Implementation of EmailShutter
       
    16 *
       
    17 */
       
    18 //  Include Files  
       
    19 
       
    20 #include <e32base.h>
       
    21 #include <e32std.h>
       
    22 #include <e32des16.h>                   // Descriptors
       
    23 
       
    24 #include <e32property.h>                // RProperty
       
    25 #include <apgtask.h>                    // TApaTaskList
       
    26 #include <w32std.h>                     // RWsSession
       
    27 #include <s32mem.h>                     // RDesRead/WriteStream
       
    28 
       
    29 #include <AlwaysOnlineManagerClient.h>  // RAlwaysOnlineClientSession
       
    30 #include <CPsRequestHandler.h>          // CPSRequestHandler
       
    31 #include <centralrepository.h>          // CRepository
       
    32 #include <aisystemuids.hrh>             // HomeScreen UIDs
       
    33 
       
    34 #include "FreestyleEmailUiConstants.h"  // FS Email UI UID
       
    35 #include "fsmtmsconstants.h"            // MCE, Phonebook & Calendar UIDs
       
    36 #include "emailstoreuids.hrh"           // KUidMessageStoreExe
       
    37 
       
    38 #include "emailtrace.h"
       
    39 #include "emailshutdownconst.h"
       
    40 #include "emailshutter.h"
       
    41 #include "emailservermonitorconst.h"
       
    42 #include "emailservermonitorutilities.h"
       
    43 #include "emailservermonitor.h"
       
    44 
       
    45 
       
    46 // UI Applications to be closed
       
    47 const TUid KApplicationsToClose[] =
       
    48     {
       
    49     KFSEmailUiUid,                     // Freestyle Email UI
       
    50     { SettingWizardUidAsTInt },        // TP Wizard
       
    51     { KMceAppUid },                    // MCE
       
    52     { KPhoneBookUid },                 // Phonebook 1 & 2
       
    53     { KCalendarAppUid1 },              // Calendar
       
    54     { KGeneralSettingsAppUidAsTInt },  // General settings
       
    55     };
       
    56 
       
    57 // Applications that should not be closed. Should include only system
       
    58 // applications that free the email resources by some other means.
       
    59 const TUid KApplicationsNotToBeClosed[] =
       
    60     {
       
    61     { AI_SID_AIFW_EXE },               // HomeScreen
       
    62     { AI_UID3_AIFW_COMMON },           // HomeScreen
       
    63     };
       
    64 
       
    65 // Non-UI clients that need to be closed
       
    66 const TUid KOtherClientsToClose[] =
       
    67     {
       
    68     { KPcsServerProcessUidAsTInt },    // PCS server
       
    69     { FSMailServerUidAsTInt },         // FSMailServer
       
    70     };
       
    71 
       
    72 // Plugin processes that need to be closed
       
    73 const TUid KPluginProcessesToClose[] =
       
    74     {
       
    75     // MfE plugin
       
    76     { 0x20012BEE },                    // KUidEasStartup
       
    77     { 0x20012BEC },                    // KUidEasTarmAccess
       
    78     { 0x20012BD4 },                    // KEasLogSenderServer
       
    79     { 0x20012BE6 },                    // KUidEasServer
       
    80     // Oz plugin
       
    81     { 0x2002136A },                    // monitor
       
    82     { 0x20021367 },                    // server
       
    83     };
       
    84 
       
    85 // Message store processes that need to be closed
       
    86 const TUid KMsgStoreProcessesToClose[] =
       
    87     {
       
    88     { KUidMessageStoreExe },           // MessageStoreExe.exe
       
    89     { KUidEmailStorePreInstallExe }    // MessageStorePreInstallExe
       
    90     };
       
    91 
       
    92 const TInt KEmailUidExtraBuffer = 2 * KEmailPlatformApiUidItemSize;
       
    93 
       
    94 // ======== MEMBER FUNCTION DEFINITIONS ========
       
    95 
       
    96 // ---------------------------------------------------------------------------
       
    97 // Two-phased class constructor.
       
    98 // ---------------------------------------------------------------------------
       
    99 //
       
   100 CEmailShutter* CEmailShutter::NewL()
       
   101     {
       
   102     FUNC_LOG;
       
   103     CEmailShutter* self = CEmailShutter::NewLC();
       
   104     CleanupStack::Pop( self );
       
   105     return self;
       
   106     }
       
   107 
       
   108 // ---------------------------------------------------------------------------
       
   109 // Two-phased class constructor, leaves newly created object in cleanup stack.
       
   110 // ---------------------------------------------------------------------------
       
   111 //
       
   112 CEmailShutter* CEmailShutter::NewLC()
       
   113     {
       
   114     FUNC_LOG;
       
   115     CEmailShutter* self = new (ELeave) CEmailShutter();
       
   116     CleanupStack::PushL( self );
       
   117     self->ConstructL();
       
   118     return self;
       
   119     }
       
   120 
       
   121 // ---------------------------------------------------------------------------
       
   122 // Default constructor
       
   123 // ---------------------------------------------------------------------------
       
   124 //
       
   125 CEmailShutter::CEmailShutter()
       
   126     : CActive( EPriorityStandard ), iMonitor( NULL )
       
   127     {
       
   128     FUNC_LOG;
       
   129     }
       
   130 
       
   131 // ---------------------------------------------------------------------------
       
   132 // Default destructor
       
   133 // ---------------------------------------------------------------------------
       
   134 //
       
   135 CEmailShutter::~CEmailShutter()
       
   136     {
       
   137     FUNC_LOG;
       
   138     iInstStatusProperty.Close();
       
   139     iPlatformApiAppsToClose.Close();
       
   140     }
       
   141 
       
   142 // ---------------------------------------------------------------------------
       
   143 // Second phase class constructor.
       
   144 // ---------------------------------------------------------------------------
       
   145 //
       
   146 void CEmailShutter::ConstructL()
       
   147     {
       
   148     FUNC_LOG;
       
   149     // Define and attach/subscribe to P&S to get the shutdown event from
       
   150     // installation initiator(s)
       
   151     TInt error = iInstStatusProperty.Define( EEmailPsKeyInstallationStatus,
       
   152                                              RProperty::EInt,
       
   153                                              KAllowAllPolicy,
       
   154                                              KPowerMgmtPolicy );
       
   155     if( error != KErrNone && error != KErrAlreadyExists )
       
   156         {
       
   157         ERROR( error, "RProperty::Define (EEmailPsKeyInstallationStatus) failed!" );
       
   158         ERROR_1( error, "    error code: ", error );
       
   159         User::Leave( error );
       
   160         }
       
   161 
       
   162     error = iInstStatusProperty.Attach( KEmailShutdownPsCategory,
       
   163                                         EEmailPsKeyInstallationStatus );
       
   164     if( error != KErrNone )
       
   165         {
       
   166         ERROR( error, "RProperty::Attach (EEmailPsKeyInstallationStatus) failed!" );
       
   167         ERROR_1( error, "    error code: ", error );
       
   168         User::Leave( error );
       
   169         }
       
   170 
       
   171     // Define P&S key used to register platform API applications
       
   172     error = RProperty::Define( EEmailPsKeyPlatformApiAppsToCloseLength,
       
   173                                RProperty::EInt,
       
   174                                KAllowAllPolicy,
       
   175                                KWriteDeviceDataPolicy );
       
   176     
       
   177     if( error != KErrNone && error != KErrAlreadyExists )
       
   178         {
       
   179         ERROR( error, "RProperty::Define (EEmailPsKeyPlatformApiAppsToCloseLength) failed!" );
       
   180         ERROR_1( error, "    error code: ", error );
       
   181         }
       
   182     
       
   183     // Define P&S key used to register platform API applications
       
   184     error = RProperty::Define( EEmailPsKeyPlatformApiAppsToClose,
       
   185                                RProperty::EByteArray,
       
   186                                KAllowAllPolicy,
       
   187                                KWriteDeviceDataPolicy );
       
   188     
       
   189     if( error != KErrNone && error != KErrAlreadyExists )
       
   190         {
       
   191         ERROR( error, "RProperty::Define (EEmailPsKeyPlatformApiAppsToClose) failed!" );
       
   192         ERROR_1( error, "    error code: ", error );
       
   193         }
       
   194     
       
   195     CActiveScheduler::Add(this);
       
   196     }
       
   197 
       
   198 // ---------------------------------------------------------------------------
       
   199 // Starts observing P&S shutdown event
       
   200 // ---------------------------------------------------------------------------
       
   201 //
       
   202 void CEmailShutter::StartObservingShutdownEvent()
       
   203     {
       
   204     FUNC_LOG;
       
   205     SetActive();
       
   206     iInstStatusProperty.Subscribe( iStatus );
       
   207     }
       
   208 
       
   209 // ---------------------------------------------------------------------------
       
   210 // Set P&S key after installation is done
       
   211 // ---------------------------------------------------------------------------
       
   212 //
       
   213 void CEmailShutter::SetPsKeyInstallationFinished()
       
   214     {
       
   215     FUNC_LOG;
       
   216     TInt error = iInstStatusProperty.Set( EEmailPsValueInstallationFinished );
       
   217     ERROR_1( error, "RProperty::Set error code: %d", error );
       
   218     }
       
   219 
       
   220 // ---------------------------------------------------------------------------
       
   221 // Restart needed services after installation is finished
       
   222 // ---------------------------------------------------------------------------
       
   223 //
       
   224 void CEmailShutter::RestartServicesAfterInstallation()
       
   225     {
       
   226     TRAP_IGNORE( StartAoPluginL() );
       
   227     TRAP_IGNORE( StartPcsServerL() );
       
   228     }
       
   229 
       
   230 // ---------------------------------------------------------------------------
       
   231 // Set pointer to Email Server Monitor object
       
   232 // ---------------------------------------------------------------------------
       
   233 //
       
   234 void CEmailShutter::SetMonitor( CEmailServerMonitor* aMonitor )
       
   235     {
       
   236     iMonitor = aMonitor;
       
   237     }
       
   238 
       
   239 // ---------------------------------------------------------------------------
       
   240 // RunL of active object
       
   241 // ---------------------------------------------------------------------------
       
   242 //
       
   243 void CEmailShutter::RunL()
       
   244     {
       
   245     FUNC_LOG;
       
   246     if( iStatus == KErrNone )
       
   247         {
       
   248         TInt value( 0 );
       
   249         TInt error = iInstStatusProperty.Get( value );
       
   250         ERROR_1( error, "RProperty::Get error code: %d", error );
       
   251         
       
   252         // Verify that the P&S value indicates that installation is starting
       
   253         if( error == KErrNone &&
       
   254             value == EEmailPsValueInstallationStarting )
       
   255             {
       
   256             StartShutdown();
       
   257     
       
   258             // Send "installation OK to continue" event to installation
       
   259             // initiator once everyting is shutdown
       
   260             error = iInstStatusProperty.Set( EEmailPsValueInstallationOkToStart );
       
   261             ERROR_1( error, "RProperty::Set error code: %d", error );
       
   262     
       
   263             // Finally shutdown ourselves also
       
   264             CActiveScheduler::Stop();
       
   265             }
       
   266         else
       
   267             {
       
   268             // Re-subscribe
       
   269             StartObservingShutdownEvent();
       
   270             }
       
   271         }
       
   272     else
       
   273         {
       
   274         ERROR_1( iStatus.Int(), "CEmailShutter::RunL error code: %d", iStatus.Int() );
       
   275         }
       
   276     }
       
   277 
       
   278 // ---------------------------------------------------------------------------
       
   279 // Cancel active object
       
   280 // ---------------------------------------------------------------------------
       
   281 //
       
   282 void CEmailShutter::DoCancel()
       
   283     {
       
   284     FUNC_LOG;
       
   285     iInstStatusProperty.Cancel();
       
   286     }
       
   287 
       
   288 // ---------------------------------------------------------------------------
       
   289 // End client applications gracefully
       
   290 // ---------------------------------------------------------------------------
       
   291 //
       
   292 void CEmailShutter::EndClients()
       
   293     {
       
   294     FUNC_LOG;
       
   295     // End UI applications, ignore errors
       
   296     TRAP_IGNORE( EndApplicationsL() );
       
   297     
       
   298     // Define and publish the P&S key to give the clients change to close
       
   299     // themselves gracefully
       
   300     PublishPsKey( EEmailPsKeyShutdownClients );
       
   301     }
       
   302 
       
   303 // ---------------------------------------------------------------------------
       
   304 // End UI applications gracefully
       
   305 // ---------------------------------------------------------------------------
       
   306 //
       
   307 void CEmailShutter::EndApplicationsL()
       
   308     {
       
   309     FUNC_LOG;
       
   310     RWsSession session;
       
   311     User::LeaveIfError( session.Connect() );
       
   312     CleanupClosePushL( session );
       
   313 
       
   314     TApaTaskList taskList( session );
       
   315 
       
   316     // First end our own applications that are defined in hard coded list
       
   317     TInt count = sizeof(KApplicationsToClose) / sizeof(TUid);
       
   318     for( TInt i = 0; i<count; i++ )
       
   319         {
       
   320         TApaTask task = taskList.FindApp( KApplicationsToClose[i] );
       
   321         if ( task.Exists() )
       
   322             {
       
   323             INFO_1( "Closing UI app with UID: %d", KApplicationsToClose[i].iUid );
       
   324 
       
   325             task.EndTask();
       
   326             }
       
   327         }
       
   328     
       
   329     // Then end applications that are registered in P&S as platform API users
       
   330     for( TInt i = 0; i<iPlatformApiAppsToClose.Count(); i++ )
       
   331         {
       
   332         TApaTask task = taskList.FindApp( iPlatformApiAppsToClose[i] );
       
   333         if ( task.Exists() )
       
   334             {
       
   335             INFO_1( "Closing API UI app with UID: %d", iPlatformApiAppsToClose[i].iUid );
       
   336 
       
   337             task.EndTask();
       
   338             }
       
   339         }
       
   340     
       
   341     CleanupStack::PopAndDestroy( &session );
       
   342     }
       
   343 
       
   344 // ---------------------------------------------------------------------------
       
   345 // Define and publish the P&S key to inform all related services about the
       
   346 // installation, so that they can shutdown themselves gracefully
       
   347 // ---------------------------------------------------------------------------
       
   348 //
       
   349 void CEmailShutter::PublishPsKey( TInt aKey )
       
   350     {
       
   351     FUNC_LOG;
       
   352     TInt error = RProperty::Define( aKey,
       
   353                                     RProperty::EInt,
       
   354                                     KAllowAllPolicy,
       
   355                                     KPowerMgmtPolicy);
       
   356     
       
   357     ERROR_1( error, "RProperty::Define error code: %d", error );
       
   358     
       
   359     RProperty psProperty;
       
   360     error = psProperty.Attach( KEmailShutdownPsCategory,
       
   361                                aKey );
       
   362     ERROR_1( error, "RProperty::Attach error code: %d", error );
       
   363     
       
   364     if( error == KErrNone )
       
   365         {
       
   366         error = psProperty.Set( KEmailShutterPsValue );
       
   367 
       
   368         ERROR_1( error, "RProperty::Set error code: %d", error );
       
   369         }
       
   370     psProperty.Close();
       
   371     }
       
   372 
       
   373 // -----------------------------------------------------------------------------
       
   374 // Closes all non-email related plugins/services
       
   375 // -----------------------------------------------------------------------------
       
   376 //
       
   377 void CEmailShutter::Close3rdPartyServices()
       
   378     {
       
   379     FUNC_LOG;
       
   380     TRAP_IGNORE( ClosePcsServerL() );
       
   381     TRAP_IGNORE( CloseAOPluginL() );
       
   382     }
       
   383 
       
   384 // -----------------------------------------------------------------------------
       
   385 // Sends command to Always Online server to stop fs email plugin
       
   386 // -----------------------------------------------------------------------------
       
   387 //
       
   388 void CEmailShutter::CloseAOPluginL()
       
   389     {
       
   390     FUNC_LOG;
       
   391 
       
   392     RAlwaysOnlineClientSession aoSession;
       
   393     CleanupClosePushL( aoSession );
       
   394     TPckgBuf<TUid> id( KAlwaysOnlineEmailPluginUid );
       
   395     aoSession.SendSinglePacketL( EServerAPIBaseCommandStop, id );
       
   396     CleanupStack::PopAndDestroy( &aoSession );
       
   397     }
       
   398 
       
   399 
       
   400 // -----------------------------------------------------------------------------
       
   401 // Sends command to Always Online server to start fs email plugin
       
   402 // -----------------------------------------------------------------------------
       
   403 //
       
   404 void CEmailShutter::StartAoPluginL() const
       
   405     {
       
   406     FUNC_LOG;
       
   407     RAlwaysOnlineClientSession aoSession;
       
   408     CleanupClosePushL( aoSession );
       
   409     TPckgBuf<TUid> id( KAlwaysOnlineEmailPluginUid );
       
   410     aoSession.SendSinglePacketL( EServerAPIBaseCommandStart, id );
       
   411     CleanupStack::PopAndDestroy( &aoSession );
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // Closes PCS (Predictive Contact Search) server
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 void CEmailShutter::ClosePcsServerL()
       
   419     {
       
   420     FUNC_LOG;
       
   421     // If PCS server not running, don't request shutdown, because in this case 
       
   422     // the server need to be started before it can process the shutdown request
       
   423     if( IsProcessRunning( KPcsServerProcessUidAsTInt ) )
       
   424         {
       
   425         INFO( "Closing PCS server" );
       
   426         CPSRequestHandler* pcs = CPSRequestHandler::NewLC();
       
   427         pcs->ShutdownServerL();
       
   428         CleanupStack::PopAndDestroy( pcs );
       
   429         }
       
   430     }
       
   431 
       
   432 // -----------------------------------------------------------------------------
       
   433 // Starts PCS (Predictive Contact Search) server
       
   434 // -----------------------------------------------------------------------------
       
   435 //
       
   436 void CEmailShutter::StartPcsServerL() const
       
   437     {
       
   438     FUNC_LOG;
       
   439     CPSRequestHandler* pcs = CPSRequestHandler::NewL();
       
   440     delete pcs;
       
   441     }
       
   442 
       
   443 // ---------------------------------------------------------------------------
       
   444 // Try to find the UID given as parameter from the array given as parameter.
       
   445 //
       
   446 // @param aSid Process UID to be searched
       
   447 // @param aArray Array from where to search
       
   448 // @param aArrayCount Item count of the aArray
       
   449 // @return ETrue if the UID can be found from the array, otherwise EFalse.
       
   450 // ---------------------------------------------------------------------------
       
   451 //
       
   452 TBool CEmailShutter::FindFromArray(
       
   453         const TUid aSid,
       
   454         const TUid aArray[],
       
   455         const TInt aArrayCount )
       
   456     {
       
   457     for( TInt i = 0; i < aArrayCount; i++ )
       
   458         {
       
   459         if( aArray[i] == aSid )
       
   460             {
       
   461             return ETrue;
       
   462             }
       
   463         }
       
   464     return EFalse;
       
   465     }
       
   466 
       
   467 // ---------------------------------------------------------------------------
       
   468 // Checks does this UID belong to the list of the services that we need to
       
   469 // close down.
       
   470 //
       
   471 // @param aSid Process UID to check
       
   472 // @param aMode Killing mode, are we now killing clients, plugins or msg store
       
   473 // @return ETrue if this is one of the services we need to close in specified
       
   474 //         mode, otherwise EFalse
       
   475 // ---------------------------------------------------------------------------
       
   476 //
       
   477 TBool CEmailShutter::NeedToKillThisProcess(
       
   478         const TUid aSid,
       
   479         const TEmailShutterKillingMode aMode )
       
   480     {
       
   481     if( aMode == EKillingModeClients ||
       
   482         aMode == EKillingModeAll )
       
   483         {
       
   484         // In case of clients we need to check applications and other clients
       
   485         TInt count = sizeof(KApplicationsToClose) / sizeof(TUid);
       
   486         if( FindFromArray( aSid, KApplicationsToClose, count ) )
       
   487             {
       
   488             return ETrue;
       
   489             }
       
   490         
       
   491         count = sizeof(KOtherClientsToClose) / sizeof(TUid);
       
   492         if( FindFromArray( aSid, KOtherClientsToClose, count ) )
       
   493             {
       
   494             return ETrue;
       
   495             }
       
   496 
       
   497         // Check also clients registered as platform API users
       
   498         if( iPlatformApiAppsToClose.Find( aSid ) != KErrNotFound )
       
   499             {
       
   500             return ETrue;
       
   501             }
       
   502         }
       
   503 
       
   504     if( aMode == EKillingModePlugins ||
       
   505         aMode == EKillingModeAll )
       
   506         {
       
   507         TInt count = sizeof(KPluginProcessesToClose) / sizeof(TUid);
       
   508         if( FindFromArray( aSid, KPluginProcessesToClose, count ) )
       
   509             {
       
   510             return ETrue;
       
   511             }
       
   512         }
       
   513 
       
   514     if( aMode == EKillingModeMsgStore ||
       
   515         aMode == EKillingModeAll )
       
   516         {
       
   517         TInt count = sizeof(KMsgStoreProcessesToClose) / sizeof(TUid);
       
   518         if( FindFromArray( aSid, KMsgStoreProcessesToClose, count ) )
       
   519             {
       
   520             return ETrue;
       
   521             }
       
   522         }
       
   523 
       
   524     return EFalse;
       
   525     }
       
   526 
       
   527 // ---------------------------------------------------------------------------
       
   528 // Kills all the related processes gracelessly. This is used as a backup for
       
   529 // those processes that didn't close themselves gracefully.
       
   530 // ---------------------------------------------------------------------------
       
   531 //
       
   532 TBool CEmailShutter::KillEmAll(
       
   533         const TEmailShutterKillingMode aMode, /* = EKillingModeAll*/
       
   534         const TBool aOnlyCheckIfRunning /* = EFalse */ )
       
   535     {
       
   536     FUNC_LOG;
       
   537     // Having tried graceful shutdown, we need to kill any remaining processes
       
   538     // matching the SID.  Note that killing a process may re-order the list of
       
   539     // remaining processes, so the search must start from the top again.
       
   540 
       
   541     TBool found( EFalse );
       
   542     TBool needToScanFullList;
       
   543     TFullName fullName;
       
   544     
       
   545     do
       
   546         {
       
   547         needToScanFullList = EFalse;
       
   548         TFindProcess findProcess;
       
   549 
       
   550         while( findProcess.Next(fullName) == KErrNone )
       
   551             {
       
   552             RProcess process;
       
   553             TInt error = process.Open( findProcess );
       
   554             // In case of error just skip this process, don't leave
       
   555             if( error == KErrNone )
       
   556                 {
       
   557                 TUid sid( process.SecureId() );
       
   558                 if ( NeedToKillThisProcess( sid, aMode ) && // Is this our process and
       
   559                      process.ExitType() == EExitPending )  // and is the process alive
       
   560                     {
       
   561                     found = ETrue;
       
   562 
       
   563                     // Kill the found process if aOnlyCheckIfRunning flag not set
       
   564                     if( !aOnlyCheckIfRunning )
       
   565                         {
       
   566                         INFO_1( "Killing process with UID: %d", sid.iUid );
       
   567     
       
   568                         process.Kill(KErrNone);
       
   569                         needToScanFullList = ETrue;
       
   570                         }
       
   571                     }
       
   572                 }
       
   573             process.Close();
       
   574             }
       
   575         
       
   576         } while (needToScanFullList);
       
   577     
       
   578     return found;
       
   579     }
       
   580 
       
   581 // ---------------------------------------------------------------------------
       
   582 // Highest level function to close everything in right order
       
   583 // ---------------------------------------------------------------------------
       
   584 //
       
   585 void CEmailShutter::StartShutdown()
       
   586     {
       
   587     FUNC_LOG;
       
   588     // Cancel Email Server monitoring before closing the server
       
   589     if( iMonitor )
       
   590         {
       
   591         iMonitor->Cancel();
       
   592         }
       
   593 
       
   594     // First read the platform API UIDs from P&S, those are needed later
       
   595     TRAP_IGNORE( ReadPlatformApiUidsL() );
       
   596 
       
   597     // End all clients
       
   598     EndClients();
       
   599     // Wait some time to give the clients some time to shut down themselves
       
   600     Wait( KTimeToWaitApplicationsInSeconds );
       
   601     
       
   602     // End all 3rd party clients
       
   603     Close3rdPartyServices();
       
   604     WaitInCycles( KMaxTimeToWaitClientsInSeconds, EKillingModeClients );
       
   605 
       
   606     // Kill gracelessly all remaining clients
       
   607     KillEmAll( EKillingModeClients );
       
   608 
       
   609     // Define and publish the P&S key to give the plugin servers change to
       
   610     // close themselves gracefully
       
   611     PublishPsKey( EEmailPsKeyShutdownPlugins );
       
   612     // Wait some time to give the plugins some time to shut down themselves
       
   613     WaitInCycles( KMaxTimeToWaitPluginsInSeconds, EKillingModePlugins );
       
   614     // Kill gracelessly all remaining plugin processes
       
   615     KillEmAll( EKillingModePlugins );
       
   616 
       
   617     // Define and publish the P&S key to give the msg store change to close
       
   618     // itself gracefully
       
   619     PublishPsKey( EEmailPsKeyShutdownMsgStore );
       
   620     // Wait some time to give the msg store some time to shut down itself
       
   621     WaitInCycles( KMaxTimeToWaitMsgStoreInSeconds, EKillingModeMsgStore );
       
   622     // Kill gracelessly all remaining message store processes
       
   623     KillEmAll( EKillingModeMsgStore );
       
   624     
       
   625     // Kill gracelessly all remaining processes
       
   626     KillEmAll();
       
   627 
       
   628     INFO( "Finished Shutdown" );
       
   629     }
       
   630 
       
   631 // ---------------------------------------------------------------------------
       
   632 // Waits in cycles and checks between cycles have all relevant processes
       
   633 // closed or do we still need to wait. Returns when either aMaxWaitTime
       
   634 // has elapsed or when all relevant processes have been shutdown.
       
   635 // ---------------------------------------------------------------------------
       
   636 //
       
   637 void CEmailShutter::WaitInCycles(
       
   638         const TInt aMaxWaitTime,
       
   639         const TEmailShutterKillingMode aMode )
       
   640     {
       
   641     FUNC_LOG;
       
   642     TInt totalWaitTime = 0;
       
   643     do
       
   644         {
       
   645         // Do the wait and increase total waiting time counter
       
   646         Wait( KWaitTimeCycleInSeconds );
       
   647         totalWaitTime += KWaitTimeCycleInSeconds;
       
   648         // Do this as long as aMaxWaitTime has not elapsed and 
       
   649         // there are some process(es) to wait for
       
   650         } while ( ( totalWaitTime < aMaxWaitTime ) && KillEmAll( aMode, ETrue ) );
       
   651     }
       
   652 
       
   653 // ---------------------------------------------------------------------------
       
   654 // Reads platform API process UIDs from Publish and Subscribe key
       
   655 // ---------------------------------------------------------------------------
       
   656 //
       
   657 void CEmailShutter::ReadPlatformApiUidsL()
       
   658     {
       
   659     FUNC_LOG;
       
   660 
       
   661     iPlatformApiAppsToClose.Reset();
       
   662 
       
   663     // Read buffer length
       
   664     TInt bufLength( 0 );
       
   665     User::LeaveIfError( RProperty::Get( KEmailShutdownPsCategory,
       
   666                                         EEmailPsKeyPlatformApiAppsToCloseLength,
       
   667                                         bufLength ) );
       
   668 
       
   669     // Allocate buffer for reading and then read the list of UIDs from P&S.
       
   670     // Adding some extra buffer just in case the size key and actual list
       
   671     // are out of sync. This shouldn't happen, but you never know.
       
   672     HBufC8* readBuf = HBufC8::NewLC( bufLength + KEmailUidExtraBuffer );
       
   673     TPtr8 readPtr = readBuf->Des();
       
   674     
       
   675     User::LeaveIfError( RProperty::Get( KEmailShutdownPsCategory,
       
   676                                         EEmailPsKeyPlatformApiAppsToClose,
       
   677                                         readPtr ) );
       
   678     
       
   679     RDesReadStream readStream( readPtr );
       
   680     CleanupClosePushL( readStream );
       
   681     
       
   682     // Get items count from the actual buffer
       
   683     TInt itemsCount = readPtr.Length() / KEmailPlatformApiUidItemSize;
       
   684     
       
   685     for ( TInt ii = 0;ii < itemsCount; ++ii )
       
   686         {
       
   687         // Read next UID from the stream
       
   688         TUid item = TUid::Uid( readStream.ReadInt32L() );
       
   689 
       
   690         // Append only UIDs of such applications that should be closed
       
   691         TInt count = sizeof(KApplicationsNotToBeClosed) / sizeof(TUid);
       
   692         if( !FindFromArray( item, KApplicationsNotToBeClosed, count ) )
       
   693             {
       
   694             iPlatformApiAppsToClose.AppendL( item );
       
   695             }
       
   696         }
       
   697     
       
   698     CleanupStack::PopAndDestroy( 2, readBuf );
       
   699     }