|         |      1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). | 
|         |      2 // All rights reserved. | 
|         |      3 // This component and the accompanying materials are made available | 
|         |      4 // under the terms of "Eclipse Public License v1.0" | 
|         |      5 // which accompanies this distribution, and is available | 
|         |      6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". | 
|         |      7 // | 
|         |      8 // Initial Contributors: | 
|         |      9 // Nokia Corporation - initial contribution. | 
|         |     10 // | 
|         |     11 // Contributors: | 
|         |     12 // | 
|         |     13 // Description: | 
|         |     14 // cwatcherssastartupmgr.cpp | 
|         |     15 // | 
|         |     16  | 
|         |     17 #include "cwatcherssastartupmgr.h" | 
|         |     18  | 
|         |     19 #include <ecom/ecom.h> | 
|         |     20 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS  | 
|         |     21 #include "cwatcher.h" | 
|         |     22 #endif | 
|         |     23  | 
|         |     24 static void CleanUpEComInfoArray(TAny* aInfoArray); | 
|         |     25  | 
|         |     26 /**  | 
|         |     27 Factory function to create a new instance of the CWatcherSSAStartupMgr | 
|         |     28 SSA start-up manager. | 
|         |     29  | 
|         |     30 The SSA start-up manager registers with the Domain Manager for the | 
|         |     31 domain KAppServicesDomain3 of the KDmHierarchyIdStartup. | 
|         |     32  | 
|         |     33 @return | 
|         |     34 A new CWatcherSSAStartupMgr object. | 
|         |     35 */ | 
|         |     36  | 
|         |     37 CWatcherSSAStartupMgr* CWatcherSSAStartupMgr::NewL() | 
|         |     38 	{ | 
|         |     39 #ifndef SYMBIAN_SYSTEM_STATE_MANAGEMENT | 
|         |     40 	CWatcherSSAStartupMgr* self = new (ELeave) CWatcherSSAStartupMgr(KDmHierarchyIdStartup, KAppServicesDomain3); | 
|         |     41 #else | 
|         |     42 	CWatcherSSAStartupMgr* self = new (ELeave) CWatcherSSAStartupMgr(KDmHierarchyIdStartup, KSM2AppServicesDomain3); | 
|         |     43 #endif | 
|         |     44 	CleanupStack::PushL(self); | 
|         |     45 	self->ConstructL(); | 
|         |     46 	CleanupStack::Pop(self); | 
|         |     47 	return self; | 
|         |     48 	} | 
|         |     49 	  | 
|         |     50  | 
|         |     51 /** | 
|         |     52 Constructor of CWatcherSSAStartupMgr | 
|         |     53  | 
|         |     54 @param aHierarchyId | 
|         |     55 The Id of the domain hierarchy to connect to | 
|         |     56 @param aDomainId | 
|         |     57 The Id of the domain to connect to | 
|         |     58 */ | 
|         |     59 CWatcherSSAStartupMgr::CWatcherSSAStartupMgr(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId) | 
|         |     60 : CDmDomain(aHierarchyId,aDomainId), iCurrentStartupState(EStartupStateUndefined) | 
|         |     61 	{ | 
|         |     62 	} | 
|         |     63 	  | 
|         |     64  | 
|         |     65 /**  | 
|         |     66 Destructor | 
|         |     67 */ | 
|         |     68 CWatcherSSAStartupMgr::~CWatcherSSAStartupMgr() | 
|         |     69 	{ | 
|         |     70 	Cancel(); | 
|         |     71 	iWatcherList.ResetAndDestroy(); | 
|         |     72 	delete iLog, | 
|         |     73 	iFs.Close(); | 
|         |     74 	REComSession::FinalClose(); | 
|         |     75 	} | 
|         |     76 	 | 
|         |     77  | 
|         |     78 /**  | 
|         |     79 Second-stage constructor. | 
|         |     80  | 
|         |     81 This method indicates how the CWatcherSSAStartupMgr interacts with the  | 
|         |     82 Domain manager to keep aware of the startup state change. | 
|         |     83 */ | 
|         |     84 void CWatcherSSAStartupMgr::ConstructL() | 
|         |     85 	{ | 
|         |     86 	 | 
|         |     87 	// Get ready to log in \logs\watcher\watcher.txt | 
|         |     88 	User::LeaveIfError(iFs.Connect()); | 
|         |     89 	iLog = CWatcherLog::NewL(iFs); | 
|         |     90 	 | 
|         |     91 	// Connect to the Domain Manager | 
|         |     92  | 
|         |     93 	TRAPD( err, CDmDomain::ConstructL() ); | 
|         |     94  | 
|         |     95 	if( err != KErrNone ) | 
|         |     96 		{ | 
|         |     97 		// The connection to the Domain Manager cannot be established, | 
|         |     98 		// we perform a full initialisation | 
|         |     99 		iLog->Printf(_L("CWatcherSSAStartupMgr::InitialiseL(): cannot connect to the Domain Manager, performing full init.")); | 
|         |    100 		PerformFullInitL(); | 
|         |    101 		iCurrentStartupState = EStartupStateNonCritical; | 
|         |    102 		return; | 
|         |    103 		} | 
|         |    104 			 | 
|         |    105 	// Get the start-up state from the Domain Manager. | 
|         |    106 	TDmDomainState state = GetState(); | 
|         |    107 	 | 
|         |    108 	// Either something wrong with the Domain Manager or final state is reached | 
|         |    109 	if( state <= EStartupStateUndefined || state >= EStartupStateNonCritical ) | 
|         |    110 		{ | 
|         |    111 		// We perform a full initialisation | 
|         |    112 		iLog->Printf(_L("CWatcherSSAStartupMgr::InitialiseL(): wrong state, performing full init.")); | 
|         |    113 		PerformFullInitL(); | 
|         |    114 		iCurrentStartupState = EStartupStateNonCritical; | 
|         |    115 		return; | 
|         |    116 		} | 
|         |    117 			 | 
|         |    118 	// Perform the initialisation for this state | 
|         |    119 	TBool notFinished = ProcessSSAEventL((TStartupStateIdentifier)state); | 
|         |    120 	if( notFinished ) | 
|         |    121 		{ | 
|         |    122 		// Still need to get the state from Domain Manager. | 
|         |    123 		RequestTransitionNotification(); | 
|         |    124 		} | 
|         |    125 	} | 
|         |    126  | 
|         |    127  | 
|         |    128 /** | 
|         |    129 Executed when the startup state change is done, it does the same thing  | 
|         |    130 as the method InitialiseL(). | 
|         |    131 */ | 
|         |    132 void CWatcherSSAStartupMgr::RunL() | 
|         |    133 	{ | 
|         |    134 	// Leave if our previous request to be notified a state change has | 
|         |    135 	// returned an error and let RunError handle this. | 
|         |    136 	User::LeaveIfError(iStatus.Int());  | 
|         |    137  | 
|         |    138 	// Get the start-up state from the Domain Manager. | 
|         |    139 	TDmDomainState state = GetState(); | 
|         |    140 	 | 
|         |    141 	//If the state is EStartupStateUndefined there must be something wrong. | 
|         |    142 	if( state == EStartupStateUndefined )  | 
|         |    143 		{ | 
|         |    144 		AcknowledgeLastState(KErrBadHandle); | 
|         |    145 		User::Leave(KErrBadHandle); //RunError will handle this. | 
|         |    146 		} | 
|         |    147 	 | 
|         |    148 	// Perform the initialisation for this state | 
|         |    149 	TBool notFinished = ProcessSSAEventL((TStartupStateIdentifier)state); | 
|         |    150 	 | 
|         |    151 	// Tell domain manager that we have processed the last state change | 
|         |    152 	AcknowledgeLastState(KErrNone); | 
|         |    153 	 | 
|         |    154 	if( notFinished ) | 
|         |    155 		{ | 
|         |    156 		RequestTransitionNotification(); | 
|         |    157 		} | 
|         |    158 	} | 
|         |    159  | 
|         |    160  | 
|         |    161 /** | 
|         |    162 Handle the error if RunL leaves. Here, we just do a full initialisation. | 
|         |    163  | 
|         |    164 @param aError  | 
|         |    165 Error code generated by the RunL(), not used here. | 
|         |    166 @return | 
|         |    167 KErrNone to avoid CActiveScheduler to panic.  | 
|         |    168 */	 | 
|         |    169 TInt CWatcherSSAStartupMgr::RunError(TInt /*aError*/) | 
|         |    170 	{ | 
|         |    171 	iLog->Printf(_L("CWatcherSSAStartupMgr::RunL() leaves, do a full initialisation")); | 
|         |    172 	TRAP_IGNORE(DoRunErrorL()); | 
|         |    173 	return KErrNone; | 
|         |    174 	} | 
|         |    175  | 
|         |    176 	 | 
|         |    177 /** | 
|         |    178 Leaving method trapped by RunError | 
|         |    179  | 
|         |    180 If RunError has been called that means RunL has left. | 
|         |    181 Because watcher.exe is started in the critical-dynamic state it is quite | 
|         |    182 likely the critical init has been done already (in ConstructL) when RunL | 
|         |    183 is called so we just want to do the non-critical part of the init. | 
|         |    184 We check our internal state for confirmation and run the non-critical init. | 
|         |    185 If our internal state is EStartupStateCriticalDynamic or before we | 
|         |    186 perform a full init. | 
|         |    187 */	 | 
|         |    188 void CWatcherSSAStartupMgr::DoRunErrorL() | 
|         |    189 	{ | 
|         |    190 	if ( iCurrentStartupState > EStartupStateCriticalDynamic ) | 
|         |    191 		{ | 
|         |    192 		PerformNonCriticalInitL(); | 
|         |    193 		} | 
|         |    194 	else | 
|         |    195 		{	 | 
|         |    196 		PerformFullInitL(); | 
|         |    197 		} | 
|         |    198 	} | 
|         |    199  | 
|         |    200 	 | 
|         |    201 /** | 
|         |    202 Perform the initialisation for a particular state. | 
|         |    203  | 
|         |    204 @param aKnownState  | 
|         |    205 The startup state passed into the MStartupStateObserver objects | 
|         |    206 @return | 
|         |    207 Whether or not a transition notification should be requested | 
|         |    208 */	 | 
|         |    209 TBool CWatcherSSAStartupMgr::ProcessSSAEventL(TStartupStateIdentifier aKnownState) | 
|         |    210 	{ | 
|         |    211 	TBool notFinished = ETrue; | 
|         |    212 	 | 
|         |    213 	if ( aKnownState != iCurrentStartupState ) | 
|         |    214 		{ | 
|         |    215 		 | 
|         |    216 		//if we have not performed critical dynamic initialisation and receive a  | 
|         |    217 		//notification for it or a state that comes after  | 
|         |    218  | 
|         |    219 		if(iCurrentStartupState<EStartupStateCriticalDynamic && | 
|         |    220 		   aKnownState >= EStartupStateCriticalDynamic) | 
|         |    221 			{ | 
|         |    222 			PerformCriticalInitL(); | 
|         |    223 			iCurrentStartupState = EStartupStateCriticalDynamic; | 
|         |    224 			} | 
|         |    225 		 | 
|         |    226 		//if we have not performed non-critical initialisation and receive a notification | 
|         |    227 		//for it or a state that comes after  | 
|         |    228  | 
|         |    229 		if(iCurrentStartupState<EStartupStateNonCritical && | 
|         |    230 		   aKnownState >= EStartupStateNonCritical) | 
|         |    231 			{ | 
|         |    232 			PerformNonCriticalInitL(); | 
|         |    233 			notFinished = EFalse; | 
|         |    234 			iCurrentStartupState = EStartupStateNonCritical; | 
|         |    235 			} | 
|         |    236 		 | 
|         |    237 		} | 
|         |    238 		 | 
|         |    239 	return notFinished; | 
|         |    240 	} | 
|         |    241  | 
|         |    242  | 
|         |    243 /** | 
|         |    244 Perform a full initialisation = start all the watchers | 
|         |    245 */	 | 
|         |    246 void CWatcherSSAStartupMgr::PerformFullInitL() | 
|         |    247 	{ | 
|         |    248 	// Watchers for the critical-dynamic state: | 
|         |    249 	PerformCriticalInitL(); | 
|         |    250 	// Watchers for the non-critical state: | 
|         |    251 	PerformNonCriticalInitL(); | 
|         |    252 	} | 
|         |    253  | 
|         |    254  | 
|         |    255 /** | 
|         |    256 Perform initialisation for the 'critical-dynamic' start-up state | 
|         |    257 */	 | 
|         |    258 void CWatcherSSAStartupMgr::PerformCriticalInitL() | 
|         |    259 	{ | 
|         |    260 	StartWatchersL(KUidEComWatcher);             // Legacy watchers | 
|         |    261 	StartWatchersL(KUidMsgCriticalWatchers);  | 
|         |    262 	} | 
|         |    263  | 
|         |    264 /** | 
|         |    265 Perform initialisation for the 'non-critical' start-up state | 
|         |    266 */	 | 
|         |    267 void CWatcherSSAStartupMgr::PerformNonCriticalInitL() | 
|         |    268 	{ | 
|         |    269 	StartWatchersL(KUidMsgNonCriticalWatchers); | 
|         |    270 	} | 
|         |    271  | 
|         |    272 /** | 
|         |    273 Starts all the watchers implementing the specified ECom interface | 
|         |    274  | 
|         |    275 @param aEComInterface  | 
|         |    276 The ECom interface of the watchers to be started | 
|         |    277 */	 | 
|         |    278 void CWatcherSSAStartupMgr::StartWatchersL(TUid aEComInterface) | 
|         |    279 	{ | 
|         |    280 	RImplInfoPtrArray watcherInfoArray; | 
|         |    281 	TCleanupItem cleanup(CleanUpEComInfoArray, &watcherInfoArray); | 
|         |    282 	CleanupStack::PushL(cleanup); | 
|         |    283 	TEComResolverParams eComResolverParams; | 
|         |    284  | 
|         |    285 	// Get the list of active watcher implementations. | 
|         |    286 	// (list only watcher implementations that are ROM, as it would be  | 
|         |    287 	// insecure to load RAM implementations) | 
|         |    288 	REComSession::ListImplementationsL(	aEComInterface, eComResolverParams,  | 
|         |    289 										KRomOnlyResolverUid, watcherInfoArray); | 
|         |    290  | 
|         |    291 	const TInt count = watcherInfoArray.Count(); | 
|         |    292  | 
|         |    293 	#ifdef __WINS__ | 
|         |    294 		_LIT(KLaunchingWatcher, "Launching ECOM watcher %S"); | 
|         |    295 	#endif | 
|         |    296 	 | 
|         |    297 	for( TInt ii=0; ii < count; ++ii ) | 
|         |    298 		{ | 
|         |    299 		CImplementationInformation* info = watcherInfoArray[ii]; | 
|         |    300 		 | 
|         |    301 		// Log details of the watcher | 
|         |    302 		const TDesC& name = info->DisplayName(); | 
|         |    303 		#ifdef __WINS__ | 
|         |    304 			iLog->Printf(KLaunchingWatcher, &name); | 
|         |    305 		#endif | 
|         |    306 	 | 
|         |    307 		// Create the watcher launcher | 
|         |    308 		CWatcherLauncher* launcher = CWatcherLauncher::NewL(name,  | 
|         |    309 															info->ImplementationUid(),  | 
|         |    310 															iFs,  | 
|         |    311 															*iLog); | 
|         |    312 		CleanupStack::PushL(launcher); | 
|         |    313 		iWatcherList.AppendL(launcher); | 
|         |    314 		CleanupStack::Pop(launcher); | 
|         |    315 		 | 
|         |    316 		} | 
|         |    317 	CleanupStack::PopAndDestroy(&watcherInfoArray); | 
|         |    318 	} | 
|         |    319  | 
|         |    320  | 
|         |    321 // CleanupEComArray function is used for cleanup support  | 
|         |    322 // of locally declared arrays. | 
|         |    323 void CleanUpEComInfoArray(TAny* aInfoArray) | 
|         |    324 	{ | 
|         |    325 	RImplInfoPtrArray* infoArray = (static_cast<RImplInfoPtrArray*>(aInfoArray)); | 
|         |    326 	infoArray->ResetAndDestroy(); | 
|         |    327 	infoArray->Close(); | 
|         |    328 	} | 
|         |    329  |