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