sysstatemgmt/systemstatemgr/sus/src/susstateadaptation.cpp
changeset 0 4e1aa6a622a0
child 21 ccb4f6b3db21
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 // Copyright (c) 2008-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 
       
    17 #include "susstateadaptation.h"
       
    18 #include <e32debug.h>
       
    19 
       
    20 /**
       
    21 @publishedPartner
       
    22 */
       
    23 
       
    24 /*
       
    25 	//Add aMessage to the queue if AO is busy
       
    26 	//else
       
    27 	//Store the message in iCurrentMessage so that RunL can call aMessage::Complete()
       
    28 	//Unpack params 
       
    29 	//Submit request
       
    30 */ 
       
    31 
       
    32 void CStateAdaptationRequests::SubmitOrQueueL(const RMessage2 &aMessage)
       
    33 	{
       
    34 	
       
    35 	CAdaptationMessage *messageCopy = new(ELeave) CAdaptationMessage(aMessage);
       
    36 		
       
    37 	if(!IsActive())
       
    38 		{
       
    39 		Submit(messageCopy);
       
    40 		}
       
    41 	else 
       
    42 		{
       
    43 		CleanupStack::PushL(messageCopy);
       
    44 		DEBUGPRINT2A("CStateAdaptationRequests queuing request with function id: %d", aMessage.Function());
       
    45 		User::LeaveIfError(iPendingRequestsQueue.Queue(messageCopy));
       
    46 		CleanupStack::Pop(messageCopy);
       
    47 		}	
       
    48 	}
       
    49  
       
    50 void CStateAdaptationRequests::Submit(CAdaptationMessage*& aMessage)
       
    51 	{
       
    52 	DEBUGPRINT2A("CStateAdaptationRequests immediate submission of request with function id: %d", aMessage->Function());
       
    53 	iCurrentMessage = aMessage;
       
    54 	switch(aMessage->Function())
       
    55 		{
       
    56 		case ERequestCoopSysStateChange :
       
    57 			{
       
    58 			TSsmState newState;
       
    59 			newState.SetFromInt(aMessage->Int0());
       
    60 			iStateAdaptation.RequestCoopSysStateChange(newState, iStatus);
       
    61 			break;
       
    62 			}
       
    63 		case ERequestCoopSysSelfTest :
       
    64 			{
       
    65 			iStateAdaptation.RequestCoopSysSelfTest(iStatus);
       
    66 			break;
       
    67 			}
       
    68 		case ERequestCoopSysPerformRestartActions :
       
    69 			{
       
    70 			TInt reason = aMessage->Int0();
       
    71 			iStateAdaptation.RequestCoopSysPerformRestartActions(reason, iStatus);
       
    72 			break;
       
    73 			}
       
    74 		case ERequestCoopSysPerformShutdownActions :
       
    75 			{
       
    76 			TInt reason = aMessage->Int0();
       
    77 			iStateAdaptation.RequestCoopSysPerformShutdownActions(reason, iStatus);
       
    78 			break;
       
    79 			}
       
    80 		case ERequestCoopSysPerformRfsActions :
       
    81 			{
       
    82 			TSsmRfsType rfsType = ( TSsmRfsType )aMessage->Int0() ;
       
    83 			iStateAdaptation.RequestCoopSysPerformRfsActions(rfsType, iStatus);
       
    84 			break;
       
    85 			}
       
    86 		default:
       
    87 			{
       
    88 			aMessage->Complete(KErrArgument);
       
    89 			return;
       
    90 			}
       
    91 		}
       
    92 	SetActive();
       
    93 	}
       
    94 
       
    95 /**
       
    96 CStateAdaptationRequests implements State Adaptation related functionality as part of CSsmAdaptationServer.
       
    97 CSsmAdaptationServer loads State Adaptation plugin and creates CStateAdaptationRequests using the NewL.
       
    98 From then the loaded State Adaptation plugin will be owned by CStateAdaptationRequests.
       
    99 
       
   100 @internalComponent
       
   101 */
       
   102 
       
   103 
       
   104 
       
   105 CStateAdaptationRequests* CStateAdaptationRequests::NewL(MStateAdaptation& aAdaptation)
       
   106 	{
       
   107 	CStateAdaptationRequests* self = new(ELeave) CStateAdaptationRequests(aAdaptation);
       
   108 	return self;
       
   109 	} 
       
   110 
       
   111 CStateAdaptationRequests::CStateAdaptationRequests(MStateAdaptation& aAdaptation) : CActive(EPriorityStandard), iStateAdaptation(aAdaptation)
       
   112 	{
       
   113 	CActiveScheduler::Add(this);
       
   114 	}
       
   115 
       
   116 CStateAdaptationRequests::~CStateAdaptationRequests()
       
   117 	{
       
   118 	iPendingRequestsQueue.NotifyAndRemoveAll();
       
   119 	Cancel();	// This call will delete iCurrentMessage if any
       
   120 	iPendingRequestsQueue.Close();
       
   121 	Release();
       
   122 	}
       
   123 
       
   124 //from MstateAdaptation
       
   125 void CStateAdaptationRequests::Release()
       
   126 	{
       
   127 	iStateAdaptation.Release();
       
   128 	}
       
   129 
       
   130 
       
   131 void CStateAdaptationRequests::DoRequestCoopSysStateChangeL(const RMessage2& aMessage)
       
   132 	{
       
   133 	SubmitOrQueueL(aMessage);
       
   134 	}  
       
   135 
       
   136 void CStateAdaptationRequests::DoRequestCoopSysSelfTestL(const RMessage2& aMessage)
       
   137 	{
       
   138 	SubmitOrQueueL(aMessage);
       
   139 	}
       
   140 
       
   141 void CStateAdaptationRequests::DoRequestCoopSysPerformRestartActionsL(const RMessage2& aMessage)
       
   142 	{
       
   143 	SubmitOrQueueL(aMessage);
       
   144 	}
       
   145 
       
   146 void CStateAdaptationRequests::DoRequestCoopSysPerformShutdownActionsL(const RMessage2& aMessage)
       
   147 	{
       
   148 	SubmitOrQueueL(aMessage);
       
   149 	}
       
   150 
       
   151 void CStateAdaptationRequests::DoRequestCoopSysPerformRfsActionsL(const RMessage2& aMessage)
       
   152 	{
       
   153 	SubmitOrQueueL(aMessage);
       
   154 	}
       
   155 
       
   156 /*
       
   157 
       
   158 ALGO
       
   159 	If iCurrentMessage == aMessage
       
   160 	then call plugin's RequestCancel()
       
   161 	otherwise 
       
   162 	search the queue and complete the message with KErrCancel
       
   163 */
       
   164 
       
   165 void CStateAdaptationRequests::DoRequestCancel(const RMessage2& aMessage)
       
   166 	{
       
   167 
       
   168 	if(iCurrentMessage != NULL)	
       
   169 		{
       
   170 		if(aMessage.Session() == iCurrentMessage->Session())
       
   171 			{
       
   172 			DEBUGPRINT1A("CStateAdaptationRequests cancelling current request as requested");
       
   173 			iStateAdaptation.RequestCancel();
       
   174 			}
       
   175 		iPendingRequestsQueue.RemoveFromQueueAndComplete(aMessage);  	
       
   176 		aMessage.Complete(KErrNone);
       
   177 		}
       
   178 	else
       
   179 		{
       
   180 		DEBUGPRINT1A("CStateAdaptationRequests nothing to cancel, but cancel requested");
       
   181 		aMessage.Complete(KErrNone);				
       
   182 		}
       
   183 		
       
   184 	}
       
   185 
       
   186 /**
       
   187  * Returns the state adaptation in use by this object
       
   188  * 
       
   189  * @internalComponent
       
   190  */
       
   191 MStateAdaptation& CStateAdaptationRequests::Adaptation()
       
   192 	{
       
   193 	return iStateAdaptation;
       
   194 	}
       
   195 
       
   196 /*
       
   197 	from CActive
       
   198 	Complete aMessage
       
   199 	Dequeue the queue and submit another request
       
   200 */
       
   201 
       
   202 void CStateAdaptationRequests::RunL()
       
   203 	{
       
   204 	
       
   205 	DEBUGPRINT2A("CStateAdaptationRequests processed the request with funtion id: %d", iCurrentMessage->Function());
       
   206 	iCurrentMessage->Complete(iStatus.Int());
       
   207 	delete iCurrentMessage;
       
   208 	iCurrentMessage = NULL;  
       
   209 
       
   210 	if( (iPendingRequestsQueue.IsEmpty()) == EFalse )
       
   211 		{
       
   212 		CAdaptationMessage *messageCopy = NULL;
       
   213 		iPendingRequestsQueue.Dequeue(messageCopy);
       
   214 		Submit(messageCopy);
       
   215 		} 
       
   216 	}
       
   217 
       
   218 TInt CStateAdaptationRequests::RunError( TInt aError)
       
   219 	{
       
   220 	if(iCurrentMessage != NULL)	
       
   221 		{
       
   222 		iCurrentMessage->Complete(aError);
       
   223 		delete iCurrentMessage;
       
   224 		iCurrentMessage = NULL; 
       
   225 		}
       
   226 	
       
   227 	while( (iPendingRequestsQueue.IsEmpty()) == EFalse )
       
   228 		{
       
   229 		iPendingRequestsQueue.Dequeue(iCurrentMessage);
       
   230 		iCurrentMessage->Complete(aError);
       
   231 		delete iCurrentMessage;
       
   232 		iCurrentMessage = NULL;
       
   233 		}
       
   234 	
       
   235 	return KErrNone;
       
   236 	}
       
   237 
       
   238 void CStateAdaptationRequests::DoCancel()
       
   239 	{
       
   240 	if(iCurrentMessage != NULL)	
       
   241 		{
       
   242 		iCurrentMessage->Complete(KErrCancel);
       
   243 		delete iCurrentMessage;
       
   244 		iCurrentMessage = NULL;
       
   245 		}
       
   246 		
       
   247 	while( (iPendingRequestsQueue.IsEmpty()) == EFalse )
       
   248 		{
       
   249 		iPendingRequestsQueue.Dequeue(iCurrentMessage);
       
   250 		iCurrentMessage->Complete(KErrCancel);
       
   251 		delete iCurrentMessage;
       
   252 		iCurrentMessage = NULL;
       
   253 		}
       
   254 	}
       
   255 
       
   256 	
       
   257 // C Class
       
   258 CStateAdaptationObservers* CStateAdaptationObservers::NewL(MStateAdaptation& aAdaptation)
       
   259 	{
       
   260 	CStateAdaptationObservers* self = new(ELeave) CStateAdaptationObservers(aAdaptation);
       
   261 	
       
   262 	CleanupStack::PushL(self);
       
   263 	CleanupStack::Pop(); // self
       
   264 	return self;
       
   265 	}
       
   266 
       
   267 CStateAdaptationObservers::CStateAdaptationObservers(MStateAdaptation& aAdaptation) : CActive(EPriorityStandard), iStateAdaptation(aAdaptation)
       
   268 	{
       
   269 	CActiveScheduler::Add(this); 
       
   270 	}
       
   271 
       
   272 CStateAdaptationObservers::~CStateAdaptationObservers()
       
   273 	{
       
   274 	Cancel();
       
   275 	iObserversList.Close();
       
   276 	}
       
   277 
       
   278 //from MstateAdaptation
       
   279 
       
   280 void CStateAdaptationObservers::DoGetLastCoopSysEvent(const RMessage2& aMessage)
       
   281 	{
       
   282 	TRAPD(err,aMessage.WriteL(0,iEventPckg));
       
   283 	aMessage.Complete(err);	
       
   284 	}
       
   285 
       
   286 
       
   287 void CStateAdaptationObservers::DoNotifyCoopSysEventL(const RMessage2& aMessage)
       
   288 	{
       
   289 	if(iObserversList.Count() == 0)
       
   290 		{
       
   291 		// First observer so start notification
       
   292 		StartNotification();
       
   293 		}
       
   294 	CAdaptationMessage *newObserver = new(ELeave) CAdaptationMessage(aMessage);
       
   295 	CleanupStack::PushL(newObserver);
       
   296 	iObserversList.AddObserverL(newObserver);	// CAdaptationMessage's ownership is passed to iObserversList
       
   297 	CleanupStack::Pop();//newObserver
       
   298 	}
       
   299 
       
   300 void CStateAdaptationObservers::DoNotifyCoopSysEventCancelL(const RMessage2& aMessage)
       
   301 	{
       
   302 	iStateAdaptation.NotifyCancel();
       
   303 	CAdaptationMessage *newObserver = new(ELeave) CAdaptationMessage(aMessage);
       
   304 	iObserversList.RemoveObserver(newObserver);	// CAdaptationMessage's ownership is passed to iObserversList
       
   305 	aMessage.Complete(KErrNone); 
       
   306 	
       
   307 	if(iObserversList.Count() == 0)
       
   308 		{
       
   309 		// Last observer cancelled, stop notification
       
   310 		if (IsActive())
       
   311 			{
       
   312 			Cancel();
       
   313 			}
       
   314 		}
       
   315 	}
       
   316 
       
   317 
       
   318 /**
       
   319  * Starts notification for this active object and sets it active
       
   320  * 
       
   321  * @internalComponent
       
   322  */
       
   323 void CStateAdaptationObservers::StartNotification()
       
   324 	{
       
   325 	DEBUGPRINT1A("CStateAdaptationObservers starting request for event notification");
       
   326 	iStateAdaptation.NotifyCoopSysEvent(iEventPckg,iStatus);
       
   327 
       
   328 	SetActive();	
       
   329 	}
       
   330 
       
   331 //from CActive
       
   332 
       
   333 
       
   334 void CStateAdaptationObservers::RunL()
       
   335 	{
       
   336 	DEBUGPRINT1A("CStateAdaptationObservers received event notification");
       
   337 	iObserversList.NotifyAndRemoveAll(iEventPckg(),iStatus.Int());
       
   338 	}
       
   339 
       
   340 TInt CStateAdaptationObservers::RunError( TInt /*aError */)
       
   341 	{
       
   342 	iObserversList.Close();
       
   343 	return KErrNone;
       
   344 	}
       
   345 
       
   346 void CStateAdaptationObservers::DoCancel()
       
   347 	{
       
   348 	DEBUGPRINT1A("CStateAdaptationObservers cancelling request for event notification");
       
   349 	iStateAdaptation.NotifyCancel();
       
   350 	iObserversList.NotifyAndRemoveAll(iEventPckg(), KErrCancel);
       
   351 	}
       
   352 
       
   353 
       
   354 //Observer related functionality
       
   355 void RStateAdaptationObserversList::AddObserverL(CAdaptationMessage *aNotificationMessage)
       
   356 	{
       
   357 	//any error will cause a leave
       
   358 	iObservers.AppendL(aNotificationMessage);
       
   359 	}
       
   360 void RStateAdaptationObserversList::Close()
       
   361 	{
       
   362 	// Before close, cleanup and signal all clients
       
   363 	NotifyAndRemoveAll(static_cast<TSsmCoopSysEventType>(0), KErrCancel);
       
   364 	// Now free the resources in the array
       
   365 	iObservers.Close();
       
   366 	}
       
   367 
       
   368 TInt RStateAdaptationObserversList::Count()
       
   369 	{
       
   370 	return iObservers.Count();
       
   371 	}
       
   372 
       
   373 void RStateAdaptationObserversList::NotifyAndRemoveAll(TSsmCoopSysEventType aEventType,TInt aCompleteCode)
       
   374 	{
       
   375 	TInt index,count = iObservers.Count();
       
   376 	
       
   377 	for(index =0;index < count ;index++)
       
   378 		{
       
   379 		TPckg<TSsmCoopSysEventType> pckgEvType(aEventType);
       
   380 		
       
   381 		// Complete the client with the requested code unless
       
   382 		// the descriptor write fails
       
   383 		TInt completeCode = aCompleteCode;
       
   384 		// Only copy across the event type if it was successful
       
   385 		if(aCompleteCode == KErrNone)
       
   386 			{		
       
   387 			TRAPD(err,iObservers[index]->WriteL(0,pckgEvType));
       
   388 			if(err != KErrNone)
       
   389 				{
       
   390 				completeCode = err;
       
   391 				}
       
   392 			}
       
   393 		iObservers[index]->Complete(completeCode);
       
   394 		delete iObservers[index];
       
   395 		iObservers[index] = NULL;
       
   396 		}
       
   397 	iObservers.Reset();
       
   398 	}
       
   399 
       
   400 
       
   401 void RStateAdaptationObserversList::RemoveObserver(CAdaptationMessage *aCancelMessage)
       
   402 	{
       
   403 	if (aCancelMessage == NULL)
       
   404 		{
       
   405 		return;
       
   406 		}
       
   407 	TInt index,count = iObservers.Count();
       
   408 	CAdaptationMessage *notificationMessage;
       
   409 	for(index =0; index < count; index++)
       
   410 		{
       
   411 		notificationMessage = iObservers[index];
       
   412 		
       
   413 		// Compare on session pointers to check that the cancel only happens to notifications from the
       
   414 		// same session
       
   415 		if( notificationMessage->Session() == aCancelMessage->Session() )
       
   416 			{
       
   417 			CAdaptationMessage *message= iObservers[index];
       
   418 			iObservers[index]->Complete(KErrCancel);
       
   419 			iObservers.Remove(index);
       
   420 			delete message;
       
   421 			break;
       
   422 			}
       
   423 		}
       
   424 	delete aCancelMessage;
       
   425 	}
       
   426 
       
   427 
       
   428 
       
   429 
       
   430