--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysstatemgmt/systemstatemgr/ssm/src/ssmswptransitionscheduler.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,223 @@
+// 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 <ssm/ssmswppolicy.h>
+
+#include "ssmdebug.h"
+#include "ssmswptransitionengine.h"
+#include "ssmswptransitionscheduler.h"
+#include "ssmswpindividualtransitionscheduler.h"
+
+//
+//Construction/Destruction
+//
+
+
+/**
+Create a scheduler
+*/
+CSsmSwpTransitionScheduler* CSsmSwpTransitionScheduler::NewL()
+ {
+ CSsmSwpTransitionScheduler* self = NewLC();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CSsmSwpTransitionScheduler* CSsmSwpTransitionScheduler::NewLC()
+ {
+ CSsmSwpTransitionScheduler* self = new (ELeave) CSsmSwpTransitionScheduler();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+void CSsmSwpTransitionScheduler::ConstructL()
+ {
+ CTimer::ConstructL();
+ CActiveScheduler::Add(this);
+ }
+
+LOCAL_C TInt OrderingFunction(const CSsmSwpIndividualTransitionScheduler& aLhs, const CSsmSwpIndividualTransitionScheduler& aRhs)
+ {
+ return aLhs.SwpKey() - aRhs.SwpKey();
+ }
+
+LOCAL_C TInt SearchingFunction(const TUint* aUint, const CSsmSwpIndividualTransitionScheduler& aObject)
+ {
+ return *aUint - aObject.SwpKey();
+ }
+
+CSsmSwpTransitionScheduler::CSsmSwpTransitionScheduler()
+: CTimer(CActive::EPriorityStandard),
+ iLinearOrder(&OrderingFunction)
+ {
+
+ }
+
+/**
+Deactivate
+Destroy queue
+*/
+CSsmSwpTransitionScheduler::~CSsmSwpTransitionScheduler()
+ {
+ CTimer::Cancel();
+ iIndividualTransitionSchedulers.ResetAndDestroy();
+ }
+
+/**
+Take ownership of the transition engine and prepare it to run
+@param aEngine - the engine to run
+*/
+void CSsmSwpTransitionScheduler::SubmitL(CSsmSwpTransitionEngine* aEngine)
+ {
+ if(!aEngine)
+ {
+ SSMLOGLEAVE(KErrArgument); //lint !e527 Suppress Unreachable. Lint is just confused by macro, warning goes away when code in macro gets expanded
+ }
+ CSsmSwpIndividualTransitionScheduler* scheduler = FindScheduler(aEngine);
+ if(scheduler == NULL)
+ {
+ // No scheduler already for this SwP, need to create one
+ scheduler = CSsmSwpIndividualTransitionScheduler::NewLC(aEngine->TransitionValue().Key(), aEngine->CleSessionProxy(), *this);
+ iIndividualTransitionSchedulers.InsertInOrderL(scheduler, iLinearOrder);
+ CleanupStack::Pop(scheduler);
+ // Submit the request
+ scheduler->SubmitL(aEngine);
+ }
+ else
+ {
+ // Already have a scheduler for this session so submit it
+ scheduler->SubmitL(aEngine);
+ }
+ }
+
+void CSsmSwpTransitionScheduler::Cancel(CSession2* aSession)
+ {
+ // Iterate through the array informing all schedulers of the cancel
+ TInt count = iIndividualTransitionSchedulers.Count();
+ for(TInt i = 0; i < count; ++i)
+ {
+ iIndividualTransitionSchedulers[i]->Cancel(aSession);
+ }
+ }
+
+CSsmSwpIndividualTransitionScheduler* CSsmSwpTransitionScheduler::FindScheduler(CSsmSwpTransitionEngine* aEngine)
+ {
+ TInt offset = iIndividualTransitionSchedulers.FindInOrder(aEngine->TransitionValue().Key(), &SearchingFunction);
+ if(offset != KErrNotFound)
+ {
+ return iIndividualTransitionSchedulers[offset];
+ }
+ return NULL;
+ }
+
+/**
+Notify the monitor (if set) that one of the transition events has occured
+*/
+void CSsmSwpTransitionScheduler::NotifyTransitionQueued()
+ {
+ if(iTransactionMonitor != NULL)
+ {
+ iTransactionMonitor->SwpTransitionQueued();
+ }
+ }
+
+void CSsmSwpTransitionScheduler::NotifyTransitionStarted()
+ {
+ if(iTransactionMonitor != NULL)
+ {
+ iTransactionMonitor->SwpTransitionStarted();
+ }
+ }
+
+// Time to wait after completion before starting lazy cleanup
+const TInt KLazyCleanupTimeOut = 5000000;
+
+void CSsmSwpTransitionScheduler::NotifyTransitionCompleted()
+ {
+ DEBUGPRINT1(_L("ERequestSwpChange Completed"));
+ if(iTransactionMonitor != NULL)
+ {
+ iTransactionMonitor->SwpTransitionCompleted(++iNumberOfCompletedTransitions);
+ }
+ if(!IsActive())
+ {
+ After(KLazyCleanupTimeOut);
+ }
+ }
+
+void CSsmSwpTransitionScheduler::RunL()
+ {
+ // ignore any error in iStatus as clean-up is a safe operations to perform anytime
+
+ // iterate through schedulers, removing them if they're not doing anything
+ TInt top = iIndividualTransitionSchedulers.Count() - 1;
+ for(TInt i = top; i >= 0; --i)
+ {
+ if (iIndividualTransitionSchedulers[i]->IsIdle())
+ {
+ delete iIndividualTransitionSchedulers[i];
+ iIndividualTransitionSchedulers[i] = NULL;
+ iIndividualTransitionSchedulers.Remove(i);
+ }
+ }
+ // If there are now none left, free the memory
+ if(iIndividualTransitionSchedulers.Count() == 0)
+ {
+ iIndividualTransitionSchedulers.GranularCompress();
+ }
+ }
+
+TInt CSsmSwpTransitionScheduler::RunError(TInt __DEBUG_ONLY(aError))
+ {
+ DEBUGPRINT2A("CSsmSwpTransitionScheduler::RunError() run with error %d, ignoring", aError);
+ // Ignore any errors with the timer as it is only used for clean up
+ return KErrNone;
+ }
+
+void CSsmSwpTransitionScheduler::NotifyTransitionFailed()
+ {
+ DEBUGPRINT1(_L("Error: ERequestSwpChange Failed"));
+ if(iTransactionMonitor != NULL)
+ {
+ iTransactionMonitor->SwpTransitionFailed(++iNumberOfFailedTransitions);
+ }
+ }
+
+/**
+ * Used for testing purposes
+ * Delete all the individual Transition Schedulers stored in the array
+ * and free the memory
+ */
+#ifdef _DEBUG
+void CSsmSwpTransitionScheduler::CleanupIndividualSchedulerArray()
+ {
+ TInt top = iIndividualTransitionSchedulers.Count() - 1;
+ for(TInt i = top; i >= 0; --i)
+ {
+ if (iIndividualTransitionSchedulers[i]->IsIdle())
+ {
+ delete iIndividualTransitionSchedulers[i];
+ iIndividualTransitionSchedulers[i] = NULL;
+ iIndividualTransitionSchedulers.Remove(i);
+ }
+ }
+ // If there are now none left, free the memory
+ if(iIndividualTransitionSchedulers.Count() == 0)
+ {
+ iIndividualTransitionSchedulers.GranularCompress();
+ }
+ }
+#endif