sysstatemgmt/systemstatereferenceplugins/clayer/src/startupadaptationadapter.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 "startupadaptationadapter.h"
       
    17 
       
    18 #include <ssm/startupadaptation.h>
       
    19 
       
    20 #include <ecom/ecom.h>
       
    21 
       
    22 #include "saastateadaptation.h"
       
    23 #include "saasimadaptation.h"
       
    24 #include "saartcadaptation.h"
       
    25 #include "saaemergencycallrfadaptation.h"
       
    26 #include "saamiscadaptation.h"
       
    27 
       
    28 #include "clayerpanic.h"
       
    29 
       
    30 #include "ssmdebug.h"
       
    31 
       
    32 
       
    33 
       
    34 /**
       
    35  * Returns the singleton @c CStartupAdaptationAdapter.
       
    36  * 
       
    37  * @return The singleton CStartupAdaptationAdapter
       
    38  * @leave KErrPermissionDenied - the caller does not have permission to perform this operation
       
    39  * 
       
    40  * @internalComponent
       
    41  */
       
    42 CStartupAdaptationAdapter* CStartupAdaptationAdapter::GetL()
       
    43 	{
       
    44 	DEBUGVERBOSE1A("Checking TLS for CStartupAdaptationAdapter");
       
    45 	CStartupAdaptationAdapter* self =
       
    46 		static_cast<CStartupAdaptationAdapter*>(Dll::Tls());
       
    47 	if(self == 0)
       
    48 		{
       
    49 		// TLS uninitialised, need to create
       
    50 		DEBUGPRINT1A("Constructing CStartupAdaptationAdapter singleton");
       
    51 		self = CStartupAdaptationAdapter::NewLC();
       
    52 		DEBUGPRINT1A("Storing CStartupAdaptationAdapter singleton in TLS");
       
    53 		TInt err = Dll::SetTls(self);
       
    54 		SSMLOGLEAVEIFERROR(err);
       
    55 		CleanupStack::Pop(self);
       
    56 		}
       
    57 	DEBUGVERBOSE1A("Returning CStartupAdaptationAdapter singleton");
       
    58 	return self;
       
    59 	}
       
    60 
       
    61 /**
       
    62  * Destroys the singleton @c CStartupAdaptationAdapter.
       
    63  * 
       
    64  * @internalComponent
       
    65  */
       
    66 void CStartupAdaptationAdapter::Destroy()
       
    67 	{
       
    68 	CStartupAdaptationAdapter* self =
       
    69 			static_cast<CStartupAdaptationAdapter*>(Dll::Tls());
       
    70 	if(self != 0)
       
    71 		{
       
    72 		DEBUGPRINT1A("Destroying CStartupAdaptationAdapter singleton");
       
    73 		delete self;
       
    74 		TInt err = Dll::SetTls(0);
       
    75 		if(err != KErrNone)
       
    76 			{
       
    77 			DEBUGPRINT2A("Error clearing TLS: %d", err);
       
    78 			return;
       
    79 			}
       
    80 		}
       
    81 	}
       
    82 
       
    83 /**
       
    84  * Creates a new CStartupAdaptationAdapter.
       
    85  * 
       
    86  * The CStartupAdaptationAdapter class should be accessed via a singleton pattern.
       
    87  * GetL() is provided to manage a thread level singleton for this class.
       
    88  * 
       
    89  * @internalComponent
       
    90  */
       
    91 CStartupAdaptationAdapter* CStartupAdaptationAdapter::NewLC()
       
    92 	{
       
    93 	CStartupAdaptationAdapter* self = new (ELeave) CStartupAdaptationAdapter();
       
    94 	CleanupStack::PushL(self);
       
    95 	self->ConstructL();
       
    96 	return self;
       
    97 	}
       
    98 
       
    99 /**
       
   100  * First phase constructor
       
   101  * 
       
   102  * @internalComponent
       
   103  */
       
   104 
       
   105 CStartupAdaptationAdapter::CStartupAdaptationAdapter()
       
   106 : CActive(EPriorityStandard)
       
   107 	{
       
   108 	
       
   109 	}
       
   110 
       
   111 /**
       
   112  * Second phase constructor
       
   113  * 
       
   114  * @internalComponent
       
   115  */
       
   116 void CStartupAdaptationAdapter::ConstructL()
       
   117 	{ 
       
   118 	iStateAdaptation = CSaaStateAdaptation::NewL(this);
       
   119 	iSimAdaptation = CSaaSimAdaptation::NewL(this);
       
   120 	iRtcAdaptation = CSaaRtcAdaptation::NewL(this);
       
   121 	iEmergencyCallRfAdaptation = CSaaEmergencyCallRfAdaptation::NewL(this);
       
   122 	iMiscAdaptation = CSaaMiscAdaptation::NewL(this);
       
   123 	CActiveScheduler::Add(this);
       
   124 	}
       
   125 
       
   126 /**
       
   127  * Destructor for CStartupAdaptationAdapters
       
   128  * 
       
   129  * @internalComponent
       
   130  */
       
   131 CStartupAdaptationAdapter::~CStartupAdaptationAdapter()
       
   132 	{
       
   133 	Cancel();
       
   134 	
       
   135 	// destroy the adaptation, which is an ECOM plugin
       
   136 	delete iStartupAdaptation;
       
   137 	
       
   138 	// Signal to ECOM that it should cleanup
       
   139 	REComSession::FinalClose();
       
   140 	
       
   141 	// Cleanup other members
       
   142 	delete iStateAdaptation;
       
   143 	delete iSimAdaptation;
       
   144 	delete iRtcAdaptation;
       
   145 	delete iEmergencyCallRfAdaptation;
       
   146 	delete iMiscAdaptation;
       
   147 	}
       
   148 
       
   149 /**
       
   150  * Returns an object conforming to the MStateAdaptation interface.
       
   151  * 
       
   152  * The objects returned from this method may be reference counted.
       
   153  * This may mean that consecutive calls to this method will return the same
       
   154  * address.
       
   155  * 
       
   156  * @internalComponent
       
   157  */
       
   158 EXPORT_C MStateAdaptation* CStartupAdaptationAdapter::NewStateAdaptationL()
       
   159 	{
       
   160 	CStartupAdaptationAdapter* adapter = GetL();
       
   161 	return static_cast<MStateAdaptation*>(adapter->iStateAdaptation);
       
   162 	}
       
   163 
       
   164 /**
       
   165  * Returns an object conforming to the MSimAdaptation interface.
       
   166  * 
       
   167  * The objects returned from this method may be reference counted.
       
   168  * This may mean that consecutive calls to this method will return the same
       
   169  * address.
       
   170  * 
       
   171  * @internalComponent
       
   172  */
       
   173 EXPORT_C MSimAdaptation* CStartupAdaptationAdapter::NewSimAdaptationL()
       
   174 	{
       
   175 	CStartupAdaptationAdapter* adapter = GetL();
       
   176 	return static_cast<MSimAdaptation*>(adapter->iSimAdaptation);
       
   177 	}
       
   178 
       
   179 /**
       
   180  * Returns an object conforming to the MRtcAdaptation interface.
       
   181  * 
       
   182  * The objects returned from this method may be reference counted.
       
   183  * This may mean that consecutive calls to this method will return the same
       
   184  * address.
       
   185  * 
       
   186  * @internalComponent
       
   187  */
       
   188 EXPORT_C MRtcAdaptation* CStartupAdaptationAdapter::NewRtcAdaptationL()
       
   189 	{
       
   190 	CStartupAdaptationAdapter* adapter = GetL();
       
   191 	return static_cast<MRtcAdaptation*>(adapter->iRtcAdaptation);
       
   192 	}
       
   193 
       
   194 /**
       
   195  * Returns an object conforming to the MEmergencyCallRfAdaptation interface.
       
   196  * 
       
   197  * The objects returned from this method may be reference counted.
       
   198  * This may mean that consecutive calls to this method will return the same
       
   199  * address.
       
   200  * 
       
   201  * @internalComponent
       
   202  */
       
   203 EXPORT_C MEmergencyCallRfAdaptation* CStartupAdaptationAdapter::NewEmergencyCallRfAdaptationL()
       
   204 	{
       
   205 	CStartupAdaptationAdapter* adapter = GetL();
       
   206 	return static_cast<MEmergencyCallRfAdaptation*>(adapter->iEmergencyCallRfAdaptation);
       
   207 	}
       
   208 
       
   209 /**
       
   210  * Returns an object conforming to the MMiscAdaptation interface.
       
   211  * 
       
   212  * The objects returned from this method may be reference counted.
       
   213  * This may mean that consecutive calls to this method will return the same
       
   214  * address.
       
   215  * 
       
   216  * @internalComponent
       
   217  */
       
   218 EXPORT_C MMiscAdaptation* CStartupAdaptationAdapter::NewMiscAdaptationL()
       
   219 	{
       
   220 	CStartupAdaptationAdapter* adapter = GetL();
       
   221 	return static_cast<MMiscAdaptation*>(adapter->iMiscAdaptation);
       
   222 	}
       
   223 
       
   224 /**
       
   225  * Returns a pointer to the adaptation class, creating and loading it if necessary 
       
   226  * 
       
   227  * @internalComponent 
       
   228  */
       
   229 CStartupAdaptation* CStartupAdaptationAdapter::GetAdaptationL()
       
   230 	{
       
   231 	if(iStartupAdaptation == NULL)
       
   232 		{
       
   233 		iStartupAdaptation = CStartupAdaptation::NewL(*this);
       
   234 		}
       
   235 	return iStartupAdaptation;
       
   236 	}
       
   237 
       
   238 /**
       
   239  * Dispatches or queues for dispatch the provided adaptation base class 
       
   240  * 
       
   241  * @internalComponent 
       
   242  */
       
   243 void CStartupAdaptationAdapter::QueueDispatchL(CAdaptationBase* aAdaptation)
       
   244 	{
       
   245 	
       
   246 	if(iDispatchedAdaptation == NULL)
       
   247 		{
       
   248 		DEBUGPRINT2A("SAA - Dispatch request immediately commandId: %d", aAdaptation->CommandId());
       
   249 		// Nothing is waiting for a response, so dispatch immediately
       
   250 		iDispatchedAdaptation = aAdaptation;
       
   251 		GetAdaptationL()->CommandL(iDispatchedAdaptation->CommandId(), *iDispatchedAdaptation->ParameterPckg());
       
   252 		iDispatchedAdaptation->SetDispatched(ETrue);
       
   253 		}
       
   254 	else
       
   255 		{
       
   256 		DEBUGPRINT3A("SAA - Queueing request for commandId: %d queue size:", aAdaptation->CommandId(), iDispatchQueueSize);
       
   257 		// Check queue size
       
   258 		if (iDispatchQueueSize == KMaxAdaptationClasses)
       
   259 			{
       
   260 			CLAYER_PANIC(ECLayerMaximumQueueSize);
       
   261 			}
       
   262 		// Add to queue
       
   263 		iDispatchQueue[iDispatchQueueSize] = aAdaptation;
       
   264 		// Update queue size
       
   265 		++iDispatchQueueSize;
       
   266 		}
       
   267 	}
       
   268 
       
   269 /**
       
   270  * Handles responses from the adaptation.
       
   271  * 
       
   272  * Defined in MStartupAdaptationObserver.
       
   273  * 
       
   274  * @internalComponent
       
   275  */
       
   276 void CStartupAdaptationAdapter::ResponseL(const StartupAdaptation::TCommand aCommandId, TDesC8& aData)
       
   277 	{
       
   278 	DEBUGPRINT2A("SAA - Response received from adaptation with commandId: %d", aCommandId);
       
   279 	// Check we were expecting a response
       
   280 	if(iDispatchedAdaptation == NULL)
       
   281 		{
       
   282 		CLAYER_PANIC(ECLayerUnexpectedResponse);
       
   283 		}
       
   284 	// Indicate that it is complete
       
   285 	iDispatchedAdaptation->RequestComplete(aCommandId, aData);
       
   286 	
       
   287 	// clear the dispatched adaptation so it can be reused
       
   288 	iDispatchedAdaptation = NULL;
       
   289 	
       
   290 	// self complete to dispatch next queued request if any
       
   291 	SelfComplete(KErrNone);
       
   292 	}
       
   293 
       
   294 /**
       
   295  * Handles events from the adaptation.
       
   296  * 
       
   297  * Defined in MStartupAdaptationObserver.
       
   298  * 
       
   299  * @internalComponent
       
   300  */
       
   301 void CStartupAdaptationAdapter::EventL(const StartupAdaptation::TEvent aEventId, TDesC8& aData)
       
   302 	{
       
   303 	using namespace StartupAdaptation;
       
   304 	// Switch on event type
       
   305 	switch(aEventId)
       
   306 		{
       
   307 		case EFatalError:
       
   308 			{
       
   309 			TFatalErrorTypePckg fatalErrorPckg;
       
   310 			fatalErrorPckg.Copy(aData);
       
   311 			if(fatalErrorPckg() == ESimRemoved)
       
   312 				{
       
   313 				// SIM event
       
   314 				iSimAdaptation->ProcessEventL(ESsmSimRemoved);
       
   315 				}
       
   316 			else
       
   317 				{
       
   318 				// State event
       
   319 				iStateAdaptation->ProcessEventL(ESsmFatalCoopSysError);
       
   320 				}
       
   321 			break;
       
   322 			}
       
   323 		case EDOSOriginatedReset:
       
   324 			{
       
   325 			iStateAdaptation->ProcessEventL(ESsmRestartDevice);
       
   326 			break;
       
   327 			}
       
   328 		case EDOSOriginatedShutdown:
       
   329 			{
       
   330 			iStateAdaptation->ProcessEventL(ESsmShutdownDevice);
       
   331 			break;
       
   332 			}
       
   333 		case ESimEvent:
       
   334 			{
       
   335 			TSimEventTypePckg simEventPckg;
       
   336 			simEventPckg.Copy(aData);
       
   337 			switch(simEventPckg())
       
   338 			{
       
   339 				case ESimUsable:
       
   340 					iSimAdaptation->ProcessEventL(ESsmSimUsable);
       
   341 					break;
       
   342 				case ESimReadable:
       
   343 					iSimAdaptation->ProcessEventL(ESsmSimReadable);
       
   344 					break;
       
   345 				case ESimNotReady:
       
   346 					iSimAdaptation->ProcessEventL(ESsmSimNotReady);
       
   347 					break;
       
   348 				default:
       
   349 					DEBUGPRINT2A("SAA - Received unknown SIM event with SIM event id: %d - ignoring", simEventPckg());
       
   350 					break;
       
   351 			}
       
   352 			break;
       
   353 			}
       
   354 		default:
       
   355 			DEBUGPRINT2A("SAA - Received unknown event with event id: %d - ignoring", aEventId);
       
   356 			break;
       
   357 		}
       
   358 	}
       
   359 
       
   360 /**
       
   361  * Cancels an already dispatched adaptation request
       
   362  * 
       
   363  * This should not be called if the response for this request has already been received.
       
   364  * 
       
   365  * @internalComponent
       
   366  */
       
   367 void CStartupAdaptationAdapter::CancelDispatchedL(CAdaptationBase* aAdaptation)
       
   368 	{
       
   369 	DEBUGPRINT3A("SAA - Cancelling dispatched request with command id: %d dispatched command id: %d", aAdaptation->CommandId(), iDispatchedAdaptation->CommandId());
       
   370 	if(aAdaptation != iDispatchedAdaptation)
       
   371 		{
       
   372 		CLAYER_PANIC(ECLayerInCorrectDispatchedCancel);
       
   373 		}
       
   374 	// Request the startup adaptation cancel the command
       
   375 	GetAdaptationL()->CancelCommandL(iDispatchedAdaptation->CommandId());
       
   376 	iDispatchedAdaptation = NULL;
       
   377 	// Dispatch any items in the queue if present
       
   378 	DispatchQueued();
       
   379 	}
       
   380 
       
   381 /**
       
   382  * Removes a queued adaptation request from the queue
       
   383  * 
       
   384  * This should not be called if the response for this request has already been dispatched.
       
   385  * 
       
   386  * @internalComponent
       
   387  */
       
   388 void CStartupAdaptationAdapter::RemoveFromDispatchQueue(CAdaptationBase* aAdaptation)
       
   389 	{
       
   390 	DEBUGPRINT2A("SAA - Cancelling queued request with command id: %d ", aAdaptation->CommandId());
       
   391 	// Search for offset
       
   392 	TInt index;
       
   393 	for(index = 0; index < iDispatchQueueSize && iDispatchQueue[index] != aAdaptation; ++index)
       
   394 		{
       
   395 		// Do nothing
       
   396 		}
       
   397 	// remove from queue
       
   398 	if (index != iDispatchQueueSize)
       
   399 		{
       
   400 		// Found it at index so remove from array and shift ones above down
       
   401 		for(TInt j = index + 1; j < iDispatchQueueSize; ++j)
       
   402 			{
       
   403 			iDispatchQueue[j-1] = iDispatchQueue[j];
       
   404 			}
       
   405 		// Decrease queue size
       
   406 		--iDispatchQueueSize;
       
   407 		}
       
   408 	else
       
   409 		{
       
   410 		DEBUGPRINT2A("SAA - Couldn't find request to de-queue with command id: %d ", aAdaptation->CommandId());
       
   411 		}
       
   412 	}
       
   413 
       
   414 
       
   415 /**
       
   416  * Dispatches the next adaptation request in the queue and removes it from the queue
       
   417  * 
       
   418  * @internalComponent
       
   419  */
       
   420 void CStartupAdaptationAdapter::DispatchQueued()
       
   421 	{
       
   422 	// Dispatch the head of the queue if any items there
       
   423 	// retry as long as there are items in the queue
       
   424 	while(iDispatchQueueSize > 0 && iDispatchedAdaptation == NULL)
       
   425 		{
       
   426 		// Update the current pointer
       
   427 		iDispatchedAdaptation = iDispatchQueue[0];
       
   428 		// shift the queue down
       
   429 		for(TInt i = 1; i < iDispatchQueueSize; ++i)
       
   430 			{
       
   431 			iDispatchQueue[i - 1] = iDispatchQueue[i]; 
       
   432 			}
       
   433 		--iDispatchQueueSize;
       
   434 		// dispatch the new request
       
   435 		DEBUGPRINT2A("SAA - Dispatch queue non empty, dispatchign command with commandId: %d", iDispatchedAdaptation->CommandId());
       
   436 		TRAPD(err, GetAdaptationL()->CommandL(iDispatchedAdaptation->CommandId(), *iDispatchedAdaptation->ParameterPckg()));
       
   437 		if(err != KErrNone)
       
   438 			{
       
   439 			// failed to dispatch
       
   440 			// return error to client
       
   441 			iDispatchedAdaptation->CompleteRequestStatus(err);
       
   442 			// clear iDispatchedAdaptation so that the while loop tries again
       
   443 			iDispatchedAdaptation = NULL;
       
   444 			}
       
   445 		}
       
   446 	}
       
   447 
       
   448 void CStartupAdaptationAdapter::SelfComplete(TInt aError)
       
   449 	{
       
   450 	TRequestStatus* trs = &iStatus;
       
   451 	iStatus = KRequestPending;
       
   452 	User::RequestComplete(trs, aError);
       
   453 	SetActive();
       
   454 	}
       
   455 
       
   456 // From CActive
       
   457 
       
   458 void CStartupAdaptationAdapter::RunL()
       
   459 	{
       
   460 	// Dispatch any queued request
       
   461 	DispatchQueued();
       
   462 	}
       
   463 
       
   464 TInt CStartupAdaptationAdapter::RunError(TInt aError)
       
   465 	{
       
   466 	DEBUGPRINT2(_L("CStartupAdaptationAdapter::RunError() called with error %d"), aError);
       
   467 	// Return the error to the active scheduler to panic as this should never occur
       
   468 	return aError;
       
   469 	}
       
   470 
       
   471 void CStartupAdaptationAdapter::DoCancel()
       
   472 	{
       
   473 	// Nothing to cancel as iStatus should never be KRequestPending
       
   474 	}