messagingfw/watcherfw/src/cwatcherssastartupmgr.cpp
changeset 62 db3f5fa34ec7
parent 0 8e480a14352b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/watcherfw/src/cwatcherssastartupmgr.cpp	Wed Nov 03 22:41:46 2010 +0530
@@ -0,0 +1,329 @@
+// Copyright (c) 2005-2009 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:
+// cwatcherssastartupmgr.cpp
+//
+
+#include "cwatcherssastartupmgr.h"
+
+#include <ecom/ecom.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS 
+#include "cwatcher.h"
+#endif
+
+static void CleanUpEComInfoArray(TAny* aInfoArray);
+
+/** 
+Factory function to create a new instance of the CWatcherSSAStartupMgr
+SSA start-up manager.
+
+The SSA start-up manager registers with the Domain Manager for the
+domain KAppServicesDomain3 of the KDmHierarchyIdStartup.
+
+@return
+A new CWatcherSSAStartupMgr object.
+*/
+
+CWatcherSSAStartupMgr* CWatcherSSAStartupMgr::NewL()
+	{
+#ifndef SYMBIAN_SYSTEM_STATE_MANAGEMENT
+	CWatcherSSAStartupMgr* self = new (ELeave) CWatcherSSAStartupMgr(KDmHierarchyIdStartup, KAppServicesDomain3);
+#else
+	CWatcherSSAStartupMgr* self = new (ELeave) CWatcherSSAStartupMgr(KDmHierarchyIdStartup, KSM2AppServicesDomain3);
+#endif
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+	 
+
+/**
+Constructor of CWatcherSSAStartupMgr
+
+@param aHierarchyId
+The Id of the domain hierarchy to connect to
+@param aDomainId
+The Id of the domain to connect to
+*/
+CWatcherSSAStartupMgr::CWatcherSSAStartupMgr(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId)
+: CDmDomain(aHierarchyId,aDomainId), iCurrentStartupState(EStartupStateUndefined)
+	{
+	}
+	 
+
+/** 
+Destructor
+*/
+CWatcherSSAStartupMgr::~CWatcherSSAStartupMgr()
+	{
+	Cancel();
+	iWatcherList.ResetAndDestroy();
+	delete iLog,
+	iFs.Close();
+	REComSession::FinalClose();
+	}
+	
+
+/** 
+Second-stage constructor.
+
+This method indicates how the CWatcherSSAStartupMgr interacts with the 
+Domain manager to keep aware of the startup state change.
+*/
+void CWatcherSSAStartupMgr::ConstructL()
+	{
+	
+	// Get ready to log in \logs\watcher\watcher.txt
+	User::LeaveIfError(iFs.Connect());
+	iLog = CWatcherLog::NewL(iFs);
+	
+	// Connect to the Domain Manager
+
+	TRAPD( err, CDmDomain::ConstructL() );
+
+	if( err != KErrNone )
+		{
+		// The connection to the Domain Manager cannot be established,
+		// we perform a full initialisation
+		iLog->Printf(_L("CWatcherSSAStartupMgr::InitialiseL(): cannot connect to the Domain Manager, performing full init."));
+		PerformFullInitL();
+		iCurrentStartupState = EStartupStateNonCritical;
+		return;
+		}
+			
+	// Get the start-up state from the Domain Manager.
+	TDmDomainState state = GetState();
+	
+	// Either something wrong with the Domain Manager or final state is reached
+	if( state <= EStartupStateUndefined || state >= EStartupStateNonCritical )
+		{
+		// We perform a full initialisation
+		iLog->Printf(_L("CWatcherSSAStartupMgr::InitialiseL(): wrong state, performing full init."));
+		PerformFullInitL();
+		iCurrentStartupState = EStartupStateNonCritical;
+		return;
+		}
+			
+	// Perform the initialisation for this state
+	TBool notFinished = ProcessSSAEventL((TStartupStateIdentifier)state);
+	if( notFinished )
+		{
+		// Still need to get the state from Domain Manager.
+		RequestTransitionNotification();
+		}
+	}
+
+
+/**
+Executed when the startup state change is done, it does the same thing 
+as the method InitialiseL().
+*/
+void CWatcherSSAStartupMgr::RunL()
+	{
+	// Leave if our previous request to be notified a state change has
+	// returned an error and let RunError handle this.
+	User::LeaveIfError(iStatus.Int()); 
+
+	// Get the start-up state from the Domain Manager.
+	TDmDomainState state = GetState();
+	
+	//If the state is EStartupStateUndefined there must be something wrong.
+	if( state == EStartupStateUndefined ) 
+		{
+		AcknowledgeLastState(KErrBadHandle);
+		User::Leave(KErrBadHandle); //RunError will handle this.
+		}
+	
+	// Perform the initialisation for this state
+	TBool notFinished = ProcessSSAEventL((TStartupStateIdentifier)state);
+	
+	// Tell domain manager that we have processed the last state change
+	AcknowledgeLastState(KErrNone);
+	
+	if( notFinished )
+		{
+		RequestTransitionNotification();
+		}
+	}
+
+
+/**
+Handle the error if RunL leaves. Here, we just do a full initialisation.
+
+@param aError 
+Error code generated by the RunL(), not used here.
+@return
+KErrNone to avoid CActiveScheduler to panic. 
+*/	
+TInt CWatcherSSAStartupMgr::RunError(TInt /*aError*/)
+	{
+	iLog->Printf(_L("CWatcherSSAStartupMgr::RunL() leaves, do a full initialisation"));
+	TRAP_IGNORE(DoRunErrorL());
+	return KErrNone;
+	}
+
+	
+/**
+Leaving method trapped by RunError
+
+If RunError has been called that means RunL has left.
+Because watcher.exe is started in the critical-dynamic state it is quite
+likely the critical init has been done already (in ConstructL) when RunL
+is called so we just want to do the non-critical part of the init.
+We check our internal state for confirmation and run the non-critical init.
+If our internal state is EStartupStateCriticalDynamic or before we
+perform a full init.
+*/	
+void CWatcherSSAStartupMgr::DoRunErrorL()
+	{
+	if ( iCurrentStartupState > EStartupStateCriticalDynamic )
+		{
+		PerformNonCriticalInitL();
+		}
+	else
+		{	
+		PerformFullInitL();
+		}
+	}
+
+	
+/**
+Perform the initialisation for a particular state.
+
+@param aKnownState 
+The startup state passed into the MStartupStateObserver objects
+@return
+Whether or not a transition notification should be requested
+*/	
+TBool CWatcherSSAStartupMgr::ProcessSSAEventL(TStartupStateIdentifier aKnownState)
+	{
+	TBool notFinished = ETrue;
+	
+	if ( aKnownState != iCurrentStartupState )
+		{
+		
+		//if we have not performed critical dynamic initialisation and receive a 
+		//notification for it or a state that comes after 
+
+		if(iCurrentStartupState<EStartupStateCriticalDynamic &&
+		   aKnownState >= EStartupStateCriticalDynamic)
+			{
+			PerformCriticalInitL();
+			iCurrentStartupState = EStartupStateCriticalDynamic;
+			}
+		
+		//if we have not performed non-critical initialisation and receive a notification
+		//for it or a state that comes after 
+
+		if(iCurrentStartupState<EStartupStateNonCritical &&
+		   aKnownState >= EStartupStateNonCritical)
+			{
+			PerformNonCriticalInitL();
+			notFinished = EFalse;
+			iCurrentStartupState = EStartupStateNonCritical;
+			}
+		
+		}
+		
+	return notFinished;
+	}
+
+
+/**
+Perform a full initialisation = start all the watchers
+*/	
+void CWatcherSSAStartupMgr::PerformFullInitL()
+	{
+	// Watchers for the critical-dynamic state:
+	PerformCriticalInitL();
+	// Watchers for the non-critical state:
+	PerformNonCriticalInitL();
+	}
+
+
+/**
+Perform initialisation for the 'critical-dynamic' start-up state
+*/	
+void CWatcherSSAStartupMgr::PerformCriticalInitL()
+	{
+	StartWatchersL(KUidEComWatcher);             // Legacy watchers
+	StartWatchersL(KUidMsgCriticalWatchers); 
+	}
+
+/**
+Perform initialisation for the 'non-critical' start-up state
+*/	
+void CWatcherSSAStartupMgr::PerformNonCriticalInitL()
+	{
+	StartWatchersL(KUidMsgNonCriticalWatchers);
+	}
+
+/**
+Starts all the watchers implementing the specified ECom interface
+
+@param aEComInterface 
+The ECom interface of the watchers to be started
+*/	
+void CWatcherSSAStartupMgr::StartWatchersL(TUid aEComInterface)
+	{
+	RImplInfoPtrArray watcherInfoArray;
+	TCleanupItem cleanup(CleanUpEComInfoArray, &watcherInfoArray);
+	CleanupStack::PushL(cleanup);
+	TEComResolverParams eComResolverParams;
+
+	// Get the list of active watcher implementations.
+	// (list only watcher implementations that are ROM, as it would be 
+	// insecure to load RAM implementations)
+	REComSession::ListImplementationsL(	aEComInterface, eComResolverParams, 
+										KRomOnlyResolverUid, watcherInfoArray);
+
+	const TInt count = watcherInfoArray.Count();
+
+	#ifdef __WINS__
+		_LIT(KLaunchingWatcher, "Launching ECOM watcher %S");
+	#endif
+	
+	for( TInt ii=0; ii < count; ++ii )
+		{
+		CImplementationInformation* info = watcherInfoArray[ii];
+		
+		// Log details of the watcher
+		const TDesC& name = info->DisplayName();
+		#ifdef __WINS__
+			iLog->Printf(KLaunchingWatcher, &name);
+		#endif
+	
+		// Create the watcher launcher
+		CWatcherLauncher* launcher = CWatcherLauncher::NewL(name, 
+															info->ImplementationUid(), 
+															iFs, 
+															*iLog);
+		CleanupStack::PushL(launcher);
+		iWatcherList.AppendL(launcher);
+		CleanupStack::Pop(launcher);
+		
+		}
+	CleanupStack::PopAndDestroy(&watcherInfoArray);
+	}
+
+
+// CleanupEComArray function is used for cleanup support 
+// of locally declared arrays.
+void CleanUpEComInfoArray(TAny* aInfoArray)
+	{
+	RImplInfoPtrArray* infoArray = (static_cast<RImplInfoPtrArray*>(aInfoArray));
+	infoArray->ResetAndDestroy();
+	infoArray->Close();
+	}
+