sysstatemgmt/systemstatemgr/cmn/src/ssmstateawaresession.cpp
changeset 76 cb32bcc88bad
parent 0 4e1aa6a622a0
equal deleted inserted replaced
73:d38941471f1c 76:cb32bcc88bad
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    18 #include <ssm/ssmstateawaresession.h>
    18 #include <ssm/ssmstateawaresession.h>
    19 
    19 
    20 #include "cmnpanic.h"
    20 #include "cmnpanic.h"
    21 #include "ssmdebug.h"
    21 #include "ssmdebug.h"
    22 #include "ssmstatemonitor.h"
    22 #include "ssmstatemonitor.h"
    23 
       
    24 /**
       
    25  @internalComponent
       
    26  @released 
       
    27  */
       
    28 static void Panic(TInt aReason)
       
    29 	{
       
    30 	User::Panic(KPanicSsmCmn, aReason);
       
    31 	}
       
    32 
    23 
    33 /**
    24 /**
    34  @internalComponent
    25  @internalComponent
    35  @released 
    26  @released 
    36  */
    27  */
    89  @return The System Wide State
    80  @return The System Wide State
    90  @panic ECmnErrState if not connected to a domain
    81  @panic ECmnErrState if not connected to a domain
    91  */
    82  */
    92 EXPORT_C TSsmState RSsmStateAwareSession::State() const
    83 EXPORT_C TSsmState RSsmStateAwareSession::State() const
    93 	{
    84 	{
    94 	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrState));
    85 	__ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrState));
    95 	
    86 	
    96 	TUint32 ds = 0;
    87 	TUint32 ds = 0;
    97 	//returned TDmDomainState is currently only 8 bits
    88 	//returned TDmDomainState is currently only 8 bits
    98 	ds = iPimpl->GetState(); //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
    89 	ds = iPimpl->GetState(); //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
    99 	TSsmState state;
    90 	TSsmState state;
   106  @param aStatus The TRequestStatus to be completed when the System State gets changed.
    97  @param aStatus The TRequestStatus to be completed when the System State gets changed.
   107  @panic ECmnErrRqstStateNotif if not connected to a domain
    98  @panic ECmnErrRqstStateNotif if not connected to a domain
   108  */
    99  */
   109 EXPORT_C void RSsmStateAwareSession::RequestStateNotification(TRequestStatus& aStatus)
   100 EXPORT_C void RSsmStateAwareSession::RequestStateNotification(TRequestStatus& aStatus)
   110 	{
   101 	{
   111 	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrRqstStateNotif));
   102 	__ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrRqstStateNotif));
   112 	iPimpl->RequestTransitionNotification(aStatus);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
   103 	iPimpl->RequestTransitionNotification(aStatus);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
   113 	}
   104 	}
   114 
   105 
   115 /**
   106 /**
   116  Cancel an outstanding @c RequestStateNotification operation.
   107  Cancel an outstanding @c RequestStateNotification operation.
   117  @panic ECmnErrRqstStateNotifCancel if not connected to a domain
   108  @panic ECmnErrRqstStateNotifCancel if not connected to a domain
   118  */
   109  */
   119 EXPORT_C void RSsmStateAwareSession::RequestStateNotificationCancel()
   110 EXPORT_C void RSsmStateAwareSession::RequestStateNotificationCancel()
   120 	{
   111 	{
   121 	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrRqstStateNotifCancel));
   112 	__ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrRqstStateNotifCancel));
   122 	iPimpl->CancelTransitionNotification();  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
   113 	iPimpl->CancelTransitionNotification();  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
   123 		
   114 		
   124 	}
   115 	}
   125 
   116 
   126 /**
   117 /**
   129  
   120  
   130  @panic ECmnErrAcknldgStateNotif if not connected to a domain
   121  @panic ECmnErrAcknldgStateNotif if not connected to a domain
   131  */
   122  */
   132 EXPORT_C void RSsmStateAwareSession::AcknowledgeStateNotification(TInt aError)
   123 EXPORT_C void RSsmStateAwareSession::AcknowledgeStateNotification(TInt aError)
   133 	{
   124 	{
   134 	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrAcknldgStateNotif));
   125 	__ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrAcknldgStateNotif));
   135 	iPimpl->AcknowledgeLastState(aError);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
   126 	iPimpl->AcknowledgeLastState(aError);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
   136 	}
   127 	}
   137 
   128 
   138 /**
   129 /**
   139  Acknowledges the state change.
   130  Acknowledges the state change.
   141  This function appears like an atomic function and minimize the risk for missing a state notification.
   132  This function appears like an atomic function and minimize the risk for missing a state notification.
   142  @panic ECmnErrAcknldgRqstStateNotif if not connected to a domain
   133  @panic ECmnErrAcknldgRqstStateNotif if not connected to a domain
   143  */
   134  */
   144 EXPORT_C void RSsmStateAwareSession::AcknowledgeAndRequestStateNotification(TInt aError, TRequestStatus& aStatus)
   135 EXPORT_C void RSsmStateAwareSession::AcknowledgeAndRequestStateNotification(TInt aError, TRequestStatus& aStatus)
   145 	{
   136 	{
   146 	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrAcknldgRqstStateNotif));
   137 	__ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrAcknldgRqstStateNotif));
   147 	//Typical pattern of using P&S is to subscribe first then get current state
   138 	//Typical pattern of using P&S is to subscribe first then get current state
   148 	iPimpl->RequestTransitionNotification(aStatus);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
   139 	iPimpl->RequestTransitionNotification(aStatus);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
   149 	//Tell domain manager that we have processed the last state change.
   140 	//Tell domain manager that we have processed the last state change.
   150 	iPimpl->AcknowledgeLastState(aError);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
   141 	iPimpl->AcknowledgeLastState(aError);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
   151 	}
   142 	}
   152 
   143 
       
   144 #ifdef SYMBIAN_INCLUDE_APP_CENTRIC
       
   145 /**
       
   146 Defers the acknowledgement requesting more time.
       
   147 To be sure of deferring in time a client should call this immediately
       
   148 after receiving notification. This asynchronous call will complete once the original deadline
       
   149 is reached (ie. one period earlier than the final deadline), at which point the member must either
       
   150 defer again or acknowledge the transition. In the meantime, the member should perform
       
   151 its transition actions, whilst remaining responsive to new completion events.
       
   152 
       
   153 @note Deferrals are not always possible,
       
   154 whether the member will actually be given more time depends on if
       
   155    - The current transition allows deferrals at all.
       
   156    - The member still has deferrals left - there may be a maximum number
       
   157      allowed.
       
   158    - The deferral request was received in time.
       
   159 
       
   160 @param aStatus Status of request
       
   161    - KErrNone Request has completed i.e. The member must either defer again or acknowledge.
       
   162    - KErrCompletion The deferral was obsoleted by a subsequent call to AcknowledgeLastState.
       
   163    - KErrNotSupported The current transition may not be deferred, or maximum deferral count reached.
       
   164    - KErrCancel The deferral was cancelled.
       
   165    - KErrNotReady Deferral attempted before a transition notification was received
       
   166      or after the deadline for the previous one.
       
   167    - KErrPermissionDenied The member lacked the necessary capabilities.
       
   168    - KErrAlreadyExists A deferral was already outstanding.
       
   169      Both new and existing calls will complete with this error.
       
   170 
       
   171 This function is provided for members to inform the Domain Manager that they
       
   172 are still active and are responding to a transition notification.
       
   173 For example, a server may have to persist data using
       
   174 the file server before shut down. Since this task should be allowed to complete
       
   175 before shutdown continues, the member should defer the transition, and then persist
       
   176 the data, using asynchronous calls.
       
   177 
       
   178 At least one of the below capabilities is required in order to defer a
       
   179 domain transition. Without them, the client will get KErrPermissionDenied.
       
   180 
       
   181 @capability WriteDeviceData
       
   182 @capability ProtServ
       
   183 
       
   184 @pre The member has been notified of a transition which it has not yet acknowledged.
       
   185  */
       
   186 EXPORT_C void RSsmStateAwareSession::DeferAcknowledgement(TRequestStatus& aStatus)
       
   187     {
       
   188     __ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrDeferAcknNotif));    
       
   189     iPimpl->DeferAcknowledgement(aStatus); //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
       
   190     
       
   191     }
       
   192 
       
   193 /**
       
   194 Cancels the deferred call.
       
   195 Will cancel a call of DeferAcknowledgement, if one was pending.
       
   196 If none was pending, it does nothing.
       
   197 */
       
   198 EXPORT_C void RSsmStateAwareSession::CancelDeferral()
       
   199     {
       
   200     __ASSERT_ALWAYS(iPimpl, User::Panic(KPanicSsmCmn, ECmnErrCancelDeferNotif));    
       
   201     iPimpl->CancelDeferral();  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS   
       
   202     }
       
   203 #else
       
   204 EXPORT_C void RSsmStateAwareSession::DeferAcknowledgement(TRequestStatus& aStatus)
       
   205     {
       
   206     TRequestStatus* pStatus = &aStatus;     
       
   207     User::RequestComplete(pStatus, KErrNotSupported);
       
   208     }
       
   209 
       
   210 EXPORT_C void RSsmStateAwareSession::CancelDeferral()
       
   211     {
       
   212     }
       
   213 #endif
   153 //
   214 //
   154 //---------------- class CSsmStateAwareSession ------------------
   215 //---------------- class CSsmStateAwareSession ------------------
   155 //
   216 //
   156 
   217 
   157 /**
   218 /**
   216  @panic ECmnErrStateMon if not connected to a domain
   277  @panic ECmnErrStateMon if not connected to a domain
   217  @return The System State 
   278  @return The System State 
   218  */
   279  */
   219 EXPORT_C TSsmState CSsmStateAwareSession::State() const
   280 EXPORT_C TSsmState CSsmStateAwareSession::State() const
   220 	{
   281 	{
   221 	__ASSERT_ALWAYS(iMonitor, Panic(ECmnErrStateMon));
   282 	__ASSERT_ALWAYS(iMonitor, User::Panic(KPanicSsmCmn, ECmnErrStateMon));
   222 	return iMonitor->State();
   283 	return iMonitor->State();
   223 	}
   284 	}
   224 
   285 
   225 /**
   286 /**
   226  Register for a callback when the System State changes.
   287  Register for a callback when the System State changes.
   268 #else
   329 #else
   269 			TRAP_IGNORE(iSubscribers[count]->StateChanged(aSsmState));
   330 			TRAP_IGNORE(iSubscribers[count]->StateChanged(aSsmState));
   270 #endif
   331 #endif
   271 		}
   332 		}
   272 	} //lint !e1746 Suppress parameter 'aSsmState' could be made const reference
   333 	} //lint !e1746 Suppress parameter 'aSsmState' could be made const reference
       
   334 
       
   335 //
       
   336 //---------------- class CExtendedSsmStateAwareSession ------------------
       
   337 //
       
   338 #ifdef SYMBIAN_INCLUDE_APP_CENTRIC
       
   339 /**
       
   340 Factory method that returns an instance of this object, connected to the domain 
       
   341 identified by the specified domain Id and setup to subscribe on System State changes.
       
   342 @param aDomainId    The Id of the domain to connect to.
       
   343 @param aSubscriber reference to MStateChangeNotificationSubscriber2 
       
   344 */
       
   345 EXPORT_C CSsmStateAwareSession2* CSsmStateAwareSession2::NewL(TDmDomainId aDomainId, MStateChangeNotificationSubscriber2& aSubscriber)
       
   346     {
       
   347     CSsmStateAwareSession2* self = new (ELeave)CSsmStateAwareSession2(aSubscriber);
       
   348     CleanupStack::PushL(self);
       
   349     self->ConstructL(aDomainId);
       
   350     CleanupStack::Pop(self);
       
   351     return self;
       
   352     }
       
   353 
       
   354 CSsmStateAwareSession2::CSsmStateAwareSession2(MStateChangeNotificationSubscriber2& aSubscriber):
       
   355 CActive(CActive::EPriorityStandard), iDeferNotification(NULL), iSubscriber(&aSubscriber)
       
   356     {
       
   357     CActiveScheduler::Add(this);
       
   358     }
       
   359 
       
   360 void CSsmStateAwareSession2::ConstructL(TDmDomainId aDomainId)
       
   361     {
       
   362     User::LeaveIfError(iSsmStateAwareSession.Connect(aDomainId));
       
   363     iDeferNotification = new (ELeave) CSsmDeferralMonitor(iSsmStateAwareSession, *this);    
       
   364  
       
   365     }
       
   366 /**
       
   367 Destructor.
       
   368 Cleanup the internal CSsmDeferralMonitor active object.
       
   369 */
       
   370 EXPORT_C  CSsmStateAwareSession2::~CSsmStateAwareSession2()        
       
   371     {
       
   372     Cancel();
       
   373     delete iDeferNotification;
       
   374     iSsmStateAwareSession.Close();
       
   375     }
       
   376 
       
   377 /**
       
   378  Gets the TSsmState state.
       
   379  */
       
   380 EXPORT_C TSsmState CSsmStateAwareSession2::GetState()
       
   381     {
       
   382     return iSsmStateAwareSession.State();
       
   383     }
       
   384 
       
   385 /**
       
   386  Use to get a notification when the System State changes.
       
   387  */
       
   388 EXPORT_C void CSsmStateAwareSession2::RequestStateNotification()
       
   389     {
       
   390     __ASSERT_ALWAYS(!IsActive(), User::Panic(KPanicSsmCmn, ECmnErrRqstStateNotif)); 
       
   391     iSsmStateAwareSession.RequestStateNotification(iStatus);
       
   392     SetActive();    
       
   393     }
       
   394 
       
   395 /**
       
   396  Cancels an outstanding RequestStateNotification operation.
       
   397  */
       
   398 EXPORT_C void CSsmStateAwareSession2::RequestStateNotificationCancel()
       
   399     {
       
   400 	iDeferNotification->Cancel();
       
   401     iSsmStateAwareSession.RequestStateNotificationCancel();
       
   402     }
       
   403 
       
   404 /**
       
   405  Acknowledges the state change.
       
   406  An application must acknowledge that it has performed all actions required by the last known state of the domain.
       
   407  @param set aError while acknowledging.
       
   408  */
       
   409 EXPORT_C void CSsmStateAwareSession2::AcknowledgeStateNotification(TInt aError)
       
   410     {
       
   411     iSsmStateAwareSession.AcknowledgeStateNotification(aError);
       
   412     iDeferNotification->NotifyOfAcknowledgement();
       
   413     }
       
   414 
       
   415 /**
       
   416  Acknowledges the state change.
       
   417  An application must acknowledge that it has performed all actions required by the last known state of the domain. 
       
   418  This function appears like an atomic function and minimize the risk for missing a state notification.
       
   419  @param aError for aknowledging with error.
       
   420  */
       
   421 EXPORT_C void CSsmStateAwareSession2::AcknowledgeAndRequestStateNotification(TInt aError)
       
   422     {
       
   423     __ASSERT_ALWAYS(!IsActive(), User::Panic(KPanicSsmCmn, ECmnErrAcknldgRqstStateNotif)); 
       
   424     iSsmStateAwareSession.AcknowledgeAndRequestStateNotification(aError,iStatus);
       
   425 	iDeferNotification->NotifyOfAcknowledgement();
       
   426     SetActive();
       
   427     }
       
   428 
       
   429 /**
       
   430  Handles the client deferral error.
       
   431  @param aError Error code to handle
       
   432  */
       
   433 TInt CSsmStateAwareSession2::HandleDeferralError(TInt aError)
       
   434     {
       
   435     return (iSubscriber->HandleDeferralError(aError));
       
   436     }
       
   437 
       
   438 /**
       
   439  Handle completion of request notifications, begins deferrals.
       
   440 @note Clients should not need to override this, they
       
   441 will be notified of events via interface HandleTransition().
       
   442  */
       
   443 void CSsmStateAwareSession2::RunL()
       
   444     {
       
   445     iDeferNotification->DeferNotification();
       
   446     iSubscriber->HandleTransition(iStatus.Int());    
       
   447     }
       
   448 
       
   449 /**
       
   450 Cancels an outstanding notification request.
       
   451 Any outstanding notification request completes with KErrCancel.
       
   452 */
       
   453 void CSsmStateAwareSession2::DoCancel()
       
   454     {
       
   455     iDeferNotification->Cancel();
       
   456     iSsmStateAwareSession.RequestStateNotificationCancel();
       
   457     }
       
   458 
       
   459 #else
       
   460 EXPORT_C CSsmStateAwareSession2* CSsmStateAwareSession2::NewL(TDmDomainId /*aDomainId*/, MStateChangeNotificationSubscriber2& /*aSubscriber*/)
       
   461     {
       
   462     //This functionality is not supported , so returning NULL.
       
   463     return NULL;
       
   464     }
       
   465 
       
   466 //All the below functionality will not be provided.
       
   467 
       
   468 EXPORT_C  CSsmStateAwareSession2::~CSsmStateAwareSession2()        
       
   469     {    
       
   470     }
       
   471 
       
   472 EXPORT_C TSsmState CSsmStateAwareSession2::GetState()
       
   473     {
       
   474     //returning dummyState to get rid of compiler warning. 
       
   475     TSsmState dummyState;
       
   476     return dummyState;
       
   477     }
       
   478 
       
   479 EXPORT_C void CSsmStateAwareSession2::RequestStateNotification()
       
   480     {    
       
   481     }
       
   482 
       
   483 EXPORT_C void CSsmStateAwareSession2::RequestStateNotificationCancel()
       
   484     {    
       
   485     }
       
   486 
       
   487 EXPORT_C void CSsmStateAwareSession2::AcknowledgeStateNotification(TInt /*aError*/)
       
   488     {    
       
   489     }
       
   490 
       
   491 EXPORT_C void CSsmStateAwareSession2::AcknowledgeAndRequestStateNotification(TInt /*aError*/)
       
   492     {    
       
   493     }
       
   494 
       
   495 void CSsmStateAwareSession2::RunL()
       
   496     {        
       
   497     }
       
   498 
       
   499 void CSsmStateAwareSession2::DoCancel()
       
   500     {    
       
   501     }
       
   502 	
       
   503 TInt CSsmStateAwareSession2::HandleDeferralError(TInt aError)
       
   504 	{
       
   505 	return aError;
       
   506 	}
       
   507 
       
   508 #endif