--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/domainmgr/src/domainsrv.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1618 @@
+// 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\domainsrv.cpp
+//
+//
+
+#include <e32debug.h>
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32property.h>
+#include <f32file.h>
+
+#include <domainpolicy.h>
+#include "domainsrv.h"
+
+#define __DS_PANIC(aError) User::Panic(_L("domainSrv.cpp"), (-(aError)) | (__LINE__ << 16))
+#define __DS_ASSERT(aCond) ((aCond) || (User::Panic(_L("domainSrv.cpp; assertion failed"), __LINE__), 1))
+
+//#define __DS_DEBUG
+
+#ifdef __DS_DEBUG
+#define __DS_TRACE(s) RDebug::Print s
+#else
+#define __DS_TRACE(s)
+#endif
+
+static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+static _LIT_SECURITY_POLICY_C1(KPowerMgmtPolicy,ECapabilityPowerMgmt);
+
+// forward refs
+class CSvrDomain;
+class CDmHierarchy;
+class CPowerUpHandler;
+class CDmHierarchyPower;
+class CDmSvrManager;
+class CDmDomainServer;
+class CDmDomainSession;
+class CDmManagerServer;
+class CDmManagerSession;
+
+
+
+// CSvrDomain
+class CSvrDomain : public CTimer
+ {
+public:
+ static CSvrDomain* New(CDmHierarchy& aHierarchy, const TDmDomainSpec&);
+
+ // from CTimer
+ void RunL();
+
+ void Attach(CDmDomainSession*);
+ void Detach(CDmDomainSession*);
+ void AddChild(CSvrDomain*);
+ CSvrDomain* Lookup(TDmDomainId);
+ TBool CheckPropValue(TInt aPropValue);
+ void RequestDomainTransition();
+ void CompleteMemberTransition(TInt aError);
+ void CancelTransition();
+ void SetObserver(TBool aSet);
+ TDmDomainState State();
+
+private:
+ CSvrDomain(CDmHierarchy& aHierarchy, const TDmDomainSpec*);
+ void Construct(const TDmDomainSpec* spec);
+
+ void RequestMembersTransition();
+ void RequestChildrenTransition();
+ void MembersTransitionDone();
+ void ChildrenTransitionDone();
+ void CompleteDomainTransition();
+
+private:
+ CDmHierarchy& iHierarchy;
+ CSvrDomain* iParent;
+ CSvrDomain* iPeer;
+ CSvrDomain* iChild;
+ RProperty iProperty;
+ CDmDomainSession* iSessions;
+ TUint16 iChildrenCount;
+ TUint16 iTransCount;
+ TTimeIntervalMicroSeconds32 iTransTimeBudget;
+
+public:
+ const TSecurityPolicy iJoinPolicy;
+ TBool iIsObserved;
+ TDmDomainId iId;
+ };
+
+
+// CDmHierarchy
+class CDmHierarchy : public CBase
+ {
+public:
+ static CDmHierarchy* New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
+
+ CSvrDomain* LookupDomain(TDmDomainId aDomainId);
+ TInt RequestDomainTransition(TDmDomainId, TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
+ void RequestTransition(const RMessage2* aMessage);
+ TInt StartObserver( TDmDomainId aDomainId,TDmNotifyType aNotifyType);
+ void SetNotifyMessage(const RMessage2* aMessage);
+ void CompleteNotification(TInt aError);
+ TBool OutstandingNotification();
+ void StopObserver();
+ virtual TInt RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
+ virtual void CompleteTransition(TInt aError);
+ virtual void NotifyCompletion(TInt aReason);
+
+protected:
+ CDmHierarchy(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
+ void SetState(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection = ETraverseDefault);
+
+private:
+ RMessagePtr2 iTransMessagePtr;
+ RMessagePtr2 iObsvrMessagePtr;
+ CSvrDomain* iObservedDomain;
+ TBool iOutstandingNotification;
+public:
+ TDmHierarchyId iHierarchyId;
+ CSvrDomain* iRootDomain;
+ CSvrDomain* iTransDomain;
+ TInt iTransPropValue;
+ TDmDomainState iTransState;
+ TDmTraverseDirection iTraverseDirection;
+ TUint8 iTransId;
+ CDmManagerSession* iControllerSession; // only one controller per hierarchy
+ TDmHierarchyPolicy iPolicy;
+ RArray<TTransitionFailure> iTransitionFailures;
+
+ // observer stuff
+ TBool iObserverStarted;
+ TDmNotifyType iNotifyType;
+ RArray<TTransInfo> iTransitions;
+ CDmManagerSession* iObserverSession; // only one observer per hierarchy
+ TInt iObservedChildren;
+ };
+
+
+// CPowerUpHandler
+// Active object used to receive power-up notifications
+// from the Kernel-level power manager
+class CPowerUpHandler : public CActive
+ {
+public:
+ static CPowerUpHandler* New(CDmHierarchyPower& aHierarchyPower);
+
+ // from CActive
+ void RunL();
+ void DoCancel();
+
+ void RequestWakeupEventNotification();
+ void Cancel();
+
+private:
+ CPowerUpHandler(CDmHierarchyPower& aHierarchyPower);
+ void Construct();
+
+private:
+ CDmHierarchyPower& iHierarchyPower;
+ };
+
+
+// CDmHierarchyPower
+// CDmHierarchy-derived class
+// Interfaces to the Kernel-level power manager
+class CDmHierarchyPower : public CDmHierarchy
+ {
+public:
+ static CDmHierarchyPower* New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
+
+ // from CDmHierarchy
+ virtual TInt RequestSystemTransition(TDmDomainState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
+ virtual void CompleteTransition(TInt aError);
+ virtual void NotifyCompletion(TInt aReason);
+
+ void PowerUp(); // called from CPowerUpHandler
+
+private:
+ CDmHierarchyPower(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
+ void Construct();
+
+private:
+ enum
+ {
+ EPoweringDown = 0x01,
+ };
+ TUint8 iTransStatus;
+ CPowerUpHandler* iPowerUpHandler;
+ };
+
+
+// CDmSvrManager
+class CDmSvrManager : public CBase
+ {
+public:
+ static CDmSvrManager* New();
+
+ TInt BuildDomainTree(TDmHierarchyId aHierarchyId, CDmHierarchy*& aHierarchy);
+ CDmHierarchy* LookupHierarchy(TDmHierarchyId aHierarchyId);
+ TInt LookupDomain(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, CSvrDomain*& aDomain);
+
+private:
+ CDmSvrManager();
+ void Construct();
+
+private:
+ RPointerArray<CDmHierarchy> iDomainHierarchies;
+ };
+
+// CDmDomainServer
+class CDmDomainServer : public CServer2
+ {
+public:
+ // from CServer2
+ CSession2* NewSessionL(const TVersion& aVer) const;
+ CSession2* NewSessionL(const TVersion& aVer, const RMessage2& aMessage) const;
+
+ CDmDomainServer(CDmSvrManager* aManager) : CServer2(CActive::EPriorityStandard), iManager(aManager)
+ {}
+
+public:
+ CDmSvrManager* iManager;
+ };
+
+// CDmDomainSession
+class CDmDomainSession : public CSession2
+ {
+public:
+ // from CBase
+ ~CDmDomainSession();
+
+ // from CSession2
+ void ServiceL(const RMessage2& aMessage);
+
+private:
+ CSvrDomain* iDomain;
+
+public:
+ CDmDomainSession* iNext;
+ TUint8 iPending;
+ TBool iNotificationEnabled;
+ };
+
+class CDmManagerServer : public CServer2
+ {
+public:
+ // from CServer2
+ CSession2* NewSessionL(const TVersion& aVer) const;
+ CSession2* NewSessionL(const TVersion& aVer, const RMessage2&) const;
+
+ CDmManagerServer(CDmSvrManager* aManager) : CServer2(CActive::EPriorityStandard), iManager(aManager)
+ {}
+ CDmSvrManager* iManager;
+ };
+
+class CDmManagerSession : public CSession2
+ {
+public:
+ // from CBase
+ ~CDmManagerSession();
+
+ // from CSession2
+ void ServiceL(const RMessage2& aMessage);
+
+ CDmManagerSession();
+private:
+ CDmHierarchy* iHierarchy; // not owned
+ };
+
+
+
+
+//*********************************************************
+// TTransitionFailure
+//*********************************************************
+/**
+@internalTechnology
+
+Constructor for transition failure info.
+
+@param aDomainID Id of the domain of interest
+@param aError error code of transition
+*/
+TTransitionFailure::TTransitionFailure(TDmDomainId aDomainId, TInt aError) :
+ iDomainId(aDomainId), iError(aError)
+ {
+ }
+
+//*********************************************************
+// TTransInfo
+//*********************************************************
+
+/**
+@internalTechnology
+
+Constructor for transition failure info.
+
+@param aDomainID Id of the domain of interest
+@param aState State of the domain after transition
+@param aError error code of transition
+*/
+TTransInfo::TTransInfo(TDmDomainId aDomainId, TDmDomainState aState, TInt aError) :
+ iDomainId(aDomainId), iState(aState), iError(aError)
+ {
+ }
+
+//*********************************************************
+// CSvrDomain
+//*********************************************************
+
+
+CSvrDomain::CSvrDomain(CDmHierarchy& aHierarchy, const TDmDomainSpec* spec)
+ : CTimer(CActive::EPriorityStandard),
+ iHierarchy(aHierarchy),
+ iTransTimeBudget(spec->iTimeBudgetUs),
+ iJoinPolicy(spec->iJoinPolicy),
+ iId(spec->iId)
+ {}
+
+CSvrDomain* CSvrDomain::New(CDmHierarchy& aHierarchy, const TDmDomainSpec& aSpec)
+ {
+
+ CSvrDomain* self = new CSvrDomain(aHierarchy, &aSpec);
+
+ if (!self)
+ __DS_PANIC(KErrNoMemory);
+ self->Construct(&aSpec);
+ return self;
+ }
+
+void CSvrDomain::Construct(const TDmDomainSpec* spec)
+ {
+ TInt r = iProperty.Define(
+ KUidDmPropertyCategory,
+ DmStatePropertyKey(iHierarchy.iHierarchyId, iId),
+ RProperty::EInt,
+ KAllowAllPolicy,KPowerMgmtPolicy);
+
+ if (r != KErrNone)
+ __DS_PANIC(r);
+
+ r = iProperty.Attach(KUidDmPropertyCategory, DmStatePropertyKey(
+ iHierarchy.iHierarchyId,
+ iId));
+
+ if (r != KErrNone)
+ __DS_PANIC(r);
+
+ r = iProperty.Set(DmStatePropertyValue(0, spec->iInitState));
+ if (r != KErrNone)
+ __DS_PANIC(r);
+
+ TRAP(r, CTimer::ConstructL());
+ if (r != KErrNone)
+ __DS_PANIC(r);
+ CActiveScheduler::Add(this);
+ }
+
+void CSvrDomain::Attach(CDmDomainSession* aSession)
+ {
+ aSession->iNext = iSessions;
+ iSessions = aSession;
+ }
+
+void CSvrDomain::Detach(CDmDomainSession* aSession)
+ {
+ CDmDomainSession** prevp = &iSessions;
+ while (*prevp != aSession)
+ {
+ prevp = &((*prevp)->iNext);
+ __DS_ASSERT(*prevp);
+ }
+ *(prevp) = aSession->iNext;
+ }
+
+void CSvrDomain::AddChild(CSvrDomain* aChild)
+ {
+ ++iChildrenCount;
+ aChild->iParent = this;
+ if(iIsObserved)
+ aChild->iIsObserved=ETrue;
+ // Insert the child in the list of its peers
+ aChild->iPeer = iChild;
+ iChild = aChild;
+ }
+
+CSvrDomain* CSvrDomain::Lookup(TDmDomainId aDomainId)
+ {
+ if (iId == aDomainId)
+ return this;
+
+ CSvrDomain* child = iChild;
+ while (child)
+ {
+ CSvrDomain* domain = child->Lookup(aDomainId);
+ if (domain)
+ return domain;
+ child = child->iPeer;
+ }
+ return NULL;
+ }
+
+TBool CSvrDomain::CheckPropValue(TInt aPropValue)
+ { return iHierarchy.iTransPropValue == aPropValue; }
+
+void CSvrDomain::RequestMembersTransition()
+ {
+ __DS_TRACE((_L("CSvrDomain::RequestMembersTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+ __DS_ASSERT(iTransCount == 0);
+
+ for(CDmDomainSession* s = iSessions; s; s = s->iNext)
+ if (s->iNotificationEnabled)
+ {
+ ++iTransCount;
+ s->iPending = ETrue;
+ // notifications will be disabled until the client makes another
+ // call to RDmDomain::RequestTransitionNotification()
+ s->iNotificationEnabled = EFalse;
+ }
+
+ if(iIsObserved)
+ {
+ if((iHierarchy.iNotifyType&EDmNotifyTransRequest)==EDmNotifyTransRequest)
+ {
+ TTransInfo transInfo(iId,State(),KDmErrOutstanding);
+ iHierarchy.iTransitions.Append(transInfo);
+ if(iHierarchy.OutstandingNotification())
+ iHierarchy.CompleteNotification(KErrNone);
+ }
+ }
+ if (iTransCount > 0)
+ CTimer::After(iTransTimeBudget);
+ iProperty.Set(iHierarchy.iTransPropValue);
+ if (iTransCount == 0)
+ MembersTransitionDone();
+ }
+
+
+void CSvrDomain::RequestChildrenTransition()
+ {
+ __DS_TRACE((_L("CSvrDomain::RequestChildrenTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+ __DS_ASSERT(iTransCount == 0);
+ iTransCount = iChildrenCount;
+ if (iTransCount)
+ {
+ CSvrDomain* child = iChild;
+ __DS_ASSERT(child);
+ do {
+ child->RequestDomainTransition();
+ child = child->iPeer;
+ }
+ while(child);
+ }
+ else
+ ChildrenTransitionDone();
+ }
+
+void CSvrDomain::RequestDomainTransition()
+ {
+ __DS_TRACE((_L("CSvrDomain::RequestDomainTransition() hierarchy=%d, domain=0x%x state=0x%x prop=0x%x"),
+ iHierarchy.iHierarchyId, iId, iHierarchy.iTransState, iHierarchy.iTransPropValue));
+ __DS_ASSERT(iTransCount == 0);
+ if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
+ RequestChildrenTransition();
+ else
+ RequestMembersTransition();
+ }
+
+void CSvrDomain::MembersTransitionDone()
+ {
+ __DS_TRACE((_L("CSvrDomain::MembersTransitionDone() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+ __DS_ASSERT(iTransCount == 0);
+ if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
+ CompleteDomainTransition();
+ else
+ RequestChildrenTransition();
+ }
+
+void CSvrDomain::ChildrenTransitionDone()
+ {
+ __DS_TRACE((_L("CSvrDomain::ChildrenTransitionDone() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+ __DS_ASSERT(iTransCount == 0);
+ if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
+ RequestMembersTransition();
+ else
+ CompleteDomainTransition();
+ }
+
+void CSvrDomain::CompleteMemberTransition(TInt aError)
+ {
+ __DS_TRACE((_L("CSvrDomain::CompleteMemberTransition() hierarchy=%d, domain=0x%x, aError = %d"), iHierarchy.iHierarchyId, iId, aError));
+ __DS_ASSERT(iTransCount);
+
+ if (aError)
+ {
+ // Add a transition failure to the array
+ TTransitionFailure failure(iId, aError);
+ iHierarchy.iTransitionFailures.Append(failure);
+
+ if(iIsObserved)
+ {
+ if((iHierarchy.iNotifyType&EDmNotifyFail)==EDmNotifyFail)
+ {
+ TTransInfo transInfo(iId,State(),aError);
+ iHierarchy.iTransitions.Append(transInfo);
+ if(iHierarchy.OutstandingNotification())
+ iHierarchy.CompleteNotification(KErrNone);
+ }
+ }
+ // examine the failure policy to work out what to do
+ if (iHierarchy.iPolicy.iFailurePolicy == ETransitionFailureStop)
+ {
+ iHierarchy.CompleteTransition(aError);
+ return;
+ }
+ }
+ else if(iIsObserved)
+ {
+ if((iHierarchy.iNotifyType&EDmNotifyPass) == EDmNotifyPass)
+ {
+ TTransInfo transInfo(iId,State(),aError);
+ iHierarchy.iTransitions.Append(transInfo);
+ if(iHierarchy.OutstandingNotification())
+ iHierarchy.CompleteNotification(KErrNone);
+ }
+ }
+
+ if (--iTransCount == 0)
+ {
+ CTimer::Cancel();
+ MembersTransitionDone();
+ }
+ }
+
+void CSvrDomain::RunL()
+ { // Timer expired
+ __DS_TRACE((_L("CSvrDomain::RunL() Members transition timeout hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+
+ // Add a transition failure to the array
+ TTransitionFailure failure(iId,KErrTimedOut);
+ iHierarchy.iTransitionFailures.Append(failure);
+
+
+ // examine the failure policy to work out what to do
+ if (iHierarchy.iPolicy.iFailurePolicy == ETransitionFailureStop)
+ {
+ iHierarchy.CompleteTransition(KErrTimedOut);
+ return;
+ }
+
+ if (iTransCount)
+ { // Complete transition of all members
+ CDmDomainSession* session = iSessions;
+ while (session)
+ {
+ session->iPending = EFalse;
+ session = session->iNext;
+ }
+ iTransCount = 0;
+ MembersTransitionDone();
+ }
+ }
+
+
+void CSvrDomain::CompleteDomainTransition()
+ {
+ __DS_TRACE((_L("CSvrDomain::CompleteDomainTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+ __DS_ASSERT(iTransCount == 0);
+ if (iHierarchy.iTransDomain == this)
+ {
+ const TInt err = (iHierarchy.iTransitionFailures.Count() > 0)?
+ iHierarchy.iTransitionFailures[0].iError : KErrNone;
+ iHierarchy.CompleteTransition(err);
+ }
+ else
+ {
+ __DS_ASSERT(iParent);
+ __DS_ASSERT(iParent->iTransCount);
+ if (--iParent->iTransCount == 0)
+ iParent->ChildrenTransitionDone();
+ }
+ }
+
+void CSvrDomain::CancelTransition()
+ {
+ __DS_TRACE((_L("CSvrDomain::CancelTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
+ CTimer::Cancel();
+ CSvrDomain* child = iChild;
+ while (child)
+ {
+ child->CancelTransition();
+ child = child->iPeer;
+ }
+ CDmDomainSession* session = iSessions;
+ while (session)
+ {
+ session->iPending = EFalse;
+ session = session->iNext;
+ }
+ iTransCount = 0;
+ }
+
+void CSvrDomain::SetObserver(TBool aSet)
+ {
+ iIsObserved=aSet;
+ if(aSet)
+ {
+ iHierarchy.iObservedChildren++;
+ }
+ else
+ {
+ // this should be zero at the end
+ iHierarchy.iObservedChildren--;
+ }
+ if(iChildrenCount!=0)
+ {
+ CSvrDomain* domain=iChild;
+ do {
+ domain->SetObserver(aSet);
+ domain = domain->iPeer;
+ }
+ while(domain);
+ }
+ }
+
+TDmDomainState CSvrDomain::State()
+ {
+ TInt value;
+ iProperty.Get(value);
+ return DmStateFromPropertyValue(value);
+ }
+
+//*********************************************************
+// CDmHierarchy
+//*********************************************************
+
+CDmHierarchy* CDmHierarchy::New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy)
+ {
+ CDmHierarchy* self;
+
+ if (aHierarchyId == KDmHierarchyIdPower)
+ self = CDmHierarchyPower::New(aHierarchyId, aPolicy);
+ else
+ self = new CDmHierarchy(aHierarchyId, aPolicy);
+
+ if (!self)
+ __DS_PANIC(KErrNoMemory);
+
+ return self;
+ }
+
+CDmHierarchy::CDmHierarchy(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy) :
+ iOutstandingNotification(EFalse),
+ iHierarchyId(aHierarchyId),
+ iPolicy(aPolicy)
+ {
+ iTransitionFailures.Reset();
+ }
+
+CSvrDomain* CDmHierarchy::LookupDomain(TDmDomainId aDomainId)
+ {
+ return iRootDomain ? iRootDomain->Lookup(aDomainId) : NULL;
+ }
+
+void CDmHierarchy::RequestTransition(const RMessage2* aMessage)
+ {
+ // reset the array of transition failures
+ iTransitionFailures.Reset();
+
+ if (aMessage)
+ iTransMessagePtr = *aMessage;
+ iTransPropValue = DmStatePropertyValue(++iTransId, iTransState);
+
+ iTransDomain->RequestDomainTransition();
+ }
+
+
+TInt CDmHierarchy::StartObserver(TDmDomainId aDomainId,TDmNotifyType aNotifyType)
+ {
+ iObservedDomain = LookupDomain(aDomainId);
+
+ if(iObservedDomain==NULL)
+ return KDmErrBadDomainId;
+
+
+ iObservedDomain->SetObserver(ETrue);
+ iNotifyType=aNotifyType;
+ iObserverStarted=ETrue;
+ return KErrNone;
+ }
+
+void CDmHierarchy::SetNotifyMessage(const RMessage2* aMessage)
+ {
+ if (aMessage)
+ {
+ iObsvrMessagePtr = *aMessage;
+ iOutstandingNotification=ETrue;
+ }
+ }
+
+TBool CDmHierarchy::OutstandingNotification()
+ {
+ return iOutstandingNotification;
+ }
+
+void CDmHierarchy::CompleteNotification(TInt aError)
+ {
+ if(iOutstandingNotification)
+ {
+ iObsvrMessagePtr.Complete(aError);
+ iOutstandingNotification=EFalse;
+ }
+ }
+
+void CDmHierarchy::StopObserver()
+ {
+
+ iObservedDomain->SetObserver(EFalse);
+ iTransitions.Reset();
+ iObserverStarted=EFalse;
+ }
+void CDmHierarchy::NotifyCompletion(TInt aReason)
+ {
+ iTransDomain = NULL;
+ iTransPropValue = 0;
+ iTransMessagePtr.Complete(aReason);
+ }
+
+TInt CDmHierarchy::RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage)
+ {
+ iTransDomain = iRootDomain;
+ SetState(aTargetState, aTraverseDirection);
+ RequestTransition(aMessage);
+ return KErrNone;
+ }
+
+
+TInt CDmHierarchy::RequestDomainTransition(
+ TDmDomainId aDomainId,
+ TDmDomainState aTargetState,
+ TDmTraverseDirection aTraverseDirection,
+ const RMessage2* aMessage)
+ {
+ __DS_TRACE((_L("CDmHierarchy::RequestTransition() hierarchy=%d domain=0x%x state=0x%x"), iHierarchyId, aDomainId, aTargetState));
+ iTransDomain = LookupDomain(aDomainId);
+ if (!iTransDomain)
+ return KDmErrBadDomainId;
+ SetState(aTargetState, aTraverseDirection);
+ RequestTransition(aMessage);
+ return KErrNone;
+ }
+
+void CDmHierarchy::CompleteTransition(TInt aError)
+ {
+ if (!iTransDomain)
+ return;
+
+ __DS_TRACE((_L("CDmHierarchy::CompleteTransition() hierarchy=%d, domain=0x%x, aError=%d"), iHierarchyId, iTransDomain->iId, aError));
+
+ if (iTransDomain)
+ {
+ iTransDomain->CancelTransition();
+ NotifyCompletion(aError);
+ }
+ }
+
+void CDmHierarchy::SetState(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection)
+ {
+ __DS_ASSERT(iTransDomain);
+
+
+ if (aTraverseDirection == ETraverseDefault)
+ {
+ TDmDomainState oldState = iTransDomain->State();
+
+ if (aTargetState >= oldState)
+ iTraverseDirection = iPolicy.iPositiveTransitions;
+ else
+ iTraverseDirection = iPolicy.iNegativeTransitions;
+ }
+ else
+ iTraverseDirection = aTraverseDirection;
+
+ __DS_ASSERT(iTraverseDirection < ETraverseMax);
+
+ iTransState = aTargetState;
+ }
+
+//*********************************************************
+// CPowerUpHandler
+//*********************************************************
+
+CPowerUpHandler* CPowerUpHandler::New(CDmHierarchyPower& aHierarchyPower)
+ {
+ CPowerUpHandler* self = new CPowerUpHandler(aHierarchyPower);
+ if (!self)
+ __DS_PANIC(KErrNoMemory);
+ self->Construct();
+ return self;
+ }
+
+CPowerUpHandler::CPowerUpHandler(CDmHierarchyPower& aHierarchyPower) :
+ CActive(CActive::EPriorityStandard),
+ iHierarchyPower(aHierarchyPower)
+ {
+ }
+
+void CPowerUpHandler::Construct()
+ {
+ CActiveScheduler::Add(this);
+ }
+
+
+void CPowerUpHandler::RequestWakeupEventNotification()
+ {
+ Power::RequestWakeupEventNotification(iStatus);
+ SetActive();
+ }
+
+
+void CPowerUpHandler::Cancel()
+ {
+ CActive::Cancel();
+ }
+
+void CPowerUpHandler::RunL()
+ {
+ // power wakeup event
+ iHierarchyPower.PowerUp();
+ }
+
+
+void CPowerUpHandler::DoCancel()
+ {
+ Power::DisableWakeupEvents();
+ Power::CancelWakeupEventNotification();
+ }
+
+
+
+//*********************************************************
+// CDmHierarchyPower
+//*********************************************************
+CDmHierarchyPower* CDmHierarchyPower::New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy)
+ {
+ CDmHierarchyPower* self;
+
+ self = new CDmHierarchyPower(aHierarchyId, aPolicy);
+
+ if (!self)
+ __DS_PANIC(KErrNoMemory);
+
+ self->Construct();
+
+ return self;
+ }
+
+CDmHierarchyPower::CDmHierarchyPower(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy) :
+ CDmHierarchy(aHierarchyId, aPolicy)
+ {
+ }
+
+
+void CDmHierarchyPower::Construct()
+ {
+ iPowerUpHandler = CPowerUpHandler::New(*this);
+ if (!iPowerUpHandler)
+ __DS_PANIC(KErrNoMemory);
+ }
+
+void CDmHierarchyPower::NotifyCompletion(TInt aReason)
+ {
+ iTransStatus = 0;
+ CDmHierarchy::NotifyCompletion(aReason);
+ }
+
+TInt CDmHierarchyPower::RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage)
+ {
+ __DS_TRACE((_L("CDmSvrManager::RequestSystemTransition() state = 0x%x"), aTargetState));
+
+ TInt r = Power::EnableWakeupEvents((TPowerState) aTargetState);
+ if (r != KErrNone)
+ return r;
+
+ iPowerUpHandler->RequestWakeupEventNotification();
+
+ iTransStatus |= EPoweringDown;
+
+ return CDmHierarchy::RequestSystemTransition(aTargetState, aTraverseDirection, aMessage);
+ }
+
+void CDmHierarchyPower::CompleteTransition(TInt aError)
+ {
+ if (!iTransDomain)
+ return;
+
+ __DS_TRACE((_L("CDmHierarchyPower::CompleteTransition() domain=0x%x"), iTransDomain->iId));
+
+ if (iTransDomain && aError == KErrCancel)
+ iPowerUpHandler->Cancel();
+
+ if (iTransStatus & EPoweringDown)
+ {
+ RFs fs;
+ TInt r=fs.Connect();
+ __DS_ASSERT(r==KErrNone);
+ __DS_TRACE((_L("CDmSvrManager::CompleteTransition() Calling FinaliseDrives")));
+ r=fs.FinaliseDrives();
+ __DS_TRACE((_L("CDmSvrManager::CompleteTransition() Finalise returned %d"),r));
+ fs.Close();
+
+ Power::PowerDown();
+ __DS_ASSERT(iTransState != (TDmDomainState) EPwOff);
+ __DS_ASSERT(iPowerUpHandler->iStatus.Int() == KErrNone);
+ }
+ else
+ {
+ CDmHierarchy::CompleteTransition(aError);
+ }
+ }
+
+
+void CDmHierarchyPower::PowerUp()
+ {
+ __DS_TRACE((_L("CDmHierarchyPower::RunL() Wakeup Event")));
+ __DS_ASSERT(iTransDomain);
+
+ Power::DisableWakeupEvents();
+
+ iTransStatus &= ~EPoweringDown;
+ iTransDomain->CancelTransition();
+ SetState((TDmDomainState) EPwActive);
+ RequestTransition(NULL);
+ }
+
+
+//*********************************************************
+// CDmSvrManager
+//*********************************************************
+
+CDmSvrManager* CDmSvrManager::New()
+ {
+ CDmSvrManager* self = new CDmSvrManager();
+ if (!self)
+ __DS_PANIC(KErrNoMemory);
+ self->Construct();
+ return self;
+ }
+
+CDmSvrManager::CDmSvrManager()
+ {
+ }
+
+void CDmSvrManager::Construct()
+ {
+ // load the power hierarchy- Other hieratchies need to be loaded
+ // explicitly using RDmDomainManager::AddDomainHierarchy()
+ CDmHierarchy* hierarchy;
+ TInt r = BuildDomainTree(KDmHierarchyIdPower, hierarchy);
+ if (r != KErrNone)
+ __DS_PANIC(r);
+
+
+ RProperty prop;
+ r = prop.Define(KUidDmPropertyCategory, KDmPropertyKeyInit, RProperty::EInt,
+ KAllowAllPolicy,KPowerMgmtPolicy);
+ if (r != KErrNone)
+ __DS_PANIC(r);
+
+ prop.Set(KUidDmPropertyCategory, KDmPropertyKeyInit, ETrue);
+ }
+
+TInt CDmSvrManager::BuildDomainTree(TDmHierarchyId aHierarchyId, CDmHierarchy*& aHierarchy)
+ {
+
+ aHierarchy = NULL;
+
+ // assume we have already checked that the hierarchy doesn't already exist
+
+ // Get the name of the policy Dll
+ // This will be "domainPolicy.dll" for the power hierarchy
+ // and "domainPolicy<n>.dll" for other hierarchies where <n> is the hierarchy ID.
+ //
+ // If the hierarchy ID is less than KMaxCriticalPolicyDll, load only from ROM
+
+ TFullName dllName;
+
+ // is this policy "critical" i.e non-replaceable ?
+ _LIT(KSysBin,"z:\\sys\\bin\\");
+ // const TInt KMaxCriticalPolicyDll = 1000;
+ // if (aHierarchyId < KMaxCriticalPolicyDll) // <-- cannot be false while aHierarchyId is a TUint8 (typedef'd to TDmHierarchyId)
+ dllName.Append(KSysBin);
+
+ dllName.Append(_L("domainPolicy"));
+ if (aHierarchyId != KDmHierarchyIdPower)
+ dllName.AppendNum(aHierarchyId);
+
+ dllName.Append(_L(".dll"));
+ RLibrary lib;
+ TInt r = lib.Load(dllName);
+ if (r == KErrNotFound)
+ return KErrBadHierarchyId;
+ else if (r != KErrNone)
+ return r;
+
+ TLibraryFunction ordinal1 = lib.Lookup(EDmPolicyGetDomainSpecs);
+ DmPolicyGetDomainSpecs getDomainSpecs = reinterpret_cast<DmPolicyGetDomainSpecs>(ordinal1);
+ if (getDomainSpecs == NULL)
+ r = KErrBadHierarchyId;
+
+ TLibraryFunction ordinal2 = lib.Lookup(EDmPolicyRelease);
+ DmPolicyRelease release = reinterpret_cast<DmPolicyRelease>(ordinal2);
+ if (release == NULL)
+ r = KErrBadHierarchyId;
+
+ TLibraryFunction ordinal3 = lib.Lookup(EDmPolicyGetPolicy);
+ DmPolicyGetPolicy getPolicy = reinterpret_cast<DmPolicyGetPolicy>(ordinal3);
+ if (getPolicy == NULL)
+ r = KErrBadHierarchyId;
+
+
+ // get the domain spec for this hierarchy
+ const TDmDomainSpec* spec = NULL;
+
+ if (r == KErrNone)
+ {
+ spec = (*getDomainSpecs)();
+ if (spec == NULL)
+ r = KErrBadHierarchyId;
+ }
+ // get the policy
+ TDmHierarchyPolicy hierarchyPolicy;
+ if (r == KErrNone)
+ {
+ r = (*getPolicy)(hierarchyPolicy);
+ if (r == KErrNone)
+ {
+ __DS_ASSERT(hierarchyPolicy.iPositiveTransitions < ETraverseMax);
+ __DS_ASSERT(hierarchyPolicy.iNegativeTransitions < ETraverseMax);
+ }
+ }
+
+ if (r != KErrNone)
+ {
+ lib.Close();
+ return r;
+ }
+
+ CDmHierarchy* hierarchy = CDmHierarchy::New(aHierarchyId, hierarchyPolicy);
+ if (hierarchy == NULL)
+ __DS_PANIC(KErrNoMemory);
+
+ while (r == KErrNone && spec->iId != KDmIdNone)
+ {
+ // make sure the domain doesn't already exist in this hierarchy
+ CSvrDomain* domain = hierarchy->LookupDomain(spec->iId);
+ if (domain)
+ {
+ r = KErrBadHierarchyId;
+ break;
+ }
+
+ domain = CSvrDomain::New(*hierarchy, *spec);
+ __DS_ASSERT(domain);
+
+ if (spec->iParentId == KDmIdNone)
+ {
+ if (hierarchy->iRootDomain)
+ {
+ r = KDmErrBadDomainSpec;
+ break;
+ }
+ hierarchy->iRootDomain = domain;
+ }
+ else
+ {
+ CSvrDomain* parent = hierarchy->LookupDomain(spec->iParentId);
+ if (!parent)
+ {
+ r = KDmErrBadDomainSpec;
+ break;
+ }
+ parent->AddChild(domain);
+ }
+ ++spec;
+ }
+
+ if (spec)
+ (*release)(spec);
+
+
+ if (r == KErrNone)
+ {
+ __DS_ASSERT(hierarchy->iRootDomain);
+ iDomainHierarchies.Append(hierarchy);
+ aHierarchy = hierarchy;
+ }
+ else
+ {
+ delete hierarchy;
+ hierarchy = NULL;
+ }
+
+ lib.Close();
+
+ return r;
+ }
+
+CDmHierarchy* CDmSvrManager::LookupHierarchy(TDmHierarchyId aHierarchyId)
+
+ {
+ // need to find the correct hierarchy first
+ TInt len = iDomainHierarchies.Count();
+
+ CDmHierarchy* hierarchy = NULL;
+ for (TInt n=0; n<len; n++)
+ {
+ if (iDomainHierarchies[n]->iHierarchyId == aHierarchyId)
+ {
+ hierarchy = iDomainHierarchies[n];
+ break;
+ }
+ }
+
+ return hierarchy;
+ }
+
+
+TInt CDmSvrManager::LookupDomain(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, CSvrDomain*& aDomain)
+ {
+ // need to find the correct hierarchy first
+ CDmHierarchy* hierarchy = LookupHierarchy(aHierarchyId);
+ if (hierarchy == NULL)
+ return KErrBadHierarchyId;
+
+ aDomain = hierarchy->LookupDomain(aDomainId);
+ if (aDomain == NULL)
+ return KDmErrBadDomainId;
+
+ return KErrNone;
+ }
+
+CSession2* CDmManagerServer::NewSessionL(const TVersion&, const RMessage2& aMessage) const
+ {
+
+ // If the client does not have ECapabilityPowerMgmt capability, then it has no
+ // right to make this request. Blow it up.
+ if (!KPowerMgmtPolicy.CheckPolicy(aMessage))
+ {
+
+ User::Leave(KErrPermissionDenied);
+
+ }
+
+ return new CDmManagerSession();
+ }
+
+CSession2* CDmManagerServer::NewSessionL(const TVersion&) const
+ {
+ __DS_PANIC(KErrGeneral);
+ return 0;
+ }
+
+CDmManagerSession::CDmManagerSession()
+ {}
+
+CDmManagerSession::~CDmManagerSession()
+ {
+ if (iHierarchy && iHierarchy->iControllerSession == this)
+ iHierarchy->iControllerSession = NULL;
+ if (iHierarchy && iHierarchy->iObserverSession == this)
+ iHierarchy->iObserverSession = NULL;
+ }
+
+class MyMessage : public RMessage2
+ {
+public:
+ TInt* ArgRef(TInt i)
+ { return &iArgs[i]; }
+ };
+
+void CDmManagerSession::ServiceL(const RMessage2& aMessage)
+ {
+ TInt r;
+ CDmSvrManager* manager = ((CDmManagerServer*) Server()) -> iManager;
+
+ // Check client has ECapabilityPowerMgmt capability
+/*
+ if (!KPowerMgmtPolicy.CheckPolicy(aMessage))
+ {
+ aMessage.Complete(KErrPermissionDenied);
+ return;
+ }
+*/
+ switch (aMessage.Function())
+ {
+ case EDmHierarchyAdd:
+ {
+ r = KErrNone;
+ TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
+
+ CDmHierarchy* hierarchy = manager->LookupHierarchy(hierarchyId);
+ if (hierarchy == NULL)
+ r = manager->BuildDomainTree(hierarchyId, hierarchy);
+ aMessage.Complete(r);
+ }
+ break;
+
+ case EDmHierarchyJoin:
+ {
+ r = KErrNone;
+ TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
+
+ iHierarchy = manager->LookupHierarchy(hierarchyId);
+ if (iHierarchy == NULL)
+ r = KErrBadHierarchyId;
+
+ if (r == KErrNone)
+ {
+ // is the hierarchy already in use ?
+ if (iHierarchy->iControllerSession)
+ r = KErrInUse;
+ else
+ iHierarchy->iControllerSession = this;
+ }
+
+ aMessage.Complete(r);
+ }
+ break;
+
+ case EDmRequestSystemTransition:
+ if (iHierarchy==NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+ if (iHierarchy->iTransDomain)
+ {
+ aMessage.Complete(KDmErrBadSequence);
+ break;
+ }
+
+ r = iHierarchy->RequestSystemTransition(
+ (TDmDomainState) aMessage.Int0(),
+ (TDmTraverseDirection) aMessage.Int1(),
+ &aMessage);
+
+ if (r != KErrNone)
+ aMessage.Complete(r);
+ break;
+
+ case EDmRequestDomainTransition:
+ if (iHierarchy==NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+ if (iHierarchy->iTransDomain)
+ {
+ aMessage.Complete(KDmErrBadSequence);
+ break;
+ }
+ r = iHierarchy->RequestDomainTransition(
+ (TDmDomainId) aMessage.Int0(),
+ (TDmDomainState) aMessage.Int1(),
+ (TDmTraverseDirection) aMessage.Int2(),
+ &aMessage);
+
+ if (r != KErrNone)
+ aMessage.Complete(r);
+ break;
+
+ case EDmGetTransitionFailureCount:
+ {
+ if (iHierarchy==NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+ TInt failureCount = iHierarchy->iTransitionFailures.Count();
+ aMessage.Complete(failureCount);
+ }
+ break;
+
+ case EDmGetTransitionFailures:
+ {
+ if (iHierarchy==NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+ TInt failureCount = iHierarchy->iTransitionFailures.Count();
+ TInt clientFailureSize = aMessage.GetDesMaxLength(0);
+ TInt clientFailureCount = clientFailureSize / sizeof(TTransitionFailure);
+ __DS_ASSERT( (clientFailureSize % sizeof(TTransitionFailure)) == 0);
+ __DS_ASSERT(failureCount >= clientFailureCount);
+
+ HBufC8* hBuf = HBufC8::New(clientFailureSize);
+ if(hBuf == NULL)
+ {
+ aMessage.Complete(KErrNoMemory);
+ break;
+ }
+ TPtr8 pBuf = hBuf->Des();
+ pBuf.Zero();
+ for (TInt i=0; i<clientFailureCount; i++)
+ {
+ TPtrC8 ptr = TPtrC8((TUint8*) &iHierarchy->iTransitionFailures[i], sizeof(TTransitionFailure));
+ pBuf.Append(ptr);
+ }
+ r = aMessage.Write(0, pBuf);
+ delete hBuf;
+
+ aMessage.Complete(r);
+ }
+ break;
+
+ case EDmCancelTransition:
+ if (iHierarchy == NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+ iHierarchy->CompleteTransition(KErrCancel);
+ if (iHierarchy->iObserverStarted)
+ {
+ iHierarchy->CompleteNotification(KErrCancel);
+ iHierarchy->StopObserver();
+ }
+ aMessage.Complete(KErrNone);
+ break;
+ case EDmObserverCancel:
+ if (iHierarchy == NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+ if(!iHierarchy->iObserverSession)
+ {
+ aMessage.Complete(KDmErrBadSequence);
+ break;
+ }
+ if (iHierarchy->iObserverStarted)
+ {
+ iHierarchy->CompleteNotification(KErrCancel);
+ iHierarchy->StopObserver();
+ }
+ aMessage.Complete(KErrNone);
+ break;
+
+ case EDmObserverJoin:
+ {
+ TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
+
+ iHierarchy = manager->LookupHierarchy(hierarchyId);
+ if(iHierarchy==NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+ if(iHierarchy->iObserverSession)
+ {
+ aMessage.Complete(KDmErrBadSequence);
+ break;
+ }
+ iHierarchy->iTransitions.Reset();
+ iHierarchy->iObserverSession = this;
+ aMessage.Complete(KErrNone);
+ }
+ break;
+
+ case EDmObserverStart:
+ {
+ if (iHierarchy==NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+
+ if(iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
+ {
+ aMessage.Complete(KDmErrBadSequence);
+ break;
+ }
+ TInt ret= iHierarchy->StartObserver((TDmDomainId)aMessage.Int0(),(TDmNotifyType)aMessage.Int1());
+ aMessage.Complete(ret);
+ }
+ break;
+
+ case EDmObserverNotify:
+ {
+ if (iHierarchy==NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+ if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
+ {
+ aMessage.Complete(KDmErrBadSequence);
+ break;
+ }
+ // Check to see if we have any events stored
+ // If so, then notify the client
+ if(iHierarchy->iTransitions.Count()>0)
+ {
+ aMessage.Complete(KErrNone);
+ break;
+ }
+ // No events are stored. complete this message later
+ iHierarchy->SetNotifyMessage(&aMessage);
+ }
+ break;
+
+ case EDmObserverEventCount:
+ {
+ if (iHierarchy==NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+ if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
+ {
+ aMessage.Complete(KDmErrBadSequence);
+ break;
+ }
+ TInt count = iHierarchy->iTransitions.Count();
+ aMessage.Complete(count);
+ }
+ break;
+
+ case EDmObserverGetEvent:
+ {
+ if (iHierarchy==NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+ if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
+ {
+ aMessage.Complete(KDmErrBadSequence);
+ break;
+ }
+ TInt transitionCount = iHierarchy->iTransitions.Count();
+ TInt clientTransitionSize = aMessage.GetDesMaxLength(0);
+ TInt clientTransitionCount = clientTransitionSize / sizeof(TTransInfo);
+ __DS_ASSERT( (clientTransitionSize % sizeof(TTransInfo)) == 0);
+ __DS_ASSERT(transitionCount >= clientTransitionCount);
+
+ HBufC8* hBuf = HBufC8::New(clientTransitionSize);
+ if(hBuf == NULL)
+ {
+ aMessage.Complete(KErrNoMemory);
+ break;
+ }
+ TPtr8 pBuf = hBuf->Des();
+ pBuf.Zero();
+ for (TInt i=0; i<clientTransitionCount; i++)
+ {
+ TPtrC8 ptr = TPtrC8((TUint8*) &iHierarchy->iTransitions[0], sizeof(TTransInfo));
+ pBuf.Append(ptr);
+ iHierarchy->iTransitions.Remove(0);
+ }
+ r = aMessage.Write(0, pBuf);
+ delete hBuf;
+
+ aMessage.Complete(r);
+ }
+ break;
+ case EDmObserveredCount:
+ {
+ if (iHierarchy==NULL)
+ {
+ aMessage.Complete(KErrBadHierarchyId);
+ break;
+ }
+ if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
+ {
+ aMessage.Complete(KDmErrBadSequence);
+ break;
+ }
+ aMessage.Complete(iHierarchy->iObservedChildren);
+ }
+ break;
+ default:
+ aMessage.Complete(KDmErrBadRequest);
+ break;
+ }
+ }
+
+CSession2* CDmDomainServer::NewSessionL(const TVersion&, const RMessage2&) const
+ {
+
+ return new CDmDomainSession();
+ }
+
+CSession2* CDmDomainServer::NewSessionL(const TVersion&) const
+ {
+ __DS_PANIC(KErrGeneral);
+ return 0;
+ }
+
+CDmDomainSession::~CDmDomainSession()
+ {
+ if (iPending)
+ iDomain->CompleteMemberTransition(KErrNone);
+ if (iDomain)
+ iDomain->Detach(this);
+ }
+
+void CDmDomainSession::ServiceL(const RMessage2& aMessage)
+ {
+ TInt r = KErrNone;
+ CDmSvrManager* manager = ((CDmManagerServer*) Server()) -> iManager;
+
+ switch (aMessage.Function())
+ {
+ case EDmDomainJoin:
+ {
+ TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
+ TDmDomainId domainId = (TDmDomainId) aMessage.Int1();
+
+ r = manager->LookupDomain(hierarchyId, domainId, iDomain);
+
+ if (r != KErrNone)
+ break;
+
+ // Check client has capability to join the domain
+ if (!iDomain->iJoinPolicy.CheckPolicy(aMessage))
+ {
+ r = KErrPermissionDenied;
+ iDomain = NULL;
+ break;
+ }
+
+ iDomain->Attach(this);
+ break;
+ }
+
+ case EDmStateRequestTransitionNotification:
+ iNotificationEnabled = ETrue;
+ break;
+
+ case EDmStateCancelTransitionNotification:
+ iNotificationEnabled = EFalse;
+ break;
+
+ case EDmStateAcknowledge:
+ {
+ TInt propValue = aMessage.Int0();
+ TInt error = aMessage.Int1();
+ if (!iDomain)
+ {
+ r = KDmErrNotJoin;
+ break;
+ }
+ if (iPending && iDomain->CheckPropValue(propValue))
+ {
+ iPending = EFalse;
+ iDomain->CompleteMemberTransition(error);
+ }
+ }
+ break;
+ default:
+ r = KDmErrBadRequest;
+ break;
+ }
+ aMessage.Complete(r);
+ }
+
+
+TInt E32Main()
+ {
+ CTrapCleanup* cleanupStack = CTrapCleanup::New();
+ if(!cleanupStack)
+ __DS_PANIC(KErrNoMemory);
+
+ CActiveScheduler* sched = new CActiveScheduler();
+ if (!sched)
+ __DS_PANIC(KErrNoMemory);
+
+ CActiveScheduler::Install(sched);
+
+ CDmSvrManager* mngr = CDmSvrManager::New();
+ __DS_ASSERT(mngr);
+
+ CDmManagerServer* msrv = new CDmManagerServer(mngr);
+ if (!msrv)
+ __DS_PANIC(KErrNoMemory);
+
+ TInt r=msrv->Start(KDmManagerServerNameLit);
+ if (r != KErrNone)
+ __DS_PANIC(r);
+
+ CDmDomainServer* dsrv = new CDmDomainServer(mngr);
+ if (!dsrv)
+ __DS_PANIC(KErrNoMemory);
+
+ r=dsrv->Start(KDmDomainServerNameLit);
+ if (r != KErrNone)
+ __DS_PANIC(r);
+
+ CActiveScheduler::Start();
+
+ __DS_PANIC(0);
+
+ return KErrNone;
+ }