lowlevellibsandfws/pluginfw/Framework/frame/ServerStartupManager.cpp
author William Roberts <williamr@symbian.org>
Thu, 22 Jul 2010 16:48:56 +0100
branchGCC_SURGE
changeset 45 4b03adbd26ca
parent 0 e4d67989cc36
permissions -rw-r--r--
Catchup to latest Symbian^4

// 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:
// The Implementation of the CServerStartupMgr class which
// connects to the Domain manager to keep aware of the current start-up
// state and distributes the state changes to the interested MStartupStateObserver
// objects.
// 
//

/**
 @internalComponent
 @file 
*/
 
#include "ServerStartupManager.h"
#include "EComServer.h"
#include "EComDebug.h"
#include "EComPerformance.h"

/**
constructor of CServerStartupMgr
@param aHierarchyId The Id of the domain hierarchy to connect to.
@param aDomainId The Id of the domain to connect to.
@param aFs A reference to a connected file server session.
*/
 CServerStartupMgr::CServerStartupMgr(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, RFs& aFs):
#ifdef __ECOM_SERVER_TESTABILITY__
 CDmDomainTestHarness(aHierarchyId,aDomainId),
#else
 CDmDomain(aHierarchyId,aDomainId),
#endif
 EKFinalStartupState(EStartupStateNonCritical),
 iCurrentStartupState(EStartupStateUndefined),
 iFs(aFs)
	 {
	 // does nothing.	
	 }
	 

/** 
destructor
@internalComponent
*/
CServerStartupMgr::~CServerStartupMgr()
	{
	Cancel();
	iObserverList.Reset();
	}
	

/** 
Accessor to the current startup state
@internalComponent
@return the current startup state
*/
TStartupStateIdentifier CServerStartupMgr::CurrentStartupState()
	{
	return iCurrentStartupState;
	}
	
/**
updates the MStartupStateObserver objects.
@internalComponent
@param aKnownState the startup state passed into the MStartupStateObserver objects. 
*/	
void CServerStartupMgr::UpdateStateAwareObjectsL(TStartupStateIdentifier aKnownState)
	{
	RECORD_STARTUP_STATE_TIMER_RESULT(aKnownState)
	RECORD_STARTUP_STATE_HEAP_RESULT(aKnownState)
	TInt observerCount=iObserverList.Count();
	for (TInt i = 0; i < observerCount; i++)
		{
		iObserverList[i]->ProcessSSAEventL(aKnownState);
		}
	RECORD_STARTUP_STATE_HEAP_RESULT(aKnownState)
	RECORD_STARTUP_STATE_TIMER_RESULT(aKnownState)
	}
	
/** 
This method takes a a startup state which can be KSS or USS as a parameter,
and returns a ECOM Known Startup State
@internalComponent
@param aStartupState a startup state which can be KSS or USS.
@return an ECOM known startup state
*/
TStartupStateIdentifier CServerStartupMgr::GetKnownStartupState(TDmDomainState aStartupState)
	{
	if(aStartupState >= EStartupStateNonCritical)
		{
		return EStartupStateNonCritical;
		}
	else if(aStartupState >= EStartupStateCriticalDynamic)
		{
		return EStartupStateCriticalDynamic;
		}
	else if(aStartupState >= EStartupStateCriticalStatic)
		{
		return EStartupStateCriticalStatic;
		}
	else
		{
		return EStartupStateUndefined;
		}
	}

	
/**
Register the MStartupStateObserver object with the CServerStartupMgr.
@internalComponent
@param aObs the pointer to the MStartupStateObserver object to be registered with CServerStartupMgr.
*/
void CServerStartupMgr::RegisterObserverL(const MStartupStateObserver* aObs)
	{
	User::LeaveIfError(iObserverList.Append(aObs));
	}
	

/**
Handle the error if RunL leaves. Panic with the error code
@internalComponent
@param aError error code generated by the RunL(), not used here.
@return KErrNone to avoid CActiveScheduler to panic. 
*/	
TInt CServerStartupMgr::RunError(TInt aError)
	{
	__ECOM_LOG1("ECOM: PANIC in CServerStartupMgr::RunError(), error= %d", aError);
	User::Panic(KEComServerPanicCategory, EEComPanic_CServerStartupMgr_RunError);	
	return KErrNone; // dummy return to stop compiler warnings
	}

/**
This method indicates how the CServerStartupMgr interacts with the Domain
manager to keep aware of the startup state change, and distribute it to the
MStartupStateObserver objects inside ECOM.
@internalComponent
@pre CServerStartupMgr is fully constructed.
*/
void CServerStartupMgr::InitialiseL(TBool aSsaEnabled)
	{
	if(!aSsaEnabled)
		{
		// it is not SSA, do a full discovery.
		__ECOM_TRACE("ECOM: CServerStartupMgr::InitialiseL(): It is not SSA, do a full discovery");
		UpdateStateAwareObjectsL(EKFinalStartupState);
		iCurrentStartupState = EKFinalStartupState;
		return;	
		}
	// it is SSA.	
	else
		{
		__ECOM_TRACE("---------------------------------------------------");
		__ECOM_TRACE("ECOM: CServerStartupMgr::InitialiseL(): SSA is on.");
#ifdef __ECOM_SERVER_TESTABILITY__
		TRAPD(err, CDmDomainTestHarness::ConstructL());
#else
		TRAPD(err, CDmDomain::ConstructL());
#endif
		if(err!=KErrNone)
			{
			// the ConstructL leaves, then do a full discovery.
			__ECOM_TRACE("ECOM: CServerStartupMgr::InitialiseL(): Can not connect to the Domain Manager, do a full discovery.");
			UpdateStateAwareObjectsL(EKFinalStartupState);
			iCurrentStartupState = EKFinalStartupState;
			return;
			}
		
		//get the state from Domain Manager in case missing any.	
#ifdef __ECOM_SERVER_TESTABILITY__
		RequestTransitionNotificationL();
#else
		RequestTransitionNotification();
#endif
		
		// 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)
			{
			// do a full discovery. Cancel outstanding request.
			UpdateStateAwareObjectsL(EKFinalStartupState);
			iCurrentStartupState = EKFinalStartupState;
			Cancel();
			return;
			}
			
		// get the ECom Known state.
		TStartupStateIdentifier nextKnownState = GetKnownStartupState(state);
	
		
		 //for EStartupStateCriticalStatic or EStartupStateCriticalDynamic.
		if(nextKnownState != EStartupStateUndefined)
			{
			// catch up to the ECOM interested state.
			UpdateStateAwareObjectsL(EStartupStateCriticalStatic);
			}
			
		iCurrentStartupState = nextKnownState;
		}
	}


/**
Executed when the startup state change is done, it does the same thing 
as the method InitialiseL() does when SSA is on and the CurrentStartupState is not EStartupStateNonCritical.
@internalComponent
*/
void CServerStartupMgr::RunL()
	{
	// Leave if something wrong with the RequestTransitionNotification().
	User::LeaveIfError(iStatus.Int()); //RunError will handle this.

	//do request transition notification in case missing any.
#ifdef __ECOM_SERVER_TESTABILITY__
	RequestTransitionNotificationL();
#else
	RequestTransitionNotification();
#endif
		
	// get the start up state from Domain Manager.
	TDmDomainState state = GetState();
	//If the state is EStartupStateUndefined there must be sth wrong.
	if(state == EStartupStateUndefined) 
		{
#ifdef __ECOM_SERVER_TESTABILITY__
		AcknowledgeLastStateL(KErrBadHandle);
#else
		AcknowledgeLastState(KErrBadHandle);
#endif
		Cancel();
		User::Leave(KErrBadHandle); //RunError will handle this.
		}

	//get the known state			
	TStartupStateIdentifier nextKnownState = GetKnownStartupState(state);

	//If the nextKnownState is a state that we are ready to switch to
	//update all the state aware objects and change the state.
	//This way if we receive a state that is same as our current state
	//we do not process it. Or the new state is less than our current
	//state, we just ignore it.
	if((iCurrentStartupState < EStartupStateCriticalStatic && nextKnownState == EStartupStateCriticalStatic)
	    || (iCurrentStartupState < EStartupStateCriticalDynamic && nextKnownState == EStartupStateCriticalDynamic)
	    || (iCurrentStartupState < EStartupStateNonCritical && nextKnownState == EStartupStateNonCritical))
		{
		UpdateStateAwareObjectsL(nextKnownState);
		iCurrentStartupState = nextKnownState;
		}
		
	//Tell domain manager that we have processed the last state change.
#ifdef __ECOM_SERVER_TESTABILITY__
	AcknowledgeLastStateL(KErrNone);
#else
	AcknowledgeLastState(KErrNone);
#endif
		
	//do not request transition notification if we have reached the last state
	if(nextKnownState == EStartupStateNonCritical)
		{
		Cancel();
		}
	}