diff -r 000000000000 -r 4e1aa6a622a0 sysstatemgmt/systemstatereferenceplugins/clayer/src/saastateadaptation.cpp --- /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 + +#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(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(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 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(ESWStateStartingUiServices) + - static_cast(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(ESWStateStartingUiServices) + - static_cast(ESsmStartupSubStateCriticalStatic); + + // Adjust the substate value + const TInt adjustedNormalSubStateValue = aState.SubState() + KNormalSubStateAdjustment; + + TGlobalState ret = static_cast(0); + + if(aState.MainState() == ESsmStartup) + { + ret = static_cast(adjustedStartupSubStateValue); + } + else if(aState.MainState() == ESsmNormal) + { + ret = static_cast(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 pckgBuf(aEventType); + // Copy event across + iEventOutputBuffer->Copy(pckgBuf); + // Complete status + User::RequestComplete(iEventStatus, KErrNone); + // Clear event status and buffer + iEventOutputBuffer = NULL; + iEventStatus = NULL; + } + }