diff -r 000000000000 -r 96e5fb8b040d userlibandfileserver/domainmgr/src/domaincli.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/userlibandfileserver/domainmgr/src/domaincli.cpp Thu Dec 17 09:24:54 2009 +0200 @@ -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 +#include +#include + +#include +#include +#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& 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(failures), failureCount * sizeof(TTransitionFailure)); + + TIpcArgs a(&dataPtr); + err = RSessionBase::SendReceive(EDmGetTransitionFailures, a); + + if (err == KErrNone) + { + for (TInt i=0; i& 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(trans), count * sizeof(TTransInfo)); + + TIpcArgs a(&dataPtr); + TInt ret=RSessionBase::SendReceive(EDmObserverGetEvent, a); + + if(ret==KErrNone) + { + for (TInt i=0; i& 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& 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