diff -r 000000000000 -r 4e1aa6a622a0 sysstatemgmt/systemstatemgr/sus/src/susstateadaptation.cpp --- /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 + +/** +@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(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 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; + } + + + + +