Update contrib.
1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // domain\src\domainsrv.cpp
20 #include <e32base_private.h>
21 #include <e32property.h>
24 #include <domainpolicy.h>
25 #include "domainsrv.h"
27 #define __DS_PANIC(aError) User::Panic(_L("domainSrv.cpp"), (-(aError)) | (__LINE__ << 16))
28 #define __DS_ASSERT(aCond) ((aCond) || (User::Panic(_L("domainSrv.cpp; assertion failed"), __LINE__), 1))
33 #define __DS_TRACE(s) RDebug::Print s
38 static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
39 static _LIT_SECURITY_POLICY_C1(KPowerMgmtPolicy,ECapabilityPowerMgmt);
44 class CPowerUpHandler;
45 class CDmHierarchyPower;
47 class CDmDomainServer;
48 class CDmDomainSession;
49 class CDmManagerServer;
50 class CDmManagerSession;
55 class CSvrDomain : public CTimer
58 static CSvrDomain* New(CDmHierarchy& aHierarchy, const TDmDomainSpec&);
63 void Attach(CDmDomainSession*);
64 void Detach(CDmDomainSession*);
65 void AddChild(CSvrDomain*);
66 CSvrDomain* Lookup(TDmDomainId);
67 TBool CheckPropValue(TInt aPropValue);
68 void RequestDomainTransition();
69 void CompleteMemberTransition(TInt aError);
70 void CancelTransition();
71 void SetObserver(TBool aSet);
72 TDmDomainState State();
75 CSvrDomain(CDmHierarchy& aHierarchy, const TDmDomainSpec*);
76 void Construct(const TDmDomainSpec* spec);
78 void RequestMembersTransition();
79 void RequestChildrenTransition();
80 void MembersTransitionDone();
81 void ChildrenTransitionDone();
82 void CompleteDomainTransition();
85 CDmHierarchy& iHierarchy;
90 CDmDomainSession* iSessions;
91 TUint16 iChildrenCount;
93 TTimeIntervalMicroSeconds32 iTransTimeBudget;
96 const TSecurityPolicy iJoinPolicy;
103 class CDmHierarchy : public CBase
106 static CDmHierarchy* New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
108 CSvrDomain* LookupDomain(TDmDomainId aDomainId);
109 TInt RequestDomainTransition(TDmDomainId, TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
110 void RequestTransition(const RMessage2* aMessage);
111 TInt StartObserver( TDmDomainId aDomainId,TDmNotifyType aNotifyType);
112 void SetNotifyMessage(const RMessage2* aMessage);
113 void CompleteNotification(TInt aError);
114 TBool OutstandingNotification();
116 virtual TInt RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
117 virtual void CompleteTransition(TInt aError);
118 virtual void NotifyCompletion(TInt aReason);
121 CDmHierarchy(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
122 void SetState(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection = ETraverseDefault);
125 RMessagePtr2 iTransMessagePtr;
126 RMessagePtr2 iObsvrMessagePtr;
127 CSvrDomain* iObservedDomain;
128 TBool iOutstandingNotification;
130 TDmHierarchyId iHierarchyId;
131 CSvrDomain* iRootDomain;
132 CSvrDomain* iTransDomain;
133 TInt iTransPropValue;
134 TDmDomainState iTransState;
135 TDmTraverseDirection iTraverseDirection;
137 CDmManagerSession* iControllerSession; // only one controller per hierarchy
138 TDmHierarchyPolicy iPolicy;
139 RArray<TTransitionFailure> iTransitionFailures;
142 TBool iObserverStarted;
143 TDmNotifyType iNotifyType;
144 RArray<TTransInfo> iTransitions;
145 CDmManagerSession* iObserverSession; // only one observer per hierarchy
146 TInt iObservedChildren;
151 // Active object used to receive power-up notifications
152 // from the Kernel-level power manager
153 class CPowerUpHandler : public CActive
156 static CPowerUpHandler* New(CDmHierarchyPower& aHierarchyPower);
162 void RequestWakeupEventNotification();
166 CPowerUpHandler(CDmHierarchyPower& aHierarchyPower);
170 CDmHierarchyPower& iHierarchyPower;
175 // CDmHierarchy-derived class
176 // Interfaces to the Kernel-level power manager
177 class CDmHierarchyPower : public CDmHierarchy
180 static CDmHierarchyPower* New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
183 virtual TInt RequestSystemTransition(TDmDomainState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
184 virtual void CompleteTransition(TInt aError);
185 virtual void NotifyCompletion(TInt aReason);
187 void PowerUp(); // called from CPowerUpHandler
190 CDmHierarchyPower(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
196 EPoweringDown = 0x01,
199 CPowerUpHandler* iPowerUpHandler;
204 class CDmSvrManager : public CBase
207 static CDmSvrManager* New();
209 TInt BuildDomainTree(TDmHierarchyId aHierarchyId, CDmHierarchy*& aHierarchy);
210 CDmHierarchy* LookupHierarchy(TDmHierarchyId aHierarchyId);
211 TInt LookupDomain(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, CSvrDomain*& aDomain);
218 RPointerArray<CDmHierarchy> iDomainHierarchies;
222 class CDmDomainServer : public CServer2
226 CSession2* NewSessionL(const TVersion& aVer) const;
227 CSession2* NewSessionL(const TVersion& aVer, const RMessage2& aMessage) const;
229 CDmDomainServer(CDmSvrManager* aManager) : CServer2(CActive::EPriorityStandard), iManager(aManager)
233 CDmSvrManager* iManager;
237 class CDmDomainSession : public CSession2
244 void ServiceL(const RMessage2& aMessage);
250 CDmDomainSession* iNext;
252 TBool iNotificationEnabled;
255 class CDmManagerServer : public CServer2
259 CSession2* NewSessionL(const TVersion& aVer) const;
260 CSession2* NewSessionL(const TVersion& aVer, const RMessage2&) const;
262 CDmManagerServer(CDmSvrManager* aManager) : CServer2(CActive::EPriorityStandard), iManager(aManager)
264 CDmSvrManager* iManager;
267 class CDmManagerSession : public CSession2
271 ~CDmManagerSession();
274 void ServiceL(const RMessage2& aMessage);
278 CDmHierarchy* iHierarchy; // not owned
284 //*********************************************************
285 // TTransitionFailure
286 //*********************************************************
290 Constructor for transition failure info.
292 @param aDomainID Id of the domain of interest
293 @param aError error code of transition
295 TTransitionFailure::TTransitionFailure(TDmDomainId aDomainId, TInt aError) :
296 iDomainId(aDomainId), iError(aError)
300 //*********************************************************
302 //*********************************************************
307 Constructor for transition failure info.
309 @param aDomainID Id of the domain of interest
310 @param aState State of the domain after transition
311 @param aError error code of transition
313 TTransInfo::TTransInfo(TDmDomainId aDomainId, TDmDomainState aState, TInt aError) :
314 iDomainId(aDomainId), iState(aState), iError(aError)
318 //*********************************************************
320 //*********************************************************
323 CSvrDomain::CSvrDomain(CDmHierarchy& aHierarchy, const TDmDomainSpec* spec)
324 : CTimer(CActive::EPriorityStandard),
325 iHierarchy(aHierarchy),
326 iTransTimeBudget(spec->iTimeBudgetUs),
327 iJoinPolicy(spec->iJoinPolicy),
331 CSvrDomain* CSvrDomain::New(CDmHierarchy& aHierarchy, const TDmDomainSpec& aSpec)
334 CSvrDomain* self = new CSvrDomain(aHierarchy, &aSpec);
337 __DS_PANIC(KErrNoMemory);
338 self->Construct(&aSpec);
342 void CSvrDomain::Construct(const TDmDomainSpec* spec)
344 TInt r = iProperty.Define(
345 KUidDmPropertyCategory,
346 DmStatePropertyKey(iHierarchy.iHierarchyId, iId),
348 KAllowAllPolicy,KPowerMgmtPolicy);
353 r = iProperty.Attach(KUidDmPropertyCategory, DmStatePropertyKey(
354 iHierarchy.iHierarchyId,
360 r = iProperty.Set(DmStatePropertyValue(0, spec->iInitState));
364 TRAP(r, CTimer::ConstructL());
367 CActiveScheduler::Add(this);
370 void CSvrDomain::Attach(CDmDomainSession* aSession)
372 aSession->iNext = iSessions;
373 iSessions = aSession;
376 void CSvrDomain::Detach(CDmDomainSession* aSession)
378 CDmDomainSession** prevp = &iSessions;
379 while (*prevp != aSession)
381 prevp = &((*prevp)->iNext);
384 *(prevp) = aSession->iNext;
387 void CSvrDomain::AddChild(CSvrDomain* aChild)
390 aChild->iParent = this;
392 aChild->iIsObserved=ETrue;
393 // Insert the child in the list of its peers
394 aChild->iPeer = iChild;
398 CSvrDomain* CSvrDomain::Lookup(TDmDomainId aDomainId)
400 if (iId == aDomainId)
403 CSvrDomain* child = iChild;
406 CSvrDomain* domain = child->Lookup(aDomainId);
409 child = child->iPeer;
414 TBool CSvrDomain::CheckPropValue(TInt aPropValue)
415 { return iHierarchy.iTransPropValue == aPropValue; }
417 void CSvrDomain::RequestMembersTransition()
419 __DS_TRACE((_L("CSvrDomain::RequestMembersTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
420 __DS_ASSERT(iTransCount == 0);
422 for(CDmDomainSession* s = iSessions; s; s = s->iNext)
423 if (s->iNotificationEnabled)
427 // notifications will be disabled until the client makes another
428 // call to RDmDomain::RequestTransitionNotification()
429 s->iNotificationEnabled = EFalse;
434 if((iHierarchy.iNotifyType&EDmNotifyTransRequest)==EDmNotifyTransRequest)
436 TTransInfo transInfo(iId,State(),KDmErrOutstanding);
437 iHierarchy.iTransitions.Append(transInfo);
438 if(iHierarchy.OutstandingNotification())
439 iHierarchy.CompleteNotification(KErrNone);
443 CTimer::After(iTransTimeBudget);
444 iProperty.Set(iHierarchy.iTransPropValue);
445 if (iTransCount == 0)
446 MembersTransitionDone();
450 void CSvrDomain::RequestChildrenTransition()
452 __DS_TRACE((_L("CSvrDomain::RequestChildrenTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
453 __DS_ASSERT(iTransCount == 0);
454 iTransCount = iChildrenCount;
457 CSvrDomain* child = iChild;
460 child->RequestDomainTransition();
461 child = child->iPeer;
466 ChildrenTransitionDone();
469 void CSvrDomain::RequestDomainTransition()
471 __DS_TRACE((_L("CSvrDomain::RequestDomainTransition() hierarchy=%d, domain=0x%x state=0x%x prop=0x%x"),
472 iHierarchy.iHierarchyId, iId, iHierarchy.iTransState, iHierarchy.iTransPropValue));
473 __DS_ASSERT(iTransCount == 0);
474 if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
475 RequestChildrenTransition();
477 RequestMembersTransition();
480 void CSvrDomain::MembersTransitionDone()
482 __DS_TRACE((_L("CSvrDomain::MembersTransitionDone() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
483 __DS_ASSERT(iTransCount == 0);
484 if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
485 CompleteDomainTransition();
487 RequestChildrenTransition();
490 void CSvrDomain::ChildrenTransitionDone()
492 __DS_TRACE((_L("CSvrDomain::ChildrenTransitionDone() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
493 __DS_ASSERT(iTransCount == 0);
494 if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
495 RequestMembersTransition();
497 CompleteDomainTransition();
500 void CSvrDomain::CompleteMemberTransition(TInt aError)
502 __DS_TRACE((_L("CSvrDomain::CompleteMemberTransition() hierarchy=%d, domain=0x%x, aError = %d"), iHierarchy.iHierarchyId, iId, aError));
503 __DS_ASSERT(iTransCount);
507 // Add a transition failure to the array
508 TTransitionFailure failure(iId, aError);
509 iHierarchy.iTransitionFailures.Append(failure);
513 if((iHierarchy.iNotifyType&EDmNotifyFail)==EDmNotifyFail)
515 TTransInfo transInfo(iId,State(),aError);
516 iHierarchy.iTransitions.Append(transInfo);
517 if(iHierarchy.OutstandingNotification())
518 iHierarchy.CompleteNotification(KErrNone);
521 // examine the failure policy to work out what to do
522 if (iHierarchy.iPolicy.iFailurePolicy == ETransitionFailureStop)
524 iHierarchy.CompleteTransition(aError);
530 if((iHierarchy.iNotifyType&EDmNotifyPass) == EDmNotifyPass)
532 TTransInfo transInfo(iId,State(),aError);
533 iHierarchy.iTransitions.Append(transInfo);
534 if(iHierarchy.OutstandingNotification())
535 iHierarchy.CompleteNotification(KErrNone);
539 if (--iTransCount == 0)
542 MembersTransitionDone();
546 void CSvrDomain::RunL()
548 __DS_TRACE((_L("CSvrDomain::RunL() Members transition timeout hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
550 // Add a transition failure to the array
551 TTransitionFailure failure(iId,KErrTimedOut);
552 iHierarchy.iTransitionFailures.Append(failure);
555 // examine the failure policy to work out what to do
556 if (iHierarchy.iPolicy.iFailurePolicy == ETransitionFailureStop)
558 iHierarchy.CompleteTransition(KErrTimedOut);
563 { // Complete transition of all members
564 CDmDomainSession* session = iSessions;
567 session->iPending = EFalse;
568 session = session->iNext;
571 MembersTransitionDone();
576 void CSvrDomain::CompleteDomainTransition()
578 __DS_TRACE((_L("CSvrDomain::CompleteDomainTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
579 __DS_ASSERT(iTransCount == 0);
580 if (iHierarchy.iTransDomain == this)
582 const TInt err = (iHierarchy.iTransitionFailures.Count() > 0)?
583 iHierarchy.iTransitionFailures[0].iError : KErrNone;
584 iHierarchy.CompleteTransition(err);
588 __DS_ASSERT(iParent);
589 __DS_ASSERT(iParent->iTransCount);
590 if (--iParent->iTransCount == 0)
591 iParent->ChildrenTransitionDone();
595 void CSvrDomain::CancelTransition()
597 __DS_TRACE((_L("CSvrDomain::CancelTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
599 CSvrDomain* child = iChild;
602 child->CancelTransition();
603 child = child->iPeer;
605 CDmDomainSession* session = iSessions;
608 session->iPending = EFalse;
609 session = session->iNext;
614 void CSvrDomain::SetObserver(TBool aSet)
619 iHierarchy.iObservedChildren++;
623 // this should be zero at the end
624 iHierarchy.iObservedChildren--;
626 if(iChildrenCount!=0)
628 CSvrDomain* domain=iChild;
630 domain->SetObserver(aSet);
631 domain = domain->iPeer;
637 TDmDomainState CSvrDomain::State()
640 iProperty.Get(value);
641 return DmStateFromPropertyValue(value);
644 //*********************************************************
646 //*********************************************************
648 CDmHierarchy* CDmHierarchy::New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy)
652 if (aHierarchyId == KDmHierarchyIdPower)
653 self = CDmHierarchyPower::New(aHierarchyId, aPolicy);
655 self = new CDmHierarchy(aHierarchyId, aPolicy);
658 __DS_PANIC(KErrNoMemory);
663 CDmHierarchy::CDmHierarchy(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy) :
664 iOutstandingNotification(EFalse),
665 iHierarchyId(aHierarchyId),
668 iTransitionFailures.Reset();
671 CSvrDomain* CDmHierarchy::LookupDomain(TDmDomainId aDomainId)
673 return iRootDomain ? iRootDomain->Lookup(aDomainId) : NULL;
676 void CDmHierarchy::RequestTransition(const RMessage2* aMessage)
678 // reset the array of transition failures
679 iTransitionFailures.Reset();
682 iTransMessagePtr = *aMessage;
683 iTransPropValue = DmStatePropertyValue(++iTransId, iTransState);
685 iTransDomain->RequestDomainTransition();
689 TInt CDmHierarchy::StartObserver(TDmDomainId aDomainId,TDmNotifyType aNotifyType)
691 iObservedDomain = LookupDomain(aDomainId);
693 if(iObservedDomain==NULL)
694 return KDmErrBadDomainId;
697 iObservedDomain->SetObserver(ETrue);
698 iNotifyType=aNotifyType;
699 iObserverStarted=ETrue;
703 void CDmHierarchy::SetNotifyMessage(const RMessage2* aMessage)
707 iObsvrMessagePtr = *aMessage;
708 iOutstandingNotification=ETrue;
712 TBool CDmHierarchy::OutstandingNotification()
714 return iOutstandingNotification;
717 void CDmHierarchy::CompleteNotification(TInt aError)
719 if(iOutstandingNotification)
721 iObsvrMessagePtr.Complete(aError);
722 iOutstandingNotification=EFalse;
726 void CDmHierarchy::StopObserver()
729 iObservedDomain->SetObserver(EFalse);
730 iTransitions.Reset();
731 iObserverStarted=EFalse;
733 void CDmHierarchy::NotifyCompletion(TInt aReason)
737 iTransMessagePtr.Complete(aReason);
740 TInt CDmHierarchy::RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage)
742 iTransDomain = iRootDomain;
743 SetState(aTargetState, aTraverseDirection);
744 RequestTransition(aMessage);
749 TInt CDmHierarchy::RequestDomainTransition(
750 TDmDomainId aDomainId,
751 TDmDomainState aTargetState,
752 TDmTraverseDirection aTraverseDirection,
753 const RMessage2* aMessage)
755 __DS_TRACE((_L("CDmHierarchy::RequestTransition() hierarchy=%d domain=0x%x state=0x%x"), iHierarchyId, aDomainId, aTargetState));
756 iTransDomain = LookupDomain(aDomainId);
758 return KDmErrBadDomainId;
759 SetState(aTargetState, aTraverseDirection);
760 RequestTransition(aMessage);
764 void CDmHierarchy::CompleteTransition(TInt aError)
769 __DS_TRACE((_L("CDmHierarchy::CompleteTransition() hierarchy=%d, domain=0x%x, aError=%d"), iHierarchyId, iTransDomain->iId, aError));
773 iTransDomain->CancelTransition();
774 NotifyCompletion(aError);
778 void CDmHierarchy::SetState(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection)
780 __DS_ASSERT(iTransDomain);
783 if (aTraverseDirection == ETraverseDefault)
785 TDmDomainState oldState = iTransDomain->State();
787 if (aTargetState >= oldState)
788 iTraverseDirection = iPolicy.iPositiveTransitions;
790 iTraverseDirection = iPolicy.iNegativeTransitions;
793 iTraverseDirection = aTraverseDirection;
795 __DS_ASSERT(iTraverseDirection < ETraverseMax);
797 iTransState = aTargetState;
800 //*********************************************************
802 //*********************************************************
804 CPowerUpHandler* CPowerUpHandler::New(CDmHierarchyPower& aHierarchyPower)
806 CPowerUpHandler* self = new CPowerUpHandler(aHierarchyPower);
808 __DS_PANIC(KErrNoMemory);
813 CPowerUpHandler::CPowerUpHandler(CDmHierarchyPower& aHierarchyPower) :
814 CActive(CActive::EPriorityStandard),
815 iHierarchyPower(aHierarchyPower)
819 void CPowerUpHandler::Construct()
821 CActiveScheduler::Add(this);
825 void CPowerUpHandler::RequestWakeupEventNotification()
827 Power::RequestWakeupEventNotification(iStatus);
832 void CPowerUpHandler::Cancel()
837 void CPowerUpHandler::RunL()
839 // power wakeup event
840 iHierarchyPower.PowerUp();
844 void CPowerUpHandler::DoCancel()
846 Power::DisableWakeupEvents();
847 Power::CancelWakeupEventNotification();
852 //*********************************************************
854 //*********************************************************
855 CDmHierarchyPower* CDmHierarchyPower::New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy)
857 CDmHierarchyPower* self;
859 self = new CDmHierarchyPower(aHierarchyId, aPolicy);
862 __DS_PANIC(KErrNoMemory);
869 CDmHierarchyPower::CDmHierarchyPower(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy) :
870 CDmHierarchy(aHierarchyId, aPolicy)
875 void CDmHierarchyPower::Construct()
877 iPowerUpHandler = CPowerUpHandler::New(*this);
878 if (!iPowerUpHandler)
879 __DS_PANIC(KErrNoMemory);
882 void CDmHierarchyPower::NotifyCompletion(TInt aReason)
885 CDmHierarchy::NotifyCompletion(aReason);
888 TInt CDmHierarchyPower::RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage)
890 __DS_TRACE((_L("CDmSvrManager::RequestSystemTransition() state = 0x%x"), aTargetState));
892 TInt r = Power::EnableWakeupEvents((TPowerState) aTargetState);
896 iPowerUpHandler->RequestWakeupEventNotification();
898 iTransStatus |= EPoweringDown;
900 return CDmHierarchy::RequestSystemTransition(aTargetState, aTraverseDirection, aMessage);
903 void CDmHierarchyPower::CompleteTransition(TInt aError)
908 __DS_TRACE((_L("CDmHierarchyPower::CompleteTransition() domain=0x%x"), iTransDomain->iId));
910 if (iTransDomain && aError == KErrCancel)
911 iPowerUpHandler->Cancel();
913 if (iTransStatus & EPoweringDown)
917 __DS_ASSERT(r==KErrNone);
918 __DS_TRACE((_L("CDmSvrManager::CompleteTransition() Calling FinaliseDrives")));
919 r=fs.FinaliseDrives();
920 __DS_TRACE((_L("CDmSvrManager::CompleteTransition() Finalise returned %d"),r));
924 __DS_ASSERT(iTransState != (TDmDomainState) EPwOff);
925 __DS_ASSERT(iPowerUpHandler->iStatus.Int() == KErrNone);
929 CDmHierarchy::CompleteTransition(aError);
934 void CDmHierarchyPower::PowerUp()
936 __DS_TRACE((_L("CDmHierarchyPower::RunL() Wakeup Event")));
937 __DS_ASSERT(iTransDomain);
939 Power::DisableWakeupEvents();
941 iTransStatus &= ~EPoweringDown;
942 iTransDomain->CancelTransition();
943 SetState((TDmDomainState) EPwActive);
944 RequestTransition(NULL);
948 //*********************************************************
950 //*********************************************************
952 CDmSvrManager* CDmSvrManager::New()
954 CDmSvrManager* self = new CDmSvrManager();
956 __DS_PANIC(KErrNoMemory);
961 CDmSvrManager::CDmSvrManager()
965 void CDmSvrManager::Construct()
967 // load the power hierarchy- Other hieratchies need to be loaded
968 // explicitly using RDmDomainManager::AddDomainHierarchy()
969 CDmHierarchy* hierarchy;
970 TInt r = BuildDomainTree(KDmHierarchyIdPower, hierarchy);
976 r = prop.Define(KUidDmPropertyCategory, KDmPropertyKeyInit, RProperty::EInt,
977 KAllowAllPolicy,KPowerMgmtPolicy);
981 prop.Set(KUidDmPropertyCategory, KDmPropertyKeyInit, ETrue);
984 TInt CDmSvrManager::BuildDomainTree(TDmHierarchyId aHierarchyId, CDmHierarchy*& aHierarchy)
989 // assume we have already checked that the hierarchy doesn't already exist
991 // Get the name of the policy Dll
992 // This will be "domainPolicy.dll" for the power hierarchy
993 // and "domainPolicy<n>.dll" for other hierarchies where <n> is the hierarchy ID.
995 // If the hierarchy ID is less than KMaxCriticalPolicyDll, load only from ROM
999 // is this policy "critical" i.e non-replaceable ?
1000 _LIT(KSysBin,"z:\\sys\\bin\\");
1001 // const TInt KMaxCriticalPolicyDll = 1000;
1002 // if (aHierarchyId < KMaxCriticalPolicyDll) // <-- cannot be false while aHierarchyId is a TUint8 (typedef'd to TDmHierarchyId)
1003 dllName.Append(KSysBin);
1005 dllName.Append(_L("domainPolicy"));
1006 if (aHierarchyId != KDmHierarchyIdPower)
1007 dllName.AppendNum(aHierarchyId);
1009 dllName.Append(_L(".dll"));
1011 TInt r = lib.Load(dllName);
1012 if (r == KErrNotFound)
1013 return KErrBadHierarchyId;
1014 else if (r != KErrNone)
1017 TLibraryFunction ordinal1 = lib.Lookup(EDmPolicyGetDomainSpecs);
1018 DmPolicyGetDomainSpecs getDomainSpecs = reinterpret_cast<DmPolicyGetDomainSpecs>(ordinal1);
1019 if (getDomainSpecs == NULL)
1020 r = KErrBadHierarchyId;
1022 TLibraryFunction ordinal2 = lib.Lookup(EDmPolicyRelease);
1023 DmPolicyRelease release = reinterpret_cast<DmPolicyRelease>(ordinal2);
1024 if (release == NULL)
1025 r = KErrBadHierarchyId;
1027 TLibraryFunction ordinal3 = lib.Lookup(EDmPolicyGetPolicy);
1028 DmPolicyGetPolicy getPolicy = reinterpret_cast<DmPolicyGetPolicy>(ordinal3);
1029 if (getPolicy == NULL)
1030 r = KErrBadHierarchyId;
1033 // get the domain spec for this hierarchy
1034 const TDmDomainSpec* spec = NULL;
1038 spec = (*getDomainSpecs)();
1040 r = KErrBadHierarchyId;
1043 TDmHierarchyPolicy hierarchyPolicy;
1046 r = (*getPolicy)(hierarchyPolicy);
1049 __DS_ASSERT(hierarchyPolicy.iPositiveTransitions < ETraverseMax);
1050 __DS_ASSERT(hierarchyPolicy.iNegativeTransitions < ETraverseMax);
1060 CDmHierarchy* hierarchy = CDmHierarchy::New(aHierarchyId, hierarchyPolicy);
1061 if (hierarchy == NULL)
1062 __DS_PANIC(KErrNoMemory);
1064 while (r == KErrNone && spec->iId != KDmIdNone)
1066 // make sure the domain doesn't already exist in this hierarchy
1067 CSvrDomain* domain = hierarchy->LookupDomain(spec->iId);
1070 r = KErrBadHierarchyId;
1074 domain = CSvrDomain::New(*hierarchy, *spec);
1075 __DS_ASSERT(domain);
1077 if (spec->iParentId == KDmIdNone)
1079 if (hierarchy->iRootDomain)
1081 r = KDmErrBadDomainSpec;
1084 hierarchy->iRootDomain = domain;
1088 CSvrDomain* parent = hierarchy->LookupDomain(spec->iParentId);
1091 r = KDmErrBadDomainSpec;
1094 parent->AddChild(domain);
1105 __DS_ASSERT(hierarchy->iRootDomain);
1106 iDomainHierarchies.Append(hierarchy);
1107 aHierarchy = hierarchy;
1120 CDmHierarchy* CDmSvrManager::LookupHierarchy(TDmHierarchyId aHierarchyId)
1123 // need to find the correct hierarchy first
1124 TInt len = iDomainHierarchies.Count();
1126 CDmHierarchy* hierarchy = NULL;
1127 for (TInt n=0; n<len; n++)
1129 if (iDomainHierarchies[n]->iHierarchyId == aHierarchyId)
1131 hierarchy = iDomainHierarchies[n];
1140 TInt CDmSvrManager::LookupDomain(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, CSvrDomain*& aDomain)
1142 // need to find the correct hierarchy first
1143 CDmHierarchy* hierarchy = LookupHierarchy(aHierarchyId);
1144 if (hierarchy == NULL)
1145 return KErrBadHierarchyId;
1147 aDomain = hierarchy->LookupDomain(aDomainId);
1148 if (aDomain == NULL)
1149 return KDmErrBadDomainId;
1154 CSession2* CDmManagerServer::NewSessionL(const TVersion&, const RMessage2& aMessage) const
1157 // If the client does not have ECapabilityPowerMgmt capability, then it has no
1158 // right to make this request. Blow it up.
1159 if (!KPowerMgmtPolicy.CheckPolicy(aMessage))
1162 User::Leave(KErrPermissionDenied);
1166 return new CDmManagerSession();
1169 CSession2* CDmManagerServer::NewSessionL(const TVersion&) const
1171 __DS_PANIC(KErrGeneral);
1175 CDmManagerSession::CDmManagerSession()
1178 CDmManagerSession::~CDmManagerSession()
1180 if (iHierarchy && iHierarchy->iControllerSession == this)
1181 iHierarchy->iControllerSession = NULL;
1182 if (iHierarchy && iHierarchy->iObserverSession == this)
1183 iHierarchy->iObserverSession = NULL;
1186 class MyMessage : public RMessage2
1189 TInt* ArgRef(TInt i)
1190 { return &iArgs[i]; }
1193 void CDmManagerSession::ServiceL(const RMessage2& aMessage)
1196 CDmSvrManager* manager = ((CDmManagerServer*) Server()) -> iManager;
1198 // Check client has ECapabilityPowerMgmt capability
1200 if (!KPowerMgmtPolicy.CheckPolicy(aMessage))
1202 aMessage.Complete(KErrPermissionDenied);
1206 switch (aMessage.Function())
1208 case EDmHierarchyAdd:
1211 TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
1213 CDmHierarchy* hierarchy = manager->LookupHierarchy(hierarchyId);
1214 if (hierarchy == NULL)
1215 r = manager->BuildDomainTree(hierarchyId, hierarchy);
1216 aMessage.Complete(r);
1220 case EDmHierarchyJoin:
1223 TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
1225 iHierarchy = manager->LookupHierarchy(hierarchyId);
1226 if (iHierarchy == NULL)
1227 r = KErrBadHierarchyId;
1231 // is the hierarchy already in use ?
1232 if (iHierarchy->iControllerSession)
1235 iHierarchy->iControllerSession = this;
1238 aMessage.Complete(r);
1242 case EDmRequestSystemTransition:
1243 if (iHierarchy==NULL)
1245 aMessage.Complete(KErrBadHierarchyId);
1248 if (iHierarchy->iTransDomain)
1250 aMessage.Complete(KDmErrBadSequence);
1254 r = iHierarchy->RequestSystemTransition(
1255 (TDmDomainState) aMessage.Int0(),
1256 (TDmTraverseDirection) aMessage.Int1(),
1260 aMessage.Complete(r);
1263 case EDmRequestDomainTransition:
1264 if (iHierarchy==NULL)
1266 aMessage.Complete(KErrBadHierarchyId);
1269 if (iHierarchy->iTransDomain)
1271 aMessage.Complete(KDmErrBadSequence);
1274 r = iHierarchy->RequestDomainTransition(
1275 (TDmDomainId) aMessage.Int0(),
1276 (TDmDomainState) aMessage.Int1(),
1277 (TDmTraverseDirection) aMessage.Int2(),
1281 aMessage.Complete(r);
1284 case EDmGetTransitionFailureCount:
1286 if (iHierarchy==NULL)
1288 aMessage.Complete(KErrBadHierarchyId);
1291 TInt failureCount = iHierarchy->iTransitionFailures.Count();
1292 aMessage.Complete(failureCount);
1296 case EDmGetTransitionFailures:
1298 if (iHierarchy==NULL)
1300 aMessage.Complete(KErrBadHierarchyId);
1303 TInt failureCount = iHierarchy->iTransitionFailures.Count();
1304 TInt clientFailureSize = aMessage.GetDesMaxLength(0);
1305 TInt clientFailureCount = clientFailureSize / sizeof(TTransitionFailure);
1306 __DS_ASSERT( (clientFailureSize % sizeof(TTransitionFailure)) == 0);
1307 __DS_ASSERT(failureCount >= clientFailureCount);
1309 HBufC8* hBuf = HBufC8::New(clientFailureSize);
1312 aMessage.Complete(KErrNoMemory);
1315 TPtr8 pBuf = hBuf->Des();
1317 for (TInt i=0; i<clientFailureCount; i++)
1319 TPtrC8 ptr = TPtrC8((TUint8*) &iHierarchy->iTransitionFailures[i], sizeof(TTransitionFailure));
1322 r = aMessage.Write(0, pBuf);
1325 aMessage.Complete(r);
1329 case EDmCancelTransition:
1330 if (iHierarchy == NULL)
1332 aMessage.Complete(KErrBadHierarchyId);
1335 iHierarchy->CompleteTransition(KErrCancel);
1336 if (iHierarchy->iObserverStarted)
1338 iHierarchy->CompleteNotification(KErrCancel);
1339 iHierarchy->StopObserver();
1341 aMessage.Complete(KErrNone);
1343 case EDmObserverCancel:
1344 if (iHierarchy == NULL)
1346 aMessage.Complete(KErrBadHierarchyId);
1349 if(!iHierarchy->iObserverSession)
1351 aMessage.Complete(KDmErrBadSequence);
1354 if (iHierarchy->iObserverStarted)
1356 iHierarchy->CompleteNotification(KErrCancel);
1357 iHierarchy->StopObserver();
1359 aMessage.Complete(KErrNone);
1362 case EDmObserverJoin:
1364 TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
1366 iHierarchy = manager->LookupHierarchy(hierarchyId);
1367 if(iHierarchy==NULL)
1369 aMessage.Complete(KErrBadHierarchyId);
1372 if(iHierarchy->iObserverSession)
1374 aMessage.Complete(KDmErrBadSequence);
1377 iHierarchy->iTransitions.Reset();
1378 iHierarchy->iObserverSession = this;
1379 aMessage.Complete(KErrNone);
1383 case EDmObserverStart:
1385 if (iHierarchy==NULL)
1387 aMessage.Complete(KErrBadHierarchyId);
1391 if(iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
1393 aMessage.Complete(KDmErrBadSequence);
1396 TInt ret= iHierarchy->StartObserver((TDmDomainId)aMessage.Int0(),(TDmNotifyType)aMessage.Int1());
1397 aMessage.Complete(ret);
1401 case EDmObserverNotify:
1403 if (iHierarchy==NULL)
1405 aMessage.Complete(KErrBadHierarchyId);
1408 if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
1410 aMessage.Complete(KDmErrBadSequence);
1413 // Check to see if we have any events stored
1414 // If so, then notify the client
1415 if(iHierarchy->iTransitions.Count()>0)
1417 aMessage.Complete(KErrNone);
1420 // No events are stored. complete this message later
1421 iHierarchy->SetNotifyMessage(&aMessage);
1425 case EDmObserverEventCount:
1427 if (iHierarchy==NULL)
1429 aMessage.Complete(KErrBadHierarchyId);
1432 if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
1434 aMessage.Complete(KDmErrBadSequence);
1437 TInt count = iHierarchy->iTransitions.Count();
1438 aMessage.Complete(count);
1442 case EDmObserverGetEvent:
1444 if (iHierarchy==NULL)
1446 aMessage.Complete(KErrBadHierarchyId);
1449 if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
1451 aMessage.Complete(KDmErrBadSequence);
1454 TInt transitionCount = iHierarchy->iTransitions.Count();
1455 TInt clientTransitionSize = aMessage.GetDesMaxLength(0);
1456 TInt clientTransitionCount = clientTransitionSize / sizeof(TTransInfo);
1457 __DS_ASSERT( (clientTransitionSize % sizeof(TTransInfo)) == 0);
1458 __DS_ASSERT(transitionCount >= clientTransitionCount);
1460 HBufC8* hBuf = HBufC8::New(clientTransitionSize);
1463 aMessage.Complete(KErrNoMemory);
1466 TPtr8 pBuf = hBuf->Des();
1468 for (TInt i=0; i<clientTransitionCount; i++)
1470 TPtrC8 ptr = TPtrC8((TUint8*) &iHierarchy->iTransitions[0], sizeof(TTransInfo));
1472 iHierarchy->iTransitions.Remove(0);
1474 r = aMessage.Write(0, pBuf);
1477 aMessage.Complete(r);
1480 case EDmObserveredCount:
1482 if (iHierarchy==NULL)
1484 aMessage.Complete(KErrBadHierarchyId);
1487 if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
1489 aMessage.Complete(KDmErrBadSequence);
1492 aMessage.Complete(iHierarchy->iObservedChildren);
1496 aMessage.Complete(KDmErrBadRequest);
1501 CSession2* CDmDomainServer::NewSessionL(const TVersion&, const RMessage2&) const
1504 return new CDmDomainSession();
1507 CSession2* CDmDomainServer::NewSessionL(const TVersion&) const
1509 __DS_PANIC(KErrGeneral);
1513 CDmDomainSession::~CDmDomainSession()
1516 iDomain->CompleteMemberTransition(KErrNone);
1518 iDomain->Detach(this);
1521 void CDmDomainSession::ServiceL(const RMessage2& aMessage)
1524 CDmSvrManager* manager = ((CDmManagerServer*) Server()) -> iManager;
1526 switch (aMessage.Function())
1530 TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
1531 TDmDomainId domainId = (TDmDomainId) aMessage.Int1();
1533 r = manager->LookupDomain(hierarchyId, domainId, iDomain);
1538 // Check client has capability to join the domain
1539 if (!iDomain->iJoinPolicy.CheckPolicy(aMessage))
1541 r = KErrPermissionDenied;
1546 iDomain->Attach(this);
1550 case EDmStateRequestTransitionNotification:
1551 iNotificationEnabled = ETrue;
1554 case EDmStateCancelTransitionNotification:
1555 iNotificationEnabled = EFalse;
1558 case EDmStateAcknowledge:
1560 TInt propValue = aMessage.Int0();
1561 TInt error = aMessage.Int1();
1567 if (iPending && iDomain->CheckPropValue(propValue))
1570 iDomain->CompleteMemberTransition(error);
1575 r = KDmErrBadRequest;
1578 aMessage.Complete(r);
1584 CTrapCleanup* cleanupStack = CTrapCleanup::New();
1586 __DS_PANIC(KErrNoMemory);
1588 CActiveScheduler* sched = new CActiveScheduler();
1590 __DS_PANIC(KErrNoMemory);
1592 CActiveScheduler::Install(sched);
1594 CDmSvrManager* mngr = CDmSvrManager::New();
1597 CDmManagerServer* msrv = new CDmManagerServer(mngr);
1599 __DS_PANIC(KErrNoMemory);
1601 TInt r=msrv->Start(KDmManagerServerNameLit);
1605 CDmDomainServer* dsrv = new CDmDomainServer(mngr);
1607 __DS_PANIC(KErrNoMemory);
1609 r=dsrv->Start(KDmDomainServerNameLit);
1613 CActiveScheduler::Start();