diff -r 000000000000 -r 4e1aa6a622a0 sysstatemgmt/systemstarter/src/StartupState.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysstatemgmt/systemstarter/src/StartupState.cpp Tue Feb 02 00:53:00 2010 +0200 @@ -0,0 +1,138 @@ +// 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: +// + +#include "StartupState.h" +#include +#include +#include "StartupStateInfo.h" +#include "StartupCommand.h" +#include "startupdomaindefs.h" + +#include "SysStartDebug.h" + +#include "sysstartpanic.h" +#include "restartsys.h" + +// +// Standard Symbian factory functions +// + +CStartupState* CStartupState::NewL(const MStartupStateInfo& aInfo) + { + CStartupState* self = CStartupState::NewLC(aInfo); + CleanupStack::Pop(self); + return self; + } + +CStartupState* CStartupState::NewLC(const MStartupStateInfo& aInfo) + { + CStartupState* self = new (ELeave) CStartupState(aInfo); + CleanupStack::PushL(self); + return self; + } + +// +// Public functions +// + +void CStartupState::Start() + { + TPtrC stateName = iStateInfo.Name(); + + // Connect to the domain manager in order to notify state transition + RDmDomainManager notifier; + TInt r = notifier.Connect(KDmHierarchyIdStartup); + if (r == KErrNone) + { + //TRequestStatus is used in the while-loop and the loop should be run for the first time, + //so its intial value is set to KErrGeneral.. + TRequestStatus stateNotifyStatus = KErrGeneral; + + // Find out from the value provisioned in the startup configuration file (SSC) + // how many times to re-attempt state change following a state transition failure. + TInt attemptsRequired = iStateInfo.NoOfRetries() + 1; + + while ((stateNotifyStatus != KErrNone) && (attemptsRequired-- >0)) + { + // Request a state change from the domain manager + DEBUGPRINT2(_L("SysStart: Send state transition request (move to %S) to domain manager"), &stateName); + notifier.RequestSystemTransition(iStateInfo.StateId(), + ETraverseParentsFirst, stateNotifyStatus); + + // Wait for result of the state change + User::WaitForRequest(stateNotifyStatus); + DEBUGPRINT2(_L("SysStart: Result of state transition request is %d"), stateNotifyStatus.Int() ); + } + + // If state transition has failed after the specified no of retries, + // take action as specified in the SSC + if (stateNotifyStatus != KErrNone) + { + // Value in configuration file can be set to panic or ignore. + if (iStateInfo.ActionOnStateTransitionFailure() == EPanicOnFailure) + { + DEBUGPRINT2(_L("SysStart: State transition to %S failed"), &stateName); + + // RestartSys will be used to trigger system restart. + TInt ret = RestartSys::RestartSystem(); + if (ret != KErrNone) + { + DEBUGPRINT2(_L("SysStart: RestartSystem failed with error %d"), ret); + PanicNow(KPanicStartupState, ERestartSystemCallFailed); + } + + User::After(5000000); // required by RestartSys API, see comments in RestartSys::RestartSystem() + } + else + { + DEBUGPRINT2(_L("SysStart: State transition to %S failed. Ignoring as specified in the SSC"), &stateName); + } + } + + notifier.Close(); + } + else // Domain manager connection failed. + { + DEBUGPRINT2(_L("SysStart: Domain manager connection failed with error %d"), r); + PanicNow(KPanicStartupState, EDomainManagerConnectionFailure); + } + + // Execute the commands relevant to this state + for (TInt i = 0; i < iStateInfo.Count(); ++i) + { + DoCommand(*(iStateInfo.GetCommand(i))); + } + } + +// +// Private functions +// + +CStartupState::CStartupState(const MStartupStateInfo& aInfo) : + iStateInfo(aInfo) + { + } + +void CStartupState::DoCommand(MStartupCommand& aCommand) + { + TRequestStatus status; + aCommand.Execute(status); + User::WaitForRequest(status); + + if (status!=KErrNone) + { + DEBUGPRINT2(_L("SSC command failed with error %d"), status.Int()); + } + }