sysstatemgmt/systemstatereferenceplugins/clayer/src/saastateadaptation.cpp
changeset 0 4e1aa6a622a0
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <ssm/ssmsubstates.hrh>
       
    17 
       
    18 #include "ssmdebug.h"
       
    19 
       
    20 #include "saastateadaptation.h"
       
    21 #include "clayerpanic.h"
       
    22 #include "startupadaptationadapter.h"
       
    23 
       
    24 
       
    25 /*
       
    26  * Creates a new object associated with the passed in CStartupAdaptationAdapter
       
    27  * 
       
    28  * @internalComponent
       
    29  */
       
    30 CSaaStateAdaptation* CSaaStateAdaptation::NewL(CStartupAdaptationAdapter* aAdapter)
       
    31 	{
       
    32 	CSaaStateAdaptation* self = new (ELeave) CSaaStateAdaptation(aAdapter);
       
    33 	CleanupStack::PushL(self);
       
    34 	self->ConstructL();
       
    35 	CleanupStack::Pop(self);
       
    36 	return self;
       
    37 	}
       
    38 
       
    39 /*
       
    40  * Destructor for this object
       
    41  * 
       
    42  * @internalComponent
       
    43  */
       
    44 CSaaStateAdaptation::~CSaaStateAdaptation()
       
    45 	{
       
    46 	iEventQueue.Close();
       
    47 	}
       
    48 
       
    49 /*
       
    50  * Decrements the reference count for this object, deleting it if necessary
       
    51  * 
       
    52  * @internalComponent
       
    53  */
       
    54 void CSaaStateAdaptation::Release()
       
    55 	{
       
    56 	// This MClass is owned by the singleton CStartupAdaptationAdapter class so
       
    57 	// release should do nothing.
       
    58 	}
       
    59 
       
    60 /*
       
    61  * 
       
    62  * 
       
    63  * @internalComponent
       
    64  */
       
    65 void CSaaStateAdaptation::RequestCoopSysStateChange(TSsmState aState, TRequestStatus& aStatus)
       
    66 	{
       
    67 	// If this adaptation is busy then complete with KErrInUse
       
    68 	if(Busy())
       
    69 		{
       
    70 		TRequestStatus* statusPtr = &aStatus;
       
    71 		User::RequestComplete(statusPtr, KErrInUse);
       
    72 		return;
       
    73 		}
       
    74 	// Set this request status
       
    75 	SetRequestStatus(&aStatus);
       
    76 	aStatus = KRequestPending;
       
    77 	// No outstand requests so set up command id
       
    78 	SetCommandId(StartupAdaptation::EGlobalStateChange);
       
    79 	// Map TSsmState to TGlobalState
       
    80 	iGlobalStatePckg() = MapToStartupAdaptationState(aState);
       
    81 	
       
    82 	// Pass this to the adapter
       
    83 	TRAPD(err, iAdapter->QueueDispatchL(this));
       
    84 	if(err != KErrNone)
       
    85 		{
       
    86 		// Failed to queue adaptation, complete with error
       
    87 		SetRequestStatus(NULL);
       
    88 		TRequestStatus* statusPtr = &aStatus;
       
    89 		User::RequestComplete(statusPtr, err);
       
    90 		}	
       
    91 	}  //lint !e1746 Suppress parameter 'aState' could be made const reference
       
    92 
       
    93 /*
       
    94  * 
       
    95  * 
       
    96  * @internalComponent
       
    97  */
       
    98 void CSaaStateAdaptation::RequestCoopSysSelfTest(TRequestStatus& aStatus)
       
    99 	{
       
   100 	// If this adaptation is busy then complete with KErrInUse
       
   101 	if(Busy())
       
   102 		{
       
   103 		TRequestStatus* statusPtr = &aStatus;
       
   104 		User::RequestComplete(statusPtr, KErrInUse);
       
   105 		return;
       
   106 		}
       
   107 	// Set this request status
       
   108 	SetRequestStatus(&aStatus);
       
   109 	aStatus = KRequestPending;
       
   110 	// No outstand requests so set up command id
       
   111 	SetCommandId(StartupAdaptation::EExecuteSelftests);
       
   112 	// No parameters to set to pass in
       
   113 	
       
   114 	// Pass this to the adapter
       
   115 	TRAPD(err, iAdapter->QueueDispatchL(this));
       
   116 	if(err != KErrNone)
       
   117 		{
       
   118 		// Failed to queue adaptation, complete with error
       
   119 		SetRequestStatus(NULL);
       
   120 		TRequestStatus* statusPtr = &aStatus;
       
   121 		User::RequestComplete(statusPtr, err);
       
   122 		}
       
   123 	}
       
   124 
       
   125 /*
       
   126  * 
       
   127  * 
       
   128  * @internalComponent
       
   129  */
       
   130 void CSaaStateAdaptation::RequestCoopSysPerformRestartActions(TInt aReason, TRequestStatus& aStatus)
       
   131 	{
       
   132 	// If this adaptation is busy then complete with KErrInUse
       
   133 	if(Busy())
       
   134 		{
       
   135 		TRequestStatus* statusPtr = &aStatus;
       
   136 		User::RequestComplete(statusPtr, KErrInUse);
       
   137 		return;
       
   138 		}
       
   139 	// Set this request status
       
   140 	SetRequestStatus(&aStatus);
       
   141 	aStatus = KRequestPending;
       
   142 	// No outstand requests so set up command id
       
   143 	SetCommandId(StartupAdaptation::EExecuteReset);
       
   144 	// Set the reason package contents
       
   145 	iResetReasonPckg() = static_cast<StartupAdaptation::TResetReason>(aReason);
       
   146 	
       
   147 	// Pass this to the adapter
       
   148 	TRAPD(err, iAdapter->QueueDispatchL(this));
       
   149 	if(err != KErrNone)
       
   150 		{
       
   151 		// Failed to queue adaptation, complete with error
       
   152 		SetRequestStatus(NULL);
       
   153 		TRequestStatus* statusPtr = &aStatus;
       
   154 		User::RequestComplete(statusPtr, err);
       
   155 		}
       
   156 	}
       
   157 
       
   158 /*
       
   159  * 
       
   160  * 
       
   161  * @internalComponent
       
   162  */
       
   163 void CSaaStateAdaptation::RequestCoopSysPerformShutdownActions(TInt /*aReason*/, TRequestStatus& aStatus)
       
   164 	{
       
   165 	// If this adaptation is busy then complete with KErrInUse
       
   166 	if(Busy())
       
   167 		{
       
   168 		TRequestStatus* statusPtr = &aStatus;
       
   169 		User::RequestComplete(statusPtr, KErrInUse);
       
   170 		return;
       
   171 		}
       
   172 	// Set this request status
       
   173 	SetRequestStatus(&aStatus);
       
   174 	aStatus = KRequestPending;
       
   175 	// No outstand requests so set up command id
       
   176 	SetCommandId(StartupAdaptation::EExecuteShutdown);
       
   177 	// No parameters to set to pass in
       
   178 	
       
   179 	// Pass this to the adapter
       
   180 	TRAPD(err, iAdapter->QueueDispatchL(this));
       
   181 	if(err != KErrNone)
       
   182 		{
       
   183 		// Failed to queue adaptation, complete with error
       
   184 		SetRequestStatus(NULL);
       
   185 		TRequestStatus* statusPtr = &aStatus;
       
   186 		User::RequestComplete(statusPtr, err);
       
   187 		}
       
   188 	}
       
   189 
       
   190 /*
       
   191  * 
       
   192  * 
       
   193  * @internalComponent
       
   194  */
       
   195 void CSaaStateAdaptation::RequestCoopSysPerformRfsActions(TSsmRfsType aRfsType, TRequestStatus& aStatus)
       
   196 	{
       
   197 	// If this adaptation is busy then complete with KErrInUse
       
   198 	if(Busy())
       
   199 		{
       
   200 		TRequestStatus* statusPtr = &aStatus;
       
   201 		User::RequestComplete(statusPtr, KErrInUse);
       
   202 		return;
       
   203 		}
       
   204 	// Set this request status
       
   205 	SetRequestStatus(&aStatus);
       
   206 	aStatus = KRequestPending;
       
   207 	// No outstand requests so set up command id
       
   208 	SetCommandId(StartupAdaptation::EExecuteDOSRfs);
       
   209 	// Set up the reason
       
   210 	switch(aRfsType)
       
   211 		{
       
   212 		case ESsmShallowRfs:
       
   213 			iRfsReasonPckg() = StartupAdaptation::ENormalRFS;
       
   214 			break;
       
   215 		case ESsmDeepRfs:
       
   216 			iRfsReasonPckg() = StartupAdaptation::EDeepRFS;
       
   217 			break;
       
   218 		default:
       
   219 			// Assume the reason is a custom one
       
   220 			iRfsReasonPckg() = static_cast<StartupAdaptation::TRFSReason>(aRfsType);
       
   221 			break;
       
   222 		}
       
   223 	// Pass this to the adapter
       
   224 	TRAPD(err, iAdapter->QueueDispatchL(this));
       
   225 	if(err != KErrNone)
       
   226 		{
       
   227 		// Failed to queue adaptation, complete with error
       
   228 		SetRequestStatus(NULL);
       
   229 		TRequestStatus* statusPtr = &aStatus;
       
   230 		User::RequestComplete(statusPtr, err);
       
   231 		}
       
   232 	}
       
   233 
       
   234 /*
       
   235  * 
       
   236  * 
       
   237  * @internalComponent
       
   238  */
       
   239 void CSaaStateAdaptation::RequestCancel()
       
   240 	{
       
   241 	CancelRequest();
       
   242 	}
       
   243 
       
   244 /*
       
   245  * 
       
   246  * 
       
   247  * @internalComponent
       
   248  */
       
   249 void CSaaStateAdaptation::NotifyCoopSysEvent(TDes8& aEvent, TRequestStatus& aStatus)
       
   250 	{
       
   251 	if(iEventStatus != NULL)
       
   252 		{
       
   253 		DEBUGPRINT1A("SAA - Multiple notify coop sys event requests detected, completing with KErrInUse");
       
   254 		TRequestStatus* statusPtr = &aStatus;
       
   255 		User::RequestComplete(statusPtr, KErrInUse);
       
   256 		return;
       
   257 		}
       
   258 	if(iEventQueue.Count() != 0)
       
   259 		{
       
   260 		// Complete immediately with an event from the queue
       
   261 		DEBUGPRINT1A("SAA - Completing notify coop sys event immediately with queued event");
       
   262 		// Read value from array
       
   263 		TPckgBuf<TSsmCoopSysEventType> pckgBuf(iEventQueue[0]);
       
   264 		// Remove value from array
       
   265 		iEventQueue.Remove(0);
       
   266 		// Copy descriptor package across
       
   267 		aEvent.Copy(pckgBuf);
       
   268 		// Complete status
       
   269 		TRequestStatus* statusPtr = &aStatus;
       
   270 		User::RequestComplete(statusPtr, KErrNone);		
       
   271 		}
       
   272 	else
       
   273 		{
       
   274 		// No events in queue so wait
       
   275 		aStatus = KRequestPending;
       
   276 		iEventStatus = &aStatus;
       
   277 		iEventOutputBuffer = &aEvent;
       
   278 		}
       
   279 	}
       
   280 
       
   281 /*
       
   282  * 
       
   283  * 
       
   284  * @internalComponent
       
   285  */
       
   286 void CSaaStateAdaptation::NotifyCancel()
       
   287 	{
       
   288 	if(iEventStatus != NULL)
       
   289 		{
       
   290 		User::RequestComplete(iEventStatus, KErrCancel);
       
   291 		iEventStatus = NULL;
       
   292 		}
       
   293 	// Clear buffer
       
   294 	iEventOutputBuffer = NULL;
       
   295 	}
       
   296 
       
   297 /*
       
   298  * Constructs a new state adaptation object and associates it with aAdapter
       
   299  * 
       
   300  * @internalComponent
       
   301  */
       
   302 CSaaStateAdaptation::CSaaStateAdaptation(CStartupAdaptationAdapter* aAdapter)
       
   303 : CAdaptationBase(aAdapter)
       
   304 	{
       
   305 	
       
   306 	}
       
   307 
       
   308 /**
       
   309  * Number of events to pre-allocate in the event queue
       
   310  * 
       
   311  * @internalComponent
       
   312  */
       
   313 const TInt KEventQueueReserveValue = 8;
       
   314 
       
   315 /*
       
   316  * Second phase of construction 
       
   317  * 
       
   318  * @internalComponent
       
   319  */
       
   320 void CSaaStateAdaptation::ConstructL()
       
   321 	{
       
   322 	// Preallocate event queue some memory
       
   323 	iEventQueue.ReserveL(KEventQueueReserveValue);
       
   324 	}
       
   325 
       
   326 /**
       
   327  * See CAdaptationBase for description of method.
       
   328  *  
       
   329  * @internalComponent
       
   330  */
       
   331 void CSaaStateAdaptation::RequestComplete(const StartupAdaptation::TCommand __DEBUG_ONLY(aCommandId), TDesC8& aRetPckg)
       
   332 	{
       
   333 	DEBUGPRINT3A("SAA - Response received from adaptation with commandId: %d, expecting %d", aCommandId, CommandId());
       
   334 	__ASSERT_DEBUG(aCommandId == CommandId(), CLAYER_PANIC(ECLayerUnexpectedCommandResponse));
       
   335 	switch(CommandId())
       
   336 		{
       
   337 		case StartupAdaptation::EGlobalStateChange: // fall through
       
   338 		case StartupAdaptation::EExecuteSelftests: // fall through
       
   339 		case StartupAdaptation::EExecuteShutdown: // fall through
       
   340 		case StartupAdaptation::EExecuteReset: // fall through
       
   341 		case StartupAdaptation::EExecuteDOSRfs:
       
   342 			{
       
   343 				StartupAdaptation::TResponsePckg responsePckg;
       
   344 				responsePckg.Copy(aRetPckg);
       
   345 				CompleteRequestStatus(responsePckg());
       
   346 				break;
       
   347 			}
       
   348 		default:
       
   349 			// Return an error to the client
       
   350 			CompleteRequestStatus(KErrArgument);
       
   351 			break;
       
   352 		}
       
   353 	}
       
   354 
       
   355 /**
       
   356  * See CAdaptationBase for description of method.
       
   357  *  
       
   358  * @internalComponent
       
   359  */
       
   360 TDesC8* CSaaStateAdaptation::ParameterPckg()
       
   361 	{
       
   362 	TDesC8* ptr = NULL;
       
   363 	switch(CommandId())
       
   364 		{
       
   365 		case StartupAdaptation::EGlobalStateChange:
       
   366 			ptr = &iGlobalStatePckg;
       
   367 			break;
       
   368 		case StartupAdaptation::EExecuteSelftests:
       
   369 			ptr = &iNullBuf;
       
   370 			break;
       
   371 		case StartupAdaptation::EExecuteShutdown:
       
   372 			ptr = &iNullBuf;
       
   373 			break;
       
   374 		case StartupAdaptation::EExecuteDOSRfs:
       
   375 			ptr = &iRfsReasonPckg;
       
   376 			break;
       
   377 		case StartupAdaptation::EExecuteReset:
       
   378 			ptr = &iResetReasonPckg;
       
   379 			break;
       
   380 		default:
       
   381 			ptr = NULL;
       
   382 			break;
       
   383 		}
       
   384 	return ptr;
       
   385 	}
       
   386 
       
   387 /**
       
   388  * Maps a TSsmState object into the associated StartupAdaptation::TGlobalState value.
       
   389  * 
       
   390  * Uses the following mappings:
       
   391  * 
       
   392  * ESWStateStartingUiServices = TSsmState(ESsmStartup, ESWStateStartingUiServices - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical); 
       
   393  * ESWStateStartingCriticalApps = TSsmState(ESsmStartup, ESWStateStartingCriticalApps - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);  
       
   394  * ESWStateSelfTestOK = TSsmState(ESsmStartup, ESWStateSelfTestOK - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
       
   395  * // States for the security check phase.
       
   396  * ESWStateSecurityCheck = TSsmState(ESsmStartup, ESWStateSecurityCheck - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
       
   397  * ESWStateCriticalPhaseOK = TSsmState(ESsmStartup, ESWStateCriticalPhaseOK - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
       
   398  * ESWStateEmergencyCallsOnly = TSsmState(ESsmStartup, ESWStateEmergencyCallsOnly - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
       
   399  * // Terminal states defined by the boot mode (and some other variables such as offline mode).
       
   400  * ESWStateTest = TSsmState(ESsmStartup, ESWStateTest - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
       
   401  * ESWStateCharging = TSsmState(ESsmStartup, ESWStateCharging - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
       
   402  * ESWStateAlarm = TSsmState(ESsmStartup, ESWStateAlarm - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
       
   403  * ESWStateNormalRfOn = TSsmState(ESsmNormal, ESWStateNormalRfOn - ESWStateStartingUiServices + ESsmStartupSubStateCriticalStatic);
       
   404  * ESWStateNormalRfOff = TSsmState(ESsmNormal, ESWStateNormalRfOff - ESWStateStartingUiServices + ESsmStartupSubStateCriticalStatic);
       
   405  * ESWStateNormalBTSap = TSsmState(ESsmNormal, ESWStateNormalBTSap - ESWStateStartingUiServices + ESsmStartupSubStateCriticalStatic);
       
   406  * // States for notifying adaptation about a terminal state change.
       
   407  * ESWStateAlarmToCharging = TSsmState(ESsmStartup, ESWStateAlarmToCharging - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
       
   408  * ESWStateChargingToAlarm = TSsmState(ESsmStartup, ESWStateChargingToAlarm - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
       
   409  * ESWStateChargingToNormal = TSsmState(ESsmStartup, ESWStateChargingToNormal - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
       
   410  * ESWStateAlarmToNormal = TSsmState(ESsmStartup, ESWStateAlarmToNormal - ESWStateStartingUiServices + ESsmStartupSubStateNonCritical);
       
   411  * // Shutdown-related states.
       
   412  * ESWStateShuttingDown = TSsmState(ESsmShutdown, KSsmAnySubState);
       
   413  * // Error states during critical phase.
       
   414  * ESWStateFatalStartupError = TSsmState(ESsmFail, KSsmAnySubState);
       
   415  * 
       
   416  * Returns 0 on invalid TSsmState
       
   417  * 
       
   418  * @internalComponent
       
   419  */
       
   420 StartupAdaptation::TGlobalState CSaaStateAdaptation::MapToStartupAdaptationState(TSsmState aState)
       
   421 	{
       
   422 	using namespace StartupAdaptation;
       
   423 	
       
   424 	// Calculate the difference from the substate to the value of TGlobalState values
       
   425 	// This uses ESsmStartupSubStateNonCritical to map to the correct part of the staged
       
   426 	// start-up architecture and therefore to map the states as described in the comment
       
   427 	// for this method.
       
   428 	const TInt KStartupSubStateAdjustment = static_cast<TInt>(ESWStateStartingUiServices) 
       
   429 											- static_cast<TInt>(ESsmStartupSubStateNonCritical);
       
   430 	// Adjust the substate value
       
   431 	const TInt adjustedStartupSubStateValue = aState.SubState() + KStartupSubStateAdjustment;
       
   432 	
       
   433 	// Calculate the difference from the substate to the value of TGlobalState values
       
   434 	// This uses ESsmStartupSubStateCriticalStatic to map to the correct states as described
       
   435 	// in the comment for this method.
       
   436 	const TInt KNormalSubStateAdjustment = static_cast<TInt>(ESWStateStartingUiServices) 
       
   437 	 										- static_cast<TInt>(ESsmStartupSubStateCriticalStatic);
       
   438 
       
   439 	// Adjust the substate value
       
   440 	const TInt adjustedNormalSubStateValue = aState.SubState() + KNormalSubStateAdjustment;
       
   441 	
       
   442 	TGlobalState ret = static_cast<TGlobalState>(0);
       
   443 	
       
   444 	if(aState.MainState() == ESsmStartup)
       
   445 		{
       
   446 		ret = static_cast<TGlobalState>(adjustedStartupSubStateValue);
       
   447 		}
       
   448 	else if(aState.MainState() == ESsmNormal)
       
   449 		{
       
   450 		ret = static_cast<TGlobalState>(adjustedNormalSubStateValue);
       
   451 		}
       
   452 	else if(aState.MainState() == ESsmShutdown)
       
   453 		{
       
   454 		ret = ESWStateShuttingDown;
       
   455 		}
       
   456 	else if(aState.MainState() == ESsmFail)
       
   457 		{
       
   458 		ret = ESWStateFatalStartupError;
       
   459 		}
       
   460 	
       
   461 	// Validate the return value is correct
       
   462 	switch(aState.MainState())
       
   463 		{
       
   464 		case ESsmStartup:
       
   465 			if(ret < ESWStateStartingUiServices || 
       
   466 					(ret > ESWStateAlarm && ret < ESWStateAlarmToCharging) || 
       
   467 					ret > ESWStateAlarmToNormal)
       
   468 				{
       
   469 				CLAYER_PANIC(ECLayerInvalidSubState);
       
   470 				}
       
   471 			break;
       
   472 		case ESsmNormal:
       
   473 			if(ret < ESWStateNormalRfOn || ret > ESWStateNormalBTSap)
       
   474 				{
       
   475 				CLAYER_PANIC(ECLayerInvalidSubState);
       
   476 				}
       
   477 			break;
       
   478 		case ESsmShutdown:
       
   479 			if(aState.SubState() != KSsmAnySubState)
       
   480 				{
       
   481 				CLAYER_PANIC(ECLayerInvalidSubState);
       
   482 				}
       
   483 			break;
       
   484 		case ESsmFail:
       
   485 			if(aState.SubState() != KSsmAnySubState)
       
   486 				{
       
   487 				CLAYER_PANIC(ECLayerInvalidSubState);
       
   488 				}
       
   489 			break;
       
   490 		default:
       
   491 			// Do nothing
       
   492 			break;
       
   493 		}
       
   494 	return ret;
       
   495 	} //lint !e1746 Suppress parameter 'aState' could be made const reference
       
   496 
       
   497 /**
       
   498  * Processes the event passed in and distributes to waiting client or queues event.
       
   499  * 
       
   500  * @internalComponent
       
   501  */
       
   502 void CSaaStateAdaptation::ProcessEventL(TSsmCoopSysEventType aEventType)
       
   503 	{
       
   504 	DEBUGPRINT2A("SAA - State adaptation processing event with type: %d", aEventType);
       
   505 	if(iEventStatus == NULL)
       
   506 		{
       
   507 		// Need to queue event as nothing is waiting to be notified
       
   508 		iEventQueue.AppendL(aEventType);
       
   509 		}
       
   510 	else
       
   511 		{
       
   512 		// Client waiting for event
       
   513 		__ASSERT_DEBUG(iEventOutputBuffer != NULL, CLAYER_PANIC(ECLayerNullStateEventBuffer));
       
   514 		TPckgBuf<TSsmCoopSysEventType> pckgBuf(aEventType);
       
   515 		// Copy event across
       
   516 		iEventOutputBuffer->Copy(pckgBuf);
       
   517 		// Complete status
       
   518 		User::RequestComplete(iEventStatus, KErrNone);
       
   519 		// Clear event status and buffer
       
   520 		iEventOutputBuffer = NULL;
       
   521 		iEventStatus = NULL;
       
   522 		}
       
   523 	}