diff -r 000000000000 -r e4d67989cc36 genericservices/taskscheduler/SCHSVR/SchSSAMan.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericservices/taskscheduler/SCHSVR/SchSSAMan.cpp Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,232 @@ +// 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: +// Implementation of CSchStartupStateMgr class which connects to +// the Domain manager to keep aware of the current start-up +// state and distributes the state changes to registered observers. +// +// + +/** + @file + @internalComponent +*/ + +#include "SchSSAMan.h" +#include "SchLogger.h" + +/** +constructor of CSchStartupStateMgr +@internalComponent +*/ +CSchStartupStateMgr::CSchStartupStateMgr(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId) : + CDmDomain(aHierarchyId,aDomainId), + iCurrentStartupState(EStartupStateUndefined) + { + } + +/** +destructor of CSchStartupStateMgr +@internalComponent +*/ +CSchStartupStateMgr::~CSchStartupStateMgr() + { + Cancel(); + iObserverList.Reset(); + } + +/** +Getter +@internalComponent +@return the current startup state +*/ +TStartupStateIdentifier CSchStartupStateMgr::CurrentStartupState() + { + return iCurrentStartupState; + } + +/** +updates the MSchStartupStateObserver objects. +@internalComponent +*/ +void CSchStartupStateMgr::UpdateStateAwareObjectsL(TStartupStateIdentifier aKnownState) + { + for (TInt i = 0; i < iObserverList.Count(); i++) + { + iObserverList[i]->ProcessSSAEventL(aKnownState); + } + } + +/** +This method takes a a startup state which can be user defined +state and maps it to a known startup state (KSS). KSS are +Symbian defined states: undefined, critical static, critical dynamic, +and non-critical. +User defined states are refered to as USS - unknown startup state. + +@internalComponent +*/ +TStartupStateIdentifier CSchStartupStateMgr::GetKnownStartupState(TDmDomainState aStartupState) + { + TStartupStateIdentifier knownStartupState = iCurrentStartupState; + + if (aStartupState >= EStartupStateNonCritical) + { + knownStartupState = EStartupStateNonCritical; + } + else if(aStartupState >= EStartupStateCriticalDynamic) + { + knownStartupState = EStartupStateCriticalDynamic; + } + else if(aStartupState >= EStartupStateCriticalStatic) + { + knownStartupState = EStartupStateCriticalStatic; + } + else + { + knownStartupState = EStartupStateUndefined; + } + + return knownStartupState; + } + +/** +Register the MSchStartupStateObserver object with the CServerStartupMgr. +@internalComponent +@param aObs the pointer to the MStartupStateObserver object to be registered with CServerStartupMgr. +*/ +void CSchStartupStateMgr::RegisterObserverL(const MSchStartupStateObserver* aObs) + { + User::LeaveIfError(iObserverList.Append(aObs)); + } + +/** +Handle the error if RunL leaves. Just tell the observers that +we have reached the final state. + +@internalComponent +@param aError error code generated by the RunL(), not used here. +@return KErrNone to avoid CActiveScheduler to panic. +*/ +TInt CSchStartupStateMgr::RunError(TInt /*aError*/) + { + LOGSTRING("CSchStartupStateMgr::RunL() leaves, set SS to final state."); + TRAP_IGNORE(UpdateStateAwareObjectsL(KSchFinalStartupState)); + return KErrNone; + } + +/** +Finsish constructing the CSchStartupStateMgr and start +interacting with Domain Manager to receive startup state +changes. +All observers should have been registered before calling this method + +@internalComponent +*/ +void CSchStartupStateMgr::InitialiseL() + { + TRAPD(err, CDmDomain::ConstructL()); + if (err != KErrNone) + { + // the ConstructL leaves, go to final state + LOGSTRING2("CDmDomain::ConstructL leaves with %d. Goto final state", err); + UpdateStateAwareObjectsL(KSchFinalStartupState); + iCurrentStartupState = KSchFinalStartupState; + return; + } + + // Typical pattern of using P&S is to subscribe first then get + // current state. Example implementation given + // in SSA Adaptation How-to also does it this way. + RequestTransitionNotification(); + + // get the start up state from the Domain Manager. + TDmDomainState rawstate = GetState(); + + // rawstate may be user defined. Map to known states. + TStartupStateIdentifier nextKnownState = GetKnownStartupState(rawstate); + + // NB: nextKnownState can be KStartupStateUndefined for 2 reasons. + // One is rawstate == 0 which we must check first. Second: + // rawstate is user defined values lower than critical static. In + // the second case we must wait for next state change. + if (rawstate == EStartupStateUndefined || + nextKnownState == KSchFinalStartupState) + { + // If either something wrong with DM or final state is reached, + // go to final state + iCurrentStartupState = KSchFinalStartupState; + UpdateStateAwareObjectsL(KSchFinalStartupState); + Cancel(); + return; + } + + iCurrentStartupState = nextKnownState; + } + +/** +Executed when the startup state change is done, it does the +same thing as the method InitialiseL() does +@internalComponent +*/ +void CSchStartupStateMgr::RunL() + { + if(iStatus != KErrNone) // something wrong with the RequestTransitionNotification(). + { + AcknowledgeLastState(iStatus.Int()); //Acknowledge the domainmanager in case of leaving, this to avoid the acknowledgement in RunError() + User::LeaveIfError(iStatus.Int()); //RunError will handle this. + } + + RequestTransitionNotification(); + + TDmDomainState rawstate = GetState(); + + // Must first check the case rawstate == undefined and deal with it here. + // GetKnowStartupState maps 1 to 15 to EStartupStateUndefined + // which means a SS before critical static. It does not mean go + // to final state. + + //If the rawstate is EStartupStateUndefined there must be sth wrong. + if(rawstate == EStartupStateUndefined) + { + Cancel(); + AcknowledgeLastState(KErrBadHandle); + User::Leave(KErrBadHandle); //RunError will handle this. + } + + // get the known state + TStartupStateIdentifier nextKnownState = GetKnownStartupState(rawstate); + + //Tell domain manager that we have processed the last state change before starting any time consuming work. + AcknowledgeLastState(KErrNone); + + //Sleep 2 tickperiods this allows the acknowledgement reach the domain manager. + TTimeIntervalMicroSeconds32 tickPeriod; + UserHal::TickPeriod(tickPeriod); + User::After(2*tickPeriod.Int()); + + // Schsvr only want to know transition to non-critical. + // Ignore all states below that level. + if (iCurrentStartupState < KSchFinalStartupState && nextKnownState == KSchFinalStartupState) + { + UpdateStateAwareObjectsL(nextKnownState); + } + + iCurrentStartupState = nextKnownState; + + //do not request transition notification if we have reached the last state + if(iCurrentStartupState == KSchFinalStartupState) + { + Cancel(); + } + }