userlibandfileserver/domainmgr/src/domainsrv.cpp
changeset 9 96e5fb8b040d
equal deleted inserted replaced
-1:000000000000 9:96e5fb8b040d
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // domain\src\domainsrv.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <e32debug.h>
       
    19 #include <e32base.h>
       
    20 #include <e32base_private.h>
       
    21 #include <e32property.h>
       
    22 #include <f32file.h>
       
    23 
       
    24 #include <domainpolicy.h>
       
    25 #include "domainsrv.h"
       
    26 
       
    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))
       
    29 
       
    30 //#define __DS_DEBUG
       
    31 
       
    32 #ifdef __DS_DEBUG
       
    33 #define __DS_TRACE(s) RDebug::Print s
       
    34 #else
       
    35 #define __DS_TRACE(s)
       
    36 #endif
       
    37 
       
    38 static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
       
    39 static _LIT_SECURITY_POLICY_C1(KPowerMgmtPolicy,ECapabilityPowerMgmt);
       
    40 
       
    41 // forward refs
       
    42 class CSvrDomain;
       
    43 class CDmHierarchy;
       
    44 class CPowerUpHandler;
       
    45 class CDmHierarchyPower;
       
    46 class CDmSvrManager;
       
    47 class CDmDomainServer;
       
    48 class CDmDomainSession;
       
    49 class CDmManagerServer;
       
    50 class CDmManagerSession;
       
    51 
       
    52 
       
    53 
       
    54 // CSvrDomain
       
    55 class CSvrDomain : public CTimer
       
    56 	{
       
    57 public: 
       
    58 	static CSvrDomain* New(CDmHierarchy& aHierarchy, const TDmDomainSpec&);
       
    59 
       
    60 	// from CTimer
       
    61 	void RunL();
       
    62 
       
    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();
       
    73 
       
    74 private:
       
    75 	CSvrDomain(CDmHierarchy& aHierarchy, const TDmDomainSpec*);
       
    76 	void Construct(const TDmDomainSpec* spec);
       
    77 
       
    78 	void RequestMembersTransition();
       
    79 	void RequestChildrenTransition();
       
    80 	void MembersTransitionDone();
       
    81 	void ChildrenTransitionDone();
       
    82 	void CompleteDomainTransition();
       
    83 
       
    84 private:
       
    85 	CDmHierarchy&		iHierarchy;
       
    86 	CSvrDomain*			iParent;
       
    87 	CSvrDomain*			iPeer;
       
    88 	CSvrDomain*			iChild;
       
    89 	RProperty			iProperty;
       
    90 	CDmDomainSession*	iSessions;
       
    91 	TUint16				iChildrenCount;
       
    92 	TUint16				iTransCount;
       
    93 	TTimeIntervalMicroSeconds32	iTransTimeBudget;
       
    94 
       
    95 public:
       
    96 	const TSecurityPolicy	iJoinPolicy;
       
    97 	TBool iIsObserved;
       
    98 	TDmDomainId			iId;
       
    99 	};
       
   100 
       
   101 
       
   102 // CDmHierarchy
       
   103 class CDmHierarchy : public CBase
       
   104 	{
       
   105 public:
       
   106 	static CDmHierarchy* New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
       
   107 
       
   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();
       
   115 	void StopObserver();
       
   116 	virtual TInt RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
       
   117 	virtual void CompleteTransition(TInt aError);
       
   118 	virtual void NotifyCompletion(TInt aReason);
       
   119 	
       
   120 protected:
       
   121 	CDmHierarchy(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
       
   122 	void SetState(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection = ETraverseDefault);
       
   123 
       
   124 private:
       
   125 	RMessagePtr2	iTransMessagePtr;
       
   126 	RMessagePtr2	iObsvrMessagePtr;
       
   127 	CSvrDomain*		iObservedDomain;
       
   128 	TBool			iOutstandingNotification;
       
   129 public:
       
   130 	TDmHierarchyId	iHierarchyId;
       
   131 	CSvrDomain*		iRootDomain;
       
   132 	CSvrDomain*		iTransDomain;
       
   133 	TInt			iTransPropValue;
       
   134 	TDmDomainState	iTransState;
       
   135 	TDmTraverseDirection	iTraverseDirection;
       
   136 	TUint8			iTransId;
       
   137 	CDmManagerSession* iControllerSession;	// only one controller per hierarchy
       
   138 	TDmHierarchyPolicy iPolicy;
       
   139 	RArray<TTransitionFailure> iTransitionFailures;
       
   140 	
       
   141 	// observer stuff
       
   142 	TBool			iObserverStarted;
       
   143 	TDmNotifyType	iNotifyType;
       
   144 	RArray<TTransInfo>	iTransitions;
       
   145 	CDmManagerSession* iObserverSession;	// only one observer per hierarchy
       
   146 	TInt			iObservedChildren;
       
   147 	};
       
   148 
       
   149 
       
   150 // CPowerUpHandler
       
   151 // Active object used to receive power-up notifications 
       
   152 // from the Kernel-level power manager
       
   153 class CPowerUpHandler : public CActive
       
   154 	{
       
   155 public: 
       
   156 	static CPowerUpHandler* New(CDmHierarchyPower& aHierarchyPower);
       
   157 	
       
   158 	// from CActive
       
   159 	void RunL();
       
   160 	void DoCancel();
       
   161 
       
   162 	void RequestWakeupEventNotification();
       
   163 	void Cancel();
       
   164 
       
   165 private:
       
   166 	CPowerUpHandler(CDmHierarchyPower& aHierarchyPower);
       
   167 	void Construct();
       
   168 
       
   169 private:
       
   170 	CDmHierarchyPower& iHierarchyPower;
       
   171 	};
       
   172 
       
   173 
       
   174 // CDmHierarchyPower
       
   175 // CDmHierarchy-derived class 
       
   176 // Interfaces to the Kernel-level power manager
       
   177 class CDmHierarchyPower : public CDmHierarchy
       
   178 	{
       
   179 public:
       
   180 	static CDmHierarchyPower* New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
       
   181 
       
   182 	// from CDmHierarchy
       
   183 	virtual TInt RequestSystemTransition(TDmDomainState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
       
   184 	virtual void CompleteTransition(TInt aError);
       
   185 	virtual void NotifyCompletion(TInt aReason);
       
   186 
       
   187 	void PowerUp();	// called from CPowerUpHandler
       
   188 
       
   189 private:
       
   190 	CDmHierarchyPower(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
       
   191 	void Construct();
       
   192 
       
   193 private:
       
   194 	enum 
       
   195 		{
       
   196 		EPoweringDown	= 0x01,
       
   197 		};
       
   198 	TUint8			iTransStatus;
       
   199 	CPowerUpHandler* iPowerUpHandler;
       
   200 	};
       
   201 
       
   202 
       
   203 // CDmSvrManager
       
   204 class CDmSvrManager : public CBase
       
   205 	{
       
   206 public:
       
   207 	static CDmSvrManager* New();
       
   208 
       
   209 	TInt BuildDomainTree(TDmHierarchyId aHierarchyId, CDmHierarchy*& aHierarchy);
       
   210 	CDmHierarchy* LookupHierarchy(TDmHierarchyId aHierarchyId);
       
   211 	TInt LookupDomain(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, CSvrDomain*& aDomain);
       
   212 
       
   213 private:
       
   214 	CDmSvrManager();
       
   215 	void Construct();
       
   216 
       
   217 private:
       
   218 	RPointerArray<CDmHierarchy> iDomainHierarchies;
       
   219 	};
       
   220 
       
   221 // CDmDomainServer
       
   222 class CDmDomainServer : public CServer2
       
   223 	{
       
   224 public: 
       
   225 	// from CServer2
       
   226 	CSession2* NewSessionL(const TVersion& aVer) const;
       
   227 	CSession2* NewSessionL(const TVersion& aVer, const RMessage2& aMessage) const;
       
   228 
       
   229 	CDmDomainServer(CDmSvrManager* aManager) : CServer2(CActive::EPriorityStandard), iManager(aManager)
       
   230 		{}
       
   231 
       
   232 public:
       
   233 	CDmSvrManager*	iManager;
       
   234 	};
       
   235 
       
   236 // CDmDomainSession
       
   237 class CDmDomainSession : public CSession2
       
   238 	{
       
   239 public: 
       
   240 	// from CBase
       
   241 	~CDmDomainSession();
       
   242 
       
   243 	// from CSession2
       
   244 	void ServiceL(const RMessage2& aMessage);
       
   245 
       
   246 private:
       
   247 	CSvrDomain*			iDomain;
       
   248 
       
   249 public:
       
   250 	CDmDomainSession*	iNext;
       
   251 	TUint8				iPending;
       
   252 	TBool				iNotificationEnabled;
       
   253 	};
       
   254 
       
   255 class CDmManagerServer : public CServer2
       
   256 	{
       
   257 public: 
       
   258 	// from CServer2
       
   259 	CSession2* NewSessionL(const TVersion& aVer) const;
       
   260 	CSession2* NewSessionL(const TVersion& aVer, const RMessage2&) const;
       
   261 
       
   262 	CDmManagerServer(CDmSvrManager* aManager) : CServer2(CActive::EPriorityStandard), iManager(aManager)
       
   263 		{}
       
   264 	CDmSvrManager*	iManager;
       
   265 	};
       
   266 
       
   267 class CDmManagerSession : public CSession2
       
   268 	{
       
   269 public: 
       
   270 	// from CBase
       
   271 	~CDmManagerSession();
       
   272 	
       
   273 	// from CSession2
       
   274 	void ServiceL(const RMessage2& aMessage);
       
   275 
       
   276 	CDmManagerSession();
       
   277 private:
       
   278 	CDmHierarchy* iHierarchy;	// not owned
       
   279 	};
       
   280 
       
   281 
       
   282 
       
   283 
       
   284 //*********************************************************
       
   285 // TTransitionFailure
       
   286 //*********************************************************
       
   287 /**
       
   288 @internalTechnology
       
   289 
       
   290 Constructor for transition failure info.
       
   291 
       
   292 @param aDomainID	Id of the domain of interest
       
   293 @param aError		error code of transition	 
       
   294 */
       
   295 TTransitionFailure::TTransitionFailure(TDmDomainId aDomainId, TInt aError) :
       
   296 	iDomainId(aDomainId), iError(aError)
       
   297 	{
       
   298 	}
       
   299 
       
   300 //*********************************************************
       
   301 // TTransInfo
       
   302 //*********************************************************
       
   303 
       
   304 /**
       
   305 @internalTechnology
       
   306 
       
   307 Constructor for transition failure info.
       
   308 
       
   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	 
       
   312 */
       
   313 TTransInfo::TTransInfo(TDmDomainId aDomainId, TDmDomainState aState, TInt aError) :
       
   314 	iDomainId(aDomainId), iState(aState), iError(aError)
       
   315 	{
       
   316 	}
       
   317 
       
   318 //*********************************************************
       
   319 // CSvrDomain
       
   320 //*********************************************************
       
   321 
       
   322 
       
   323 CSvrDomain::CSvrDomain(CDmHierarchy& aHierarchy, const TDmDomainSpec* spec)
       
   324 	:	CTimer(CActive::EPriorityStandard), 
       
   325 		iHierarchy(aHierarchy),
       
   326 		iTransTimeBudget(spec->iTimeBudgetUs),
       
   327 		iJoinPolicy(spec->iJoinPolicy),
       
   328 		iId(spec->iId)
       
   329 	{}
       
   330 
       
   331 CSvrDomain* CSvrDomain::New(CDmHierarchy& aHierarchy, const TDmDomainSpec& aSpec)
       
   332 	{
       
   333 
       
   334 	CSvrDomain* self = new CSvrDomain(aHierarchy, &aSpec);
       
   335 
       
   336 	if (!self)
       
   337 		__DS_PANIC(KErrNoMemory);
       
   338 	self->Construct(&aSpec);
       
   339 	return self;
       
   340 	}
       
   341 
       
   342 void CSvrDomain::Construct(const TDmDomainSpec* spec)
       
   343 	{
       
   344 	TInt r = iProperty.Define(
       
   345 		KUidDmPropertyCategory, 
       
   346 		DmStatePropertyKey(iHierarchy.iHierarchyId, iId), 
       
   347 		RProperty::EInt,
       
   348 		KAllowAllPolicy,KPowerMgmtPolicy);
       
   349 
       
   350 	if (r != KErrNone)
       
   351 		__DS_PANIC(r);
       
   352 	
       
   353 	r = iProperty.Attach(KUidDmPropertyCategory, DmStatePropertyKey(
       
   354 		iHierarchy.iHierarchyId, 
       
   355 		iId));
       
   356 
       
   357 	if (r != KErrNone)
       
   358 		__DS_PANIC(r);
       
   359 
       
   360 	r = iProperty.Set(DmStatePropertyValue(0, spec->iInitState));
       
   361 	if (r != KErrNone)
       
   362 		__DS_PANIC(r);
       
   363 
       
   364 	TRAP(r, CTimer::ConstructL());
       
   365 	if (r != KErrNone)
       
   366 		__DS_PANIC(r);
       
   367 	CActiveScheduler::Add(this);
       
   368 	}
       
   369 
       
   370 void CSvrDomain::Attach(CDmDomainSession* aSession)
       
   371 	{
       
   372 	aSession->iNext = iSessions;
       
   373 	iSessions = aSession;
       
   374 	}
       
   375 
       
   376 void CSvrDomain::Detach(CDmDomainSession* aSession)
       
   377 	{
       
   378 	CDmDomainSession** prevp = &iSessions;
       
   379 	while (*prevp != aSession)
       
   380 		{
       
   381 		prevp = &((*prevp)->iNext);
       
   382 		__DS_ASSERT(*prevp);
       
   383 		}
       
   384 	*(prevp) = aSession->iNext;
       
   385 	}
       
   386 
       
   387 void CSvrDomain::AddChild(CSvrDomain* aChild)
       
   388 	{
       
   389 	++iChildrenCount;
       
   390 	aChild->iParent = this;
       
   391 	if(iIsObserved)
       
   392 		aChild->iIsObserved=ETrue;
       
   393 	// Insert the child in the list of its peers
       
   394 	aChild->iPeer = iChild;
       
   395 	iChild = aChild;
       
   396 	}
       
   397 
       
   398 CSvrDomain* CSvrDomain::Lookup(TDmDomainId aDomainId)
       
   399 	{
       
   400 	if (iId == aDomainId)
       
   401 		return this;
       
   402 
       
   403 	CSvrDomain* child = iChild;
       
   404 	while (child)
       
   405 		{
       
   406 		CSvrDomain* domain = child->Lookup(aDomainId);
       
   407 		if (domain)
       
   408 			return domain;
       
   409 		child = child->iPeer;
       
   410 		}
       
   411 	return NULL;
       
   412 	}
       
   413 
       
   414 TBool CSvrDomain::CheckPropValue(TInt aPropValue)
       
   415 	{ return iHierarchy.iTransPropValue == aPropValue; }
       
   416 
       
   417 void CSvrDomain::RequestMembersTransition()
       
   418 	{
       
   419 	__DS_TRACE((_L("CSvrDomain::RequestMembersTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
       
   420 	__DS_ASSERT(iTransCount == 0);
       
   421 	
       
   422 	for(CDmDomainSession* s = iSessions; s; s = s->iNext)
       
   423 		if (s->iNotificationEnabled)
       
   424 			{
       
   425 			++iTransCount;
       
   426 			s->iPending = ETrue;
       
   427 			// notifications will be disabled until the client makes another 
       
   428 			// call to RDmDomain::RequestTransitionNotification()
       
   429 			s->iNotificationEnabled = EFalse;
       
   430 			}
       
   431 
       
   432 	if(iIsObserved)
       
   433 		{
       
   434 		if((iHierarchy.iNotifyType&EDmNotifyTransRequest)==EDmNotifyTransRequest)
       
   435 			{
       
   436 			TTransInfo transInfo(iId,State(),KDmErrOutstanding);
       
   437 			iHierarchy.iTransitions.Append(transInfo);
       
   438 			if(iHierarchy.OutstandingNotification())
       
   439 					iHierarchy.CompleteNotification(KErrNone);	
       
   440 			}
       
   441 		}
       
   442 	if (iTransCount > 0)
       
   443 		CTimer::After(iTransTimeBudget);
       
   444 	iProperty.Set(iHierarchy.iTransPropValue);
       
   445 	if (iTransCount == 0)
       
   446 		MembersTransitionDone();
       
   447 	}
       
   448 
       
   449 
       
   450 void CSvrDomain::RequestChildrenTransition()
       
   451 	{
       
   452 	__DS_TRACE((_L("CSvrDomain::RequestChildrenTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
       
   453 	__DS_ASSERT(iTransCount == 0);
       
   454 	iTransCount = iChildrenCount;
       
   455 	if (iTransCount)
       
   456 		{
       
   457 		CSvrDomain* child = iChild;
       
   458 		__DS_ASSERT(child);
       
   459 		do	{
       
   460 			child->RequestDomainTransition();
       
   461 			child = child->iPeer;
       
   462 			}
       
   463 		while(child);
       
   464 		}
       
   465 	else
       
   466 		ChildrenTransitionDone();
       
   467 	}
       
   468 
       
   469 void CSvrDomain::RequestDomainTransition()
       
   470 	{
       
   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();
       
   476 	else
       
   477 		RequestMembersTransition();
       
   478 	}
       
   479 		
       
   480 void CSvrDomain::MembersTransitionDone()
       
   481 	{
       
   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();
       
   486 	else
       
   487 		RequestChildrenTransition();
       
   488 	}
       
   489 
       
   490 void CSvrDomain::ChildrenTransitionDone()
       
   491 	{
       
   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();
       
   496 	else
       
   497 		CompleteDomainTransition();
       
   498 	}
       
   499 
       
   500 void CSvrDomain::CompleteMemberTransition(TInt aError)
       
   501 	{
       
   502 	__DS_TRACE((_L("CSvrDomain::CompleteMemberTransition() hierarchy=%d, domain=0x%x, aError = %d"), iHierarchy.iHierarchyId, iId, aError));
       
   503 	__DS_ASSERT(iTransCount);
       
   504 
       
   505 	if (aError)
       
   506 		{
       
   507 		// Add a transition failure to the array
       
   508 		TTransitionFailure failure(iId, aError);
       
   509 		iHierarchy.iTransitionFailures.Append(failure);
       
   510 		
       
   511 		if(iIsObserved)
       
   512 			{
       
   513 				if((iHierarchy.iNotifyType&EDmNotifyFail)==EDmNotifyFail)
       
   514 				{
       
   515 				TTransInfo transInfo(iId,State(),aError);
       
   516 				iHierarchy.iTransitions.Append(transInfo);
       
   517 				if(iHierarchy.OutstandingNotification())
       
   518 					iHierarchy.CompleteNotification(KErrNone);
       
   519 				}
       
   520 			}
       
   521 		// examine the failure policy to work out what to do
       
   522 		if (iHierarchy.iPolicy.iFailurePolicy == ETransitionFailureStop)
       
   523 			{
       
   524 			iHierarchy.CompleteTransition(aError);
       
   525 			return;
       
   526 			}
       
   527 		}
       
   528 	else if(iIsObserved)
       
   529 			{
       
   530 				if((iHierarchy.iNotifyType&EDmNotifyPass) == EDmNotifyPass)
       
   531 				{
       
   532 				TTransInfo transInfo(iId,State(),aError);
       
   533 				iHierarchy.iTransitions.Append(transInfo);
       
   534 				if(iHierarchy.OutstandingNotification())
       
   535 					iHierarchy.CompleteNotification(KErrNone);
       
   536 				}
       
   537 			}
       
   538 
       
   539 	if (--iTransCount == 0)
       
   540 		{
       
   541 		CTimer::Cancel();
       
   542 		MembersTransitionDone();
       
   543 		}
       
   544 	}
       
   545 
       
   546 void CSvrDomain::RunL()
       
   547 	{ // Timer expired 
       
   548 	__DS_TRACE((_L("CSvrDomain::RunL() Members transition timeout hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
       
   549 
       
   550 	// Add a transition failure to the array
       
   551 	TTransitionFailure failure(iId,KErrTimedOut);
       
   552 	iHierarchy.iTransitionFailures.Append(failure);
       
   553 
       
   554 
       
   555 	// examine the failure policy to work out what to do
       
   556 	if (iHierarchy.iPolicy.iFailurePolicy == ETransitionFailureStop)
       
   557 		{
       
   558 		iHierarchy.CompleteTransition(KErrTimedOut);
       
   559 		return;
       
   560 		}
       
   561 
       
   562 	if (iTransCount)
       
   563 		{ // Complete transition of all members
       
   564 		CDmDomainSession* session = iSessions;
       
   565 		while (session)
       
   566 			{
       
   567 			session->iPending = EFalse;
       
   568 			session = session->iNext;
       
   569 			}
       
   570 		iTransCount = 0;
       
   571 		MembersTransitionDone();
       
   572 		}
       
   573 	}
       
   574 
       
   575 
       
   576 void CSvrDomain::CompleteDomainTransition()
       
   577 	{
       
   578 	__DS_TRACE((_L("CSvrDomain::CompleteDomainTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
       
   579 	__DS_ASSERT(iTransCount == 0);
       
   580 	if (iHierarchy.iTransDomain == this)
       
   581 		{
       
   582 		const TInt err = (iHierarchy.iTransitionFailures.Count() > 0)? 
       
   583 			iHierarchy.iTransitionFailures[0].iError : KErrNone;
       
   584 		iHierarchy.CompleteTransition(err);
       
   585 		}
       
   586 	else
       
   587 		{
       
   588 		__DS_ASSERT(iParent);
       
   589 		__DS_ASSERT(iParent->iTransCount);
       
   590 		if (--iParent->iTransCount == 0)
       
   591 			iParent->ChildrenTransitionDone();
       
   592 		}
       
   593 	}
       
   594 
       
   595 void CSvrDomain::CancelTransition()
       
   596 	{
       
   597 	__DS_TRACE((_L("CSvrDomain::CancelTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
       
   598 	CTimer::Cancel();
       
   599 	CSvrDomain* child = iChild;
       
   600 	while (child)
       
   601 		{
       
   602 		child->CancelTransition();
       
   603 		child = child->iPeer;
       
   604 		}
       
   605 	CDmDomainSession* session = iSessions;
       
   606 	while (session)
       
   607 		{
       
   608 		session->iPending = EFalse;
       
   609 		session = session->iNext;
       
   610 		}
       
   611 	iTransCount = 0;
       
   612 	}
       
   613 
       
   614 void CSvrDomain::SetObserver(TBool aSet)
       
   615 	{
       
   616 	iIsObserved=aSet;
       
   617 	if(aSet)
       
   618 		{
       
   619 		iHierarchy.iObservedChildren++;
       
   620 		}
       
   621 	else 
       
   622 		{
       
   623 		// this should be zero at the end
       
   624 		iHierarchy.iObservedChildren--;
       
   625 		}
       
   626 	if(iChildrenCount!=0)
       
   627 		{
       
   628 		CSvrDomain* domain=iChild;
       
   629 		do	{
       
   630 			domain->SetObserver(aSet);
       
   631 			domain = domain->iPeer;
       
   632 			}
       
   633 		while(domain);
       
   634 		}
       
   635 	}
       
   636 
       
   637 TDmDomainState CSvrDomain::State()
       
   638 	{
       
   639 	TInt value;
       
   640 	iProperty.Get(value);
       
   641 	return DmStateFromPropertyValue(value);
       
   642 	}
       
   643 
       
   644 //*********************************************************
       
   645 // CDmHierarchy
       
   646 //*********************************************************
       
   647 
       
   648 CDmHierarchy* CDmHierarchy::New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy)
       
   649 	{
       
   650 	CDmHierarchy* self;
       
   651 	
       
   652 	if (aHierarchyId == KDmHierarchyIdPower)
       
   653 		self = CDmHierarchyPower::New(aHierarchyId, aPolicy);
       
   654 	else 
       
   655 		self = new CDmHierarchy(aHierarchyId, aPolicy);
       
   656 
       
   657 	if (!self)
       
   658 		__DS_PANIC(KErrNoMemory);
       
   659 
       
   660 	return self;
       
   661 	}
       
   662 
       
   663 CDmHierarchy::CDmHierarchy(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy) :
       
   664 	iOutstandingNotification(EFalse),
       
   665 	iHierarchyId(aHierarchyId),
       
   666 	iPolicy(aPolicy)
       
   667 	{
       
   668 	iTransitionFailures.Reset();
       
   669 	}
       
   670 
       
   671 CSvrDomain* CDmHierarchy::LookupDomain(TDmDomainId aDomainId)
       
   672 	{
       
   673 	return iRootDomain ? iRootDomain->Lookup(aDomainId) : NULL;
       
   674 	}
       
   675 
       
   676 void CDmHierarchy::RequestTransition(const RMessage2* aMessage)
       
   677 	{
       
   678 	// reset the array of transition failures
       
   679 	iTransitionFailures.Reset();
       
   680 
       
   681 	if (aMessage)
       
   682 		iTransMessagePtr = *aMessage;
       
   683 	iTransPropValue = DmStatePropertyValue(++iTransId, iTransState);
       
   684 
       
   685 	iTransDomain->RequestDomainTransition();
       
   686 	}
       
   687 
       
   688 
       
   689 TInt CDmHierarchy::StartObserver(TDmDomainId aDomainId,TDmNotifyType aNotifyType)
       
   690 	{
       
   691 	iObservedDomain = LookupDomain(aDomainId);
       
   692 		
       
   693 	if(iObservedDomain==NULL)
       
   694 		return KDmErrBadDomainId;
       
   695 	
       
   696 
       
   697 	iObservedDomain->SetObserver(ETrue);
       
   698 	iNotifyType=aNotifyType;
       
   699 	iObserverStarted=ETrue;
       
   700 	return KErrNone;
       
   701 	}
       
   702 
       
   703 void CDmHierarchy::SetNotifyMessage(const RMessage2* aMessage)
       
   704 	{
       
   705 	if (aMessage)
       
   706 		{
       
   707 		iObsvrMessagePtr = *aMessage;
       
   708 		iOutstandingNotification=ETrue;
       
   709 		}		
       
   710 	}
       
   711 
       
   712 TBool CDmHierarchy::OutstandingNotification()
       
   713 	{
       
   714 	return iOutstandingNotification;
       
   715 	}
       
   716 
       
   717 void CDmHierarchy::CompleteNotification(TInt aError)
       
   718 	{
       
   719 	if(iOutstandingNotification)
       
   720 		{
       
   721 		iObsvrMessagePtr.Complete(aError);
       
   722 		iOutstandingNotification=EFalse;
       
   723 		}
       
   724 	}
       
   725 
       
   726 void CDmHierarchy::StopObserver()
       
   727 	{
       
   728 	
       
   729 	iObservedDomain->SetObserver(EFalse);
       
   730 	iTransitions.Reset();
       
   731 	iObserverStarted=EFalse;
       
   732 	}
       
   733 void CDmHierarchy::NotifyCompletion(TInt aReason)
       
   734 	{
       
   735 	iTransDomain = NULL;
       
   736 	iTransPropValue = 0;
       
   737 	iTransMessagePtr.Complete(aReason);
       
   738 	}
       
   739 
       
   740 TInt CDmHierarchy::RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage)
       
   741 	{
       
   742 	iTransDomain = iRootDomain;
       
   743 	SetState(aTargetState, aTraverseDirection);
       
   744 	RequestTransition(aMessage);
       
   745 	return KErrNone;
       
   746 	}
       
   747 
       
   748 
       
   749 TInt CDmHierarchy::RequestDomainTransition(
       
   750 	TDmDomainId aDomainId, 
       
   751 	TDmDomainState aTargetState, 
       
   752 	TDmTraverseDirection aTraverseDirection, 
       
   753 	const RMessage2* aMessage)
       
   754 	{
       
   755 	__DS_TRACE((_L("CDmHierarchy::RequestTransition() hierarchy=%d domain=0x%x state=0x%x"), iHierarchyId, aDomainId, aTargetState)); 
       
   756 	iTransDomain = LookupDomain(aDomainId);
       
   757 	if (!iTransDomain)
       
   758 		return KDmErrBadDomainId;
       
   759 	SetState(aTargetState, aTraverseDirection);
       
   760 	RequestTransition(aMessage);
       
   761 	return KErrNone;
       
   762 	}
       
   763 
       
   764 void CDmHierarchy::CompleteTransition(TInt aError)
       
   765 	{
       
   766 	if (!iTransDomain)
       
   767 		return;
       
   768 
       
   769 	__DS_TRACE((_L("CDmHierarchy::CompleteTransition() hierarchy=%d, domain=0x%x, aError=%d"), iHierarchyId, iTransDomain->iId, aError));
       
   770 
       
   771 	if (iTransDomain)
       
   772 		{
       
   773 		iTransDomain->CancelTransition();
       
   774 		NotifyCompletion(aError);
       
   775 		}
       
   776 	}
       
   777 
       
   778 void CDmHierarchy::SetState(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection)
       
   779 	{
       
   780 	__DS_ASSERT(iTransDomain);
       
   781 
       
   782 
       
   783 	if (aTraverseDirection == ETraverseDefault)
       
   784 		{
       
   785 		TDmDomainState oldState = iTransDomain->State();
       
   786 
       
   787 		if (aTargetState >= oldState)
       
   788 			iTraverseDirection = iPolicy.iPositiveTransitions;
       
   789 		else
       
   790 			iTraverseDirection = iPolicy.iNegativeTransitions;
       
   791 		}
       
   792 	else
       
   793 		iTraverseDirection = aTraverseDirection;
       
   794 
       
   795 	__DS_ASSERT(iTraverseDirection < ETraverseMax);
       
   796 
       
   797 	iTransState = aTargetState;
       
   798 	}
       
   799 
       
   800 //*********************************************************
       
   801 // CPowerUpHandler
       
   802 //*********************************************************
       
   803 
       
   804 CPowerUpHandler* CPowerUpHandler::New(CDmHierarchyPower& aHierarchyPower)
       
   805 	{
       
   806 	CPowerUpHandler* self = new CPowerUpHandler(aHierarchyPower);
       
   807 	if (!self)
       
   808 		__DS_PANIC(KErrNoMemory);
       
   809 	self->Construct();
       
   810 	return self;
       
   811 	}
       
   812 
       
   813 CPowerUpHandler::CPowerUpHandler(CDmHierarchyPower& aHierarchyPower) : 
       
   814 	CActive(CActive::EPriorityStandard),
       
   815 	iHierarchyPower(aHierarchyPower)
       
   816 	{
       
   817 	}
       
   818 
       
   819 void CPowerUpHandler::Construct()
       
   820 	{
       
   821 	CActiveScheduler::Add(this);
       
   822 	}
       
   823 
       
   824 
       
   825 void CPowerUpHandler::RequestWakeupEventNotification()
       
   826 	{
       
   827 	Power::RequestWakeupEventNotification(iStatus);
       
   828 	SetActive();
       
   829 	}
       
   830 
       
   831 
       
   832 void CPowerUpHandler::Cancel()
       
   833 	{
       
   834 	CActive::Cancel();
       
   835 	}
       
   836 
       
   837 void CPowerUpHandler::RunL()
       
   838 	{ 
       
   839 	// power wakeup event
       
   840 	iHierarchyPower.PowerUp();
       
   841 	}
       
   842 
       
   843 
       
   844 void CPowerUpHandler::DoCancel()
       
   845 	{
       
   846 	Power::DisableWakeupEvents();
       
   847 	Power::CancelWakeupEventNotification(); 
       
   848 	}
       
   849 
       
   850 
       
   851 
       
   852 //*********************************************************
       
   853 // CDmHierarchyPower
       
   854 //*********************************************************
       
   855 CDmHierarchyPower* CDmHierarchyPower::New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy)
       
   856 	{
       
   857 	CDmHierarchyPower* self;
       
   858 
       
   859 	self = new CDmHierarchyPower(aHierarchyId, aPolicy);
       
   860 
       
   861 	if (!self)
       
   862 		__DS_PANIC(KErrNoMemory);
       
   863 
       
   864 	self->Construct();
       
   865 
       
   866 	return self;
       
   867 	}
       
   868 
       
   869 CDmHierarchyPower::CDmHierarchyPower(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy) :
       
   870 	CDmHierarchy(aHierarchyId, aPolicy)
       
   871 	{
       
   872 	}
       
   873 
       
   874 
       
   875 void CDmHierarchyPower::Construct()
       
   876 	{
       
   877 	iPowerUpHandler = CPowerUpHandler::New(*this);
       
   878 	if (!iPowerUpHandler)
       
   879 		__DS_PANIC(KErrNoMemory);
       
   880 	}
       
   881 
       
   882 void CDmHierarchyPower::NotifyCompletion(TInt aReason)
       
   883 	{
       
   884 	iTransStatus = 0;
       
   885 	CDmHierarchy::NotifyCompletion(aReason);
       
   886 	}
       
   887 
       
   888 TInt CDmHierarchyPower::RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage)
       
   889 	{
       
   890 	__DS_TRACE((_L("CDmSvrManager::RequestSystemTransition() state = 0x%x"), aTargetState));
       
   891 	
       
   892 	TInt r = Power::EnableWakeupEvents((TPowerState) aTargetState);
       
   893 	if (r != KErrNone)
       
   894 		return r;
       
   895 	
       
   896 	iPowerUpHandler->RequestWakeupEventNotification();
       
   897 
       
   898 	iTransStatus |= EPoweringDown;
       
   899 
       
   900 	return CDmHierarchy::RequestSystemTransition(aTargetState, aTraverseDirection, aMessage);
       
   901 	}
       
   902 
       
   903 void CDmHierarchyPower::CompleteTransition(TInt aError)
       
   904 	{
       
   905 	if (!iTransDomain)
       
   906 		return;
       
   907 
       
   908 	__DS_TRACE((_L("CDmHierarchyPower::CompleteTransition() domain=0x%x"), iTransDomain->iId));
       
   909 
       
   910 	if (iTransDomain && aError == KErrCancel)
       
   911 		iPowerUpHandler->Cancel();
       
   912 
       
   913 	if (iTransStatus & EPoweringDown)
       
   914 		{
       
   915 		RFs fs;
       
   916 		TInt r=fs.Connect();
       
   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)); 
       
   921 		fs.Close();
       
   922 
       
   923 		Power::PowerDown();
       
   924 		__DS_ASSERT(iTransState != (TDmDomainState) EPwOff);
       
   925 		__DS_ASSERT(iPowerUpHandler->iStatus.Int() == KErrNone);
       
   926 		}	
       
   927 	else
       
   928 		{
       
   929 		CDmHierarchy::CompleteTransition(aError);
       
   930 		}
       
   931 	}
       
   932 
       
   933 
       
   934 void CDmHierarchyPower::PowerUp()
       
   935 	{
       
   936 	__DS_TRACE((_L("CDmHierarchyPower::RunL() Wakeup Event")));
       
   937 	__DS_ASSERT(iTransDomain);
       
   938 
       
   939 	Power::DisableWakeupEvents();
       
   940 
       
   941 	iTransStatus &= ~EPoweringDown;
       
   942 	iTransDomain->CancelTransition();
       
   943 	SetState((TDmDomainState) EPwActive);
       
   944 	RequestTransition(NULL);
       
   945 	}
       
   946 
       
   947 
       
   948 //*********************************************************
       
   949 // CDmSvrManager
       
   950 //*********************************************************
       
   951 
       
   952 CDmSvrManager* CDmSvrManager::New()
       
   953 	{
       
   954 	CDmSvrManager* self = new CDmSvrManager();
       
   955 	if (!self)
       
   956 		__DS_PANIC(KErrNoMemory);
       
   957 	self->Construct();
       
   958 	return self;
       
   959 	}
       
   960 
       
   961 CDmSvrManager::CDmSvrManager()
       
   962 	{
       
   963 	}
       
   964 
       
   965 void CDmSvrManager::Construct()
       
   966 	{
       
   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);
       
   971 	if (r != KErrNone)
       
   972 		__DS_PANIC(r);
       
   973 
       
   974 
       
   975 	RProperty prop;
       
   976 	r = prop.Define(KUidDmPropertyCategory, KDmPropertyKeyInit, RProperty::EInt,
       
   977 							KAllowAllPolicy,KPowerMgmtPolicy);
       
   978 	if (r != KErrNone)
       
   979 		__DS_PANIC(r);
       
   980 
       
   981 	prop.Set(KUidDmPropertyCategory, KDmPropertyKeyInit, ETrue);
       
   982 	}
       
   983 
       
   984 TInt CDmSvrManager::BuildDomainTree(TDmHierarchyId aHierarchyId, CDmHierarchy*& aHierarchy)
       
   985 	{
       
   986 
       
   987 	aHierarchy = NULL;
       
   988 
       
   989 	// assume we have already checked that the hierarchy doesn't already exist
       
   990 
       
   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.
       
   994 	//
       
   995 	// If the hierarchy ID is less than KMaxCriticalPolicyDll, load only from ROM
       
   996 
       
   997 	TFullName dllName;
       
   998 
       
   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);
       
  1004 
       
  1005 	dllName.Append(_L("domainPolicy"));
       
  1006 	if (aHierarchyId != KDmHierarchyIdPower)
       
  1007 		dllName.AppendNum(aHierarchyId);
       
  1008 
       
  1009 	dllName.Append(_L(".dll"));
       
  1010 	RLibrary lib;
       
  1011 	TInt r = lib.Load(dllName);
       
  1012 	if (r == KErrNotFound)
       
  1013 		return KErrBadHierarchyId;
       
  1014 	else if (r != KErrNone)
       
  1015 		return r;
       
  1016 
       
  1017 	TLibraryFunction ordinal1 = lib.Lookup(EDmPolicyGetDomainSpecs);
       
  1018 	DmPolicyGetDomainSpecs getDomainSpecs = reinterpret_cast<DmPolicyGetDomainSpecs>(ordinal1);
       
  1019 	if (getDomainSpecs == NULL)
       
  1020 		r = KErrBadHierarchyId;
       
  1021 
       
  1022 	TLibraryFunction ordinal2 = lib.Lookup(EDmPolicyRelease);
       
  1023 	DmPolicyRelease release = reinterpret_cast<DmPolicyRelease>(ordinal2);
       
  1024 	if (release == NULL)
       
  1025 		r = KErrBadHierarchyId;
       
  1026 
       
  1027 	TLibraryFunction ordinal3 = lib.Lookup(EDmPolicyGetPolicy);
       
  1028 	DmPolicyGetPolicy getPolicy = reinterpret_cast<DmPolicyGetPolicy>(ordinal3);
       
  1029 	if (getPolicy == NULL)
       
  1030 		r = KErrBadHierarchyId;
       
  1031 
       
  1032 
       
  1033 	// get the domain spec for this hierarchy
       
  1034 	const TDmDomainSpec* spec = NULL;
       
  1035 
       
  1036 	if (r == KErrNone)
       
  1037 		{
       
  1038 		spec = (*getDomainSpecs)();
       
  1039 		if (spec == NULL)
       
  1040 			r = KErrBadHierarchyId;
       
  1041 		}
       
  1042 	// get the policy
       
  1043 	TDmHierarchyPolicy hierarchyPolicy;
       
  1044 	if (r == KErrNone)
       
  1045 		{
       
  1046 		r = (*getPolicy)(hierarchyPolicy);
       
  1047 		if (r == KErrNone)
       
  1048 			{
       
  1049 			__DS_ASSERT(hierarchyPolicy.iPositiveTransitions < ETraverseMax);
       
  1050 			__DS_ASSERT(hierarchyPolicy.iNegativeTransitions < ETraverseMax);
       
  1051 			}
       
  1052 		}
       
  1053 
       
  1054 	if (r != KErrNone)
       
  1055 		{
       
  1056 		lib.Close();
       
  1057 		return r;
       
  1058 		}
       
  1059 
       
  1060 	CDmHierarchy* hierarchy = CDmHierarchy::New(aHierarchyId, hierarchyPolicy);
       
  1061 	if (hierarchy == NULL)
       
  1062 		__DS_PANIC(KErrNoMemory);
       
  1063 
       
  1064 	while (r == KErrNone && spec->iId != KDmIdNone)
       
  1065 		{
       
  1066 		// make sure the domain doesn't already exist in this hierarchy
       
  1067 		CSvrDomain* domain = hierarchy->LookupDomain(spec->iId);
       
  1068 		if (domain)
       
  1069 			{
       
  1070 			r = KErrBadHierarchyId;
       
  1071 			break;
       
  1072 			}
       
  1073 
       
  1074 		domain = CSvrDomain::New(*hierarchy, *spec);
       
  1075 		__DS_ASSERT(domain);
       
  1076 	
       
  1077 		if (spec->iParentId == KDmIdNone)
       
  1078 			{
       
  1079 			if (hierarchy->iRootDomain)
       
  1080 				{
       
  1081 				r = KDmErrBadDomainSpec;
       
  1082 				break;
       
  1083 				}
       
  1084 			hierarchy->iRootDomain = domain;
       
  1085 			}
       
  1086 		else
       
  1087 			{
       
  1088 			CSvrDomain* parent = hierarchy->LookupDomain(spec->iParentId);
       
  1089 			if (!parent)
       
  1090 				{
       
  1091 				r = KDmErrBadDomainSpec;
       
  1092 				break;
       
  1093 				}
       
  1094 			parent->AddChild(domain);
       
  1095 			}
       
  1096 		++spec;
       
  1097 		}
       
  1098 
       
  1099 	if (spec)
       
  1100 		(*release)(spec);
       
  1101 
       
  1102 
       
  1103 	if (r == KErrNone)
       
  1104 		{
       
  1105 		__DS_ASSERT(hierarchy->iRootDomain);
       
  1106 		iDomainHierarchies.Append(hierarchy);
       
  1107 		aHierarchy = hierarchy;
       
  1108 		}
       
  1109 	else
       
  1110 		{
       
  1111 		delete hierarchy;
       
  1112 		hierarchy = NULL;
       
  1113 		}
       
  1114 
       
  1115 	lib.Close();
       
  1116 
       
  1117 	return r;
       
  1118 	}
       
  1119 
       
  1120 CDmHierarchy* CDmSvrManager::LookupHierarchy(TDmHierarchyId aHierarchyId)
       
  1121 
       
  1122 	{
       
  1123 	// need to find the correct hierarchy first
       
  1124 	TInt len = iDomainHierarchies.Count();
       
  1125 
       
  1126 	CDmHierarchy* hierarchy = NULL;
       
  1127 	for (TInt n=0; n<len; n++)
       
  1128 		{
       
  1129 		if (iDomainHierarchies[n]->iHierarchyId == aHierarchyId)
       
  1130 			{
       
  1131 			hierarchy = iDomainHierarchies[n];
       
  1132 			break;
       
  1133 			}
       
  1134 		}
       
  1135 
       
  1136 	return hierarchy;
       
  1137 	}
       
  1138 	
       
  1139 
       
  1140 TInt CDmSvrManager::LookupDomain(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, CSvrDomain*& aDomain)
       
  1141 	{
       
  1142 	// need to find the correct hierarchy first
       
  1143 	CDmHierarchy* hierarchy = LookupHierarchy(aHierarchyId);
       
  1144 	if (hierarchy == NULL)
       
  1145 		return KErrBadHierarchyId;
       
  1146 
       
  1147 	aDomain = hierarchy->LookupDomain(aDomainId);
       
  1148 	if (aDomain == NULL)
       
  1149 		return KDmErrBadDomainId;
       
  1150 	
       
  1151 	return KErrNone;
       
  1152 	}
       
  1153 	
       
  1154 CSession2* CDmManagerServer::NewSessionL(const TVersion&, const RMessage2& aMessage) const
       
  1155 	{
       
  1156 
       
  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))
       
  1160 		{
       
  1161 
       
  1162         User::Leave(KErrPermissionDenied);
       
  1163 
       
  1164 		}
       
  1165 
       
  1166 	return new CDmManagerSession();
       
  1167 	}
       
  1168 
       
  1169 CSession2* CDmManagerServer::NewSessionL(const TVersion&) const
       
  1170 	{
       
  1171 	__DS_PANIC(KErrGeneral);
       
  1172 	return 0;
       
  1173 	}
       
  1174 
       
  1175 CDmManagerSession::CDmManagerSession()
       
  1176 	{}
       
  1177 
       
  1178 CDmManagerSession::~CDmManagerSession()
       
  1179 	{
       
  1180 	if (iHierarchy && iHierarchy->iControllerSession == this)
       
  1181 		iHierarchy->iControllerSession = NULL;
       
  1182 	if (iHierarchy && iHierarchy->iObserverSession == this)
       
  1183 		iHierarchy->iObserverSession = NULL;
       
  1184 	}
       
  1185 
       
  1186 class MyMessage : public RMessage2
       
  1187 	{
       
  1188 public:
       
  1189 	TInt* ArgRef(TInt i)
       
  1190 		{ return &iArgs[i]; }
       
  1191 	};
       
  1192 
       
  1193 void CDmManagerSession::ServiceL(const RMessage2& aMessage)
       
  1194 	{
       
  1195 	TInt r;
       
  1196 	CDmSvrManager* manager = ((CDmManagerServer*) Server()) -> iManager;
       
  1197 
       
  1198 	// Check client has ECapabilityPowerMgmt capability
       
  1199 /*	
       
  1200     if (!KPowerMgmtPolicy.CheckPolicy(aMessage))
       
  1201 		{
       
  1202 		aMessage.Complete(KErrPermissionDenied);
       
  1203 		return;
       
  1204 		}
       
  1205 */
       
  1206 	switch (aMessage.Function())
       
  1207 		{
       
  1208 		case EDmHierarchyAdd:
       
  1209 			{
       
  1210 			r = KErrNone;
       
  1211 			TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
       
  1212 
       
  1213 			CDmHierarchy* hierarchy = manager->LookupHierarchy(hierarchyId);
       
  1214 			if (hierarchy == NULL)
       
  1215 				r = manager->BuildDomainTree(hierarchyId, hierarchy);
       
  1216 			aMessage.Complete(r);
       
  1217 			}
       
  1218 			break;
       
  1219 
       
  1220 		case EDmHierarchyJoin:
       
  1221 			{
       
  1222 			r = KErrNone;
       
  1223 			TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
       
  1224 
       
  1225 			iHierarchy = manager->LookupHierarchy(hierarchyId);
       
  1226 			if (iHierarchy == NULL)
       
  1227 				r = KErrBadHierarchyId;
       
  1228 
       
  1229 			if (r == KErrNone)
       
  1230 				{
       
  1231 				// is the hierarchy already in use ?
       
  1232 				if (iHierarchy->iControllerSession)
       
  1233 					r = KErrInUse;
       
  1234 				else
       
  1235 					iHierarchy->iControllerSession = this;
       
  1236 				}
       
  1237 
       
  1238 			aMessage.Complete(r);
       
  1239 			}
       
  1240 			break;
       
  1241 
       
  1242 		case EDmRequestSystemTransition:
       
  1243 			if (iHierarchy==NULL)
       
  1244 				{
       
  1245 				aMessage.Complete(KErrBadHierarchyId);
       
  1246 				break;
       
  1247 				}
       
  1248 			if (iHierarchy->iTransDomain)
       
  1249 				{
       
  1250 				aMessage.Complete(KDmErrBadSequence);
       
  1251 				break;
       
  1252 				}
       
  1253 
       
  1254 			r = iHierarchy->RequestSystemTransition(
       
  1255 				(TDmDomainState) aMessage.Int0(),
       
  1256 				(TDmTraverseDirection) aMessage.Int1(),
       
  1257 				&aMessage);
       
  1258 
       
  1259 			if (r != KErrNone)
       
  1260 				aMessage.Complete(r);
       
  1261 			break;
       
  1262 
       
  1263 		case EDmRequestDomainTransition:
       
  1264 			if (iHierarchy==NULL)
       
  1265 				{
       
  1266 				aMessage.Complete(KErrBadHierarchyId);
       
  1267 				break;
       
  1268 				}
       
  1269 			if (iHierarchy->iTransDomain)
       
  1270 				{
       
  1271 				aMessage.Complete(KDmErrBadSequence);
       
  1272 				break;
       
  1273 				}
       
  1274 			r = iHierarchy->RequestDomainTransition(
       
  1275 				(TDmDomainId) aMessage.Int0(), 
       
  1276 				(TDmDomainState) aMessage.Int1(), 
       
  1277 				(TDmTraverseDirection) aMessage.Int2(),
       
  1278 				&aMessage);
       
  1279 
       
  1280 			if (r != KErrNone)
       
  1281 				aMessage.Complete(r);
       
  1282 			break;
       
  1283 
       
  1284 		case EDmGetTransitionFailureCount:
       
  1285 			{
       
  1286 			if (iHierarchy==NULL)
       
  1287 				{
       
  1288 				aMessage.Complete(KErrBadHierarchyId);
       
  1289 				break;
       
  1290 				}
       
  1291 			TInt failureCount = iHierarchy->iTransitionFailures.Count();
       
  1292 			aMessage.Complete(failureCount);
       
  1293 			}
       
  1294 			break;
       
  1295 		
       
  1296 		case EDmGetTransitionFailures:
       
  1297 			{
       
  1298 			if (iHierarchy==NULL)
       
  1299 				{
       
  1300 				aMessage.Complete(KErrBadHierarchyId);
       
  1301 				break;
       
  1302 				}
       
  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);
       
  1308 			
       
  1309 			HBufC8* hBuf = HBufC8::New(clientFailureSize);
       
  1310 			if(hBuf == NULL)
       
  1311 				{
       
  1312 				aMessage.Complete(KErrNoMemory);
       
  1313 				break;
       
  1314 				}
       
  1315 			TPtr8 pBuf = hBuf->Des();
       
  1316 			pBuf.Zero();
       
  1317 			for (TInt i=0; i<clientFailureCount; i++)
       
  1318 				{
       
  1319 				TPtrC8 ptr = TPtrC8((TUint8*) &iHierarchy->iTransitionFailures[i], sizeof(TTransitionFailure));
       
  1320 				pBuf.Append(ptr);
       
  1321 				}
       
  1322 			r = aMessage.Write(0, pBuf);
       
  1323 			delete hBuf;
       
  1324 
       
  1325 			aMessage.Complete(r);
       
  1326 			}
       
  1327 			break;
       
  1328 
       
  1329 		case EDmCancelTransition:
       
  1330 			if (iHierarchy == NULL)
       
  1331 				{
       
  1332 				aMessage.Complete(KErrBadHierarchyId);
       
  1333 				break;
       
  1334 				}
       
  1335 			iHierarchy->CompleteTransition(KErrCancel);
       
  1336 			if (iHierarchy->iObserverStarted)
       
  1337 				{
       
  1338 				iHierarchy->CompleteNotification(KErrCancel);
       
  1339 				iHierarchy->StopObserver();
       
  1340 				}
       
  1341 			aMessage.Complete(KErrNone);
       
  1342 			break;
       
  1343 		case EDmObserverCancel:
       
  1344 			if (iHierarchy == NULL)
       
  1345 				{
       
  1346 				aMessage.Complete(KErrBadHierarchyId);
       
  1347 				break;
       
  1348 				}
       
  1349 			if(!iHierarchy->iObserverSession)
       
  1350 				{
       
  1351 				aMessage.Complete(KDmErrBadSequence);
       
  1352 				break;
       
  1353 				}
       
  1354 			if (iHierarchy->iObserverStarted)
       
  1355 				{
       
  1356 				iHierarchy->CompleteNotification(KErrCancel);
       
  1357 				iHierarchy->StopObserver();
       
  1358 				}
       
  1359 			aMessage.Complete(KErrNone);
       
  1360 			break;
       
  1361 
       
  1362 		case EDmObserverJoin:
       
  1363 			{
       
  1364 			TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
       
  1365 
       
  1366 			iHierarchy = manager->LookupHierarchy(hierarchyId);
       
  1367 			if(iHierarchy==NULL)
       
  1368 				{
       
  1369 				aMessage.Complete(KErrBadHierarchyId);
       
  1370 				break;
       
  1371 				}
       
  1372 			if(iHierarchy->iObserverSession)
       
  1373 				{
       
  1374 				aMessage.Complete(KDmErrBadSequence);
       
  1375 				break;
       
  1376 				}
       
  1377 			iHierarchy->iTransitions.Reset();
       
  1378 			iHierarchy->iObserverSession = this;
       
  1379 			aMessage.Complete(KErrNone);
       
  1380 			}
       
  1381 			break;
       
  1382 
       
  1383 		case EDmObserverStart:
       
  1384 			{
       
  1385 			if (iHierarchy==NULL)
       
  1386 				{
       
  1387 				aMessage.Complete(KErrBadHierarchyId);
       
  1388 				break;
       
  1389 				}
       
  1390 			
       
  1391 			if(iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
       
  1392 				{
       
  1393 				aMessage.Complete(KDmErrBadSequence); 
       
  1394 				break;
       
  1395 				}
       
  1396 			TInt ret= iHierarchy->StartObserver((TDmDomainId)aMessage.Int0(),(TDmNotifyType)aMessage.Int1());
       
  1397 			aMessage.Complete(ret);
       
  1398 			}
       
  1399 			break;
       
  1400 
       
  1401 		case EDmObserverNotify:
       
  1402 			{
       
  1403 			if (iHierarchy==NULL)
       
  1404 				{
       
  1405 				aMessage.Complete(KErrBadHierarchyId);
       
  1406 				break;
       
  1407 				}
       
  1408 			if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
       
  1409 				{
       
  1410 				aMessage.Complete(KDmErrBadSequence); 
       
  1411 				break;
       
  1412 				}
       
  1413 			//	Check to see if we have any events stored 
       
  1414 			//	If so, then notify the client
       
  1415 			if(iHierarchy->iTransitions.Count()>0)
       
  1416 				{
       
  1417 				aMessage.Complete(KErrNone);
       
  1418 				break;
       
  1419 				}
       
  1420 			//	No events are stored. complete this message later
       
  1421 			iHierarchy->SetNotifyMessage(&aMessage);
       
  1422 			}
       
  1423 			break;
       
  1424 		
       
  1425 		case EDmObserverEventCount:
       
  1426 			{
       
  1427 			if (iHierarchy==NULL)
       
  1428 				{
       
  1429 				aMessage.Complete(KErrBadHierarchyId);
       
  1430 				break;
       
  1431 				}
       
  1432 			if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
       
  1433 				{
       
  1434 				aMessage.Complete(KDmErrBadSequence);
       
  1435 				break;
       
  1436 				}
       
  1437 			TInt count = iHierarchy->iTransitions.Count();
       
  1438 			aMessage.Complete(count);
       
  1439 			}
       
  1440 			break;
       
  1441 		
       
  1442 		case EDmObserverGetEvent:
       
  1443 			{
       
  1444 			if (iHierarchy==NULL)
       
  1445 				{
       
  1446 				aMessage.Complete(KErrBadHierarchyId);
       
  1447 				break;
       
  1448 				}
       
  1449 			if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
       
  1450 				{
       
  1451 				aMessage.Complete(KDmErrBadSequence);
       
  1452 				break;
       
  1453 				}
       
  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);
       
  1459 			
       
  1460 			HBufC8* hBuf = HBufC8::New(clientTransitionSize);
       
  1461 			if(hBuf == NULL)
       
  1462 				{
       
  1463 				aMessage.Complete(KErrNoMemory);
       
  1464 				break;
       
  1465 				}
       
  1466 			TPtr8 pBuf = hBuf->Des();
       
  1467 			pBuf.Zero();
       
  1468 			for (TInt i=0; i<clientTransitionCount; i++)
       
  1469 				{
       
  1470 				TPtrC8 ptr = TPtrC8((TUint8*) &iHierarchy->iTransitions[0], sizeof(TTransInfo));
       
  1471 				pBuf.Append(ptr);
       
  1472 				iHierarchy->iTransitions.Remove(0);
       
  1473 				}
       
  1474 			r = aMessage.Write(0, pBuf);
       
  1475 			delete hBuf;
       
  1476 
       
  1477 			aMessage.Complete(r);
       
  1478 			}
       
  1479 			break;
       
  1480 		case EDmObserveredCount:
       
  1481 			{
       
  1482 			if (iHierarchy==NULL)
       
  1483 				{
       
  1484 				aMessage.Complete(KErrBadHierarchyId);
       
  1485 				break;
       
  1486 				}
       
  1487 			if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
       
  1488 				{
       
  1489 				aMessage.Complete(KDmErrBadSequence);
       
  1490 				break;
       
  1491 				}
       
  1492 			aMessage.Complete(iHierarchy->iObservedChildren);
       
  1493 			}
       
  1494 			break;
       
  1495 		default:
       
  1496 			aMessage.Complete(KDmErrBadRequest);
       
  1497 			break;
       
  1498 		}
       
  1499 	}
       
  1500 
       
  1501 CSession2* CDmDomainServer::NewSessionL(const TVersion&, const RMessage2&) const
       
  1502 	{
       
  1503 
       
  1504 	return new CDmDomainSession();
       
  1505 	}
       
  1506 
       
  1507 CSession2* CDmDomainServer::NewSessionL(const TVersion&) const
       
  1508 	{
       
  1509 	__DS_PANIC(KErrGeneral);
       
  1510 	return 0;
       
  1511 	}
       
  1512 
       
  1513 CDmDomainSession::~CDmDomainSession()
       
  1514 	{
       
  1515 	if (iPending)
       
  1516 		iDomain->CompleteMemberTransition(KErrNone);
       
  1517 	if (iDomain)
       
  1518 		iDomain->Detach(this);
       
  1519 	}
       
  1520 
       
  1521 void CDmDomainSession::ServiceL(const RMessage2& aMessage)
       
  1522 	{
       
  1523 	TInt r = KErrNone;
       
  1524 	CDmSvrManager* manager = ((CDmManagerServer*) Server()) -> iManager;
       
  1525 
       
  1526 	switch (aMessage.Function())
       
  1527 		{
       
  1528 	case EDmDomainJoin:
       
  1529 		{
       
  1530 		TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
       
  1531 		TDmDomainId domainId = (TDmDomainId) aMessage.Int1();
       
  1532 
       
  1533 		r = manager->LookupDomain(hierarchyId, domainId, iDomain);
       
  1534 
       
  1535 		if (r != KErrNone)
       
  1536 			break;
       
  1537 
       
  1538 		// Check client has capability to join the domain
       
  1539 		if (!iDomain->iJoinPolicy.CheckPolicy(aMessage))
       
  1540 			{
       
  1541 			r = KErrPermissionDenied;
       
  1542 			iDomain = NULL;
       
  1543 			break;
       
  1544 			}
       
  1545 
       
  1546 		iDomain->Attach(this);
       
  1547 		break;
       
  1548 		}
       
  1549 
       
  1550 	case EDmStateRequestTransitionNotification:
       
  1551 		iNotificationEnabled = ETrue;
       
  1552 		break;
       
  1553 
       
  1554 	case EDmStateCancelTransitionNotification:
       
  1555 		iNotificationEnabled = EFalse;
       
  1556 		break;
       
  1557 
       
  1558 	case EDmStateAcknowledge:
       
  1559 		{
       
  1560 		TInt propValue = aMessage.Int0();
       
  1561 		TInt error = aMessage.Int1();
       
  1562 		if (!iDomain)
       
  1563 			{
       
  1564 			r = KDmErrNotJoin;
       
  1565 			break;
       
  1566 			}
       
  1567 		if (iPending && iDomain->CheckPropValue(propValue))
       
  1568 			{
       
  1569 			iPending = EFalse;
       
  1570 			iDomain->CompleteMemberTransition(error);
       
  1571 			}
       
  1572 		}
       
  1573 		break;
       
  1574 	default:
       
  1575 		r = KDmErrBadRequest;
       
  1576 		break;
       
  1577 		}
       
  1578 	aMessage.Complete(r);
       
  1579 	}
       
  1580 
       
  1581 	
       
  1582 TInt E32Main()
       
  1583 	{
       
  1584 	CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
  1585 	if(!cleanupStack)
       
  1586 		__DS_PANIC(KErrNoMemory);
       
  1587 
       
  1588 	CActiveScheduler* sched = new CActiveScheduler();
       
  1589 	if (!sched)
       
  1590 		__DS_PANIC(KErrNoMemory);
       
  1591 
       
  1592 	CActiveScheduler::Install(sched);
       
  1593 
       
  1594 	CDmSvrManager* mngr = CDmSvrManager::New();
       
  1595 	__DS_ASSERT(mngr);
       
  1596 
       
  1597 	CDmManagerServer* msrv = new CDmManagerServer(mngr);
       
  1598 	if (!msrv)
       
  1599 		__DS_PANIC(KErrNoMemory);
       
  1600 
       
  1601 	TInt r=msrv->Start(KDmManagerServerNameLit);
       
  1602 	if (r != KErrNone)
       
  1603 		__DS_PANIC(r);
       
  1604 
       
  1605 	CDmDomainServer* dsrv = new CDmDomainServer(mngr);
       
  1606 	if (!dsrv)
       
  1607 		__DS_PANIC(KErrNoMemory);
       
  1608 
       
  1609 	r=dsrv->Start(KDmDomainServerNameLit);
       
  1610 	if (r != KErrNone)
       
  1611 		__DS_PANIC(r);
       
  1612 
       
  1613 	CActiveScheduler::Start();
       
  1614 
       
  1615 	__DS_PANIC(0);
       
  1616 
       
  1617 	return KErrNone;
       
  1618 	}