sysstatemgmt/systemstarter/src/StartupState.cpp
changeset 0 4e1aa6a622a0
--- /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 <domainmanager.h>
+#include <startup.hrh>
+#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());
+		}			
+	}