--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysstatemgmt/systemstatemgr/sus/src/susstateadaptation.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,430 @@
+// Copyright (c) 2008-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 "susstateadaptation.h"
+#include <e32debug.h>
+
+/**
+@publishedPartner
+*/
+
+/*
+ //Add aMessage to the queue if AO is busy
+ //else
+ //Store the message in iCurrentMessage so that RunL can call aMessage::Complete()
+ //Unpack params
+ //Submit request
+*/
+
+void CStateAdaptationRequests::SubmitOrQueueL(const RMessage2 &aMessage)
+ {
+
+ CAdaptationMessage *messageCopy = new(ELeave) CAdaptationMessage(aMessage);
+
+ if(!IsActive())
+ {
+ Submit(messageCopy);
+ }
+ else
+ {
+ CleanupStack::PushL(messageCopy);
+ DEBUGPRINT2A("CStateAdaptationRequests queuing request with function id: %d", aMessage.Function());
+ User::LeaveIfError(iPendingRequestsQueue.Queue(messageCopy));
+ CleanupStack::Pop(messageCopy);
+ }
+ }
+
+void CStateAdaptationRequests::Submit(CAdaptationMessage*& aMessage)
+ {
+ DEBUGPRINT2A("CStateAdaptationRequests immediate submission of request with function id: %d", aMessage->Function());
+ iCurrentMessage = aMessage;
+ switch(aMessage->Function())
+ {
+ case ERequestCoopSysStateChange :
+ {
+ TSsmState newState;
+ newState.SetFromInt(aMessage->Int0());
+ iStateAdaptation.RequestCoopSysStateChange(newState, iStatus);
+ break;
+ }
+ case ERequestCoopSysSelfTest :
+ {
+ iStateAdaptation.RequestCoopSysSelfTest(iStatus);
+ break;
+ }
+ case ERequestCoopSysPerformRestartActions :
+ {
+ TInt reason = aMessage->Int0();
+ iStateAdaptation.RequestCoopSysPerformRestartActions(reason, iStatus);
+ break;
+ }
+ case ERequestCoopSysPerformShutdownActions :
+ {
+ TInt reason = aMessage->Int0();
+ iStateAdaptation.RequestCoopSysPerformShutdownActions(reason, iStatus);
+ break;
+ }
+ case ERequestCoopSysPerformRfsActions :
+ {
+ TSsmRfsType rfsType = ( TSsmRfsType )aMessage->Int0() ;
+ iStateAdaptation.RequestCoopSysPerformRfsActions(rfsType, iStatus);
+ break;
+ }
+ default:
+ {
+ aMessage->Complete(KErrArgument);
+ return;
+ }
+ }
+ SetActive();
+ }
+
+/**
+CStateAdaptationRequests implements State Adaptation related functionality as part of CSsmAdaptationServer.
+CSsmAdaptationServer loads State Adaptation plugin and creates CStateAdaptationRequests using the NewL.
+From then the loaded State Adaptation plugin will be owned by CStateAdaptationRequests.
+
+@internalComponent
+*/
+
+
+
+CStateAdaptationRequests* CStateAdaptationRequests::NewL(MStateAdaptation& aAdaptation)
+ {
+ CStateAdaptationRequests* self = new(ELeave) CStateAdaptationRequests(aAdaptation);
+ return self;
+ }
+
+CStateAdaptationRequests::CStateAdaptationRequests(MStateAdaptation& aAdaptation) : CActive(EPriorityStandard), iStateAdaptation(aAdaptation)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CStateAdaptationRequests::~CStateAdaptationRequests()
+ {
+ iPendingRequestsQueue.NotifyAndRemoveAll();
+ Cancel(); // This call will delete iCurrentMessage if any
+ iPendingRequestsQueue.Close();
+ Release();
+ }
+
+//from MstateAdaptation
+void CStateAdaptationRequests::Release()
+ {
+ iStateAdaptation.Release();
+ }
+
+
+void CStateAdaptationRequests::DoRequestCoopSysStateChangeL(const RMessage2& aMessage)
+ {
+ SubmitOrQueueL(aMessage);
+ }
+
+void CStateAdaptationRequests::DoRequestCoopSysSelfTestL(const RMessage2& aMessage)
+ {
+ SubmitOrQueueL(aMessage);
+ }
+
+void CStateAdaptationRequests::DoRequestCoopSysPerformRestartActionsL(const RMessage2& aMessage)
+ {
+ SubmitOrQueueL(aMessage);
+ }
+
+void CStateAdaptationRequests::DoRequestCoopSysPerformShutdownActionsL(const RMessage2& aMessage)
+ {
+ SubmitOrQueueL(aMessage);
+ }
+
+void CStateAdaptationRequests::DoRequestCoopSysPerformRfsActionsL(const RMessage2& aMessage)
+ {
+ SubmitOrQueueL(aMessage);
+ }
+
+/*
+
+ALGO
+ If iCurrentMessage == aMessage
+ then call plugin's RequestCancel()
+ otherwise
+ search the queue and complete the message with KErrCancel
+*/
+
+void CStateAdaptationRequests::DoRequestCancel(const RMessage2& aMessage)
+ {
+
+ if(iCurrentMessage != NULL)
+ {
+ if(aMessage.Session() == iCurrentMessage->Session())
+ {
+ DEBUGPRINT1A("CStateAdaptationRequests cancelling current request as requested");
+ iStateAdaptation.RequestCancel();
+ }
+ iPendingRequestsQueue.RemoveFromQueueAndComplete(aMessage);
+ aMessage.Complete(KErrNone);
+ }
+ else
+ {
+ DEBUGPRINT1A("CStateAdaptationRequests nothing to cancel, but cancel requested");
+ aMessage.Complete(KErrNone);
+ }
+
+ }
+
+/**
+ * Returns the state adaptation in use by this object
+ *
+ * @internalComponent
+ */
+MStateAdaptation& CStateAdaptationRequests::Adaptation()
+ {
+ return iStateAdaptation;
+ }
+
+/*
+ from CActive
+ Complete aMessage
+ Dequeue the queue and submit another request
+*/
+
+void CStateAdaptationRequests::RunL()
+ {
+
+ DEBUGPRINT2A("CStateAdaptationRequests processed the request with funtion id: %d", iCurrentMessage->Function());
+ iCurrentMessage->Complete(iStatus.Int());
+ delete iCurrentMessage;
+ iCurrentMessage = NULL;
+
+ if( (iPendingRequestsQueue.IsEmpty()) == EFalse )
+ {
+ CAdaptationMessage *messageCopy = NULL;
+ iPendingRequestsQueue.Dequeue(messageCopy);
+ Submit(messageCopy);
+ }
+ }
+
+TInt CStateAdaptationRequests::RunError( TInt aError)
+ {
+ if(iCurrentMessage != NULL)
+ {
+ iCurrentMessage->Complete(aError);
+ delete iCurrentMessage;
+ iCurrentMessage = NULL;
+ }
+
+ while( (iPendingRequestsQueue.IsEmpty()) == EFalse )
+ {
+ iPendingRequestsQueue.Dequeue(iCurrentMessage);
+ iCurrentMessage->Complete(aError);
+ delete iCurrentMessage;
+ iCurrentMessage = NULL;
+ }
+
+ return KErrNone;
+ }
+
+void CStateAdaptationRequests::DoCancel()
+ {
+ if(iCurrentMessage != NULL)
+ {
+ iCurrentMessage->Complete(KErrCancel);
+ delete iCurrentMessage;
+ iCurrentMessage = NULL;
+ }
+
+ while( (iPendingRequestsQueue.IsEmpty()) == EFalse )
+ {
+ iPendingRequestsQueue.Dequeue(iCurrentMessage);
+ iCurrentMessage->Complete(KErrCancel);
+ delete iCurrentMessage;
+ iCurrentMessage = NULL;
+ }
+ }
+
+
+// C Class
+CStateAdaptationObservers* CStateAdaptationObservers::NewL(MStateAdaptation& aAdaptation)
+ {
+ CStateAdaptationObservers* self = new(ELeave) CStateAdaptationObservers(aAdaptation);
+
+ CleanupStack::PushL(self);
+ CleanupStack::Pop(); // self
+ return self;
+ }
+
+CStateAdaptationObservers::CStateAdaptationObservers(MStateAdaptation& aAdaptation) : CActive(EPriorityStandard), iStateAdaptation(aAdaptation)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CStateAdaptationObservers::~CStateAdaptationObservers()
+ {
+ Cancel();
+ iObserversList.Close();
+ }
+
+//from MstateAdaptation
+
+void CStateAdaptationObservers::DoGetLastCoopSysEvent(const RMessage2& aMessage)
+ {
+ TRAPD(err,aMessage.WriteL(0,iEventPckg));
+ aMessage.Complete(err);
+ }
+
+
+void CStateAdaptationObservers::DoNotifyCoopSysEventL(const RMessage2& aMessage)
+ {
+ if(iObserversList.Count() == 0)
+ {
+ // First observer so start notification
+ StartNotification();
+ }
+ CAdaptationMessage *newObserver = new(ELeave) CAdaptationMessage(aMessage);
+ CleanupStack::PushL(newObserver);
+ iObserversList.AddObserverL(newObserver); // CAdaptationMessage's ownership is passed to iObserversList
+ CleanupStack::Pop();//newObserver
+ }
+
+void CStateAdaptationObservers::DoNotifyCoopSysEventCancelL(const RMessage2& aMessage)
+ {
+ iStateAdaptation.NotifyCancel();
+ CAdaptationMessage *newObserver = new(ELeave) CAdaptationMessage(aMessage);
+ iObserversList.RemoveObserver(newObserver); // CAdaptationMessage's ownership is passed to iObserversList
+ aMessage.Complete(KErrNone);
+
+ if(iObserversList.Count() == 0)
+ {
+ // Last observer cancelled, stop notification
+ if (IsActive())
+ {
+ Cancel();
+ }
+ }
+ }
+
+
+/**
+ * Starts notification for this active object and sets it active
+ *
+ * @internalComponent
+ */
+void CStateAdaptationObservers::StartNotification()
+ {
+ DEBUGPRINT1A("CStateAdaptationObservers starting request for event notification");
+ iStateAdaptation.NotifyCoopSysEvent(iEventPckg,iStatus);
+
+ SetActive();
+ }
+
+//from CActive
+
+
+void CStateAdaptationObservers::RunL()
+ {
+ DEBUGPRINT1A("CStateAdaptationObservers received event notification");
+ iObserversList.NotifyAndRemoveAll(iEventPckg(),iStatus.Int());
+ }
+
+TInt CStateAdaptationObservers::RunError( TInt /*aError */)
+ {
+ iObserversList.Close();
+ return KErrNone;
+ }
+
+void CStateAdaptationObservers::DoCancel()
+ {
+ DEBUGPRINT1A("CStateAdaptationObservers cancelling request for event notification");
+ iStateAdaptation.NotifyCancel();
+ iObserversList.NotifyAndRemoveAll(iEventPckg(), KErrCancel);
+ }
+
+
+//Observer related functionality
+void RStateAdaptationObserversList::AddObserverL(CAdaptationMessage *aNotificationMessage)
+ {
+ //any error will cause a leave
+ iObservers.AppendL(aNotificationMessage);
+ }
+void RStateAdaptationObserversList::Close()
+ {
+ // Before close, cleanup and signal all clients
+ NotifyAndRemoveAll(static_cast<TSsmCoopSysEventType>(0), KErrCancel);
+ // Now free the resources in the array
+ iObservers.Close();
+ }
+
+TInt RStateAdaptationObserversList::Count()
+ {
+ return iObservers.Count();
+ }
+
+void RStateAdaptationObserversList::NotifyAndRemoveAll(TSsmCoopSysEventType aEventType,TInt aCompleteCode)
+ {
+ TInt index,count = iObservers.Count();
+
+ for(index =0;index < count ;index++)
+ {
+ TPckg<TSsmCoopSysEventType> pckgEvType(aEventType);
+
+ // Complete the client with the requested code unless
+ // the descriptor write fails
+ TInt completeCode = aCompleteCode;
+ // Only copy across the event type if it was successful
+ if(aCompleteCode == KErrNone)
+ {
+ TRAPD(err,iObservers[index]->WriteL(0,pckgEvType));
+ if(err != KErrNone)
+ {
+ completeCode = err;
+ }
+ }
+ iObservers[index]->Complete(completeCode);
+ delete iObservers[index];
+ iObservers[index] = NULL;
+ }
+ iObservers.Reset();
+ }
+
+
+void RStateAdaptationObserversList::RemoveObserver(CAdaptationMessage *aCancelMessage)
+ {
+ if (aCancelMessage == NULL)
+ {
+ return;
+ }
+ TInt index,count = iObservers.Count();
+ CAdaptationMessage *notificationMessage;
+ for(index =0; index < count; index++)
+ {
+ notificationMessage = iObservers[index];
+
+ // Compare on session pointers to check that the cancel only happens to notifications from the
+ // same session
+ if( notificationMessage->Session() == aCancelMessage->Session() )
+ {
+ CAdaptationMessage *message= iObservers[index];
+ iObservers[index]->Complete(KErrCancel);
+ iObservers.Remove(index);
+ delete message;
+ break;
+ }
+ }
+ delete aCancelMessage;
+ }
+
+
+
+
+