sysstatemgmt/systemstatereferenceplugins/clayer/src/saastateadaptation.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysstatemgmt/systemstatereferenceplugins/clayer/src/saastateadaptation.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,523 @@
+// Copyright (c) 2007-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 <ssm/ssmsubstates.hrh>
+
+#include "ssmdebug.h"
+
+#include "saastateadaptation.h"
+#include "clayerpanic.h"
+#include "startupadaptationadapter.h"
+
+
+/*
+ * Creates a new object associated with the passed in CStartupAdaptationAdapter
+ * 
+ * @internalComponent
+ */
+CSaaStateAdaptation* CSaaStateAdaptation::NewL(CStartupAdaptationAdapter* aAdapter)
+	{
+	CSaaStateAdaptation* self = new (ELeave) CSaaStateAdaptation(aAdapter);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/*
+ * Destructor for this object
+ * 
+ * @internalComponent
+ */
+CSaaStateAdaptation::~CSaaStateAdaptation()
+	{
+	iEventQueue.Close();
+	}
+
+/*
+ * Decrements the reference count for this object, deleting it if necessary
+ * 
+ * @internalComponent
+ */
+void CSaaStateAdaptation::Release()
+	{
+	// This MClass is owned by the singleton CStartupAdaptationAdapter class so
+	// release should do nothing.
+	}
+
+/*
+ * 
+ * 
+ * @internalComponent
+ */
+void CSaaStateAdaptation::RequestCoopSysStateChange(TSsmState aState, TRequestStatus& aStatus)
+	{
+	// If this adaptation is busy then complete with KErrInUse
+	if(Busy())
+		{
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, KErrInUse);
+		return;
+		}
+	// Set this request status
+	SetRequestStatus(&aStatus);
+	aStatus = KRequestPending;
+	// No outstand requests so set up command id
+	SetCommandId(StartupAdaptation::EGlobalStateChange);
+	// Map TSsmState to TGlobalState
+	iGlobalStatePckg() = MapToStartupAdaptationState(aState);
+	
+	// Pass this to the adapter
+	TRAPD(err, iAdapter->QueueDispatchL(this));
+	if(err != KErrNone)
+		{
+		// Failed to queue adaptation, complete with error
+		SetRequestStatus(NULL);
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, err);
+		}	
+	}  //lint !e1746 Suppress parameter 'aState' could be made const reference
+
+/*
+ * 
+ * 
+ * @internalComponent
+ */
+void CSaaStateAdaptation::RequestCoopSysSelfTest(TRequestStatus& aStatus)
+	{
+	// If this adaptation is busy then complete with KErrInUse
+	if(Busy())
+		{
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, KErrInUse);
+		return;
+		}
+	// Set this request status
+	SetRequestStatus(&aStatus);
+	aStatus = KRequestPending;
+	// No outstand requests so set up command id
+	SetCommandId(StartupAdaptation::EExecuteSelftests);
+	// No parameters to set to pass in
+	
+	// Pass this to the adapter
+	TRAPD(err, iAdapter->QueueDispatchL(this));
+	if(err != KErrNone)
+		{
+		// Failed to queue adaptation, complete with error
+		SetRequestStatus(NULL);
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, err);
+		}
+	}
+
+/*
+ * 
+ * 
+ * @internalComponent
+ */
+void CSaaStateAdaptation::RequestCoopSysPerformRestartActions(TInt aReason, TRequestStatus& aStatus)
+	{
+	// If this adaptation is busy then complete with KErrInUse
+	if(Busy())
+		{
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, KErrInUse);
+		return;
+		}
+	// Set this request status
+	SetRequestStatus(&aStatus);
+	aStatus = KRequestPending;
+	// No outstand requests so set up command id
+	SetCommandId(StartupAdaptation::EExecuteReset);
+	// Set the reason package contents
+	iResetReasonPckg() = static_cast<StartupAdaptation::TResetReason>(aReason);
+	
+	// Pass this to the adapter
+	TRAPD(err, iAdapter->QueueDispatchL(this));
+	if(err != KErrNone)
+		{
+		// Failed to queue adaptation, complete with error
+		SetRequestStatus(NULL);
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, err);
+		}
+	}
+
+/*
+ * 
+ * 
+ * @internalComponent
+ */
+void CSaaStateAdaptation::RequestCoopSysPerformShutdownActions(TInt /*aReason*/, TRequestStatus& aStatus)
+	{
+	// If this adaptation is busy then complete with KErrInUse
+	if(Busy())
+		{
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, KErrInUse);
+		return;
+		}
+	// Set this request status
+	SetRequestStatus(&aStatus);
+	aStatus = KRequestPending;
+	// No outstand requests so set up command id
+	SetCommandId(StartupAdaptation::EExecuteShutdown);
+	// No parameters to set to pass in
+	
+	// Pass this to the adapter
+	TRAPD(err, iAdapter->QueueDispatchL(this));
+	if(err != KErrNone)
+		{
+		// Failed to queue adaptation, complete with error
+		SetRequestStatus(NULL);
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, err);
+		}
+	}
+
+/*
+ * 
+ * 
+ * @internalComponent
+ */
+void CSaaStateAdaptation::RequestCoopSysPerformRfsActions(TSsmRfsType aRfsType, TRequestStatus& aStatus)
+	{
+	// If this adaptation is busy then complete with KErrInUse
+	if(Busy())
+		{
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, KErrInUse);
+		return;
+		}
+	// Set this request status
+	SetRequestStatus(&aStatus);
+	aStatus = KRequestPending;
+	// No outstand requests so set up command id
+	SetCommandId(StartupAdaptation::EExecuteDOSRfs);
+	// Set up the reason
+	switch(aRfsType)
+		{
+		case ESsmShallowRfs:
+			iRfsReasonPckg() = StartupAdaptation::ENormalRFS;
+			break;
+		case ESsmDeepRfs:
+			iRfsReasonPckg() = StartupAdaptation::EDeepRFS;
+			break;
+		default:
+			// Assume the reason is a custom one
+			iRfsReasonPckg() = static_cast<StartupAdaptation::TRFSReason>(aRfsType);
+			break;
+		}
+	// Pass this to the adapter
+	TRAPD(err, iAdapter->QueueDispatchL(this));
+	if(err != KErrNone)
+		{
+		// Failed to queue adaptation, complete with error
+		SetRequestStatus(NULL);
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, err);
+		}
+	}
+
+/*
+ * 
+ * 
+ * @internalComponent
+ */
+void CSaaStateAdaptation::RequestCancel()
+	{
+	CancelRequest();
+	}
+
+/*
+ * 
+ * 
+ * @internalComponent
+ */
+void CSaaStateAdaptation::NotifyCoopSysEvent(TDes8& aEvent, TRequestStatus& aStatus)
+	{
+	if(iEventStatus != NULL)
+		{
+		DEBUGPRINT1A("SAA - Multiple notify coop sys event requests detected, completing with KErrInUse");
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, KErrInUse);
+		return;
+		}
+	if(iEventQueue.Count() != 0)
+		{
+		// Complete immediately with an event from the queue
+		DEBUGPRINT1A("SAA - Completing notify coop sys event immediately with queued event");
+		// Read value from array
+		TPckgBuf<TSsmCoopSysEventType> pckgBuf(iEventQueue[0]);
+		// Remove value from array
+		iEventQueue.Remove(0);
+		// Copy descriptor package across
+		aEvent.Copy(pckgBuf);
+		// Complete status
+		TRequestStatus* statusPtr = &aStatus;
+		User::RequestComplete(statusPtr, KErrNone);		
+		}
+	else
+		{
+		// No events in queue so wait
+		aStatus = KRequestPending;
+		iEventStatus = &aStatus;
+		iEventOutputBuffer = &aEvent;
+		}
+	}
+
+/*
+ * 
+ * 
+ * @internalComponent
+ */
+void CSaaStateAdaptation::NotifyCancel()
+	{
+	if(iEventStatus != NULL)
+		{
+		User::RequestComplete(iEventStatus, KErrCancel);
+		iEventStatus = NULL;
+		}
+	// Clear buffer
+	iEventOutputBuffer = NULL;
+	}
+
+/*
+ * Constructs a new state adaptation object and associates it with aAdapter
+ * 
+ * @internalComponent
+ */
+CSaaStateAdaptation::CSaaStateAdaptation(CStartupAdaptationAdapter* aAdapter)
+: CAdaptationBase(aAdapter)
+	{
+	
+	}
+
+/**
+ * Number of events to pre-allocate in the event queue
+ * 
+ * @internalComponent
+ */
+const TInt KEventQueueReserveValue = 8;
+
+/*
+ * Second phase of construction 
+ * 
+ * @internalComponent
+ */
+void CSaaStateAdaptation::ConstructL()
+	{
+	// Preallocate event queue some memory
+	iEventQueue.ReserveL(KEventQueueReserveValue);
+	}
+
+/**
+ * See CAdaptationBase for description of method.
+ *  
+ * @internalComponent
+ */
+void CSaaStateAdaptation::RequestComplete(const StartupAdaptation::TCommand __DEBUG_ONLY(aCommandId), TDesC8& aRetPckg)
+	{
+	DEBUGPRINT3A("SAA - Response received from adaptation with commandId: %d, expecting %d", aCommandId, CommandId());
+	__ASSERT_DEBUG(aCommandId == CommandId(), CLAYER_PANIC(ECLayerUnexpectedCommandResponse));
+	switch(CommandId())
+		{
+		case StartupAdaptation::EGlobalStateChange: // fall through
+		case StartupAdaptation::EExecuteSelftests: // fall through
+		case StartupAdaptation::EExecuteShutdown: // fall through
+		case StartupAdaptation::EExecuteReset: // fall through
+		case StartupAdaptation::EExecuteDOSRfs:
+			{
+				StartupAdaptation::TResponsePckg responsePckg;
+				responsePckg.Copy(aRetPckg);
+				CompleteRequestStatus(responsePckg());
+				break;
+			}
+		default:
+			// Return an error to the client
+			CompleteRequestStatus(KErrArgument);
+			break;
+		}
+	}
+
+/**
+ * See CAdaptationBase for description of method.
+ *  
+ * @internalComponent
+ */
+TDesC8* CSaaStateAdaptation::ParameterPckg()
+	{
+	TDesC8* ptr = NULL;
+	switch(CommandId())
+		{
+		case StartupAdaptation::EGlobalStateChange:
+			ptr = &iGlobalStatePckg;
+			break;
+		case StartupAdaptation::EExecuteSelftests:
+			ptr = &iNullBuf;
+			break;
+		case StartupAdaptation::EExecuteShutdown:
+			ptr = &iNullBuf;
+			break;
+		case StartupAdaptation::EExecuteDOSRfs:
+			ptr = &iRfsReasonPckg;
+			break;
+		case StartupAdaptation::EExecuteReset:
+			ptr = &iResetReasonPckg;
+			break;
+		default:
+			ptr = NULL;
+			break;
+		}
+	return ptr;
+	}
+
+/**
+ * Maps a TSsmState object into the associated StartupAdaptation::TGlobalState value.
+ * 
+ * Uses the following mappings:
+ * 
+ * ESWStateStartingUiServices = TSsmState(ESsmStartup, ESWStateStartingUiServices - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); 
+ * ESWStateStartingCriticalApps = TSsmState(ESsmStartup, ESWStateStartingCriticalApps - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);  
+ * ESWStateSelfTestOK = TSsmState(ESsmStartup, ESWStateSelfTestOK - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
+ * // States for the security check phase.
+ * ESWStateSecurityCheck = TSsmState(ESsmStartup, ESWStateSecurityCheck - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
+ * ESWStateCriticalPhaseOK = TSsmState(ESsmStartup, ESWStateCriticalPhaseOK - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
+ * ESWStateEmergencyCallsOnly = TSsmState(ESsmStartup, ESWStateEmergencyCallsOnly - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
+ * // Terminal states defined by the boot mode (and some other variables such as offline mode).
+ * ESWStateTest = TSsmState(ESsmStartup, ESWStateTest - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
+ * ESWStateCharging = TSsmState(ESsmStartup, ESWStateCharging - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
+ * ESWStateAlarm = TSsmState(ESsmStartup, ESWStateAlarm - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
+ * ESWStateNormalRfOn = TSsmState(ESsmNormal, ESWStateNormalRfOn - ESWStateStartingUiServices + ESsmStartupSubStateCriticalStatic);
+ * ESWStateNormalRfOff = TSsmState(ESsmNormal, ESWStateNormalRfOff - ESWStateStartingUiServices + ESsmStartupSubStateCriticalStatic);
+ * ESWStateNormalBTSap = TSsmState(ESsmNormal, ESWStateNormalBTSap - ESWStateStartingUiServices + ESsmStartupSubStateCriticalStatic);
+ * // States for notifying adaptation about a terminal state change.
+ * ESWStateAlarmToCharging = TSsmState(ESsmStartup, ESWStateAlarmToCharging - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
+ * ESWStateChargingToAlarm = TSsmState(ESsmStartup, ESWStateChargingToAlarm - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
+ * ESWStateChargingToNormal = TSsmState(ESsmStartup, ESWStateChargingToNormal - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
+ * ESWStateAlarmToNormal = TSsmState(ESsmStartup, ESWStateAlarmToNormal - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
+ * // Shutdown-related states.
+ * ESWStateShuttingDown = TSsmState(ESsmShutdown, KSsmAnySubState);
+ * // Error states during critical phase.
+ * ESWStateFatalStartupError = TSsmState(ESsmFail, KSsmAnySubState);
+ * 
+ * Returns 0 on invalid TSsmState
+ * 
+ * @internalComponent
+ */
+StartupAdaptation::TGlobalState CSaaStateAdaptation::MapToStartupAdaptationState(TSsmState aState)
+	{
+	using namespace StartupAdaptation;
+	
+	// Calculate the difference from the substate to the value of TGlobalState values
+	// This uses ESsmStartupSubStateNonCritical to map to the correct part of the staged
+	// start-up architecture and therefore to map the states as described in the comment
+	// for this method.
+	const TInt KStartupSubStateAdjustment = static_cast<TInt>(ESWStateStartingUiServices) 
+											- static_cast<TInt>(ESsmStartupSubStateNonCritical);
+	// Adjust the substate value
+	const TInt adjustedStartupSubStateValue = aState.SubState() + KStartupSubStateAdjustment;
+	
+	// Calculate the difference from the substate to the value of TGlobalState values
+	// This uses ESsmStartupSubStateCriticalStatic to map to the correct states as described
+	// in the comment for this method.
+	const TInt KNormalSubStateAdjustment = static_cast<TInt>(ESWStateStartingUiServices) 
+	 										- static_cast<TInt>(ESsmStartupSubStateCriticalStatic);
+
+	// Adjust the substate value
+	const TInt adjustedNormalSubStateValue = aState.SubState() + KNormalSubStateAdjustment;
+	
+	TGlobalState ret = static_cast<TGlobalState>(0);
+	
+	if(aState.MainState() == ESsmStartup)
+		{
+		ret = static_cast<TGlobalState>(adjustedStartupSubStateValue);
+		}
+	else if(aState.MainState() == ESsmNormal)
+		{
+		ret = static_cast<TGlobalState>(adjustedNormalSubStateValue);
+		}
+	else if(aState.MainState() == ESsmShutdown)
+		{
+		ret = ESWStateShuttingDown;
+		}
+	else if(aState.MainState() == ESsmFail)
+		{
+		ret = ESWStateFatalStartupError;
+		}
+	
+	// Validate the return value is correct
+	switch(aState.MainState())
+		{
+		case ESsmStartup:
+			if(ret < ESWStateStartingUiServices || 
+					(ret > ESWStateAlarm && ret < ESWStateAlarmToCharging) || 
+					ret > ESWStateAlarmToNormal)
+				{
+				CLAYER_PANIC(ECLayerInvalidSubState);
+				}
+			break;
+		case ESsmNormal:
+			if(ret < ESWStateNormalRfOn || ret > ESWStateNormalBTSap)
+				{
+				CLAYER_PANIC(ECLayerInvalidSubState);
+				}
+			break;
+		case ESsmShutdown:
+			if(aState.SubState() != KSsmAnySubState)
+				{
+				CLAYER_PANIC(ECLayerInvalidSubState);
+				}
+			break;
+		case ESsmFail:
+			if(aState.SubState() != KSsmAnySubState)
+				{
+				CLAYER_PANIC(ECLayerInvalidSubState);
+				}
+			break;
+		default:
+			// Do nothing
+			break;
+		}
+	return ret;
+	} //lint !e1746 Suppress parameter 'aState' could be made const reference
+
+/**
+ * Processes the event passed in and distributes to waiting client or queues event.
+ * 
+ * @internalComponent
+ */
+void CSaaStateAdaptation::ProcessEventL(TSsmCoopSysEventType aEventType)
+	{
+	DEBUGPRINT2A("SAA - State adaptation processing event with type: %d", aEventType);
+	if(iEventStatus == NULL)
+		{
+		// Need to queue event as nothing is waiting to be notified
+		iEventQueue.AppendL(aEventType);
+		}
+	else
+		{
+		// Client waiting for event
+		__ASSERT_DEBUG(iEventOutputBuffer != NULL, CLAYER_PANIC(ECLayerNullStateEventBuffer));
+		TPckgBuf<TSsmCoopSysEventType> pckgBuf(aEventType);
+		// Copy event across
+		iEventOutputBuffer->Copy(pckgBuf);
+		// Complete status
+		User::RequestComplete(iEventStatus, KErrNone);
+		// Clear event status and buffer
+		iEventOutputBuffer = NULL;
+		iEventStatus = NULL;
+		}
+	}