userlibandfileserver/domainmgr/src/domaincli.cpp
changeset 0 a41df078684a
child 42 a179b74831c9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/domainmgr/src/domaincli.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1175 @@
+// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "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:
+// domain\src\domaincli.cpp
+// 
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32property.h>
+
+#include <domainmember.h>
+#include <domainmanager.h>
+#include "domainobserver.h"
+#include "domainsrv.h"
+
+#define __DM_PANIC(aError) User::Panic(_L("domainCli.cpp"), (-(aError)) | (__LINE__ << 16))
+#define __DM_ASSERT(aCond) __ASSERT_DEBUG(aCond,User::Panic(_L("domainCli.cpp; assertion failed"), __LINE__))
+
+TInt RDmDomainSession::Connect(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, TUint* aKey)
+	{
+	TInt r = RSessionBase::CreateSession(KDmDomainServerNameLit, KDmDomainServerVersion, 1);
+	if (r != KErrNone)
+		return r;
+	TIpcArgs a( (TInt)aHierarchyId, (TInt)aDomainId );
+	r = RSessionBase::SendReceive(EDmDomainJoin, a);
+	if (r != KErrNone)
+		{
+		RSessionBase::Close();
+		return r;
+		}
+	*aKey = DmStatePropertyKey(
+		aHierarchyId, 
+		aDomainId);
+
+	return KErrNone;
+	}
+
+void RDmDomainSession::Acknowledge(TInt aValue, TInt aError)
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+
+	TIpcArgs a(aValue, aError);
+	TInt r = RSessionBase::SendReceive(EDmStateAcknowledge, a);
+	if (r != KErrNone)
+		__DM_PANIC(r);
+	}
+
+void RDmDomainSession::RequestTransitionNotification()
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+	TInt r = RSessionBase::SendReceive(EDmStateRequestTransitionNotification);
+	if (r != KErrNone)
+		__DM_PANIC(r);
+	}
+
+void RDmDomainSession::CancelTransitionNotification()
+	{
+	if (Handle() != KNullHandle)
+		{
+		TInt r = RSessionBase::SendReceive(EDmStateCancelTransitionNotification);
+		if (r != KErrNone)
+			__DM_PANIC(r);
+		}
+	}
+
+
+
+/**
+Connects to the domain identified by the specified domain Id.
+
+To connect to the root domain, which has the Id KDmIdRoot,
+the capability WriteDeviceData is required.
+
+Once connected, an  application can use this RDmDomain object to read
+the domain's power state and to request notification
+when the power state changes.
+
+@param aDomainId The identifier of the domain to be connected to.
+
+@return KErrNone, if successful; otherwise one of the other system-wide
+        or domain manager specific error codes.
+
+@capability WriteDeviceData If aDomainId==KDmIdRoot
+*/
+EXPORT_C TInt RDmDomain::Connect(TDmDomainId aDomainId)
+	{
+	TUint key;
+	TInt r = iSession.Connect(KDmHierarchyIdPower, aDomainId, &key);
+	if (r != KErrNone)
+		return r;
+	r = iStateProperty.Attach(KUidDmPropertyCategory, key);
+	if (r != KErrNone)
+		{
+		iSession.Close();
+		return r;
+		}
+	return KErrNone;
+	}
+	
+
+
+
+/**
+Connects to the domain identified by the specified domain Id.
+
+To connect to the root domain, which has the Id KDmIdRoot,
+the capability WriteDeviceData is required.
+
+Once connected, an  application can use this RDmDomain object to read
+the domain's state and to request notification
+when the state changes.
+
+@param aHierarchyId	The Id of the domain hierarchy to connect to.
+@param aDomainId    The identifier of the domain to be connected to.
+
+@return KErrNone, if successful; otherwise one of the other system-wide
+        or domain manager specific error codes.
+
+@capability WriteDeviceData If aDomainId==KDmIdRoot
+*/
+EXPORT_C TInt RDmDomain::Connect(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId)
+	{
+	TUint key;
+	TInt r = iSession.Connect(aHierarchyId, aDomainId, &key);
+	if (r != KErrNone)
+		return r;
+	r = iStateProperty.Attach(KUidDmPropertyCategory, key);
+	if (r != KErrNone)
+		{
+		iSession.Close();
+		return r;
+		}
+	return KErrNone;
+	}
+	
+
+	
+	
+/**
+Disconnects from the associated domain.
+	
+If this object is not connected to any domain, then it returns silently.
+*/
+EXPORT_C void RDmDomain::Close()
+	{
+	iSession.Close();
+	iStateProperty.Close();
+	}
+
+
+
+
+/**
+Requests notification when the domain's state changes.
+
+This is an asynchronous request that completes when
+the domain's state changes.
+
+@param aStatus The request status object for this asynchronous request.
+
+@see RDmDomain::CancelTransitionNotification()
+*/
+EXPORT_C void RDmDomain::RequestTransitionNotification(TRequestStatus& aStatus)
+	{
+	iStateProperty.Subscribe(aStatus);
+	iSession.RequestTransitionNotification();
+	}
+
+
+
+
+/**
+Cancels an outstanding notification request.
+
+Any outstanding notification request completes with KErrCancel.
+*/
+EXPORT_C void RDmDomain::CancelTransitionNotification()
+	{
+	iSession.CancelTransitionNotification();
+	iStateProperty.Cancel();
+	}
+
+
+
+
+/**
+Gets the domain's power state.
+	
+An application normally calls this function after a notification request
+has completed. It then performs any application-dependent action demanded by
+the power state, and then acknowledges the state transition.
+
+Note that the domain manager requires any domain power state change to be
+acknowledged by all applications connected to the domain.
+
+@return The connected domain's power state.
+
+@see RDmDomain::AcknowledgeLastState()
+*/
+EXPORT_C TPowerState RDmDomain::GetPowerState()
+	{
+	TInt value;
+	TInt r = iStateProperty.Get(value);
+	if (r != KErrNone)
+		__DM_PANIC(r);
+	iLastStatePropertyValue = value;
+	return (TPowerState) DmStateFromPropertyValue(value);
+	}
+
+
+
+
+/**
+Acknowledges the state change.
+	
+An application must acknowledge that it has performed all actions required
+by the last known state of the domain.
+*/
+EXPORT_C void RDmDomain::AcknowledgeLastState()
+	{
+	iSession.Acknowledge(iLastStatePropertyValue, KErrNone);
+	}
+
+
+/**
+Acknowledges the state change with the specified error
+	
+An application must acknowledge that it has performed all actions required
+by the last known state of the domain.
+
+@param aError KDmErrNotJoin if domain is not part of the hierarhcy or a 
+	system wide error value associated with the state change.
+*/
+EXPORT_C void RDmDomain::AcknowledgeLastState(TInt aError)
+	{
+	iSession.Acknowledge(iLastStatePropertyValue, aError);
+	}
+
+
+
+/**
+Gets the domain's state.
+	
+An application normally calls this function after a notification request
+has completed. It then performs any application-dependent action demanded by
+the state, and then acknowledges the state transition.
+
+Note, that the domain manager requires any domain state change to be
+acknowledged by all applications connected to the domain.
+
+@return The connected domain's state.
+*/
+EXPORT_C TDmDomainState RDmDomain::GetState()
+	{
+	TInt value;
+	TInt r = iStateProperty.Get(value);
+	if (r != KErrNone)
+		__DM_PANIC(r);
+	iLastStatePropertyValue = value;
+	return DmStateFromPropertyValue(value);
+	}
+
+TInt RDmManagerSession::Connect()
+	{
+	__DM_ASSERT(Handle() == KNullHandle);
+
+	return RSessionBase::CreateSession(
+				KDmManagerServerNameLit, 
+				KDmManagerServerVersion, 
+				2);
+	}
+
+TInt RDmManagerSession::ConnectObserver(TDmHierarchyId aHierarchyId)
+	{
+	TInt r = Connect();
+	if (r != KErrNone)
+		return r;
+
+	TIpcArgs a( (TInt)aHierarchyId);
+	r = RSessionBase::SendReceive(EDmObserverJoin, a);
+	if (r != KErrNone)
+		{
+		RSessionBase::Close();
+		return r;
+		}
+	return KErrNone;
+	}
+
+TInt RDmManagerSession::Connect(TDmHierarchyId aHierarchyId)
+	{
+	TInt r = Connect();
+	if (r != KErrNone)
+		return r;
+
+	TIpcArgs a( (TInt)aHierarchyId);
+	r = RSessionBase::SendReceive(EDmHierarchyJoin, a);
+	if (r != KErrNone)
+		{
+		RSessionBase::Close();
+		return r;
+		}
+	return KErrNone;
+	}
+
+void RDmManagerSession::RequestDomainTransition(
+	TDmDomainId aDomainId, 
+	TDmDomainState aState,
+	TDmTraverseDirection aDirection,
+	TRequestStatus& aStatus)
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+	
+	if(aDirection < 0 || aDirection > ETraverseMax)
+		__DM_PANIC(KErrArgument);
+
+	TIpcArgs a(aDomainId, aState, aDirection);
+	RSessionBase::SendReceive(EDmRequestDomainTransition, a, aStatus);
+	}
+
+void RDmManagerSession::CancelTransition()
+	{
+	if (Handle() != KNullHandle)
+		{
+		TInt r = RSessionBase::SendReceive(EDmCancelTransition);
+		if (r != KErrNone)
+			__DM_PANIC(r);
+		}
+	}
+
+void RDmManagerSession::CancelObserver()
+	{
+	if (Handle() != KNullHandle)
+		{
+		TInt r = RSessionBase::SendReceive(EDmObserverCancel);
+		if (r != KErrNone)
+			__DM_PANIC(r);
+		}
+	}
+
+void RDmManagerSession::RequestSystemTransition(
+	TDmDomainState aState,
+	TDmTraverseDirection aDirection,
+	TRequestStatus& aStatus)
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+
+	TIpcArgs a(aState, aDirection);
+	RSessionBase::SendReceive(EDmRequestSystemTransition, a, aStatus);
+	}
+
+TInt RDmManagerSession::AddDomainHierarchy(TDmHierarchyId aHierarchyId)
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+
+	TIpcArgs a( (TInt)aHierarchyId);
+	TInt r = RSessionBase::SendReceive(EDmHierarchyAdd, a);
+
+	return r;
+	}
+
+TInt RDmManagerSession::GetTransitionFailureCount()
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+
+	return RSessionBase::SendReceive(EDmGetTransitionFailureCount);
+	}
+
+TInt RDmManagerSession::GetTransitionFailures(RArray<const TTransitionFailure>& aTransitionFailures)
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+
+	aTransitionFailures.Reset();
+
+	TInt err = KErrNone;
+
+	TInt failureCount = GetTransitionFailureCount();
+	if (failureCount <= 0)
+		return failureCount;
+
+	TTransitionFailure* failures = new TTransitionFailure[failureCount];
+	if(failures == NULL)
+		return(KErrNoMemory);
+	TPtr8 dataPtr(reinterpret_cast<TUint8*>(failures), failureCount * sizeof(TTransitionFailure));
+
+	TIpcArgs a(&dataPtr);
+	err = RSessionBase::SendReceive(EDmGetTransitionFailures, a);
+	
+	if (err == KErrNone)
+		{
+		for (TInt i=0; i<failureCount; i++)
+			aTransitionFailures.Append(failures[i]);
+		}
+
+	delete [] failures;
+
+	return err;
+	}
+
+TInt RDmManagerSession::StartObserver(TDmDomainId aDomainId, TDmNotifyType aNotifyType)
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+	
+	TIpcArgs a(aDomainId,aNotifyType);
+	return(RSessionBase::SendReceive(EDmObserverStart,a));
+	}
+
+void RDmManagerSession::GetNotification(TRequestStatus& aStatus)
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+	RSessionBase::SendReceive(EDmObserverNotify,aStatus);
+	}
+	
+TInt RDmManagerSession::GetEventCount()
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+	return(RSessionBase::SendReceive(EDmObserverEventCount));
+	}
+
+TInt RDmManagerSession::GetEvents(RArray<const TTransInfo>& aTransitions)
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+
+	aTransitions.Reset();
+
+
+	TInt count = GetEventCount();
+	// This shouldn't happen unless something gone terribly wrong
+	if (count <= 0)
+		return KErrGeneral;
+
+	TTransInfo* trans = new TTransInfo[count];
+	if(trans == NULL)
+		return(KErrNoMemory);
+	
+	TPtr8 dataPtr(reinterpret_cast<TUint8*>(trans), count * sizeof(TTransInfo));
+
+	TIpcArgs a(&dataPtr);
+	TInt ret=RSessionBase::SendReceive(EDmObserverGetEvent, a);
+	
+	if(ret==KErrNone)
+		{
+		for (TInt i=0; i<count; i++)
+			aTransitions.Append(trans[i]);
+		}
+	
+	delete [] trans;
+	return ret;
+	
+	}
+
+TInt RDmManagerSession::ObserverDomainCount()
+	{
+	__DM_ASSERT(Handle() != KNullHandle);
+	return(RSessionBase::SendReceive(EDmObserveredCount));
+	}
+
+/**
+@internalAll
+@released
+*/
+EXPORT_C TInt RDmDomainManager::WaitForInitialization()
+	{
+	RProperty prop;
+	TInt r = prop.Attach(KUidDmPropertyCategory, KDmPropertyKeyInit);
+	if (r != KErrNone)
+		return r;
+
+#ifdef _DEBUG
+	TInt count = RThread().RequestCount();
+#endif
+
+	TRequestStatus status;
+	for (;;)
+		{
+		prop.Subscribe(status);
+		TInt value;
+		r = prop.Get(value);
+		if (r == KErrNone)
+			{
+			if (value) break; // initialized
+			// property exists but the server is not intialized yet
+			}
+		else
+			{
+			if (r != KErrNotFound) break; // error
+			// property doesn't exist yet
+			}
+		User::WaitForRequest(status);
+		if (status.Int() != KErrNone)
+			break;	// error
+		}
+
+	if (status.Int() == KRequestPending)
+		{
+		prop.Cancel();
+		User::WaitForRequest(status);
+		}
+	prop.Close();
+
+	__DM_ASSERT(RThread().RequestCount() == count);
+
+	return r;
+	}
+
+
+
+
+/**
+Opens a controlling connection to the standard power domain hierarchy
+in the domain manager.
+
+The domain manger allows only one open connection at any one time to the 
+power domain hierarchy.
+Connection is usually made by the power policy entity.
+
+@return KErrNone, if successful; otherwise one of the other system-wide
+        or the domain manager specific error codes.
+        
+@see KDmErrAlreadyJoin   
+*/
+EXPORT_C TInt RDmDomainManager::Connect()
+	{
+	return iSession.Connect(KDmHierarchyIdPower);
+	}
+
+
+
+
+/**
+Opens a controlling connection to a specific domain hieararchy owned 
+by the domain manager.
+
+The domain manger allows only one open connection at any one time to a 
+particular hierarchy.
+
+@param	aHierarchyId	The Id of the domain hierarchy to connect to.
+
+@return KErrNone, if successful; otherwise one of the other system-wide
+        or domain manager specific error codes.
+        
+@see KDmErrAlreadyJoin
+@see KErrBadHierarchyId       
+*/
+EXPORT_C TInt RDmDomainManager::Connect(TDmHierarchyId aHierarchyId)
+
+	{
+	return iSession.Connect(aHierarchyId);
+	}
+
+
+
+
+/**
+Closes this connection to the domain manager.
+	
+If there is no existing connection, then it returns silently.
+*/
+EXPORT_C void RDmDomainManager::Close()
+	{
+	iSession.Close();
+	}
+
+
+
+
+/**
+Requests a system-wide power state transition.
+
+The domain hierarchy is traversed in the default direction
+		
+@param aState   The target power state.
+@param aStatus  The request status object for this asynchronous request.
+
+@see RDmDomainManager::CancelTransition()
+*/
+EXPORT_C void RDmDomainManager::RequestSystemTransition(TPowerState aState, TRequestStatus& aStatus)
+	{
+	if (aState == EPwActive)
+		{
+		TRequestStatus* status = &aStatus;
+		User::RequestComplete(status, KErrArgument);
+		return;
+		}
+	RequestSystemTransition((TDmDomainState) aState, ETraverseDefault, aStatus);
+	}
+
+
+
+
+/**
+Requests a system-wide power shutdown.
+
+This is a request to change the system's power state to EPwOff.
+This call does not return; the system can only return by rebooting.
+*/
+EXPORT_C void RDmDomainManager::SystemShutdown()
+	{
+	TRequestStatus status;
+	RequestSystemTransition((TDmDomainState) EPwOff, ETraverseDefault, status);
+	User::WaitForRequest(status);
+	__DM_ASSERT(0);
+	}
+
+
+
+
+/**
+Requests a domain state transition.
+
+The domain hierarchy is traversed in the default direction.
+
+@param aDomainId The Id of the domain for which the state transition
+                 is being requested.
+@param aState    The target state.
+@param aStatus   The request status object for this asynchronous request.
+
+@see RDmDomainManager::CancelTransition()
+*/
+EXPORT_C void RDmDomainManager::RequestDomainTransition(
+	TDmDomainId aDomainId, 
+	TPowerState aState, 
+	TRequestStatus& aStatus)
+	{
+	RequestDomainTransition(aDomainId,(TDmDomainState)  aState, ETraverseDefault, aStatus);
+	}
+
+
+
+
+/**
+Cancels a state transition, whether initiated by a call
+to RequestSystemTransition() or RequestDomainTransition().
+
+An outstanding state transition request completes with KErrCancel.
+*/
+EXPORT_C void RDmDomainManager::CancelTransition()
+	{
+	iSession.CancelTransition();
+	}
+
+
+
+
+/**
+Requests a system-wide state transition.
+
+The domain hierarchy is traversed in the specified direction.
+		
+@param aState   The target state.
+@param aDirection The direction in which to traverse the hierarchy
+@param aStatus  The request status object for this asynchronous request.
+
+@see RDmDomainManager::CancelTransition()
+
+@panic domainCli.cpp; assertion failed VARNUM if the numerical value of aDirection
+       is greater than the value of ETraverseMax. NOTE: VARNUM is the line number
+       in the source code and may change if the implementation changes.
+*/
+EXPORT_C void RDmDomainManager::RequestSystemTransition(
+	TDmDomainState aState, 
+	TDmTraverseDirection aDirection, 
+	TRequestStatus& aStatus)
+	{
+	__DM_ASSERT(aDirection <= ETraverseMax);
+	iSession.RequestSystemTransition(aState, aDirection, aStatus);
+	}
+
+
+
+
+/**
+Requests a domain state transition.
+
+The domain hierarchy is traversed in the specified direction
+
+@param aDomainId The Id of the domain for which the state transition
+                 is being requested.
+@param aState    The target state.
+@param aDirection The direction in which to traverse the hierarchy.
+@param aStatus   The request status object for this asynchronous request.
+
+@see RDmDomainManager::CancelTransition()
+
+@panic domainCli.cpp; assertion failed VARNUM if the numerical value of aDirection
+       is greater than the value of ETraverseMax. NOTE: VARNUM is the line number
+       in the source code and may change if the implementation changes.
+*/
+EXPORT_C void RDmDomainManager::RequestDomainTransition(
+	TDmDomainId aDomainId, 
+	TDmDomainState aState, 
+	TDmTraverseDirection aDirection,
+	TRequestStatus& aStatus)
+	{
+	__DM_ASSERT(aDirection <= ETraverseMax);
+	iSession.RequestDomainTransition(aDomainId, aState, aDirection, aStatus);
+	}
+
+
+
+
+/**
+Adds a domain hierarchy to the domain manager.
+
+@param aHierarchyId The Id of the domain hierarchy to be added.
+
+@return	KErrNone if successful; otherwise one of the other system-wide
+        or domain manager specific error codes.
+*/
+EXPORT_C TInt RDmDomainManager::AddDomainHierarchy(TDmHierarchyId aHierarchyId)
+	{
+	RDmManagerSession	session;
+	TInt r = session.Connect();
+	if (r != KErrNone)
+		return r;
+	r = session.AddDomainHierarchy(aHierarchyId);
+	session.Close();
+	return r;
+	}
+
+
+
+/**
+Requests a list of transition failures since the last transition request.
+
+@param aTransitionFailures A client-supplied array of TTransitionFailure objects which 
+		on exit will contain the failures that have occurred since the last transition 
+		request. 
+@pre	The session must be connected.
+
+@return KErrNone, if successful; otherwise one of the other system-wide
+        or domain manager specific error codes.
+*/
+EXPORT_C TInt RDmDomainManager::GetTransitionFailures(RArray<const TTransitionFailure>& aTransitionFailures)
+	{
+	return iSession.GetTransitionFailures(aTransitionFailures);
+	}
+
+
+
+/**
+Gets the number of transition failures since the last transition request.
+
+@return	The number of failures, if successful; otherwise one of the other system-wide
+        or domain manager specific error codes.
+*/
+EXPORT_C TInt RDmDomainManager::GetTransitionFailureCount()
+	{
+	return iSession.GetTransitionFailureCount();
+	}
+
+
+
+// CDmDomain
+
+/**
+Constructor.
+
+Adds this active object to the active scheduler. The priority of the active object
+is the standard value, i.e. CActive::EPriorityStandard.
+
+@param aHierarchyId The Id of the domain hierarchy to connect to.
+@param aDomainId	The Id of the domain to connect to.
+
+@see CActive
+@see CActive::TPriority
+*/
+EXPORT_C CDmDomain::CDmDomain(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId) : 
+	CActive(CActive::EPriorityStandard), 
+	iHierarchyId(aHierarchyId), 
+	iDomainId(aDomainId)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+
+
+
+/**
+Destructor.
+
+Closes the session to the domain manager.
+*/
+EXPORT_C CDmDomain::~CDmDomain()
+	{
+	Cancel();
+	iDomain.Close();
+	}
+
+
+
+
+/**
+Second-phase constructor.
+
+The function attempts to connect to the domain specified in the constructor.
+
+@leave One of the system-wide error codes
+*/
+EXPORT_C void CDmDomain::ConstructL()
+	{
+	User::LeaveIfError(iDomain.Connect(iHierarchyId, iDomainId));
+	}
+
+
+
+
+/**
+Requests notification when the domain's state changes.
+
+RunL() will be called when this happens.
+*/
+EXPORT_C void CDmDomain::RequestTransitionNotification()
+	{
+	__DM_ASSERT(!IsActive());
+	iDomain.RequestTransitionNotification(iStatus);
+	SetActive();
+	}
+
+
+
+
+/**
+Cancels an outstanding notification request.
+
+Any outstanding notification request completes with KErrCancel.
+*/
+EXPORT_C void CDmDomain::DoCancel()
+	{
+	iDomain.CancelTransitionNotification();
+	}
+
+
+
+
+/**
+Acknowledges the last state change.
+	
+An application must acknowledge that it has performed all actions required
+by the last known state of the domain.
+
+@param aError	The error to return to the domain manager. The client should
+				set this to KErrNone if it successfully transitioned to the 
+				new state or to one of the system-wide error codes.
+*/
+EXPORT_C void CDmDomain::AcknowledgeLastState(TInt aError)
+	{
+	iDomain.AcknowledgeLastState(aError);
+	}
+
+
+
+
+/**
+Gets the domain's state.
+	
+An application normally calls this function after a notification request
+has completed. It then performs any application-dependent action demanded by
+the state, and then acknowledges the state transition.
+
+@return The connected domain's state.
+*/
+EXPORT_C TDmDomainState CDmDomain::GetState()
+	{
+	return iDomain.GetState();
+	}
+
+// CDmDomainManager
+
+/**
+Constructor.
+
+Adds this active object to the active scheduler.
+
+@param aHierarchyId The Id of the domain hierarchy to connect to
+*/
+EXPORT_C CDmDomainManager::CDmDomainManager(TDmHierarchyId aHierarchyId) : 
+	CActive(CActive::EPriorityStandard), 
+	iHierarchyId(aHierarchyId)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+
+
+
+/**
+Destructor.
+
+Closes the session to the domain manager.
+*/
+EXPORT_C CDmDomainManager::~CDmDomainManager()
+	{
+	Cancel();
+	iManager.Close();
+	}
+
+
+
+
+/**
+The second-phase constructor.
+
+This function attempts to connect to the hierarchy 
+specified in the constructor.
+
+@leave One of the system-wide error codes.
+*/
+EXPORT_C void CDmDomainManager::ConstructL()
+	{
+	User::LeaveIfError(iManager.Connect(iHierarchyId));
+	}
+
+
+
+
+/**
+Requests a system-wide state transition.
+
+The domain hierarchy is traversed in the specified direction
+		
+@param aState   The target state.
+@param aDirection The direction in which to traverse the hierarchy.
+*/
+EXPORT_C void CDmDomainManager::RequestSystemTransition(TDmDomainState aState, TDmTraverseDirection aDirection)
+	{
+	__DM_ASSERT(!IsActive());
+	iStatus = KRequestPending;
+	iManager.RequestSystemTransition(aState, aDirection, iStatus);
+	SetActive();
+	}
+
+
+
+
+/**
+Requests a domain state transition.
+
+The domain hierarchy is traversed in the specified direction.
+
+@param aDomain The Id of the domain for which the state transition
+                 is being requested.
+@param aState    The target state.
+@param aDirection The direction in which to traverse the hierarchy.
+*/
+EXPORT_C void CDmDomainManager::RequestDomainTransition(TDmDomainId aDomain, TDmDomainState aState, TDmTraverseDirection aDirection)
+	{
+	__DM_ASSERT(!IsActive());
+	iStatus = KRequestPending;
+	iManager.RequestDomainTransition(aDomain, aState, aDirection, iStatus);
+	SetActive();
+	}
+
+
+
+
+/**
+Adds a domain hierarchy to the domain manager.
+
+@param aHierarchyId The Id of the domain hierarchy to add
+
+@return	KErrNone if successful; otherwise one of the other system-wide
+        or domain manager specific error codes.
+*/
+EXPORT_C TInt CDmDomainManager::AddDomainHierarchy(TDmHierarchyId aHierarchyId)
+	{
+	RDmManagerSession	session;
+	TInt r = session.Connect();
+	if (r != KErrNone)
+		return r;
+	r = session.AddDomainHierarchy(aHierarchyId);
+	session.Close();
+	return r;
+
+	}
+
+
+
+
+/**
+Cancels a pending event.
+*/
+EXPORT_C void CDmDomainManager::DoCancel()
+	{
+	iManager.CancelTransition();
+	}
+
+
+
+
+/**
+Requests a list of transition failures since the last transition request.
+
+@param aTransitionFailures A client-supplied array of TTransitionFailure objects which 
+		on exit will contain the failures that have occurred since the last transition 
+		request. 
+@pre	The session must be connected.
+
+@return KErrNone, if successful; otherwise one of the other system-wide
+        or domain manager specific error codes.
+*/
+EXPORT_C TInt CDmDomainManager::GetTransitionFailures(RArray<const TTransitionFailure>& aTransitionFailures)
+	{
+	return iManager.GetTransitionFailures(aTransitionFailures);
+	}
+
+
+
+
+/**
+Gets the number of transition failures since the last transition request.
+
+@return	The number of failures if successful, otherwise one of the other system-wide
+        or domain manager specific error codes.
+*/
+EXPORT_C TInt CDmDomainManager::GetTransitionFailureCount()
+	{
+	return iManager.GetTransitionFailureCount();
+	}
+
+
+
+
+CHierarchyObserver::CHierarchyObserver(MHierarchyObserver& aHierarchyObserver, TDmHierarchyId aHierarchyId):
+	CActive(CActive::EPriorityStandard), 
+	iHierarchyId(aHierarchyId),
+	iObserver(aHierarchyObserver)
+	{
+	iTransitionEvents.Reset();
+	CActiveScheduler::Add(this);
+	}
+
+
+
+
+/**
+Constructs a new observer on the domain hierarchy.
+
+Note that only one observer per domain hierarchy is allowed.
+
+@param	aHierarchyObserver	The implementation of the interface to the domain manager.
+@param	aHierarchyId		The Id of the domain hierarchy.
+
+@return The newly created CHierarchyObserver object.
+*/
+EXPORT_C CHierarchyObserver* CHierarchyObserver::NewL(MHierarchyObserver& aHierarchyObserver,TDmHierarchyId aHierarchyId)
+	{
+	CHierarchyObserver* observer=new(ELeave)CHierarchyObserver(aHierarchyObserver,aHierarchyId);
+
+	CleanupStack::PushL(observer);
+	User::LeaveIfError(observer->iSession.ConnectObserver(aHierarchyId));
+	CleanupStack::Pop();
+	
+	return(observer);
+	}
+
+
+
+
+/**
+Destructor.
+
+Frees resources prior to destruction of the object.
+*/
+EXPORT_C CHierarchyObserver::~CHierarchyObserver()
+	{
+	Cancel();
+	iSession.Close();
+	iTransitionEvents.Reset();
+	}
+
+void CHierarchyObserver::DoCancel()
+	{
+	iObserverStarted=EFalse;
+	iSession.CancelObserver();
+	}
+
+void CHierarchyObserver::RunL()
+//
+// Process the reply to client's request for domain transition/failure
+//
+	{
+
+	TInt ret= iSession.GetEvents(iTransitionEvents);
+	
+	User::LeaveIfError(ret);
+	
+	TInt count = iTransitionEvents.Count();
+
+	for(TInt i=0;i<count;i++)
+		{
+		if(iTransitionEvents[i].iError==KErrNone)
+			iObserver.TransProgEvent(iTransitionEvents[i].iDomainId,iTransitionEvents[i].iState);
+		else if(iTransitionEvents[i].iError==KDmErrOutstanding)
+			iObserver.TransReqEvent(iTransitionEvents[i].iDomainId,iTransitionEvents[i].iState);
+		else
+			iObserver.TransFailEvent(iTransitionEvents[i].iDomainId,iTransitionEvents[i].iState,iTransitionEvents[i].iError);
+		}
+
+	GetNotification();
+	}
+
+
+
+
+/**
+Starts the observer. 
+
+@param	aDomainId		The Id of the domain to which the obsever is attached.
+@param	aNotifyType		The type of notifications of interest to the observer.
+
+@return KErrNone on successful start, otherwise one of the other system wide error codes.
+*/
+EXPORT_C TInt CHierarchyObserver::StartObserver(TDmDomainId aDomainId, TDmNotifyType aNotifyType)
+	{
+	iNotifyType=aNotifyType;
+	iDomainId=aDomainId;
+	
+	TInt ret=iSession.StartObserver(iDomainId, iNotifyType);
+	if(ret!=KErrNone)
+		return ret;
+	iObserverStarted=ETrue;
+	GetNotification();
+	return KErrNone;
+	}
+
+
+
+
+/**
+Stops the observer. 
+
+@return KErrNone if successful; KDmErrBadSequence, if the observer 
+        has not already started.
+*/
+EXPORT_C TInt CHierarchyObserver::StopObserver()
+	{
+	if(!iObserverStarted)
+		return(KDmErrBadSequence);
+	Cancel();
+	return(KErrNone);
+	}
+
+void CHierarchyObserver::GetNotification()
+	{
+	iSession.GetNotification(iStatus);
+	SetActive();
+	}
+
+/**
+Gets the number of domains that are being observed.
+
+This value is the number of children of the domain member to which the observer
+is attached, including itself. 
+
+@return The number of observed domain members.
+        One of the other system wide error codes may be returned on failure;
+        specifically KErrNotFound if the observer is not already started.
+*/
+EXPORT_C TInt CHierarchyObserver::ObserverDomainCount()
+	{
+	if(!iObserverStarted)
+		return KErrNotFound;
+	return(iSession.ObserverDomainCount());	
+	}