sysstatemgmt/systemstatemgr/cmn/src/ssmstateawaresession.cpp
changeset 0 4e1aa6a622a0
child 76 cb32bcc88bad
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32base.h>
       
    17 #include <domainmember.h>
       
    18 #include <ssm/ssmstateawaresession.h>
       
    19 
       
    20 #include "cmnpanic.h"
       
    21 #include "ssmdebug.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 
       
    33 /**
       
    34  @internalComponent
       
    35  @released 
       
    36  */
       
    37 class RSsmStateAwareSession::RPrivateImpl : public RDmDomain
       
    38 	{
       
    39 	};
       
    40 
       
    41 //
       
    42 //---------------- class RSsmStateAwareSession ------------------
       
    43 //
       
    44 
       
    45 /**
       
    46  Default constructor
       
    47  */
       
    48 EXPORT_C RSsmStateAwareSession::RSsmStateAwareSession()
       
    49 	: iPimpl(NULL)
       
    50 	{
       
    51 	}
       
    52 
       
    53 /**
       
    54  Connects to the domain identified by the specified domain Id.
       
    55  
       
    56  @param aId The identifier of the domain to be connected to.
       
    57  @return KErrNone, if successful; otherwise one of the other system-wide error codes. 
       
    58  */
       
    59 EXPORT_C TInt RSsmStateAwareSession::Connect(TDmDomainId aId)
       
    60 	{
       
    61 	iPimpl = new RPrivateImpl;
       
    62 	if(!iPimpl)
       
    63 		{
       
    64 		return KErrNoMemory;
       
    65 		}
       
    66 	TInt err = iPimpl->Connect(KDmHierarchyIdStartup, aId);
       
    67 	if (KErrNone != err)
       
    68 		{
       
    69 		Close();
       
    70 		}
       
    71 	return err;
       
    72 	}
       
    73 
       
    74 /**
       
    75  Disconnect from the domain.  
       
    76  */
       
    77 EXPORT_C void RSsmStateAwareSession::Close()
       
    78 	{
       
    79 	if(iPimpl)
       
    80 		{
       
    81 		iPimpl->Close();
       
    82 		}
       
    83 	delete iPimpl;
       
    84 	iPimpl = NULL;
       
    85 	}
       
    86 
       
    87 /**
       
    88  Reads the System Wide State.
       
    89  @return The System Wide State
       
    90  @panic ECmnErrState if not connected to a domain
       
    91  */
       
    92 EXPORT_C TSsmState RSsmStateAwareSession::State() const
       
    93 	{
       
    94 	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrState));
       
    95 	
       
    96 	TUint32 ds = 0;
       
    97 	//returned TDmDomainState is currently only 8 bits
       
    98 	ds = iPimpl->GetState(); //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
       
    99 	TSsmState state;
       
   100 	state.SetFromInt(ds);
       
   101 	return state;
       
   102 	}
       
   103 
       
   104 /**
       
   105  Use to get a notification when the System State changes.
       
   106  @param aStatus The TRequestStatus to be completed when the System State gets changed.
       
   107  @panic ECmnErrRqstStateNotif if not connected to a domain
       
   108  */
       
   109 EXPORT_C void RSsmStateAwareSession::RequestStateNotification(TRequestStatus& aStatus)
       
   110 	{
       
   111 	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrRqstStateNotif));
       
   112 	iPimpl->RequestTransitionNotification(aStatus);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
       
   113 	}
       
   114 
       
   115 /**
       
   116  Cancel an outstanding @c RequestStateNotification operation.
       
   117  @panic ECmnErrRqstStateNotifCancel if not connected to a domain
       
   118  */
       
   119 EXPORT_C void RSsmStateAwareSession::RequestStateNotificationCancel()
       
   120 	{
       
   121 	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrRqstStateNotifCancel));
       
   122 	iPimpl->CancelTransitionNotification();  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
       
   123 		
       
   124 	}
       
   125 
       
   126 /**
       
   127  Acknowledges the state change.
       
   128  An application must acknowledge that it has performed all actions required by the last known state of the domain. 
       
   129  
       
   130  @panic ECmnErrAcknldgStateNotif if not connected to a domain
       
   131  */
       
   132 EXPORT_C void RSsmStateAwareSession::AcknowledgeStateNotification(TInt aError)
       
   133 	{
       
   134 	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrAcknldgStateNotif));
       
   135 	iPimpl->AcknowledgeLastState(aError);  //lint !e613 Possible use of NULL pointer - caught by ASSERT_ALWAYS
       
   136 	}
       
   137 
       
   138 /**
       
   139  Acknowledges the state change.
       
   140  An application must acknowledge that it has performed all actions required by the last known state of the domain. 
       
   141  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
       
   143  */
       
   144 EXPORT_C void RSsmStateAwareSession::AcknowledgeAndRequestStateNotification(TInt aError, TRequestStatus& aStatus)
       
   145 	{
       
   146 	__ASSERT_ALWAYS(iPimpl, Panic(ECmnErrAcknldgRqstStateNotif));
       
   147 	//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
       
   149 	//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
       
   151 	}
       
   152 
       
   153 //
       
   154 //---------------- class CSsmStateAwareSession ------------------
       
   155 //
       
   156 
       
   157 /**
       
   158  Factory method that returns an instance of this object, connected to the domain 
       
   159  identified by the specified domain Id and setup to subscribe on System State changes.
       
   160  @param aId The identifier of the domain to be connected to.
       
   161  @return A new instance of this class, connected to the domain @c aId.   
       
   162  */
       
   163 EXPORT_C CSsmStateAwareSession* CSsmStateAwareSession::NewL(TDmDomainId aId)
       
   164 	{
       
   165 	CSsmStateAwareSession* self = CSsmStateAwareSession::NewLC(aId);
       
   166  	CleanupStack::Pop(self);
       
   167  	return self;
       
   168 	}
       
   169 
       
   170 /**
       
   171  Factory method that returns an instance of this object, connected to the domain 
       
   172  identified by the specified domain Id and setup to subscribe on System State changes.
       
   173  @param aId The identifier of the domain to be connected to.
       
   174  @return A new instance of this class, connected to the domain @c aId.   
       
   175  */
       
   176 EXPORT_C CSsmStateAwareSession* CSsmStateAwareSession::NewLC(TDmDomainId aId)
       
   177 	{
       
   178 	CSsmStateAwareSession* self = new (ELeave) CSsmStateAwareSession;
       
   179 	CleanupStack::PushL(self);
       
   180 	self->ConstructL(aId);
       
   181 	return self;
       
   182 	}
       
   183 
       
   184 /**
       
   185  @internalComponent 
       
   186  */
       
   187 void CSsmStateAwareSession::ConstructL(TDmDomainId aId)
       
   188 	{
       
   189 	iMonitor = CSsmStateMonitor::NewL(*this, aId);
       
   190 	}
       
   191 
       
   192 /**
       
   193  Used to coordinate array granularity with Compress() operations.
       
   194  @internalComponent 
       
   195  */
       
   196 const TInt KDefaultPtrArrayGranularity = 8;
       
   197 
       
   198 /**
       
   199  @internalComponent 
       
   200  */
       
   201 CSsmStateAwareSession::CSsmStateAwareSession() : iSubscribers(KDefaultPtrArrayGranularity)
       
   202 	{
       
   203 	}
       
   204 
       
   205 /**
       
   206  Destructor
       
   207  */
       
   208 EXPORT_C CSsmStateAwareSession::~CSsmStateAwareSession()
       
   209 	{
       
   210 	iSubscribers.Close();
       
   211 	delete 	iMonitor;
       
   212 	}
       
   213 
       
   214 /**
       
   215  Reads the System State
       
   216  @panic ECmnErrStateMon if not connected to a domain
       
   217  @return The System State 
       
   218  */
       
   219 EXPORT_C TSsmState CSsmStateAwareSession::State() const
       
   220 	{
       
   221 	__ASSERT_ALWAYS(iMonitor, Panic(ECmnErrStateMon));
       
   222 	return iMonitor->State();
       
   223 	}
       
   224 
       
   225 /**
       
   226  Register for a callback when the System State changes.
       
   227  @param aSubscriber The object to receive the callback
       
   228  */
       
   229 EXPORT_C void CSsmStateAwareSession::AddSubscriberL(MStateChangeNotificationSubscriber& aSubscriber)
       
   230 	{
       
   231 	iSubscribers.AppendL(&aSubscriber);
       
   232 	}
       
   233 
       
   234 /**
       
   235  Cancel callback subscription for System State Changes
       
   236  @param aSubscriber The object for which to cancel subsription.
       
   237  */
       
   238 EXPORT_C void CSsmStateAwareSession::RemoveSubscriber(const MStateChangeNotificationSubscriber& aSubscriber)
       
   239 	{
       
   240 	const TInt index = iSubscribers.Find(&aSubscriber);
       
   241 	if(index > KErrNotFound)
       
   242 		{
       
   243 		iSubscribers.Remove(index);
       
   244 		
       
   245 		const TInt count = iSubscribers.Count();
       
   246 		if((count % KDefaultPtrArrayGranularity) == 0)
       
   247 			{
       
   248 			iSubscribers.Compress();
       
   249 			}
       
   250 		}
       
   251 	}
       
   252 
       
   253 /**
       
   254  Called from CSsmStateMonitor when the System State have changed.
       
   255  @internalComponent
       
   256  */
       
   257 void CSsmStateAwareSession::NotifySubscribers(TSsmState aSsmState)
       
   258 	{
       
   259 	TInt count = iSubscribers.Count();
       
   260 	while (count--)
       
   261 		{
       
   262 #ifdef _DEBUG
       
   263 			TRAPD(err, iSubscribers[count]->StateChanged(aSsmState));
       
   264 			if(KErrNone != err)
       
   265 				{
       
   266 				DEBUGPRINT2A("Illegal leave (leavecode: %d) detected. Will be ignored", err);
       
   267 				}
       
   268 #else
       
   269 			TRAP_IGNORE(iSubscribers[count]->StateChanged(aSsmState));
       
   270 #endif
       
   271 		}
       
   272 	} //lint !e1746 Suppress parameter 'aSsmState' could be made const reference