sysstatemgmt/systemstatemgr/cmn/src/ssmstateawaresession.cpp
changeset 76 cb32bcc88bad
parent 0 4e1aa6a622a0
--- a/sysstatemgmt/systemstatemgr/cmn/src/ssmstateawaresession.cpp	Wed Sep 29 15:13:21 2010 +0300
+++ b/sysstatemgmt/systemstatemgr/cmn/src/ssmstateawaresession.cpp	Fri Oct 08 14:33:25 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-2010 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"
@@ -25,15 +25,6 @@
  @internalComponent
  @released 
  */
-static void Panic(TInt aReason)
-	{
-	User::Panic(KPanicSsmCmn, aReason);
-	}
-
-/**
- @internalComponent
- @released 
- */
 class RSsmStateAwareSession::RPrivateImpl : public RDmDomain
 	{
 	};
@@ -91,7 +82,7 @@
  */
 EXPORT_C TSsmState RSsmStateAwareSession::State() const
 	{
-	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrState));
+	__ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrState));
 	
 	TUint32 ds = 0;
 	//returned TDmDomainState is currently only 8 bits
@@ -108,7 +99,7 @@
  */
 EXPORT_C void RSsmStateAwareSession::RequestStateNotification(TRequestStatus& aStatus)
 	{
-	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrRqstStateNotif));
+	__ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrRqstStateNotif));
 	iPimpl->RequestTransitionNotification(aStatus);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
 	}
 
@@ -118,7 +109,7 @@
  */
 EXPORT_C void RSsmStateAwareSession::RequestStateNotificationCancel()
 	{
-	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrRqstStateNotifCancel));
+	__ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrRqstStateNotifCancel));
 	iPimpl->CancelTransitionNotification();  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
 		
 	}
@@ -131,7 +122,7 @@
  */
 EXPORT_C void RSsmStateAwareSession::AcknowledgeStateNotification(TInt aError)
 	{
-	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrAcknldgStateNotif));
+	__ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrAcknldgStateNotif));
 	iPimpl->AcknowledgeLastState(aError);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
 	}
 
@@ -143,13 +134,83 @@
  */
 EXPORT_C void RSsmStateAwareSession::AcknowledgeAndRequestStateNotification(TInt aError, TRequestStatus& aStatus)
 	{
-	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrAcknldgRqstStateNotif));
+	__ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrAcknldgRqstStateNotif));
 	//Typical pattern of using P&S is to subscribe first then get current state
 	iPimpl->RequestTransitionNotification(aStatus);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
 	//Tell domain manager that we have processed the last state change.
 	iPimpl->AcknowledgeLastState(aError);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
 	}
 
+#ifdef SYMBIAN_INCLUDE_APP_CENTRIC
+/**
+Defers the acknowledgement requesting more time.
+To be sure of deferring in time a client should call this immediately
+after receiving notification. This asynchronous call will complete once the original deadline
+is reached (ie. one period earlier than the final deadline), at which point the member must either
+defer again or acknowledge the transition. In the meantime, the member should perform
+its transition actions, whilst remaining responsive to new completion events.
+
+@note Deferrals are not always possible,
+whether the member will actually be given more time depends on if
+   - The current transition allows deferrals at all.
+   - The member still has deferrals left - there may be a maximum number
+     allowed.
+   - The deferral request was received in time.
+
+@param aStatus Status of request
+   - KErrNone Request has completed i.e. The member must either defer again or acknowledge.
+   - KErrCompletion The deferral was obsoleted by a subsequent call to AcknowledgeLastState.
+   - KErrNotSupported The current transition may not be deferred, or maximum deferral count reached.
+   - KErrCancel The deferral was cancelled.
+   - KErrNotReady Deferral attempted before a transition notification was received
+     or after the deadline for the previous one.
+   - KErrPermissionDenied The member lacked the necessary capabilities.
+   - KErrAlreadyExists A deferral was already outstanding.
+     Both new and existing calls will complete with this error.
+
+This function is provided for members to inform the Domain Manager that they
+are still active and are responding to a transition notification.
+For example, a server may have to persist data using
+the file server before shut down. Since this task should be allowed to complete
+before shutdown continues, the member should defer the transition, and then persist
+the data, using asynchronous calls.
+
+At least one of the below capabilities is required in order to defer a
+domain transition. Without them, the client will get KErrPermissionDenied.
+
+@capability WriteDeviceData
+@capability ProtServ
+
+@pre The member has been notified of a transition which it has not yet acknowledged.
+ */
+EXPORT_C void RSsmStateAwareSession::DeferAcknowledgement(TRequestStatus& aStatus)
+    {
+    __ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrDeferAcknNotif));    
+    iPimpl->DeferAcknowledgement(aStatus); //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
+    
+    }
+
+/**
+Cancels the deferred call.
+Will cancel a call of DeferAcknowledgement, if one was pending.
+If none was pending, it does nothing.
+*/
+EXPORT_C void RSsmStateAwareSession::CancelDeferral()
+    {
+    __ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrCancelDeferNotif));    
+    iPimpl->CancelDeferral();  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS   
+    }
+#else
+EXPORT_C void RSsmStateAwareSession::DeferAcknowledgement(TRequestStatus& aStatus)
+    {
+    TRequestStatus* pStatus = &aStatus;     
+    User::RequestComplete(pStatus, KErrNotSupported);
+    }
+
+EXPORT_C void RSsmStateAwareSession::CancelDeferral()
+    {
+    }
+#endif
 //
 //---------------- class CSsmStateAwareSession ------------------
 //
@@ -218,7 +279,7 @@
  */
 EXPORT_C TSsmState CSsmStateAwareSession::State() const
 	{
-	__ASSERT_ALWAYS(iMonitor, Panic(ECmnErrStateMon));
+	__ASSERT_ALWAYS(iMonitor, User::Panic(KPanicSsmCmn, ECmnErrStateMon));
 	return iMonitor->State();
 	}
 
@@ -270,3 +331,178 @@
 #endif
 		}
 	} //lint !e1746 Suppress parameter 'aSsmState' could be made const reference
+
+//
+//---------------- class CExtendedSsmStateAwareSession ------------------
+//
+#ifdef SYMBIAN_INCLUDE_APP_CENTRIC
+/**
+Factory method that returns an instance of this object, connected to the domain 
+identified by the specified domain Id and setup to subscribe on System State changes.
+@param aDomainId    The Id of the domain to connect to.
+@param aSubscriber reference to MStateChangeNotificationSubscriber2 
+*/
+EXPORT_C CSsmStateAwareSession2* CSsmStateAwareSession2::NewL(TDmDomainId aDomainId, MStateChangeNotificationSubscriber2& aSubscriber)
+    {
+    CSsmStateAwareSession2* self = new (ELeave)CSsmStateAwareSession2(aSubscriber);
+    CleanupStack::PushL(self);
+    self->ConstructL(aDomainId);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CSsmStateAwareSession2::CSsmStateAwareSession2(MStateChangeNotificationSubscriber2& aSubscriber):
+CActive(CActive::EPriorityStandard), iDeferNotification(NULL), iSubscriber(&aSubscriber)
+    {
+    CActiveScheduler::Add(this);
+    }
+
+void CSsmStateAwareSession2::ConstructL(TDmDomainId aDomainId)
+    {
+    User::LeaveIfError(iSsmStateAwareSession.Connect(aDomainId));
+    iDeferNotification = new (ELeave) CSsmDeferralMonitor(iSsmStateAwareSession, *this);    
+ 
+    }
+/**
+Destructor.
+Cleanup the internal CSsmDeferralMonitor active object.
+*/
+EXPORT_C  CSsmStateAwareSession2::~CSsmStateAwareSession2()        
+    {
+    Cancel();
+    delete iDeferNotification;
+    iSsmStateAwareSession.Close();
+    }
+
+/**
+ Gets the TSsmState state.
+ */
+EXPORT_C TSsmState CSsmStateAwareSession2::GetState()
+    {
+    return iSsmStateAwareSession.State();
+    }
+
+/**
+ Use to get a notification when the System State changes.
+ */
+EXPORT_C void CSsmStateAwareSession2::RequestStateNotification()
+    {
+    __ASSERT_ALWAYS(!IsActive(), User::Panic(KPanicSsmCmn, ECmnErrRqstStateNotif)); 
+    iSsmStateAwareSession.RequestStateNotification(iStatus);
+    SetActive();    
+    }
+
+/**
+ Cancels an outstanding RequestStateNotification operation.
+ */
+EXPORT_C void CSsmStateAwareSession2::RequestStateNotificationCancel()
+    {
+	iDeferNotification->Cancel();
+    iSsmStateAwareSession.RequestStateNotificationCancel();
+    }
+
+/**
+ Acknowledges the state change.
+ An application must acknowledge that it has performed all actions required by the last known state of the domain.
+ @param set aError while acknowledging.
+ */
+EXPORT_C void CSsmStateAwareSession2::AcknowledgeStateNotification(TInt aError)
+    {
+    iSsmStateAwareSession.AcknowledgeStateNotification(aError);
+    iDeferNotification->NotifyOfAcknowledgement();
+    }
+
+/**
+ Acknowledges the state change.
+ An application must acknowledge that it has performed all actions required by the last known state of the domain. 
+ This function appears like an atomic function and minimize the risk for missing a state notification.
+ @param aError for aknowledging with error.
+ */
+EXPORT_C void CSsmStateAwareSession2::AcknowledgeAndRequestStateNotification(TInt aError)
+    {
+    __ASSERT_ALWAYS(!IsActive(), User::Panic(KPanicSsmCmn, ECmnErrAcknldgRqstStateNotif)); 
+    iSsmStateAwareSession.AcknowledgeAndRequestStateNotification(aError,iStatus);
+	iDeferNotification->NotifyOfAcknowledgement();
+    SetActive();
+    }
+
+/**
+ Handles the client deferral error.
+ @param aError Error code to handle
+ */
+TInt CSsmStateAwareSession2::HandleDeferralError(TInt aError)
+    {
+    return (iSubscriber->HandleDeferralError(aError));
+    }
+
+/**
+ Handle completion of request notifications, begins deferrals.
+@note Clients should not need to override this, they
+will be notified of events via interface HandleTransition().
+ */
+void CSsmStateAwareSession2::RunL()
+    {
+    iDeferNotification->DeferNotification();
+    iSubscriber->HandleTransition(iStatus.Int());    
+    }
+
+/**
+Cancels an outstanding notification request.
+Any outstanding notification request completes with KErrCancel.
+*/
+void CSsmStateAwareSession2::DoCancel()
+    {
+    iDeferNotification->Cancel();
+    iSsmStateAwareSession.RequestStateNotificationCancel();
+    }
+
+#else
+EXPORT_C CSsmStateAwareSession2* CSsmStateAwareSession2::NewL(TDmDomainId /*aDomainId*/, MStateChangeNotificationSubscriber2& /*aSubscriber*/)
+    {
+    //This functionality is not supported , so returning NULL.
+    return NULL;
+    }
+
+//All the below functionality will not be provided.
+
+EXPORT_C  CSsmStateAwareSession2::~CSsmStateAwareSession2()        
+    {    
+    }
+
+EXPORT_C TSsmState CSsmStateAwareSession2::GetState()
+    {
+    //returning dummyState to get rid of compiler warning. 
+    TSsmState dummyState;
+    return dummyState;
+    }
+
+EXPORT_C void CSsmStateAwareSession2::RequestStateNotification()
+    {    
+    }
+
+EXPORT_C void CSsmStateAwareSession2::RequestStateNotificationCancel()
+    {    
+    }
+
+EXPORT_C void CSsmStateAwareSession2::AcknowledgeStateNotification(TInt /*aError*/)
+    {    
+    }
+
+EXPORT_C void CSsmStateAwareSession2::AcknowledgeAndRequestStateNotification(TInt /*aError*/)
+    {    
+    }
+
+void CSsmStateAwareSession2::RunL()
+    {        
+    }
+
+void CSsmStateAwareSession2::DoCancel()
+    {    
+    }
+	
+TInt CSsmStateAwareSession2::HandleDeferralError(TInt aError)
+	{
+	return aError;
+	}
+
+#endif