sysstatemgmt/systemstatemgr/ssm/src/ssmswpindividualtransitionscheduler.cpp
changeset 0 4e1aa6a622a0
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 #include <ssm/ssmswppolicy.h>
       
    17 
       
    18 #include "ssmdebug.h"
       
    19 #include "ssmserverpanic.h"
       
    20 #include "clesessionproxy.h"
       
    21 #include "ssmswptransitionengine.h"
       
    22 #include "ssmswptransitionscheduler.h"
       
    23 #include "ssmswpindividualtransitionscheduler.h"
       
    24 
       
    25 
       
    26 //
       
    27 //Construction/Destruction
       
    28 //
       
    29 
       
    30 
       
    31 /**
       
    32 Create a scheduler
       
    33 */
       
    34 CSsmSwpIndividualTransitionScheduler* CSsmSwpIndividualTransitionScheduler::NewLC(TUint aSwpKey, MCleSessionProxy* aCleSession, CSsmSwpTransitionScheduler& aParent)
       
    35 	{
       
    36 	CSsmSwpIndividualTransitionScheduler* self = new (ELeave) CSsmSwpIndividualTransitionScheduler(aSwpKey, aParent);
       
    37 	CleanupStack::PushL(self);
       
    38 	self->ConstructL(aCleSession);
       
    39 	return self;
       
    40 	}
       
    41 
       
    42 void CSsmSwpIndividualTransitionScheduler::ConstructL(MCleSessionProxy* aCleSession)
       
    43 	{
       
    44 	// Need to create an individual CLE session proxy for each transition scheduler
       
    45 	iCleSession = aCleSession->CreateNewProxyL();
       
    46 	
       
    47 	// Need to create an individual swppolicy session for each transition scheduler
       
    48 	iSsmSwpPolicySession = CSsmSwpPolicyCliSession::NewL();
       
    49 	}
       
    50 
       
    51 CSsmSwpIndividualTransitionScheduler::CSsmSwpIndividualTransitionScheduler(TUint aSwpKey, CSsmSwpTransitionScheduler& aParent)
       
    52 	: 	CActive(CActive::EPriorityStandard),
       
    53 		iSchedulerState(EIdle),
       
    54 		iSwpKey(aSwpKey),
       
    55 		iParent(aParent)
       
    56 	{
       
    57 	CActiveScheduler::Add(this);
       
    58 	}
       
    59 
       
    60 /**
       
    61 Deactivate
       
    62 Destroy queue
       
    63 */
       
    64 CSsmSwpIndividualTransitionScheduler::~CSsmSwpIndividualTransitionScheduler()
       
    65 	{
       
    66 	CActive::Cancel();
       
    67 	__ASSERT_DEBUG(iTransitionQueue.Count() == 0, PanicNow(KPanicSysStateMgr,ESwpTransitionSchedulerError1));
       
    68 	DestroyTransitionQueue();
       
    69 	if(iCleSession)
       
    70 		{
       
    71 		iCleSession->Close();
       
    72 		iCleSession->ReleaseCle();
       
    73 		iCleSession = NULL;
       
    74 		}
       
    75 	if(iSsmSwpPolicySession)
       
    76 		{
       
    77 		delete iSsmSwpPolicySession;
       
    78 		}
       
    79 	}
       
    80 
       
    81 /**
       
    82 Take ownership of the transition engine and prepare to run it
       
    83 @param aEngine - the engine to run
       
    84 */
       
    85 void CSsmSwpIndividualTransitionScheduler::SubmitL(CSsmSwpTransitionEngine* aEngine)
       
    86 	{
       
    87 	if(!aEngine)
       
    88 		{
       
    89 		SSMLOGLEAVE(KErrArgument); //lint !e527 Suppress Unreachable. Lint is just confused by macro, warning goes away when code in macro gets expanded
       
    90 		}
       
    91 	// Change aEngine to having the cle proxy from this scheduler
       
    92 	// This allows multiple SwP transitions
       
    93 	aEngine->SetCleSessionProxy(iCleSession);
       
    94 
       
    95 	// Change aEngine to have the SsmSwpPolicySession from this scheduler. i.e, same SsmSwpPolicySession
       
    96 	// instance will be used for the all the individual Swp transitions.(the same swp policy session would be used).
       
    97 	// This allows multiple SwP transitions
       
    98 	aEngine->SetSsmSwpPolicySession(iSsmSwpPolicySession);
       
    99 	DoSubmitL(aEngine);
       
   100 	}
       
   101 
       
   102 void CSsmSwpIndividualTransitionScheduler::Cancel(CSession2* aSession)
       
   103 	{
       
   104 	//Cancel all queued requests that originates from aSession
       
   105 	CancelTransitionQueue(aSession);
       
   106 
       
   107 	// Cancel iCurrentTransition if it originates from aSession && still possible to Cancel (i.e. not started)
       
   108 	if(CurrentTransitionOriginatesFrom(aSession) && !iCurrentTransition->InTransition())
       
   109 		{
       
   110 		iCancellingSession = aSession;
       
   111 		CActive::Cancel();
       
   112 		iCancellingSession = NULL;
       
   113 
       
   114 		//We cancelled the currently running engine, see if there is anything left in the queue
       
   115 		iCurrentTransition = GetNextFromQueue();
       
   116 		if(iCurrentTransition != NULL) // we have more
       
   117 			{
       
   118 			ScheduleTransition();
       
   119 			}
       
   120 		}
       
   121 	}
       
   122 
       
   123 TBool CSsmSwpIndividualTransitionScheduler::CurrentTransitionOriginatesFrom(CSession2* aSession)
       
   124 	{
       
   125 	return (iCurrentTransition != NULL) && (iCurrentTransition->OriginatingSesssion() == aSession);
       
   126 	}
       
   127 
       
   128 TUint CSsmSwpIndividualTransitionScheduler::SwpKey() const
       
   129 	{
       
   130 	return iSwpKey;
       
   131 	}
       
   132 
       
   133 TBool CSsmSwpIndividualTransitionScheduler::IsIdle() const
       
   134 	{
       
   135 	return iTransitionQueue.Count() == 0 && iCurrentTransition == NULL;
       
   136 	}
       
   137 
       
   138 //
       
   139 // from CActive
       
   140 //
       
   141 
       
   142 /**
       
   143 Cancel running transition if any and destroy any transition in the queue that originates from the cancelling session
       
   144 */
       
   145 void CSsmSwpIndividualTransitionScheduler::DoCancel()
       
   146 	{
       
   147 	// Cancel the running transition if it originates from the calling session
       
   148 	if(CurrentTransitionOriginatesFrom(iCancellingSession))
       
   149 		{
       
   150 		iCurrentTransition->Cancel();
       
   151 		delete iCurrentTransition;
       
   152 		iCurrentTransition = NULL;
       
   153 		}
       
   154 	}
       
   155 
       
   156 /**
       
   157 The only valid event at the moment is completion of engine for any reason.
       
   158 Except few errors (for example, when a transition is not allowed),
       
   159 most of the unexpected transition errors are identified and dealt in the engine. 
       
   160 Notes: Tries to start the next engine even if there was an error.
       
   161 */
       
   162 void CSsmSwpIndividualTransitionScheduler::RunL()
       
   163 	{
       
   164 	if(KErrNone == iStatus.Int())
       
   165 		{
       
   166 		NotifyTransitionCompleted();
       
   167 		}
       
   168 	else
       
   169 		{
       
   170 		NotifyTransitionFailed();
       
   171 		}
       
   172 
       
   173 	// try to start the next transition
       
   174 	delete iCurrentTransition;
       
   175 	iCurrentTransition = NULL;
       
   176 	iCurrentTransition = GetNextFromQueue();
       
   177 	if(iCurrentTransition != NULL) // we have more
       
   178 		{
       
   179 		ScheduleTransition();
       
   180 		}
       
   181 	}
       
   182 
       
   183 /**
       
   184 Log an error occured
       
   185 
       
   186 @param aError the error
       
   187 
       
   188 */
       
   189 TInt CSsmSwpIndividualTransitionScheduler::RunError(TInt aError)
       
   190 	{
       
   191 	(void)aError;
       
   192 	DEBUGPRINT2(_L("CSsmSwpIndividualTransitionScheduler leave detected in RunL, error: %d"), aError);
       
   193 	PanicNow(KPanicSysStateMgr,ESwpTransitionSchedulerError5);
       
   194 	return KErrNone;
       
   195 	}
       
   196 
       
   197 //
       
   198 // private: methods
       
   199 //
       
   200 
       
   201 /**
       
   202 Start a transition if none is running, otherwise put it into the queue
       
   203 
       
   204 @param aEngine the transition engine to submit
       
   205 @leave one of the system wide error codes if insert fails
       
   206 
       
   207 */
       
   208 void CSsmSwpIndividualTransitionScheduler::DoSubmitL(CSsmSwpTransitionEngine* aEngine)
       
   209 	{
       
   210 	if(IsActive())
       
   211 		{
       
   212 		// add to Queue
       
   213 		iTransitionQueue.InsertL(aEngine, 0);
       
   214 		NotifyTransitionQueued();
       
   215 		}
       
   216 	else
       
   217 		{
       
   218 		// start immediately
       
   219 		__ASSERT_DEBUG(iCurrentTransition == NULL,  PanicNow(KPanicSysStateMgr,ESwpTransitionSchedulerError2));
       
   220 		iCurrentTransition = aEngine;
       
   221 		ScheduleTransition();
       
   222 		}
       
   223 	}
       
   224 
       
   225 /**
       
   226 Start the transition running and make it current
       
   227 
       
   228 @param aEngine the transition engine to submit
       
   229 @leave one of the system wide error codes
       
   230 */
       
   231 void CSsmSwpIndividualTransitionScheduler::ScheduleTransition()
       
   232 	{
       
   233 	__ASSERT_DEBUG(!IsActive() && IsAdded(), PanicNow(KPanicSysStateMgr,ESwpTransitionSchedulerError3));
       
   234 	__ASSERT_DEBUG(iCurrentTransition != NULL, PanicNow(KPanicSysStateMgr,ESwpTransitionSchedulerError4));
       
   235 
       
   236 	iCurrentTransition->Submit(iStatus);
       
   237 	NotifyTransitionStarted();
       
   238 	SetActive();
       
   239 	}
       
   240 
       
   241 /**
       
   242 Retrieve the next transition engine from the queue
       
   243 return NULL if the queue is empty
       
   244 
       
   245 @return - the next transition engine or NULL
       
   246 */
       
   247 CSsmSwpTransitionEngine* CSsmSwpIndividualTransitionScheduler::GetNextFromQueue()
       
   248 	{
       
   249 	TInt nextPos = iTransitionQueue.Count() - 1;
       
   250 	if(nextPos < 0) // Q empty
       
   251 		{
       
   252 		return NULL;
       
   253 		}
       
   254 	CSsmSwpTransitionEngine* ret = iTransitionQueue[nextPos];
       
   255 	iTransitionQueue.Remove(nextPos);
       
   256 	return ret;
       
   257 	}
       
   258 
       
   259 /**
       
   260 Remove and delete all queue entries, cancel any pending entries
       
   261 */
       
   262 void CSsmSwpIndividualTransitionScheduler::DestroyTransitionQueue()
       
   263 	{
       
   264 	const TInt count = iTransitionQueue.Count();
       
   265 	for(TInt i=0; i<count; i++)
       
   266 		{
       
   267 		iTransitionQueue[i]->CompleteClientMessage(KErrCancel);
       
   268 		}
       
   269 	iTransitionQueue.ResetAndDestroy();
       
   270 	}
       
   271 
       
   272 /**
       
   273 Cancel, remove and delete all queue entries originating from aSession
       
   274 */
       
   275 void CSsmSwpIndividualTransitionScheduler::CancelTransitionQueue(CSession2* aSession)
       
   276 	{
       
   277 	TInt count = iTransitionQueue.Count();
       
   278 	while(count--)
       
   279 		{
       
   280 		CSsmSwpTransitionEngine* engine = iTransitionQueue[count];
       
   281 		if( engine && (engine->OriginatingSesssion() == aSession) )
       
   282 			{
       
   283 			engine->CompleteClientMessage(KErrCancel);
       
   284 			iTransitionQueue.Remove(count);
       
   285 			delete engine;
       
   286 			}
       
   287 		}
       
   288 	}
       
   289 
       
   290 /**
       
   291 Notify the monitor (if set) that one of the transition events has occured
       
   292 */
       
   293 void CSsmSwpIndividualTransitionScheduler::NotifyTransitionQueued()
       
   294 	{
       
   295 	iParent.NotifyTransitionQueued();
       
   296 	}
       
   297 
       
   298 void CSsmSwpIndividualTransitionScheduler::NotifyTransitionStarted()
       
   299 	{
       
   300 	iParent.NotifyTransitionStarted();
       
   301 	}
       
   302 
       
   303 void CSsmSwpIndividualTransitionScheduler::NotifyTransitionCompleted()
       
   304 	{
       
   305 	DEBUGPRINT1(_L("ERequestSwpChange Completed"));
       
   306 	iParent.NotifyTransitionCompleted();
       
   307 	}
       
   308 
       
   309 void CSsmSwpIndividualTransitionScheduler::NotifyTransitionFailed()
       
   310 	{
       
   311 	DEBUGPRINT1(_L("Error: ERequestSwpChange Failed"));
       
   312 	iParent.NotifyTransitionFailed();
       
   313 	}