1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/userlibandfileserver/domainmgr/src/domainsrv.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1618 @@
1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// domain\src\domainsrv.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include <e32debug.h>
1.22 +#include <e32base.h>
1.23 +#include <e32base_private.h>
1.24 +#include <e32property.h>
1.25 +#include <f32file.h>
1.26 +
1.27 +#include <domainpolicy.h>
1.28 +#include "domainsrv.h"
1.29 +
1.30 +#define __DS_PANIC(aError) User::Panic(_L("domainSrv.cpp"), (-(aError)) | (__LINE__ << 16))
1.31 +#define __DS_ASSERT(aCond) ((aCond) || (User::Panic(_L("domainSrv.cpp; assertion failed"), __LINE__), 1))
1.32 +
1.33 +//#define __DS_DEBUG
1.34 +
1.35 +#ifdef __DS_DEBUG
1.36 +#define __DS_TRACE(s) RDebug::Print s
1.37 +#else
1.38 +#define __DS_TRACE(s)
1.39 +#endif
1.40 +
1.41 +static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
1.42 +static _LIT_SECURITY_POLICY_C1(KPowerMgmtPolicy,ECapabilityPowerMgmt);
1.43 +
1.44 +// forward refs
1.45 +class CSvrDomain;
1.46 +class CDmHierarchy;
1.47 +class CPowerUpHandler;
1.48 +class CDmHierarchyPower;
1.49 +class CDmSvrManager;
1.50 +class CDmDomainServer;
1.51 +class CDmDomainSession;
1.52 +class CDmManagerServer;
1.53 +class CDmManagerSession;
1.54 +
1.55 +
1.56 +
1.57 +// CSvrDomain
1.58 +class CSvrDomain : public CTimer
1.59 + {
1.60 +public:
1.61 + static CSvrDomain* New(CDmHierarchy& aHierarchy, const TDmDomainSpec&);
1.62 +
1.63 + // from CTimer
1.64 + void RunL();
1.65 +
1.66 + void Attach(CDmDomainSession*);
1.67 + void Detach(CDmDomainSession*);
1.68 + void AddChild(CSvrDomain*);
1.69 + CSvrDomain* Lookup(TDmDomainId);
1.70 + TBool CheckPropValue(TInt aPropValue);
1.71 + void RequestDomainTransition();
1.72 + void CompleteMemberTransition(TInt aError);
1.73 + void CancelTransition();
1.74 + void SetObserver(TBool aSet);
1.75 + TDmDomainState State();
1.76 +
1.77 +private:
1.78 + CSvrDomain(CDmHierarchy& aHierarchy, const TDmDomainSpec*);
1.79 + void Construct(const TDmDomainSpec* spec);
1.80 +
1.81 + void RequestMembersTransition();
1.82 + void RequestChildrenTransition();
1.83 + void MembersTransitionDone();
1.84 + void ChildrenTransitionDone();
1.85 + void CompleteDomainTransition();
1.86 +
1.87 +private:
1.88 + CDmHierarchy& iHierarchy;
1.89 + CSvrDomain* iParent;
1.90 + CSvrDomain* iPeer;
1.91 + CSvrDomain* iChild;
1.92 + RProperty iProperty;
1.93 + CDmDomainSession* iSessions;
1.94 + TUint16 iChildrenCount;
1.95 + TUint16 iTransCount;
1.96 + TTimeIntervalMicroSeconds32 iTransTimeBudget;
1.97 +
1.98 +public:
1.99 + const TSecurityPolicy iJoinPolicy;
1.100 + TBool iIsObserved;
1.101 + TDmDomainId iId;
1.102 + };
1.103 +
1.104 +
1.105 +// CDmHierarchy
1.106 +class CDmHierarchy : public CBase
1.107 + {
1.108 +public:
1.109 + static CDmHierarchy* New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
1.110 +
1.111 + CSvrDomain* LookupDomain(TDmDomainId aDomainId);
1.112 + TInt RequestDomainTransition(TDmDomainId, TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
1.113 + void RequestTransition(const RMessage2* aMessage);
1.114 + TInt StartObserver( TDmDomainId aDomainId,TDmNotifyType aNotifyType);
1.115 + void SetNotifyMessage(const RMessage2* aMessage);
1.116 + void CompleteNotification(TInt aError);
1.117 + TBool OutstandingNotification();
1.118 + void StopObserver();
1.119 + virtual TInt RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
1.120 + virtual void CompleteTransition(TInt aError);
1.121 + virtual void NotifyCompletion(TInt aReason);
1.122 +
1.123 +protected:
1.124 + CDmHierarchy(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
1.125 + void SetState(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection = ETraverseDefault);
1.126 +
1.127 +private:
1.128 + RMessagePtr2 iTransMessagePtr;
1.129 + RMessagePtr2 iObsvrMessagePtr;
1.130 + CSvrDomain* iObservedDomain;
1.131 + TBool iOutstandingNotification;
1.132 +public:
1.133 + TDmHierarchyId iHierarchyId;
1.134 + CSvrDomain* iRootDomain;
1.135 + CSvrDomain* iTransDomain;
1.136 + TInt iTransPropValue;
1.137 + TDmDomainState iTransState;
1.138 + TDmTraverseDirection iTraverseDirection;
1.139 + TUint8 iTransId;
1.140 + CDmManagerSession* iControllerSession; // only one controller per hierarchy
1.141 + TDmHierarchyPolicy iPolicy;
1.142 + RArray<TTransitionFailure> iTransitionFailures;
1.143 +
1.144 + // observer stuff
1.145 + TBool iObserverStarted;
1.146 + TDmNotifyType iNotifyType;
1.147 + RArray<TTransInfo> iTransitions;
1.148 + CDmManagerSession* iObserverSession; // only one observer per hierarchy
1.149 + TInt iObservedChildren;
1.150 + };
1.151 +
1.152 +
1.153 +// CPowerUpHandler
1.154 +// Active object used to receive power-up notifications
1.155 +// from the Kernel-level power manager
1.156 +class CPowerUpHandler : public CActive
1.157 + {
1.158 +public:
1.159 + static CPowerUpHandler* New(CDmHierarchyPower& aHierarchyPower);
1.160 +
1.161 + // from CActive
1.162 + void RunL();
1.163 + void DoCancel();
1.164 +
1.165 + void RequestWakeupEventNotification();
1.166 + void Cancel();
1.167 +
1.168 +private:
1.169 + CPowerUpHandler(CDmHierarchyPower& aHierarchyPower);
1.170 + void Construct();
1.171 +
1.172 +private:
1.173 + CDmHierarchyPower& iHierarchyPower;
1.174 + };
1.175 +
1.176 +
1.177 +// CDmHierarchyPower
1.178 +// CDmHierarchy-derived class
1.179 +// Interfaces to the Kernel-level power manager
1.180 +class CDmHierarchyPower : public CDmHierarchy
1.181 + {
1.182 +public:
1.183 + static CDmHierarchyPower* New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
1.184 +
1.185 + // from CDmHierarchy
1.186 + virtual TInt RequestSystemTransition(TDmDomainState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage);
1.187 + virtual void CompleteTransition(TInt aError);
1.188 + virtual void NotifyCompletion(TInt aReason);
1.189 +
1.190 + void PowerUp(); // called from CPowerUpHandler
1.191 +
1.192 +private:
1.193 + CDmHierarchyPower(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy);
1.194 + void Construct();
1.195 +
1.196 +private:
1.197 + enum
1.198 + {
1.199 + EPoweringDown = 0x01,
1.200 + };
1.201 + TUint8 iTransStatus;
1.202 + CPowerUpHandler* iPowerUpHandler;
1.203 + };
1.204 +
1.205 +
1.206 +// CDmSvrManager
1.207 +class CDmSvrManager : public CBase
1.208 + {
1.209 +public:
1.210 + static CDmSvrManager* New();
1.211 +
1.212 + TInt BuildDomainTree(TDmHierarchyId aHierarchyId, CDmHierarchy*& aHierarchy);
1.213 + CDmHierarchy* LookupHierarchy(TDmHierarchyId aHierarchyId);
1.214 + TInt LookupDomain(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, CSvrDomain*& aDomain);
1.215 +
1.216 +private:
1.217 + CDmSvrManager();
1.218 + void Construct();
1.219 +
1.220 +private:
1.221 + RPointerArray<CDmHierarchy> iDomainHierarchies;
1.222 + };
1.223 +
1.224 +// CDmDomainServer
1.225 +class CDmDomainServer : public CServer2
1.226 + {
1.227 +public:
1.228 + // from CServer2
1.229 + CSession2* NewSessionL(const TVersion& aVer) const;
1.230 + CSession2* NewSessionL(const TVersion& aVer, const RMessage2& aMessage) const;
1.231 +
1.232 + CDmDomainServer(CDmSvrManager* aManager) : CServer2(CActive::EPriorityStandard), iManager(aManager)
1.233 + {}
1.234 +
1.235 +public:
1.236 + CDmSvrManager* iManager;
1.237 + };
1.238 +
1.239 +// CDmDomainSession
1.240 +class CDmDomainSession : public CSession2
1.241 + {
1.242 +public:
1.243 + // from CBase
1.244 + ~CDmDomainSession();
1.245 +
1.246 + // from CSession2
1.247 + void ServiceL(const RMessage2& aMessage);
1.248 +
1.249 +private:
1.250 + CSvrDomain* iDomain;
1.251 +
1.252 +public:
1.253 + CDmDomainSession* iNext;
1.254 + TUint8 iPending;
1.255 + TBool iNotificationEnabled;
1.256 + };
1.257 +
1.258 +class CDmManagerServer : public CServer2
1.259 + {
1.260 +public:
1.261 + // from CServer2
1.262 + CSession2* NewSessionL(const TVersion& aVer) const;
1.263 + CSession2* NewSessionL(const TVersion& aVer, const RMessage2&) const;
1.264 +
1.265 + CDmManagerServer(CDmSvrManager* aManager) : CServer2(CActive::EPriorityStandard), iManager(aManager)
1.266 + {}
1.267 + CDmSvrManager* iManager;
1.268 + };
1.269 +
1.270 +class CDmManagerSession : public CSession2
1.271 + {
1.272 +public:
1.273 + // from CBase
1.274 + ~CDmManagerSession();
1.275 +
1.276 + // from CSession2
1.277 + void ServiceL(const RMessage2& aMessage);
1.278 +
1.279 + CDmManagerSession();
1.280 +private:
1.281 + CDmHierarchy* iHierarchy; // not owned
1.282 + };
1.283 +
1.284 +
1.285 +
1.286 +
1.287 +//*********************************************************
1.288 +// TTransitionFailure
1.289 +//*********************************************************
1.290 +/**
1.291 +@internalTechnology
1.292 +
1.293 +Constructor for transition failure info.
1.294 +
1.295 +@param aDomainID Id of the domain of interest
1.296 +@param aError error code of transition
1.297 +*/
1.298 +TTransitionFailure::TTransitionFailure(TDmDomainId aDomainId, TInt aError) :
1.299 + iDomainId(aDomainId), iError(aError)
1.300 + {
1.301 + }
1.302 +
1.303 +//*********************************************************
1.304 +// TTransInfo
1.305 +//*********************************************************
1.306 +
1.307 +/**
1.308 +@internalTechnology
1.309 +
1.310 +Constructor for transition failure info.
1.311 +
1.312 +@param aDomainID Id of the domain of interest
1.313 +@param aState State of the domain after transition
1.314 +@param aError error code of transition
1.315 +*/
1.316 +TTransInfo::TTransInfo(TDmDomainId aDomainId, TDmDomainState aState, TInt aError) :
1.317 + iDomainId(aDomainId), iState(aState), iError(aError)
1.318 + {
1.319 + }
1.320 +
1.321 +//*********************************************************
1.322 +// CSvrDomain
1.323 +//*********************************************************
1.324 +
1.325 +
1.326 +CSvrDomain::CSvrDomain(CDmHierarchy& aHierarchy, const TDmDomainSpec* spec)
1.327 + : CTimer(CActive::EPriorityStandard),
1.328 + iHierarchy(aHierarchy),
1.329 + iTransTimeBudget(spec->iTimeBudgetUs),
1.330 + iJoinPolicy(spec->iJoinPolicy),
1.331 + iId(spec->iId)
1.332 + {}
1.333 +
1.334 +CSvrDomain* CSvrDomain::New(CDmHierarchy& aHierarchy, const TDmDomainSpec& aSpec)
1.335 + {
1.336 +
1.337 + CSvrDomain* self = new CSvrDomain(aHierarchy, &aSpec);
1.338 +
1.339 + if (!self)
1.340 + __DS_PANIC(KErrNoMemory);
1.341 + self->Construct(&aSpec);
1.342 + return self;
1.343 + }
1.344 +
1.345 +void CSvrDomain::Construct(const TDmDomainSpec* spec)
1.346 + {
1.347 + TInt r = iProperty.Define(
1.348 + KUidDmPropertyCategory,
1.349 + DmStatePropertyKey(iHierarchy.iHierarchyId, iId),
1.350 + RProperty::EInt,
1.351 + KAllowAllPolicy,KPowerMgmtPolicy);
1.352 +
1.353 + if (r != KErrNone)
1.354 + __DS_PANIC(r);
1.355 +
1.356 + r = iProperty.Attach(KUidDmPropertyCategory, DmStatePropertyKey(
1.357 + iHierarchy.iHierarchyId,
1.358 + iId));
1.359 +
1.360 + if (r != KErrNone)
1.361 + __DS_PANIC(r);
1.362 +
1.363 + r = iProperty.Set(DmStatePropertyValue(0, spec->iInitState));
1.364 + if (r != KErrNone)
1.365 + __DS_PANIC(r);
1.366 +
1.367 + TRAP(r, CTimer::ConstructL());
1.368 + if (r != KErrNone)
1.369 + __DS_PANIC(r);
1.370 + CActiveScheduler::Add(this);
1.371 + }
1.372 +
1.373 +void CSvrDomain::Attach(CDmDomainSession* aSession)
1.374 + {
1.375 + aSession->iNext = iSessions;
1.376 + iSessions = aSession;
1.377 + }
1.378 +
1.379 +void CSvrDomain::Detach(CDmDomainSession* aSession)
1.380 + {
1.381 + CDmDomainSession** prevp = &iSessions;
1.382 + while (*prevp != aSession)
1.383 + {
1.384 + prevp = &((*prevp)->iNext);
1.385 + __DS_ASSERT(*prevp);
1.386 + }
1.387 + *(prevp) = aSession->iNext;
1.388 + }
1.389 +
1.390 +void CSvrDomain::AddChild(CSvrDomain* aChild)
1.391 + {
1.392 + ++iChildrenCount;
1.393 + aChild->iParent = this;
1.394 + if(iIsObserved)
1.395 + aChild->iIsObserved=ETrue;
1.396 + // Insert the child in the list of its peers
1.397 + aChild->iPeer = iChild;
1.398 + iChild = aChild;
1.399 + }
1.400 +
1.401 +CSvrDomain* CSvrDomain::Lookup(TDmDomainId aDomainId)
1.402 + {
1.403 + if (iId == aDomainId)
1.404 + return this;
1.405 +
1.406 + CSvrDomain* child = iChild;
1.407 + while (child)
1.408 + {
1.409 + CSvrDomain* domain = child->Lookup(aDomainId);
1.410 + if (domain)
1.411 + return domain;
1.412 + child = child->iPeer;
1.413 + }
1.414 + return NULL;
1.415 + }
1.416 +
1.417 +TBool CSvrDomain::CheckPropValue(TInt aPropValue)
1.418 + { return iHierarchy.iTransPropValue == aPropValue; }
1.419 +
1.420 +void CSvrDomain::RequestMembersTransition()
1.421 + {
1.422 + __DS_TRACE((_L("CSvrDomain::RequestMembersTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
1.423 + __DS_ASSERT(iTransCount == 0);
1.424 +
1.425 + for(CDmDomainSession* s = iSessions; s; s = s->iNext)
1.426 + if (s->iNotificationEnabled)
1.427 + {
1.428 + ++iTransCount;
1.429 + s->iPending = ETrue;
1.430 + // notifications will be disabled until the client makes another
1.431 + // call to RDmDomain::RequestTransitionNotification()
1.432 + s->iNotificationEnabled = EFalse;
1.433 + }
1.434 +
1.435 + if(iIsObserved)
1.436 + {
1.437 + if((iHierarchy.iNotifyType&EDmNotifyTransRequest)==EDmNotifyTransRequest)
1.438 + {
1.439 + TTransInfo transInfo(iId,State(),KDmErrOutstanding);
1.440 + iHierarchy.iTransitions.Append(transInfo);
1.441 + if(iHierarchy.OutstandingNotification())
1.442 + iHierarchy.CompleteNotification(KErrNone);
1.443 + }
1.444 + }
1.445 + if (iTransCount > 0)
1.446 + CTimer::After(iTransTimeBudget);
1.447 + iProperty.Set(iHierarchy.iTransPropValue);
1.448 + if (iTransCount == 0)
1.449 + MembersTransitionDone();
1.450 + }
1.451 +
1.452 +
1.453 +void CSvrDomain::RequestChildrenTransition()
1.454 + {
1.455 + __DS_TRACE((_L("CSvrDomain::RequestChildrenTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
1.456 + __DS_ASSERT(iTransCount == 0);
1.457 + iTransCount = iChildrenCount;
1.458 + if (iTransCount)
1.459 + {
1.460 + CSvrDomain* child = iChild;
1.461 + __DS_ASSERT(child);
1.462 + do {
1.463 + child->RequestDomainTransition();
1.464 + child = child->iPeer;
1.465 + }
1.466 + while(child);
1.467 + }
1.468 + else
1.469 + ChildrenTransitionDone();
1.470 + }
1.471 +
1.472 +void CSvrDomain::RequestDomainTransition()
1.473 + {
1.474 + __DS_TRACE((_L("CSvrDomain::RequestDomainTransition() hierarchy=%d, domain=0x%x state=0x%x prop=0x%x"),
1.475 + iHierarchy.iHierarchyId, iId, iHierarchy.iTransState, iHierarchy.iTransPropValue));
1.476 + __DS_ASSERT(iTransCount == 0);
1.477 + if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
1.478 + RequestChildrenTransition();
1.479 + else
1.480 + RequestMembersTransition();
1.481 + }
1.482 +
1.483 +void CSvrDomain::MembersTransitionDone()
1.484 + {
1.485 + __DS_TRACE((_L("CSvrDomain::MembersTransitionDone() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
1.486 + __DS_ASSERT(iTransCount == 0);
1.487 + if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
1.488 + CompleteDomainTransition();
1.489 + else
1.490 + RequestChildrenTransition();
1.491 + }
1.492 +
1.493 +void CSvrDomain::ChildrenTransitionDone()
1.494 + {
1.495 + __DS_TRACE((_L("CSvrDomain::ChildrenTransitionDone() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
1.496 + __DS_ASSERT(iTransCount == 0);
1.497 + if (iHierarchy.iTraverseDirection == ETraverseChildrenFirst)
1.498 + RequestMembersTransition();
1.499 + else
1.500 + CompleteDomainTransition();
1.501 + }
1.502 +
1.503 +void CSvrDomain::CompleteMemberTransition(TInt aError)
1.504 + {
1.505 + __DS_TRACE((_L("CSvrDomain::CompleteMemberTransition() hierarchy=%d, domain=0x%x, aError = %d"), iHierarchy.iHierarchyId, iId, aError));
1.506 + __DS_ASSERT(iTransCount);
1.507 +
1.508 + if (aError)
1.509 + {
1.510 + // Add a transition failure to the array
1.511 + TTransitionFailure failure(iId, aError);
1.512 + iHierarchy.iTransitionFailures.Append(failure);
1.513 +
1.514 + if(iIsObserved)
1.515 + {
1.516 + if((iHierarchy.iNotifyType&EDmNotifyFail)==EDmNotifyFail)
1.517 + {
1.518 + TTransInfo transInfo(iId,State(),aError);
1.519 + iHierarchy.iTransitions.Append(transInfo);
1.520 + if(iHierarchy.OutstandingNotification())
1.521 + iHierarchy.CompleteNotification(KErrNone);
1.522 + }
1.523 + }
1.524 + // examine the failure policy to work out what to do
1.525 + if (iHierarchy.iPolicy.iFailurePolicy == ETransitionFailureStop)
1.526 + {
1.527 + iHierarchy.CompleteTransition(aError);
1.528 + return;
1.529 + }
1.530 + }
1.531 + else if(iIsObserved)
1.532 + {
1.533 + if((iHierarchy.iNotifyType&EDmNotifyPass) == EDmNotifyPass)
1.534 + {
1.535 + TTransInfo transInfo(iId,State(),aError);
1.536 + iHierarchy.iTransitions.Append(transInfo);
1.537 + if(iHierarchy.OutstandingNotification())
1.538 + iHierarchy.CompleteNotification(KErrNone);
1.539 + }
1.540 + }
1.541 +
1.542 + if (--iTransCount == 0)
1.543 + {
1.544 + CTimer::Cancel();
1.545 + MembersTransitionDone();
1.546 + }
1.547 + }
1.548 +
1.549 +void CSvrDomain::RunL()
1.550 + { // Timer expired
1.551 + __DS_TRACE((_L("CSvrDomain::RunL() Members transition timeout hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
1.552 +
1.553 + // Add a transition failure to the array
1.554 + TTransitionFailure failure(iId,KErrTimedOut);
1.555 + iHierarchy.iTransitionFailures.Append(failure);
1.556 +
1.557 +
1.558 + // examine the failure policy to work out what to do
1.559 + if (iHierarchy.iPolicy.iFailurePolicy == ETransitionFailureStop)
1.560 + {
1.561 + iHierarchy.CompleteTransition(KErrTimedOut);
1.562 + return;
1.563 + }
1.564 +
1.565 + if (iTransCount)
1.566 + { // Complete transition of all members
1.567 + CDmDomainSession* session = iSessions;
1.568 + while (session)
1.569 + {
1.570 + session->iPending = EFalse;
1.571 + session = session->iNext;
1.572 + }
1.573 + iTransCount = 0;
1.574 + MembersTransitionDone();
1.575 + }
1.576 + }
1.577 +
1.578 +
1.579 +void CSvrDomain::CompleteDomainTransition()
1.580 + {
1.581 + __DS_TRACE((_L("CSvrDomain::CompleteDomainTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
1.582 + __DS_ASSERT(iTransCount == 0);
1.583 + if (iHierarchy.iTransDomain == this)
1.584 + {
1.585 + const TInt err = (iHierarchy.iTransitionFailures.Count() > 0)?
1.586 + iHierarchy.iTransitionFailures[0].iError : KErrNone;
1.587 + iHierarchy.CompleteTransition(err);
1.588 + }
1.589 + else
1.590 + {
1.591 + __DS_ASSERT(iParent);
1.592 + __DS_ASSERT(iParent->iTransCount);
1.593 + if (--iParent->iTransCount == 0)
1.594 + iParent->ChildrenTransitionDone();
1.595 + }
1.596 + }
1.597 +
1.598 +void CSvrDomain::CancelTransition()
1.599 + {
1.600 + __DS_TRACE((_L("CSvrDomain::CancelTransition() hierarchy=%d, domain=0x%x"), iHierarchy.iHierarchyId, iId));
1.601 + CTimer::Cancel();
1.602 + CSvrDomain* child = iChild;
1.603 + while (child)
1.604 + {
1.605 + child->CancelTransition();
1.606 + child = child->iPeer;
1.607 + }
1.608 + CDmDomainSession* session = iSessions;
1.609 + while (session)
1.610 + {
1.611 + session->iPending = EFalse;
1.612 + session = session->iNext;
1.613 + }
1.614 + iTransCount = 0;
1.615 + }
1.616 +
1.617 +void CSvrDomain::SetObserver(TBool aSet)
1.618 + {
1.619 + iIsObserved=aSet;
1.620 + if(aSet)
1.621 + {
1.622 + iHierarchy.iObservedChildren++;
1.623 + }
1.624 + else
1.625 + {
1.626 + // this should be zero at the end
1.627 + iHierarchy.iObservedChildren--;
1.628 + }
1.629 + if(iChildrenCount!=0)
1.630 + {
1.631 + CSvrDomain* domain=iChild;
1.632 + do {
1.633 + domain->SetObserver(aSet);
1.634 + domain = domain->iPeer;
1.635 + }
1.636 + while(domain);
1.637 + }
1.638 + }
1.639 +
1.640 +TDmDomainState CSvrDomain::State()
1.641 + {
1.642 + TInt value;
1.643 + iProperty.Get(value);
1.644 + return DmStateFromPropertyValue(value);
1.645 + }
1.646 +
1.647 +//*********************************************************
1.648 +// CDmHierarchy
1.649 +//*********************************************************
1.650 +
1.651 +CDmHierarchy* CDmHierarchy::New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy)
1.652 + {
1.653 + CDmHierarchy* self;
1.654 +
1.655 + if (aHierarchyId == KDmHierarchyIdPower)
1.656 + self = CDmHierarchyPower::New(aHierarchyId, aPolicy);
1.657 + else
1.658 + self = new CDmHierarchy(aHierarchyId, aPolicy);
1.659 +
1.660 + if (!self)
1.661 + __DS_PANIC(KErrNoMemory);
1.662 +
1.663 + return self;
1.664 + }
1.665 +
1.666 +CDmHierarchy::CDmHierarchy(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy) :
1.667 + iOutstandingNotification(EFalse),
1.668 + iHierarchyId(aHierarchyId),
1.669 + iPolicy(aPolicy)
1.670 + {
1.671 + iTransitionFailures.Reset();
1.672 + }
1.673 +
1.674 +CSvrDomain* CDmHierarchy::LookupDomain(TDmDomainId aDomainId)
1.675 + {
1.676 + return iRootDomain ? iRootDomain->Lookup(aDomainId) : NULL;
1.677 + }
1.678 +
1.679 +void CDmHierarchy::RequestTransition(const RMessage2* aMessage)
1.680 + {
1.681 + // reset the array of transition failures
1.682 + iTransitionFailures.Reset();
1.683 +
1.684 + if (aMessage)
1.685 + iTransMessagePtr = *aMessage;
1.686 + iTransPropValue = DmStatePropertyValue(++iTransId, iTransState);
1.687 +
1.688 + iTransDomain->RequestDomainTransition();
1.689 + }
1.690 +
1.691 +
1.692 +TInt CDmHierarchy::StartObserver(TDmDomainId aDomainId,TDmNotifyType aNotifyType)
1.693 + {
1.694 + iObservedDomain = LookupDomain(aDomainId);
1.695 +
1.696 + if(iObservedDomain==NULL)
1.697 + return KDmErrBadDomainId;
1.698 +
1.699 +
1.700 + iObservedDomain->SetObserver(ETrue);
1.701 + iNotifyType=aNotifyType;
1.702 + iObserverStarted=ETrue;
1.703 + return KErrNone;
1.704 + }
1.705 +
1.706 +void CDmHierarchy::SetNotifyMessage(const RMessage2* aMessage)
1.707 + {
1.708 + if (aMessage)
1.709 + {
1.710 + iObsvrMessagePtr = *aMessage;
1.711 + iOutstandingNotification=ETrue;
1.712 + }
1.713 + }
1.714 +
1.715 +TBool CDmHierarchy::OutstandingNotification()
1.716 + {
1.717 + return iOutstandingNotification;
1.718 + }
1.719 +
1.720 +void CDmHierarchy::CompleteNotification(TInt aError)
1.721 + {
1.722 + if(iOutstandingNotification)
1.723 + {
1.724 + iObsvrMessagePtr.Complete(aError);
1.725 + iOutstandingNotification=EFalse;
1.726 + }
1.727 + }
1.728 +
1.729 +void CDmHierarchy::StopObserver()
1.730 + {
1.731 +
1.732 + iObservedDomain->SetObserver(EFalse);
1.733 + iTransitions.Reset();
1.734 + iObserverStarted=EFalse;
1.735 + }
1.736 +void CDmHierarchy::NotifyCompletion(TInt aReason)
1.737 + {
1.738 + iTransDomain = NULL;
1.739 + iTransPropValue = 0;
1.740 + iTransMessagePtr.Complete(aReason);
1.741 + }
1.742 +
1.743 +TInt CDmHierarchy::RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage)
1.744 + {
1.745 + iTransDomain = iRootDomain;
1.746 + SetState(aTargetState, aTraverseDirection);
1.747 + RequestTransition(aMessage);
1.748 + return KErrNone;
1.749 + }
1.750 +
1.751 +
1.752 +TInt CDmHierarchy::RequestDomainTransition(
1.753 + TDmDomainId aDomainId,
1.754 + TDmDomainState aTargetState,
1.755 + TDmTraverseDirection aTraverseDirection,
1.756 + const RMessage2* aMessage)
1.757 + {
1.758 + __DS_TRACE((_L("CDmHierarchy::RequestTransition() hierarchy=%d domain=0x%x state=0x%x"), iHierarchyId, aDomainId, aTargetState));
1.759 + iTransDomain = LookupDomain(aDomainId);
1.760 + if (!iTransDomain)
1.761 + return KDmErrBadDomainId;
1.762 + SetState(aTargetState, aTraverseDirection);
1.763 + RequestTransition(aMessage);
1.764 + return KErrNone;
1.765 + }
1.766 +
1.767 +void CDmHierarchy::CompleteTransition(TInt aError)
1.768 + {
1.769 + if (!iTransDomain)
1.770 + return;
1.771 +
1.772 + __DS_TRACE((_L("CDmHierarchy::CompleteTransition() hierarchy=%d, domain=0x%x, aError=%d"), iHierarchyId, iTransDomain->iId, aError));
1.773 +
1.774 + if (iTransDomain)
1.775 + {
1.776 + iTransDomain->CancelTransition();
1.777 + NotifyCompletion(aError);
1.778 + }
1.779 + }
1.780 +
1.781 +void CDmHierarchy::SetState(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection)
1.782 + {
1.783 + __DS_ASSERT(iTransDomain);
1.784 +
1.785 +
1.786 + if (aTraverseDirection == ETraverseDefault)
1.787 + {
1.788 + TDmDomainState oldState = iTransDomain->State();
1.789 +
1.790 + if (aTargetState >= oldState)
1.791 + iTraverseDirection = iPolicy.iPositiveTransitions;
1.792 + else
1.793 + iTraverseDirection = iPolicy.iNegativeTransitions;
1.794 + }
1.795 + else
1.796 + iTraverseDirection = aTraverseDirection;
1.797 +
1.798 + __DS_ASSERT(iTraverseDirection < ETraverseMax);
1.799 +
1.800 + iTransState = aTargetState;
1.801 + }
1.802 +
1.803 +//*********************************************************
1.804 +// CPowerUpHandler
1.805 +//*********************************************************
1.806 +
1.807 +CPowerUpHandler* CPowerUpHandler::New(CDmHierarchyPower& aHierarchyPower)
1.808 + {
1.809 + CPowerUpHandler* self = new CPowerUpHandler(aHierarchyPower);
1.810 + if (!self)
1.811 + __DS_PANIC(KErrNoMemory);
1.812 + self->Construct();
1.813 + return self;
1.814 + }
1.815 +
1.816 +CPowerUpHandler::CPowerUpHandler(CDmHierarchyPower& aHierarchyPower) :
1.817 + CActive(CActive::EPriorityStandard),
1.818 + iHierarchyPower(aHierarchyPower)
1.819 + {
1.820 + }
1.821 +
1.822 +void CPowerUpHandler::Construct()
1.823 + {
1.824 + CActiveScheduler::Add(this);
1.825 + }
1.826 +
1.827 +
1.828 +void CPowerUpHandler::RequestWakeupEventNotification()
1.829 + {
1.830 + Power::RequestWakeupEventNotification(iStatus);
1.831 + SetActive();
1.832 + }
1.833 +
1.834 +
1.835 +void CPowerUpHandler::Cancel()
1.836 + {
1.837 + CActive::Cancel();
1.838 + }
1.839 +
1.840 +void CPowerUpHandler::RunL()
1.841 + {
1.842 + // power wakeup event
1.843 + iHierarchyPower.PowerUp();
1.844 + }
1.845 +
1.846 +
1.847 +void CPowerUpHandler::DoCancel()
1.848 + {
1.849 + Power::DisableWakeupEvents();
1.850 + Power::CancelWakeupEventNotification();
1.851 + }
1.852 +
1.853 +
1.854 +
1.855 +//*********************************************************
1.856 +// CDmHierarchyPower
1.857 +//*********************************************************
1.858 +CDmHierarchyPower* CDmHierarchyPower::New(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy)
1.859 + {
1.860 + CDmHierarchyPower* self;
1.861 +
1.862 + self = new CDmHierarchyPower(aHierarchyId, aPolicy);
1.863 +
1.864 + if (!self)
1.865 + __DS_PANIC(KErrNoMemory);
1.866 +
1.867 + self->Construct();
1.868 +
1.869 + return self;
1.870 + }
1.871 +
1.872 +CDmHierarchyPower::CDmHierarchyPower(TDmHierarchyId aHierarchyId, TDmHierarchyPolicy& aPolicy) :
1.873 + CDmHierarchy(aHierarchyId, aPolicy)
1.874 + {
1.875 + }
1.876 +
1.877 +
1.878 +void CDmHierarchyPower::Construct()
1.879 + {
1.880 + iPowerUpHandler = CPowerUpHandler::New(*this);
1.881 + if (!iPowerUpHandler)
1.882 + __DS_PANIC(KErrNoMemory);
1.883 + }
1.884 +
1.885 +void CDmHierarchyPower::NotifyCompletion(TInt aReason)
1.886 + {
1.887 + iTransStatus = 0;
1.888 + CDmHierarchy::NotifyCompletion(aReason);
1.889 + }
1.890 +
1.891 +TInt CDmHierarchyPower::RequestSystemTransition(TDmDomainState aTargetState, TDmTraverseDirection aTraverseDirection, const RMessage2* aMessage)
1.892 + {
1.893 + __DS_TRACE((_L("CDmSvrManager::RequestSystemTransition() state = 0x%x"), aTargetState));
1.894 +
1.895 + TInt r = Power::EnableWakeupEvents((TPowerState) aTargetState);
1.896 + if (r != KErrNone)
1.897 + return r;
1.898 +
1.899 + iPowerUpHandler->RequestWakeupEventNotification();
1.900 +
1.901 + iTransStatus |= EPoweringDown;
1.902 +
1.903 + return CDmHierarchy::RequestSystemTransition(aTargetState, aTraverseDirection, aMessage);
1.904 + }
1.905 +
1.906 +void CDmHierarchyPower::CompleteTransition(TInt aError)
1.907 + {
1.908 + if (!iTransDomain)
1.909 + return;
1.910 +
1.911 + __DS_TRACE((_L("CDmHierarchyPower::CompleteTransition() domain=0x%x"), iTransDomain->iId));
1.912 +
1.913 + if (iTransDomain && aError == KErrCancel)
1.914 + iPowerUpHandler->Cancel();
1.915 +
1.916 + if (iTransStatus & EPoweringDown)
1.917 + {
1.918 + RFs fs;
1.919 + TInt r=fs.Connect();
1.920 + __DS_ASSERT(r==KErrNone);
1.921 + __DS_TRACE((_L("CDmSvrManager::CompleteTransition() Calling FinaliseDrives")));
1.922 + r=fs.FinaliseDrives();
1.923 + __DS_TRACE((_L("CDmSvrManager::CompleteTransition() Finalise returned %d"),r));
1.924 + fs.Close();
1.925 +
1.926 + Power::PowerDown();
1.927 + __DS_ASSERT(iTransState != (TDmDomainState) EPwOff);
1.928 + __DS_ASSERT(iPowerUpHandler->iStatus.Int() == KErrNone);
1.929 + }
1.930 + else
1.931 + {
1.932 + CDmHierarchy::CompleteTransition(aError);
1.933 + }
1.934 + }
1.935 +
1.936 +
1.937 +void CDmHierarchyPower::PowerUp()
1.938 + {
1.939 + __DS_TRACE((_L("CDmHierarchyPower::RunL() Wakeup Event")));
1.940 + __DS_ASSERT(iTransDomain);
1.941 +
1.942 + Power::DisableWakeupEvents();
1.943 +
1.944 + iTransStatus &= ~EPoweringDown;
1.945 + iTransDomain->CancelTransition();
1.946 + SetState((TDmDomainState) EPwActive);
1.947 + RequestTransition(NULL);
1.948 + }
1.949 +
1.950 +
1.951 +//*********************************************************
1.952 +// CDmSvrManager
1.953 +//*********************************************************
1.954 +
1.955 +CDmSvrManager* CDmSvrManager::New()
1.956 + {
1.957 + CDmSvrManager* self = new CDmSvrManager();
1.958 + if (!self)
1.959 + __DS_PANIC(KErrNoMemory);
1.960 + self->Construct();
1.961 + return self;
1.962 + }
1.963 +
1.964 +CDmSvrManager::CDmSvrManager()
1.965 + {
1.966 + }
1.967 +
1.968 +void CDmSvrManager::Construct()
1.969 + {
1.970 + // load the power hierarchy- Other hieratchies need to be loaded
1.971 + // explicitly using RDmDomainManager::AddDomainHierarchy()
1.972 + CDmHierarchy* hierarchy;
1.973 + TInt r = BuildDomainTree(KDmHierarchyIdPower, hierarchy);
1.974 + if (r != KErrNone)
1.975 + __DS_PANIC(r);
1.976 +
1.977 +
1.978 + RProperty prop;
1.979 + r = prop.Define(KUidDmPropertyCategory, KDmPropertyKeyInit, RProperty::EInt,
1.980 + KAllowAllPolicy,KPowerMgmtPolicy);
1.981 + if (r != KErrNone)
1.982 + __DS_PANIC(r);
1.983 +
1.984 + prop.Set(KUidDmPropertyCategory, KDmPropertyKeyInit, ETrue);
1.985 + }
1.986 +
1.987 +TInt CDmSvrManager::BuildDomainTree(TDmHierarchyId aHierarchyId, CDmHierarchy*& aHierarchy)
1.988 + {
1.989 +
1.990 + aHierarchy = NULL;
1.991 +
1.992 + // assume we have already checked that the hierarchy doesn't already exist
1.993 +
1.994 + // Get the name of the policy Dll
1.995 + // This will be "domainPolicy.dll" for the power hierarchy
1.996 + // and "domainPolicy<n>.dll" for other hierarchies where <n> is the hierarchy ID.
1.997 + //
1.998 + // If the hierarchy ID is less than KMaxCriticalPolicyDll, load only from ROM
1.999 +
1.1000 + TFullName dllName;
1.1001 +
1.1002 + // is this policy "critical" i.e non-replaceable ?
1.1003 + _LIT(KSysBin,"z:\\sys\\bin\\");
1.1004 + // const TInt KMaxCriticalPolicyDll = 1000;
1.1005 + // if (aHierarchyId < KMaxCriticalPolicyDll) // <-- cannot be false while aHierarchyId is a TUint8 (typedef'd to TDmHierarchyId)
1.1006 + dllName.Append(KSysBin);
1.1007 +
1.1008 + dllName.Append(_L("domainPolicy"));
1.1009 + if (aHierarchyId != KDmHierarchyIdPower)
1.1010 + dllName.AppendNum(aHierarchyId);
1.1011 +
1.1012 + dllName.Append(_L(".dll"));
1.1013 + RLibrary lib;
1.1014 + TInt r = lib.Load(dllName);
1.1015 + if (r == KErrNotFound)
1.1016 + return KErrBadHierarchyId;
1.1017 + else if (r != KErrNone)
1.1018 + return r;
1.1019 +
1.1020 + TLibraryFunction ordinal1 = lib.Lookup(EDmPolicyGetDomainSpecs);
1.1021 + DmPolicyGetDomainSpecs getDomainSpecs = reinterpret_cast<DmPolicyGetDomainSpecs>(ordinal1);
1.1022 + if (getDomainSpecs == NULL)
1.1023 + r = KErrBadHierarchyId;
1.1024 +
1.1025 + TLibraryFunction ordinal2 = lib.Lookup(EDmPolicyRelease);
1.1026 + DmPolicyRelease release = reinterpret_cast<DmPolicyRelease>(ordinal2);
1.1027 + if (release == NULL)
1.1028 + r = KErrBadHierarchyId;
1.1029 +
1.1030 + TLibraryFunction ordinal3 = lib.Lookup(EDmPolicyGetPolicy);
1.1031 + DmPolicyGetPolicy getPolicy = reinterpret_cast<DmPolicyGetPolicy>(ordinal3);
1.1032 + if (getPolicy == NULL)
1.1033 + r = KErrBadHierarchyId;
1.1034 +
1.1035 +
1.1036 + // get the domain spec for this hierarchy
1.1037 + const TDmDomainSpec* spec = NULL;
1.1038 +
1.1039 + if (r == KErrNone)
1.1040 + {
1.1041 + spec = (*getDomainSpecs)();
1.1042 + if (spec == NULL)
1.1043 + r = KErrBadHierarchyId;
1.1044 + }
1.1045 + // get the policy
1.1046 + TDmHierarchyPolicy hierarchyPolicy;
1.1047 + if (r == KErrNone)
1.1048 + {
1.1049 + r = (*getPolicy)(hierarchyPolicy);
1.1050 + if (r == KErrNone)
1.1051 + {
1.1052 + __DS_ASSERT(hierarchyPolicy.iPositiveTransitions < ETraverseMax);
1.1053 + __DS_ASSERT(hierarchyPolicy.iNegativeTransitions < ETraverseMax);
1.1054 + }
1.1055 + }
1.1056 +
1.1057 + if (r != KErrNone)
1.1058 + {
1.1059 + lib.Close();
1.1060 + return r;
1.1061 + }
1.1062 +
1.1063 + CDmHierarchy* hierarchy = CDmHierarchy::New(aHierarchyId, hierarchyPolicy);
1.1064 + if (hierarchy == NULL)
1.1065 + __DS_PANIC(KErrNoMemory);
1.1066 +
1.1067 + while (r == KErrNone && spec->iId != KDmIdNone)
1.1068 + {
1.1069 + // make sure the domain doesn't already exist in this hierarchy
1.1070 + CSvrDomain* domain = hierarchy->LookupDomain(spec->iId);
1.1071 + if (domain)
1.1072 + {
1.1073 + r = KErrBadHierarchyId;
1.1074 + break;
1.1075 + }
1.1076 +
1.1077 + domain = CSvrDomain::New(*hierarchy, *spec);
1.1078 + __DS_ASSERT(domain);
1.1079 +
1.1080 + if (spec->iParentId == KDmIdNone)
1.1081 + {
1.1082 + if (hierarchy->iRootDomain)
1.1083 + {
1.1084 + r = KDmErrBadDomainSpec;
1.1085 + break;
1.1086 + }
1.1087 + hierarchy->iRootDomain = domain;
1.1088 + }
1.1089 + else
1.1090 + {
1.1091 + CSvrDomain* parent = hierarchy->LookupDomain(spec->iParentId);
1.1092 + if (!parent)
1.1093 + {
1.1094 + r = KDmErrBadDomainSpec;
1.1095 + break;
1.1096 + }
1.1097 + parent->AddChild(domain);
1.1098 + }
1.1099 + ++spec;
1.1100 + }
1.1101 +
1.1102 + if (spec)
1.1103 + (*release)(spec);
1.1104 +
1.1105 +
1.1106 + if (r == KErrNone)
1.1107 + {
1.1108 + __DS_ASSERT(hierarchy->iRootDomain);
1.1109 + iDomainHierarchies.Append(hierarchy);
1.1110 + aHierarchy = hierarchy;
1.1111 + }
1.1112 + else
1.1113 + {
1.1114 + delete hierarchy;
1.1115 + hierarchy = NULL;
1.1116 + }
1.1117 +
1.1118 + lib.Close();
1.1119 +
1.1120 + return r;
1.1121 + }
1.1122 +
1.1123 +CDmHierarchy* CDmSvrManager::LookupHierarchy(TDmHierarchyId aHierarchyId)
1.1124 +
1.1125 + {
1.1126 + // need to find the correct hierarchy first
1.1127 + TInt len = iDomainHierarchies.Count();
1.1128 +
1.1129 + CDmHierarchy* hierarchy = NULL;
1.1130 + for (TInt n=0; n<len; n++)
1.1131 + {
1.1132 + if (iDomainHierarchies[n]->iHierarchyId == aHierarchyId)
1.1133 + {
1.1134 + hierarchy = iDomainHierarchies[n];
1.1135 + break;
1.1136 + }
1.1137 + }
1.1138 +
1.1139 + return hierarchy;
1.1140 + }
1.1141 +
1.1142 +
1.1143 +TInt CDmSvrManager::LookupDomain(TDmHierarchyId aHierarchyId, TDmDomainId aDomainId, CSvrDomain*& aDomain)
1.1144 + {
1.1145 + // need to find the correct hierarchy first
1.1146 + CDmHierarchy* hierarchy = LookupHierarchy(aHierarchyId);
1.1147 + if (hierarchy == NULL)
1.1148 + return KErrBadHierarchyId;
1.1149 +
1.1150 + aDomain = hierarchy->LookupDomain(aDomainId);
1.1151 + if (aDomain == NULL)
1.1152 + return KDmErrBadDomainId;
1.1153 +
1.1154 + return KErrNone;
1.1155 + }
1.1156 +
1.1157 +CSession2* CDmManagerServer::NewSessionL(const TVersion&, const RMessage2& aMessage) const
1.1158 + {
1.1159 +
1.1160 + // If the client does not have ECapabilityPowerMgmt capability, then it has no
1.1161 + // right to make this request. Blow it up.
1.1162 + if (!KPowerMgmtPolicy.CheckPolicy(aMessage))
1.1163 + {
1.1164 +
1.1165 + User::Leave(KErrPermissionDenied);
1.1166 +
1.1167 + }
1.1168 +
1.1169 + return new CDmManagerSession();
1.1170 + }
1.1171 +
1.1172 +CSession2* CDmManagerServer::NewSessionL(const TVersion&) const
1.1173 + {
1.1174 + __DS_PANIC(KErrGeneral);
1.1175 + return 0;
1.1176 + }
1.1177 +
1.1178 +CDmManagerSession::CDmManagerSession()
1.1179 + {}
1.1180 +
1.1181 +CDmManagerSession::~CDmManagerSession()
1.1182 + {
1.1183 + if (iHierarchy && iHierarchy->iControllerSession == this)
1.1184 + iHierarchy->iControllerSession = NULL;
1.1185 + if (iHierarchy && iHierarchy->iObserverSession == this)
1.1186 + iHierarchy->iObserverSession = NULL;
1.1187 + }
1.1188 +
1.1189 +class MyMessage : public RMessage2
1.1190 + {
1.1191 +public:
1.1192 + TInt* ArgRef(TInt i)
1.1193 + { return &iArgs[i]; }
1.1194 + };
1.1195 +
1.1196 +void CDmManagerSession::ServiceL(const RMessage2& aMessage)
1.1197 + {
1.1198 + TInt r;
1.1199 + CDmSvrManager* manager = ((CDmManagerServer*) Server()) -> iManager;
1.1200 +
1.1201 + // Check client has ECapabilityPowerMgmt capability
1.1202 +/*
1.1203 + if (!KPowerMgmtPolicy.CheckPolicy(aMessage))
1.1204 + {
1.1205 + aMessage.Complete(KErrPermissionDenied);
1.1206 + return;
1.1207 + }
1.1208 +*/
1.1209 + switch (aMessage.Function())
1.1210 + {
1.1211 + case EDmHierarchyAdd:
1.1212 + {
1.1213 + r = KErrNone;
1.1214 + TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
1.1215 +
1.1216 + CDmHierarchy* hierarchy = manager->LookupHierarchy(hierarchyId);
1.1217 + if (hierarchy == NULL)
1.1218 + r = manager->BuildDomainTree(hierarchyId, hierarchy);
1.1219 + aMessage.Complete(r);
1.1220 + }
1.1221 + break;
1.1222 +
1.1223 + case EDmHierarchyJoin:
1.1224 + {
1.1225 + r = KErrNone;
1.1226 + TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
1.1227 +
1.1228 + iHierarchy = manager->LookupHierarchy(hierarchyId);
1.1229 + if (iHierarchy == NULL)
1.1230 + r = KErrBadHierarchyId;
1.1231 +
1.1232 + if (r == KErrNone)
1.1233 + {
1.1234 + // is the hierarchy already in use ?
1.1235 + if (iHierarchy->iControllerSession)
1.1236 + r = KErrInUse;
1.1237 + else
1.1238 + iHierarchy->iControllerSession = this;
1.1239 + }
1.1240 +
1.1241 + aMessage.Complete(r);
1.1242 + }
1.1243 + break;
1.1244 +
1.1245 + case EDmRequestSystemTransition:
1.1246 + if (iHierarchy==NULL)
1.1247 + {
1.1248 + aMessage.Complete(KErrBadHierarchyId);
1.1249 + break;
1.1250 + }
1.1251 + if (iHierarchy->iTransDomain)
1.1252 + {
1.1253 + aMessage.Complete(KDmErrBadSequence);
1.1254 + break;
1.1255 + }
1.1256 +
1.1257 + r = iHierarchy->RequestSystemTransition(
1.1258 + (TDmDomainState) aMessage.Int0(),
1.1259 + (TDmTraverseDirection) aMessage.Int1(),
1.1260 + &aMessage);
1.1261 +
1.1262 + if (r != KErrNone)
1.1263 + aMessage.Complete(r);
1.1264 + break;
1.1265 +
1.1266 + case EDmRequestDomainTransition:
1.1267 + if (iHierarchy==NULL)
1.1268 + {
1.1269 + aMessage.Complete(KErrBadHierarchyId);
1.1270 + break;
1.1271 + }
1.1272 + if (iHierarchy->iTransDomain)
1.1273 + {
1.1274 + aMessage.Complete(KDmErrBadSequence);
1.1275 + break;
1.1276 + }
1.1277 + r = iHierarchy->RequestDomainTransition(
1.1278 + (TDmDomainId) aMessage.Int0(),
1.1279 + (TDmDomainState) aMessage.Int1(),
1.1280 + (TDmTraverseDirection) aMessage.Int2(),
1.1281 + &aMessage);
1.1282 +
1.1283 + if (r != KErrNone)
1.1284 + aMessage.Complete(r);
1.1285 + break;
1.1286 +
1.1287 + case EDmGetTransitionFailureCount:
1.1288 + {
1.1289 + if (iHierarchy==NULL)
1.1290 + {
1.1291 + aMessage.Complete(KErrBadHierarchyId);
1.1292 + break;
1.1293 + }
1.1294 + TInt failureCount = iHierarchy->iTransitionFailures.Count();
1.1295 + aMessage.Complete(failureCount);
1.1296 + }
1.1297 + break;
1.1298 +
1.1299 + case EDmGetTransitionFailures:
1.1300 + {
1.1301 + if (iHierarchy==NULL)
1.1302 + {
1.1303 + aMessage.Complete(KErrBadHierarchyId);
1.1304 + break;
1.1305 + }
1.1306 + TInt failureCount = iHierarchy->iTransitionFailures.Count();
1.1307 + TInt clientFailureSize = aMessage.GetDesMaxLength(0);
1.1308 + TInt clientFailureCount = clientFailureSize / sizeof(TTransitionFailure);
1.1309 + __DS_ASSERT( (clientFailureSize % sizeof(TTransitionFailure)) == 0);
1.1310 + __DS_ASSERT(failureCount >= clientFailureCount);
1.1311 +
1.1312 + HBufC8* hBuf = HBufC8::New(clientFailureSize);
1.1313 + if(hBuf == NULL)
1.1314 + {
1.1315 + aMessage.Complete(KErrNoMemory);
1.1316 + break;
1.1317 + }
1.1318 + TPtr8 pBuf = hBuf->Des();
1.1319 + pBuf.Zero();
1.1320 + for (TInt i=0; i<clientFailureCount; i++)
1.1321 + {
1.1322 + TPtrC8 ptr = TPtrC8((TUint8*) &iHierarchy->iTransitionFailures[i], sizeof(TTransitionFailure));
1.1323 + pBuf.Append(ptr);
1.1324 + }
1.1325 + r = aMessage.Write(0, pBuf);
1.1326 + delete hBuf;
1.1327 +
1.1328 + aMessage.Complete(r);
1.1329 + }
1.1330 + break;
1.1331 +
1.1332 + case EDmCancelTransition:
1.1333 + if (iHierarchy == NULL)
1.1334 + {
1.1335 + aMessage.Complete(KErrBadHierarchyId);
1.1336 + break;
1.1337 + }
1.1338 + iHierarchy->CompleteTransition(KErrCancel);
1.1339 + if (iHierarchy->iObserverStarted)
1.1340 + {
1.1341 + iHierarchy->CompleteNotification(KErrCancel);
1.1342 + iHierarchy->StopObserver();
1.1343 + }
1.1344 + aMessage.Complete(KErrNone);
1.1345 + break;
1.1346 + case EDmObserverCancel:
1.1347 + if (iHierarchy == NULL)
1.1348 + {
1.1349 + aMessage.Complete(KErrBadHierarchyId);
1.1350 + break;
1.1351 + }
1.1352 + if(!iHierarchy->iObserverSession)
1.1353 + {
1.1354 + aMessage.Complete(KDmErrBadSequence);
1.1355 + break;
1.1356 + }
1.1357 + if (iHierarchy->iObserverStarted)
1.1358 + {
1.1359 + iHierarchy->CompleteNotification(KErrCancel);
1.1360 + iHierarchy->StopObserver();
1.1361 + }
1.1362 + aMessage.Complete(KErrNone);
1.1363 + break;
1.1364 +
1.1365 + case EDmObserverJoin:
1.1366 + {
1.1367 + TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
1.1368 +
1.1369 + iHierarchy = manager->LookupHierarchy(hierarchyId);
1.1370 + if(iHierarchy==NULL)
1.1371 + {
1.1372 + aMessage.Complete(KErrBadHierarchyId);
1.1373 + break;
1.1374 + }
1.1375 + if(iHierarchy->iObserverSession)
1.1376 + {
1.1377 + aMessage.Complete(KDmErrBadSequence);
1.1378 + break;
1.1379 + }
1.1380 + iHierarchy->iTransitions.Reset();
1.1381 + iHierarchy->iObserverSession = this;
1.1382 + aMessage.Complete(KErrNone);
1.1383 + }
1.1384 + break;
1.1385 +
1.1386 + case EDmObserverStart:
1.1387 + {
1.1388 + if (iHierarchy==NULL)
1.1389 + {
1.1390 + aMessage.Complete(KErrBadHierarchyId);
1.1391 + break;
1.1392 + }
1.1393 +
1.1394 + if(iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
1.1395 + {
1.1396 + aMessage.Complete(KDmErrBadSequence);
1.1397 + break;
1.1398 + }
1.1399 + TInt ret= iHierarchy->StartObserver((TDmDomainId)aMessage.Int0(),(TDmNotifyType)aMessage.Int1());
1.1400 + aMessage.Complete(ret);
1.1401 + }
1.1402 + break;
1.1403 +
1.1404 + case EDmObserverNotify:
1.1405 + {
1.1406 + if (iHierarchy==NULL)
1.1407 + {
1.1408 + aMessage.Complete(KErrBadHierarchyId);
1.1409 + break;
1.1410 + }
1.1411 + if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
1.1412 + {
1.1413 + aMessage.Complete(KDmErrBadSequence);
1.1414 + break;
1.1415 + }
1.1416 + // Check to see if we have any events stored
1.1417 + // If so, then notify the client
1.1418 + if(iHierarchy->iTransitions.Count()>0)
1.1419 + {
1.1420 + aMessage.Complete(KErrNone);
1.1421 + break;
1.1422 + }
1.1423 + // No events are stored. complete this message later
1.1424 + iHierarchy->SetNotifyMessage(&aMessage);
1.1425 + }
1.1426 + break;
1.1427 +
1.1428 + case EDmObserverEventCount:
1.1429 + {
1.1430 + if (iHierarchy==NULL)
1.1431 + {
1.1432 + aMessage.Complete(KErrBadHierarchyId);
1.1433 + break;
1.1434 + }
1.1435 + if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
1.1436 + {
1.1437 + aMessage.Complete(KDmErrBadSequence);
1.1438 + break;
1.1439 + }
1.1440 + TInt count = iHierarchy->iTransitions.Count();
1.1441 + aMessage.Complete(count);
1.1442 + }
1.1443 + break;
1.1444 +
1.1445 + case EDmObserverGetEvent:
1.1446 + {
1.1447 + if (iHierarchy==NULL)
1.1448 + {
1.1449 + aMessage.Complete(KErrBadHierarchyId);
1.1450 + break;
1.1451 + }
1.1452 + if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
1.1453 + {
1.1454 + aMessage.Complete(KDmErrBadSequence);
1.1455 + break;
1.1456 + }
1.1457 + TInt transitionCount = iHierarchy->iTransitions.Count();
1.1458 + TInt clientTransitionSize = aMessage.GetDesMaxLength(0);
1.1459 + TInt clientTransitionCount = clientTransitionSize / sizeof(TTransInfo);
1.1460 + __DS_ASSERT( (clientTransitionSize % sizeof(TTransInfo)) == 0);
1.1461 + __DS_ASSERT(transitionCount >= clientTransitionCount);
1.1462 +
1.1463 + HBufC8* hBuf = HBufC8::New(clientTransitionSize);
1.1464 + if(hBuf == NULL)
1.1465 + {
1.1466 + aMessage.Complete(KErrNoMemory);
1.1467 + break;
1.1468 + }
1.1469 + TPtr8 pBuf = hBuf->Des();
1.1470 + pBuf.Zero();
1.1471 + for (TInt i=0; i<clientTransitionCount; i++)
1.1472 + {
1.1473 + TPtrC8 ptr = TPtrC8((TUint8*) &iHierarchy->iTransitions[0], sizeof(TTransInfo));
1.1474 + pBuf.Append(ptr);
1.1475 + iHierarchy->iTransitions.Remove(0);
1.1476 + }
1.1477 + r = aMessage.Write(0, pBuf);
1.1478 + delete hBuf;
1.1479 +
1.1480 + aMessage.Complete(r);
1.1481 + }
1.1482 + break;
1.1483 + case EDmObserveredCount:
1.1484 + {
1.1485 + if (iHierarchy==NULL)
1.1486 + {
1.1487 + aMessage.Complete(KErrBadHierarchyId);
1.1488 + break;
1.1489 + }
1.1490 + if(!iHierarchy->iObserverStarted || iHierarchy->iObserverSession != this)
1.1491 + {
1.1492 + aMessage.Complete(KDmErrBadSequence);
1.1493 + break;
1.1494 + }
1.1495 + aMessage.Complete(iHierarchy->iObservedChildren);
1.1496 + }
1.1497 + break;
1.1498 + default:
1.1499 + aMessage.Complete(KDmErrBadRequest);
1.1500 + break;
1.1501 + }
1.1502 + }
1.1503 +
1.1504 +CSession2* CDmDomainServer::NewSessionL(const TVersion&, const RMessage2&) const
1.1505 + {
1.1506 +
1.1507 + return new CDmDomainSession();
1.1508 + }
1.1509 +
1.1510 +CSession2* CDmDomainServer::NewSessionL(const TVersion&) const
1.1511 + {
1.1512 + __DS_PANIC(KErrGeneral);
1.1513 + return 0;
1.1514 + }
1.1515 +
1.1516 +CDmDomainSession::~CDmDomainSession()
1.1517 + {
1.1518 + if (iPending)
1.1519 + iDomain->CompleteMemberTransition(KErrNone);
1.1520 + if (iDomain)
1.1521 + iDomain->Detach(this);
1.1522 + }
1.1523 +
1.1524 +void CDmDomainSession::ServiceL(const RMessage2& aMessage)
1.1525 + {
1.1526 + TInt r = KErrNone;
1.1527 + CDmSvrManager* manager = ((CDmManagerServer*) Server()) -> iManager;
1.1528 +
1.1529 + switch (aMessage.Function())
1.1530 + {
1.1531 + case EDmDomainJoin:
1.1532 + {
1.1533 + TDmHierarchyId hierarchyId = (TDmHierarchyId) aMessage.Int0();
1.1534 + TDmDomainId domainId = (TDmDomainId) aMessage.Int1();
1.1535 +
1.1536 + r = manager->LookupDomain(hierarchyId, domainId, iDomain);
1.1537 +
1.1538 + if (r != KErrNone)
1.1539 + break;
1.1540 +
1.1541 + // Check client has capability to join the domain
1.1542 + if (!iDomain->iJoinPolicy.CheckPolicy(aMessage))
1.1543 + {
1.1544 + r = KErrPermissionDenied;
1.1545 + iDomain = NULL;
1.1546 + break;
1.1547 + }
1.1548 +
1.1549 + iDomain->Attach(this);
1.1550 + break;
1.1551 + }
1.1552 +
1.1553 + case EDmStateRequestTransitionNotification:
1.1554 + iNotificationEnabled = ETrue;
1.1555 + break;
1.1556 +
1.1557 + case EDmStateCancelTransitionNotification:
1.1558 + iNotificationEnabled = EFalse;
1.1559 + break;
1.1560 +
1.1561 + case EDmStateAcknowledge:
1.1562 + {
1.1563 + TInt propValue = aMessage.Int0();
1.1564 + TInt error = aMessage.Int1();
1.1565 + if (!iDomain)
1.1566 + {
1.1567 + r = KDmErrNotJoin;
1.1568 + break;
1.1569 + }
1.1570 + if (iPending && iDomain->CheckPropValue(propValue))
1.1571 + {
1.1572 + iPending = EFalse;
1.1573 + iDomain->CompleteMemberTransition(error);
1.1574 + }
1.1575 + }
1.1576 + break;
1.1577 + default:
1.1578 + r = KDmErrBadRequest;
1.1579 + break;
1.1580 + }
1.1581 + aMessage.Complete(r);
1.1582 + }
1.1583 +
1.1584 +
1.1585 +TInt E32Main()
1.1586 + {
1.1587 + CTrapCleanup* cleanupStack = CTrapCleanup::New();
1.1588 + if(!cleanupStack)
1.1589 + __DS_PANIC(KErrNoMemory);
1.1590 +
1.1591 + CActiveScheduler* sched = new CActiveScheduler();
1.1592 + if (!sched)
1.1593 + __DS_PANIC(KErrNoMemory);
1.1594 +
1.1595 + CActiveScheduler::Install(sched);
1.1596 +
1.1597 + CDmSvrManager* mngr = CDmSvrManager::New();
1.1598 + __DS_ASSERT(mngr);
1.1599 +
1.1600 + CDmManagerServer* msrv = new CDmManagerServer(mngr);
1.1601 + if (!msrv)
1.1602 + __DS_PANIC(KErrNoMemory);
1.1603 +
1.1604 + TInt r=msrv->Start(KDmManagerServerNameLit);
1.1605 + if (r != KErrNone)
1.1606 + __DS_PANIC(r);
1.1607 +
1.1608 + CDmDomainServer* dsrv = new CDmDomainServer(mngr);
1.1609 + if (!dsrv)
1.1610 + __DS_PANIC(KErrNoMemory);
1.1611 +
1.1612 + r=dsrv->Start(KDmDomainServerNameLit);
1.1613 + if (r != KErrNone)
1.1614 + __DS_PANIC(r);
1.1615 +
1.1616 + CActiveScheduler::Start();
1.1617 +
1.1618 + __DS_PANIC(0);
1.1619 +
1.1620 + return KErrNone;
1.1621 + }