os/kernelhwsrv/kerneltest/e32test/resourceman/d_rescontrolcli.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2007-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 // e32test\resourceman\d_rescontrol_cli.cpp
    15 // 
    16 //
    17 
    18 #include <kernel/kern_priv.h>
    19 #include <drivers/resource_extend.h>
    20 #include <drivers/resourceman.h>
    21 #include "d_rescontrolcli.h"
    22 #ifdef PRM_ENABLE_EXTENDED_VERSION
    23 #include "dynamicresource.h"
    24 #endif
    25 #include "./resourceman_psl/rescontrol_psl.h"
    26 
    27 #ifndef PRM_ENABLE_EXTENDED_VERSION
    28 _LIT(KTestPowerRCName, "D_RESCONTROLCLI.LDD");
    29 #else
    30 _LIT(KTestPowerRCName, "D_EXTENDEDRESCONTROLCLI.LDD");
    31 #endif
    32 
    33 const TInt KTestResManLddThreadPriority  = 0x5;
    34 _LIT(KTestResManLddThread, "TestResManLddThread");
    35 
    36 #ifdef PRM_ENABLE_EXTENDED_VERSION
    37 #define EXPECTED_POST_NOTI_COUNT 6 //Expected number of notifications as a result of post boot level setting. 
    38 #else
    39 #define EXPECTED_POST_NOTI_COUNT 5
    40 #endif
    41 #define MAX_DYNAMIC_RES_NUM 5
    42 /** 
    43 Structure for holding resource information
    44 */
    45 struct SClientInfo
    46 	{
    47 	HBuf8* pName;
    48 	TUint iClientId;
    49 	};
    50 /**
    51 The logical device (factory class) for the resource manager client side test.
    52 */
    53 class DTestResManLddFactory : public DLogicalDevice
    54 	{
    55 public:
    56 	DTestResManLddFactory();
    57 	~DTestResManLddFactory();
    58 	virtual TInt Install();
    59 	virtual void GetCaps(TDes8 &aDes) const;
    60 	virtual TInt Create(DLogicalChannelBase*& aChannel);
    61 	static void PostBootNotificationFunc(TUint aClientId, TUint aResId, TInt aLevel, TInt aLevelOwnerId, TInt aResult, TAny* aParam);
    62 	void SetPostBootLevelAndRequestNotification(TUint aClientId, TUint aResId, TInt aPostBootLevel);
    63 	TDynamicDfcQue* iDfcQ;
    64 	DStaticPowerResource *iStaticRes;
    65 	DStaticPowerResource *iStaticResArray[3];
    66 	static SClientInfo iClient; //Need to be static to access them in PostBootNotificationFunc (callback function).
    67 	static TUint iPostBootNotiCount;
    68 	};
    69 
    70 /** Logical channel class for Resource manager test LDD */
    71 class DTestResManLdd : public DLogicalChannel
    72 	{
    73 public:
    74 	DTestResManLdd();
    75 	virtual ~DTestResManLdd();
    76 	// Inherited from DLogicalChannel
    77 	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
    78 	virtual void HandleMsg(TMessageBase* aMsg);
    79 private:
    80 	TInt DoControl(TInt aFunction, TAny* a1, TAny* a2);
    81 	TInt DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2);
    82 	TInt DoCancel(TUint aMask);
    83 	static void CallbackFunc(TUint aClientId, TUint aResId, TInt aLevel, TInt aLevelOwnerId, TInt aResult, TAny* aParam);
    84 	static void CondNotificationFunc(TUint aClientId, TUint aResId, TInt aLevel, TInt aLevelOwnerId, TInt aResult, TAny* aParam);
    85 	static void UnCondNotificationFunc(TUint aClientId, TUint aResId, TInt aLevel, TInt aLevelOwnerId, TInt aResult, TAny* aParam);
    86 private:
    87    	DThread* iClientThreadPtr;
    88    	TPowerResourceCb iAsyncResourceCallback; //Callback object for handling long latency resources.
    89 	//Structure for storing the notification information
    90 	struct SNotificationList
    91 		{
    92 		TUint iClientId;
    93 		TUint iResourceId;
    94 		TUint iCount;
    95 		DPowerResourceNotification *iNoti;
    96 		SNotificationList *iNext;
    97 		};
    98 	SNotificationList *iCondList; //List for maintaining conditional notification
    99 	SNotificationList *iUnCondList; //List for maintaining unconditional notification
   100 	TRequestStatus *iStatus; //Store the status and complete on callback function.
   101 	TBool iCallbackCancel; 
   102 	TInt iClientId; //ID of the client that requested long latency operation, to compare in callback and notifications.
   103 	TUint iResourceId; //Id of the resource of long latency operation, to compare in callback and notifications.
   104 	//Below 2 variables are used only for asynchronous get resource state operation
   105 	TInt *iStatePtr; //Pointer to hold the address of state variable, where state is updated in callback function.
   106 	TInt *iLevelOwnerIdPtr; //Pointer to hold the address of level owner Id variable, where owner Id is updated in callback function.
   107 	HBuf *pBuf; //Buffer for testing caching of resource information for Idle power management 
   108 	SClientInfo clientInfo[MAX_CLIENTS];
   109 #ifdef PRM_ENABLE_EXTENDED_VERSION
   110 	TUint iTestParallelResourceId; //Variable to hold the long latency resource id, this is used only in test parallel execution of DFC's
   111 	static void TestParallelExecutionCallback(TUint aClientId, TUint aResId, TInt aLevel, TInt aLevelOwnerId, TInt aResult, TAny* aParam);
   112 	TBool iCallbackReceived;
   113 	TBool iValidateCallbackReceived;
   114 	TPowerResourceCb iAsyncTestParallelCallback; //Callback object for handling long latency resources change state while deregistering non-dependency resource.
   115 	RArray <DDynamicPowerResource*> iDynamicArray; //Array to hold dynamic resources. This includes dynamic dependent resource
   116 #endif
   117 	};
   118 
   119 //class definition for multilevel single instantaneous positive resource
   120 class DLaterRegisterStaticResource : public DStaticPowerResource
   121 	{
   122 public:
   123 	DLaterRegisterStaticResource();
   124 	TInt DoRequest(TPowerRequest &req);
   125 	TInt GetInfo(TDes8* aInfo) const;
   126 private:
   127 	TInt iMinLevel;
   128 	TInt iMaxLevel;
   129 	TInt iCurrentLevel;
   130 	};
   131 
   132 //Constructors of the resource
   133 _LIT(KLaterRegisterStaticResource, "LaterRegisterStaticResource");
   134 DLaterRegisterStaticResource::DLaterRegisterStaticResource() : DStaticPowerResource(KLaterRegisterStaticResource, E_OFF), iMinLevel(0), iMaxLevel(1), iCurrentLevel(0)
   135 	{
   136 	iFlags = KBinary;
   137 	}
   138 
   139 TInt DLaterRegisterStaticResource::DoRequest(TPowerRequest& req)
   140 	{
   141 	Kern::Printf("DLaterRegisterStaticResource::DoRequest\n");
   142 	if(req.ReqType() == TPowerRequest::EGet)
   143 		{
   144 		req.Level() = iCurrentLevel;
   145 		}
   146 	else if(req.ReqType() == TPowerRequest::EChange)
   147 		{
   148 		iCurrentLevel = req.Level();
   149 		}
   150 	else if(req.ReqType() == TPowerRequest::ESetDefaultLevel)
   151 		{
   152 		req.Level() = iDefaultLevel;
   153 		iCurrentLevel = iDefaultLevel;
   154 		}
   155 	else
   156 		return KErrNotSupported;
   157 	return KErrNone;
   158 	}
   159 
   160 TInt DLaterRegisterStaticResource::GetInfo(TDes8* info) const
   161 	{
   162 	DStaticPowerResource::GetInfo((TDes8*)info);
   163 	TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)info;
   164 	buf1->iDefaultLevel = iDefaultLevel;
   165 	buf1->iMinLevel = iMinLevel;
   166 	buf1->iMaxLevel = iMaxLevel;
   167 	return KErrNone;
   168 	}
   169 
   170 //class definition for multilevel single instantaneous positive resource
   171 class DLaterRegisterStaticResource1 : public DStaticPowerResource
   172 	{
   173 public:
   174 	DLaterRegisterStaticResource1();
   175 	TInt DoRequest(TPowerRequest &req);
   176 	TInt GetInfo(TDes8* aInfo) const;
   177 private:
   178 	TInt iMinLevel;
   179 	TInt iMaxLevel;
   180 	TInt iCurrentLevel;
   181 	};
   182 
   183 //Constructors of the resource
   184 _LIT(KLaterRegisterStaticResource1, "LaterRegisterStaticResource1");
   185 DLaterRegisterStaticResource1::DLaterRegisterStaticResource1() : DStaticPowerResource(KLaterRegisterStaticResource1, E_OFF), iMinLevel(0), iMaxLevel(1), iCurrentLevel(0)
   186 	{
   187 	iFlags = KBinary;
   188 	}
   189 
   190 TInt DLaterRegisterStaticResource1::DoRequest(TPowerRequest& req)
   191 	{
   192 	Kern::Printf("DLaterRegisterStaticResource1::DoRequest\n");
   193 	if(req.ReqType() == TPowerRequest::EGet)
   194 		{
   195 		req.Level() = iCurrentLevel;
   196 		}
   197 	else if(req.ReqType() == TPowerRequest::EChange)
   198 		{
   199 		iCurrentLevel = req.Level();
   200 		}
   201 	else if(req.ReqType() == TPowerRequest::ESetDefaultLevel)
   202 		{
   203 		req.Level() = iDefaultLevel;
   204 		iCurrentLevel = iDefaultLevel;
   205 		}
   206 	else
   207 		return KErrNotSupported;
   208 	return KErrNone;
   209 	}
   210 
   211 TInt DLaterRegisterStaticResource1::GetInfo(TDes8* info) const
   212 	{
   213 	DStaticPowerResource::GetInfo((TDes8*)info);
   214 	TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)info;
   215 	buf1->iDefaultLevel = iDefaultLevel;
   216 	buf1->iMinLevel = iMinLevel;
   217 	buf1->iMaxLevel = iMaxLevel;
   218 	return KErrNone;
   219 	}
   220 
   221 //class definition for multilevel single instantaneous positive resource
   222 class DLaterRegisterStaticResource2 : public DStaticPowerResource
   223 	{
   224 public:
   225 	DLaterRegisterStaticResource2();
   226 	TInt DoRequest(TPowerRequest &req);
   227 	TInt GetInfo(TDes8* aInfo) const;
   228 private:
   229 	TInt iMinLevel;
   230 	TInt iMaxLevel;
   231 	TInt iCurrentLevel;
   232 	};
   233 
   234 //Constructors of the resource
   235 _LIT(KLaterRegisterStaticResource2, "LaterRegisterStaticResource2");
   236 DLaterRegisterStaticResource2::DLaterRegisterStaticResource2() : DStaticPowerResource(KLaterRegisterStaticResource2, E_OFF), iMinLevel(0), iMaxLevel(1), iCurrentLevel(0)
   237 	{
   238 	iFlags = KBinary;
   239 	}
   240 
   241 TInt DLaterRegisterStaticResource2::DoRequest(TPowerRequest& req)
   242 	{
   243 	Kern::Printf("DLaterRegisterStaticResource2::DoRequest\n");
   244 	if(req.ReqType() == TPowerRequest::EGet)
   245 		{
   246 		req.Level() = iCurrentLevel;
   247 		}
   248 	else if(req.ReqType() == TPowerRequest::EChange)
   249 		{
   250 		iCurrentLevel = req.Level();
   251 		}
   252 	else if(req.ReqType() == TPowerRequest::ESetDefaultLevel)
   253 		{
   254 		req.Level() = iDefaultLevel;
   255 		iCurrentLevel = iDefaultLevel;
   256 		}
   257 	else
   258 		return KErrNotSupported;
   259 	return KErrNone;
   260 	}
   261 
   262 TInt DLaterRegisterStaticResource2::GetInfo(TDes8* info) const
   263 	{
   264 	DStaticPowerResource::GetInfo((TDes8*)info);
   265 	TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)info;
   266 	buf1->iDefaultLevel = iDefaultLevel;
   267 	buf1->iMinLevel = iMinLevel;
   268 	buf1->iMaxLevel = iMaxLevel;
   269 	return KErrNone;
   270 	}
   271 
   272 TUint DTestResManLddFactory::iPostBootNotiCount = 0;
   273 SClientInfo DTestResManLddFactory::iClient = {NULL, 0};
   274 DTestResManLddFactory::DTestResManLddFactory()
   275 	{
   276 	iParseMask=0; // Allow info and pdd, but not units
   277 	iUnitsMask=0;
   278 	// Set version number for this device
   279 	iVersion=RTestResMan::VersionRequired();
   280 	}
   281 
   282 DTestResManLddFactory::~DTestResManLddFactory()
   283 	{
   284 	if(iDfcQ)
   285 	  iDfcQ->Destroy();
   286 	if(iStaticRes)
   287 		delete iStaticRes;
   288 	if(iStaticResArray[0])
   289 		delete iStaticResArray[0];
   290 	if(iStaticResArray[2])
   291 		delete iStaticResArray[2];
   292 	}
   293 
   294 /** Entry point for this driver */
   295 DECLARE_STANDARD_LDD()
   296 	{
   297 	DTestResManLddFactory* p = new DTestResManLddFactory;
   298 	if(!p)
   299 		return NULL;
   300 	TInt r = Kern::DynamicDfcQCreate(p->iDfcQ, KTestResManLddThreadPriority, KTestResManLddThread);
   301 	if(r != KErrNone)
   302 		{
   303 		Kern::Printf("Memory not allocated");
   304 		p->AsyncDelete();
   305 		return NULL;
   306 		}
   307 
   308 #ifdef CPU_AFFINITY_ANY
   309 		NKern::ThreadSetCpuAffinity((NThread*)(p->iDfcQ->iThread), KCpuAffinityAny);			
   310 #endif
   311 
   312 	//Register client with Resource Controller
   313 	TBuf8<32> ClientName(_L8("Client"));
   314 	p->iClient.pName = HBuf::New((const TDesC&)ClientName);
   315 	if(!p->iClient.pName)
   316 		{
   317 		p->iDfcQ->Destroy();
   318 		p->AsyncDelete();
   319 		return NULL;
   320 		}
   321 	//Allocating memory earlier so that during failure conditions can cleanup easily
   322 	p->iStaticRes = new DLaterRegisterStaticResource();
   323 	if(!p->iStaticRes)
   324 		{
   325 		delete p->iClient.pName;
   326 		p->iDfcQ->Destroy();
   327 		p->AsyncDelete();
   328 		return NULL;
   329 		}
   330 	p->iStaticResArray[0] = new DLaterRegisterStaticResource1();
   331 	if(!p->iStaticResArray[0])
   332 		{
   333 		delete p->iStaticRes;
   334 		delete p->iClient.pName;
   335 		p->iDfcQ->Destroy();
   336 		p->AsyncDelete();
   337 		return NULL;
   338 		}	
   339 	p->iStaticResArray[2] = new DLaterRegisterStaticResource2();
   340 	if(!p->iStaticResArray[2])
   341 		{
   342 		delete p->iStaticRes;
   343 		delete p->iStaticResArray[0];
   344 		delete p->iClient.pName;
   345 		p->iDfcQ->Destroy();
   346 		p->AsyncDelete();
   347 		return NULL;
   348 		}
   349 	r = PowerResourceManager::RegisterClient(DTestResManLddFactory::iClient.iClientId, (const TDesC&)*DTestResManLddFactory::iClient.pName);
   350 	if(r != KErrNone)
   351 		{
   352 		Kern::Printf("RegisterClient Failed\n");
   353 		Kern::Fault("PRM REGISTER CLIENT FAILED", __LINE__);
   354 		}
   355 	//Set postbootlevel for these resources.
   356 	p->SetPostBootLevelAndRequestNotification(DTestResManLddFactory::iClient.iClientId, 1, 0);
   357 	p->SetPostBootLevelAndRequestNotification(DTestResManLddFactory::iClient.iClientId, 6, 12);
   358 	p->SetPostBootLevelAndRequestNotification(DTestResManLddFactory::iClient.iClientId, 7, 1);
   359 	p->SetPostBootLevelAndRequestNotification(DTestResManLddFactory::iClient.iClientId, 12, 10);
   360 	p->SetPostBootLevelAndRequestNotification(DTestResManLddFactory::iClient.iClientId, 15, 0);
   361 #ifdef PRM_ENABLE_EXTENDED_VERSION
   362 	p->SetPostBootLevelAndRequestNotification(DTestResManLddFactory::iClient.iClientId, 65537, -50);
   363 #endif
   364 	//Test the later registration of static resources.
   365 	r = DPowerResourceController::RegisterStaticResource(DTestResManLddFactory::iClient.iClientId, p->iStaticRes);
   366 	if(r != KErrNone)
   367 		Kern::Fault("PRM REGISTER STATIC RESOURCE FAILED", __LINE__);
   368 	DStaticPowerResource **resPtr = &p->iStaticResArray[0];
   369 	r = DPowerResourceController::RegisterArrayOfStaticResources(DTestResManLddFactory::iClient.iClientId, resPtr, 3);
   370 	if(r != KErrNone)
   371 		Kern::Fault("PRM REGISTER STATIC RESOURCE FAILED", __LINE__);
   372 	r = DSimulatedPowerResourceController::CompleteResourceControllerInitialisation();
   373 	if(r != KErrNone)
   374 		Kern::Fault("PRM INIT FAILED", __LINE__);
   375 	return p;
   376 	}
   377 
   378 void DTestResManLddFactory::SetPostBootLevelAndRequestNotification(TUint aClientId, TUint aResId, TInt aPostBootLevel)
   379 	{
   380 	DPowerResourceController::PostBootLevel(aResId, aPostBootLevel);
   381 	DPowerResourceNotification* iNoti = new DPowerResourceNotification(PostBootNotificationFunc, (TAny*)NULL, Kern::DfcQue0(), 3);
   382 	if(!iNoti)
   383 		{
   384 		Kern::Fault("PRM NOTI FAILED", __LINE__);
   385 		}
   386 	//Passing the address of the object so that it could be deleted in callback function
   387 	new (iNoti) DPowerResourceNotification(PostBootNotificationFunc, iNoti, Kern::DfcQue0(), 3);
   388 	TInt r = PowerResourceManager::RequestNotification(aClientId, aResId, *iNoti);
   389 	if(r != KErrNone)
   390 		Kern::Fault("PRM REQ NOTI FAILED", __LINE__);
   391 	}
   392 
   393 
   394 /** Second stage constuctor */
   395 TInt DTestResManLddFactory::Install()
   396 	{
   397    	return(SetName(&KTestPowerRCName));
   398 	}
   399 
   400 /** Device capabilities */
   401 void DTestResManLddFactory::GetCaps(TDes8& aDes)const
   402 	{
   403 	// Create a capabilities object
   404 	RTestResMan::TCaps caps;
   405 	caps.iVersion = iVersion;
   406 	// Write it back to user memory
   407 	Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps));
   408 	}
   409 
   410 /** Create logical channel, only open of one channel is allowed */
   411 TInt DTestResManLddFactory::Create(DLogicalChannelBase*& aChannel)
   412 	{
   413    	if (iOpenChannels != 0) //A Channel is already open
   414 		return KErrInUse;
   415 	//Deregister the client registered in ldd init. 
   416 	TInt r = PowerResourceManager::DeRegisterClient(DTestResManLddFactory::iClient.iClientId);
   417 	if(r != KErrNone)
   418 		Kern::Fault("PRM CLIENT DEREGISTER FAILED", __LINE__);
   419 	delete DTestResManLddFactory::iClient.pName;
   420 	DTestResManLddFactory::iClient.pName = NULL;
   421 	DTestResManLddFactory::iClient.iClientId = 0;
   422 	aChannel = new DTestResManLdd;
   423 	if(!aChannel)
   424 		return KErrNoMemory;
   425 	return KErrNone;
   426 	}
   427 
   428 /** Constructor */
   429 DTestResManLdd::DTestResManLdd(): iAsyncResourceCallback(CallbackFunc, this, 3)
   430 #ifdef PRM_ENABLE_EXTENDED_VERSION
   431 				, iAsyncTestParallelCallback(TestParallelExecutionCallback, this, 3)
   432 #endif
   433 	{
   434 	iCondList = NULL;
   435 	iUnCondList = NULL;
   436 	iCallbackCancel = EFalse;
   437 	iClientId = 0;
   438 	iResourceId = 0;
   439 	iStatePtr = NULL;
   440 	iLevelOwnerIdPtr = NULL;
   441 	for(TUint c = 0; c < MAX_CLIENTS; c++)
   442 		{
   443 		clientInfo[c].iClientId = 0;
   444 		clientInfo[c].pName = NULL;
   445 		}
   446 	iClientThreadPtr=&Kern::CurrentThread();
   447 	// Increase the DThread's ref count so that it does not close without us
   448 	((DObject*)iClientThreadPtr)->Open();;
   449 	}
   450 
   451 /** Destructor */
   452 DTestResManLdd::~DTestResManLdd()
   453 	{
   454 	if(pBuf) //Buffer created for storing idle resource information
   455 		delete pBuf;
   456 #ifdef PRM_ENABLE_EXTENDED_VERSION
   457 	for(TInt c = 0; c < iDynamicArray.Count(); c++)
   458 		{
   459 		delete iDynamicArray[c]; //Delete the dynamic array. This includes dynamic dependent resource.
   460 		}
   461 	iDynamicArray.Close();
   462 #endif
   463 	// Close our reference on the client thread
   464 	Kern::SafeClose((DObject*&)iClientThreadPtr,NULL);
   465 	}
   466 
   467 /** Second stage constructor. */
   468 TInt DTestResManLdd::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
   469 	{
   470    	// Check version
   471 	if (!Kern::QueryVersionSupported(RTestResMan::VersionRequired(),aVer))
   472 		return KErrNotSupported;
   473 	SetDfcQ(((DTestResManLddFactory*)iDevice)->iDfcQ);
   474 	iAsyncResourceCallback.SetDfcQ(iDfcQ);
   475 #ifdef PRM_ENABLE_EXTENDED_VERSION
   476 	iAsyncTestParallelCallback.SetDfcQ(iDfcQ);
   477 #endif
   478  	iMsgQ.Receive();
   479 	return KErrNone;
   480 	}
   481 
   482 /** Process a message for this logical channel */
   483 void DTestResManLdd::HandleMsg(TMessageBase* aMsg)
   484 	{
   485 	TThreadMessage& m=*(TThreadMessage*)aMsg;
   486 	TInt id=m.iValue;
   487 
   488 	if (id==(TInt)ECloseMsg)
   489 		{
   490 		// Channel close.
   491 		m.Complete(KErrNone,EFalse);
   492 		return;
   493 		}
   494 	else if (id==KMaxTInt)
   495 		{
   496 		// DoCancel
   497 		m.Complete(KErrNone,ETrue);
   498 		return;
   499 		}
   500 	else if (id<0)
   501 		{
   502 		// DoRequest
   503 		TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
   504 		TInt r=DoRequest(~id,pS,m.Ptr1(),m.Ptr2());
   505 		if (r!=KErrNone)
   506 			Kern::RequestComplete(iClientThreadPtr,pS,r);
   507 		m.Complete(KErrNone,ETrue);
   508 		}
   509 	else
   510 		{
   511 		// DoControl
   512 		TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
   513 		m.Complete(r,ETrue);
   514 		}
   515 	}
   516 
   517 
   518 /**
   519   Process synchronous 'control' requests
   520 */
   521 TInt DTestResManLdd::DoControl(TInt aFunction, TAny* a1, TAny* a2)
   522 	{
   523 	TInt r = KErrNone;
   524 	TParameterListInfo ptr = {0, 0, 0, 0, 0};
   525 	//Copy parameter structure from user space.
   526 	if((aFunction != RTestResMan::EDeRegisterClient) 
   527 		&& (aFunction != RTestResMan::ERequestNotificationUncond) 
   528 		&& (aFunction != RTestResMan::EGetIdleResourcesInfo) 
   529 		&& (aFunction != RTestResMan::EDeRegisterClientLevelFromResource) 
   530 		&& (aFunction != RTestResMan::ECheckPostBootLevelNotifications)
   531 		&& (aFunction != RTestResMan::EGetControllerVersion)
   532 #ifdef PRM_ENABLE_EXTENDED_VERSION
   533 		   && (aFunction != RTestResMan::ERegisterDynamicResource))
   534 #else
   535 		   )
   536 #endif
   537 		{
   538 		r = Kern::ThreadRawRead(iClientThreadPtr, (TParameterListInfo*)a1, &ptr, sizeof(TParameterListInfo));
   539 		if(r != KErrNone)
   540 			return r;
   541 		}
   542 	switch(aFunction)
   543 		{
   544 		case RTestResMan::ERegisterClient:
   545 			{
   546 			TBuf8<256> aName;
   547 			TUint c;
   548 			//Copy name from user address space
   549 			r = Kern::ThreadDesRead(iClientThreadPtr, (const TDesC*)ptr.iPtr2, (TDes8&)aName, 0);
   550 			if(r != KErrNone)
   551 				{
   552 				Kern::Printf("RTestResMan::ERegisterClient ThreadDesRead failed with %d", r);
   553 				break;
   554 				}
   555 			for(c = 0; c < MAX_CLIENTS; c++)
   556 				{
   557 				if(clientInfo[c].pName == NULL)
   558 					break;
   559 				if(!clientInfo[c].pName->Compare(aName))
   560 					return KErrAlreadyExists;
   561 				}
   562 			if(c == MAX_CLIENTS)
   563 				return KErrOverflow;
   564 			clientInfo[c].pName = HBuf::New((const TDesC8&)aName);
   565 			if(!clientInfo[c].pName)
   566 				return KErrNoMemory;
   567 			r = PowerResourceManager::RegisterClient(clientInfo[c].iClientId, (const TDesC&)*clientInfo[c].pName, (TOwnerType)(TInt)ptr.iPtr3);
   568 			if(r != KErrNone)
   569 				{
   570 				delete clientInfo[c].pName;
   571 				clientInfo[c].pName = NULL;
   572 				clientInfo[c].iClientId = 0;
   573 				}
   574 			if(r == KErrNone)
   575 				{
   576 				r = Kern::ThreadRawWrite(iClientThreadPtr, ptr.iPtr1, &clientInfo[c].iClientId, sizeof(TUint));
   577 				if(r != KErrNone)
   578 					Kern::Printf("RTestResMan::ERegisterClient ThreadRawWrite failed with %d", r);
   579 				}
   580 			break;
   581 			}
   582 		case RTestResMan::EDeRegisterClient: //Deregister client from RM
   583 			{
   584 			//Cancel all notification pending for this client
   585 			SNotificationList *pL;
   586 			SNotificationList* pN = iCondList;
   587 			while(pN != NULL)
   588 				{
   589 				if(pN->iClientId == (TUint)a1)
   590 					{
   591 					PowerResourceManager::CancelNotification(pN->iClientId, pN->iResourceId, *pN->iNoti);
   592 					pL = pN;
   593 					pN = pN->iNext;
   594 					LIST_REMOVE(iCondList, pL, iNext, SNotificationList);
   595 					delete pL->iNoti;
   596 					delete pL;
   597 					}
   598 				else
   599 					pN = pN->iNext;
   600 				}
   601 			pN = iUnCondList;
   602 			while(pN != NULL)
   603 				{
   604 				if(pN->iClientId == (TUint)a1)
   605 					{
   606 					PowerResourceManager::CancelNotification(pN->iClientId, pN->iResourceId, *pN->iNoti);
   607 					pL = pN;
   608 					pN = pN->iNext;
   609 					LIST_REMOVE(iUnCondList, pL, iNext, SNotificationList);
   610 					delete pL->iNoti;
   611 					delete pL;
   612 					}
   613 				else
   614 				   pN = pN->iNext;
   615 				}
   616 			iClientId = -1;
   617 			r = PowerResourceManager::DeRegisterClient((TUint)a1);
   618 			if(r != KErrNone)
   619 				break;
   620 			r = KErrNotFound;
   621 			for(TUint c = 0; c < MAX_CLIENTS; c++)
   622 				{
   623 				if(clientInfo[c].iClientId == (TUint)a1)
   624 					{
   625 					delete clientInfo[c].pName;
   626 					clientInfo[c].pName = 0;
   627 					clientInfo[c].iClientId = 0;
   628 					r = KErrNone;
   629 					break;
   630 					}
   631 				}
   632 
   633 			break;
   634 			}
   635 		case RTestResMan::EGetClientName: //Get Client Name
   636 			{
   637 			TBuf8<32> aName; 
   638 			r = PowerResourceManager::GetClientName((TUint)ptr.iClientId, (TUint)ptr.iPtr1, (TDes &)aName);
   639 			if(r== KErrNone)
   640 				{
   641 				r = Kern::ThreadDesWrite(iClientThreadPtr, ptr.iPtr2, (const TDesC8&)aName, 0);
   642 				if(r != KErrNone)
   643 					Kern::Printf("RTestResMan::EGetClientName ThreadDesWrite failed with %d", r);
   644 				}
   645 			break;
   646 			}
   647 		case RTestResMan::EGetClientId: //Get Client Id
   648 			{
   649 			TBuf8<256> aName;
   650 			TUint aClientId; 
   651 			r = Kern::ThreadDesRead(iClientThreadPtr, (const TDesC*)ptr.iPtr1, (TDes8&)aName, 0,KChunkShiftBy0);
   652 			if(r != KErrNone)
   653 				{
   654 				Kern::Printf("RTestResMan::EGetClientId ThreadDesRead failed with %d", r);
   655 				break;
   656 				}
   657 			r = PowerResourceManager::GetClientId(ptr.iClientId, (TDesC&)aName, aClientId);
   658 			if(r == KErrNone)
   659 				{
   660 				r = Kern::ThreadRawWrite(iClientThreadPtr, ptr.iPtr2, &aClientId, sizeof(TUint));
   661 				if(r != KErrNone)
   662 					Kern::Printf("RTestResMan::EGetClientId ThreadRawWrite failed with %d", r);
   663 				}
   664 			break;
   665 			}
   666 		case RTestResMan::EGetResourceId: //Get Resource Id
   667 			{
   668 			TBuf8<256> aName; 
   669 			TUint aResourceId;
   670 			r = Kern::ThreadDesRead(iClientThreadPtr, (const TDesC*)ptr.iPtr1, (TDes8&)aName, 0,KChunkShiftBy0);
   671 			if(r != KErrNone)
   672 				{
   673 				Kern::Printf("RTestResMan::EGetResourceId ThreadDesRead failed with %d", r);
   674 				break;
   675 				}
   676 			r = PowerResourceManager::GetResourceId(ptr.iClientId, (TDesC&)aName, aResourceId);
   677 			if(r == KErrNone)
   678 				{
   679 				r = Kern::ThreadRawWrite(iClientThreadPtr, ptr.iPtr2, &aResourceId, sizeof(TUint));
   680 				if(r != KErrNone)
   681 					Kern::Printf("RTestResMan::EGetResourceId ThreadRawWrite failed with %d", r);
   682 				}
   683 			break;
   684 			}
   685 		case RTestResMan::EGetResourceInfo: //Get resource information
   686 			{
   687 			NKern::ThreadEnterCS();
   688 			HBuf *info = HBuf::New(sizeof(TPowerResourceInfoV01));
   689 			NKern::ThreadLeaveCS();
   690 			r = PowerResourceManager::GetResourceInfo(ptr.iClientId, (TUint)ptr.iPtr1, (TAny*)info);
   691 			if(r == KErrNone)
   692 				{
   693 				r = Kern::ThreadDesWrite(iClientThreadPtr, ptr.iPtr2, (const TDesC8&)*info, 0);
   694 				if(r != KErrNone)
   695 					Kern::Printf("RTestResMan::EGetResourceInfo ThreadRawWrite failed with %d", r);
   696 				}
   697 			Kern::Free(info);
   698 			break;
   699 			} 
   700 		case RTestResMan::EGetNumResourcesInUseByClient: 
   701 			{
   702 			TUint numResource;
   703 			r = PowerResourceManager::GetNumResourcesInUseByClient(ptr.iClientId, (TUint)ptr.iPtr1, numResource);
   704 			if(r == KErrNone)
   705 				{
   706 				r = Kern::ThreadRawWrite(iClientThreadPtr, ptr.iPtr2, &numResource, sizeof(TUint));
   707 				if(r != KErrNone)
   708 					Kern::Printf("RTestResMan::EGetNumResourcesInUseByClient ThreadRawWrite failed with %d", r);
   709 				}
   710 			 break;
   711 			}
   712 		case RTestResMan::EGetInfoOnResourcesInUseByClient:
   713 			{
   714 			TUint numResource;
   715 			HBuf* info = NULL;
   716 			r = Kern::ThreadRawRead(iClientThreadPtr, ptr.iPtr2, &numResource, sizeof(TUint));
   717 			if(r != KErrNone)
   718 				{
   719 				Kern::Printf("RTestResMan::GetInfoOnResourceInUseByClient ThreadRawRead failed with %d", r);
   720 				break;
   721 				}
   722 			if(ptr.iPtr3 != NULL)
   723 				{
   724 				NKern::ThreadEnterCS();
   725 				info = HBuf::New(numResource * sizeof(TPowerResourceInfoV01));
   726 				NKern::ThreadLeaveCS();
   727 				}
   728 			r = PowerResourceManager::GetInfoOnResourcesInUseByClient(ptr.iClientId, (TUint)ptr.iPtr1, numResource, (TAny*)info);
   729 			if(r == KErrNone)
   730 				{
   731 				r = Kern::ThreadRawWrite(iClientThreadPtr, ptr.iPtr2, &numResource, sizeof(TUint));
   732 				if(r !=KErrNone)
   733 					{
   734 					Kern::Printf("RTestResMan::GetInfoOnResourceInUseByClient ThreadRawWrite failed with %d", r);
   735 					Kern::Free(info);
   736 					break;
   737 					}
   738 				if(ptr.iPtr3)
   739 					r = Kern::ThreadDesWrite(iClientThreadPtr, ptr.iPtr3, (const TDesC8&)*info, 0);
   740 				}
   741 			Kern::Free(info);
   742 			break;
   743 			}
   744 		case RTestResMan::EGetNumClientsUsingResource:
   745 			{
   746 			TUint numClient;
   747 			r = PowerResourceManager::GetNumClientsUsingResource(ptr.iClientId, (TUint)ptr.iPtr1, numClient);
   748 			if(r == KErrNone)
   749 				{
   750 				r = Kern::ThreadRawWrite(iClientThreadPtr, ptr.iPtr2, &numClient, sizeof(TUint));
   751 				if(r != KErrNone)
   752 					Kern::Printf("RTestResMan::EGetNumResourcesInUseByClient ThreadRawWrite failed with %d", r);
   753 				}
   754 			break;
   755 			}
   756 		case RTestResMan::EGetInfoOnClientsUsingResource:
   757 			{
   758 			TUint numClient;
   759 			HBuf* info = NULL;
   760 			r = Kern::ThreadRawRead(iClientThreadPtr, ptr.iPtr2, &numClient, sizeof(TUint));
   761 			if(r != KErrNone)
   762 				{
   763 				Kern::Printf("RTestResMan::GetInfoOnResourceInUseByClient ThreadRawRead failed with %d", r);
   764 				break;
   765 				}
   766 			if(ptr.iPtr3 != NULL)
   767 				{
   768 				NKern::ThreadEnterCS();
   769 				info = HBuf::New(numClient * sizeof(TPowerClientInfoV01));
   770 				NKern::ThreadLeaveCS();
   771 				}
   772 			r = PowerResourceManager::GetInfoOnClientsUsingResource(ptr.iClientId, (TUint)ptr.iPtr1, numClient, (TAny*)info);
   773 			if(r == KErrNone)
   774 				{
   775 				r = Kern::ThreadRawWrite(iClientThreadPtr, ptr.iPtr2, &numClient, sizeof(TUint));
   776 				if(r !=KErrNone)
   777 					{
   778 					Kern::Printf("RTestResMan::GetInfoOnResourceInUseByClient ThreadRawWrite failed with %d", r);
   779 					Kern::Free(info);
   780 					break;
   781 					}
   782 				 if(ptr.iPtr3)
   783 					r = Kern::ThreadDesWrite(iClientThreadPtr, ptr.iPtr3, (const TDesC8&)*info, 0);
   784 				}
   785 			Kern::Free(info);
   786 			break;
   787 			}
   788 		case RTestResMan::EAllocReserve:
   789 			{
   790 			r = PowerResourceManager::AllocReserve(ptr.iClientId, (TUint8)(TUint)ptr.iPtr1, (TUint8)(TUint)ptr.iPtr2);
   791 			break;
   792 			}
   793 		case RTestResMan::EChangeResourceStateSync:
   794 			{
   795 			SNotificationList* pN; 
   796 			//Zero the conditional notification count for the resource id.
   797 			for(pN=iCondList; pN != NULL; pN=pN->iNext)
   798 				{
   799 				if(pN->iResourceId == (TUint)ptr.iPtr1)
   800 					{
   801 					pN->iCount = 0;
   802 					break;
   803 					}
   804 				}
   805 			//Zero the unconditional notification count for the resource id.
   806 			for(pN=iUnCondList; pN != NULL; pN=pN->iNext)
   807 				{
   808 				if(pN->iResourceId == (TUint)ptr.iPtr1)
   809 					{
   810 					pN->iCount = 0;
   811 					break;
   812 					}
   813 				}
   814 			iClientId = ptr.iClientId;
   815 			iResourceId = (TUint)ptr.iPtr1;
   816 			r = PowerResourceManager::ChangeResourceState(ptr.iClientId, (TUint)ptr.iPtr1, (TInt)ptr.iPtr2);
   817 			break;
   818 			}
   819 		case RTestResMan::EGetResourceStateSync:
   820 			{
   821 			TInt newState, levelOwnerId;
   822 			r = PowerResourceManager::GetResourceState(ptr.iClientId, (TUint)ptr.iPtr1, (TBool)ptr.iPtr2, newState, levelOwnerId);
   823 			if(r == KErrNone)
   824 				{
   825 				r = Kern::ThreadRawWrite(iClientThreadPtr, ptr.iPtr3, (TAny*)&newState, sizeof(TInt));
   826 				if(r != KErrNone)
   827 					{
   828 					Kern::Printf("RTestResMan::GetResourceStateSync ThreadRawWrite failed with %d", r);
   829 					break;
   830 					}
   831 				r = Kern::ThreadRawWrite(iClientThreadPtr, ptr.iPtr4, (TAny*)&levelOwnerId, sizeof(TInt));
   832 				if(r != KErrNone)
   833 					Kern::Printf("RTestResMan::GetResourceStateSync ThreadRawWrite failed with %d", r);
   834 				}
   835 			break;
   836 			}
   837 		case RTestResMan::ERequestNotificationUncond:
   838 			{
   839 			SNotificationList *notiList;
   840 			notiList = new SNotificationList; //Create new notification list
   841 			if(!notiList)
   842 				{
   843 				r = KErrNoMemory;
   844 				break;
   845 				}
   846 			//Create notification object to pass to RM
   847 			notiList->iNoti = new DPowerResourceNotification(UnCondNotificationFunc, this, ((DTestResManLddFactory*)iDevice)->iDfcQ, 3);
   848 			if(!notiList->iNoti)
   849 				{
   850 				delete notiList;
   851 				r = KErrNoMemory;
   852 				break;
   853 				}
   854 			notiList->iClientId = (TUint)a1;
   855 			notiList->iResourceId = (TUint)a2;
   856 			notiList->iCount = 0;
   857 			LIST_PUSH(iUnCondList, notiList, iNext); //Add to unconditional list.							 
   858 			r = PowerResourceManager::RequestNotification((TUint)a1, (TUint)a2, *notiList->iNoti);
   859 			break;
   860 			}
   861 		case RTestResMan::ERequestNotificationCond:
   862 			{
   863 			SNotificationList *notiList;
   864 			notiList = new SNotificationList; // Create new notification list
   865 			if(!notiList)
   866 				{
   867 				r = KErrNoMemory;
   868 				break;
   869 				}
   870 			//Create notification object to pass to RM
   871 			notiList->iNoti = new DPowerResourceNotification(CondNotificationFunc, this, ((DTestResManLddFactory*)iDevice)->iDfcQ, 3);
   872 			if(!notiList->iNoti)
   873 				{
   874 				delete notiList;
   875 				r = KErrNoMemory;
   876 				break;
   877 				}
   878 			notiList->iClientId = ptr.iClientId;
   879 			notiList->iResourceId = (TUint)ptr.iPtr1;
   880 			notiList->iCount = 0;
   881 			LIST_PUSH(iCondList, notiList, iNext); //Add to conditional list.
   882 			r = PowerResourceManager::RequestNotification((TUint)ptr.iClientId, (TUint)ptr.iPtr1, *notiList->iNoti, (TInt)ptr.iPtr2, (TBool)ptr.iPtr3);
   883 			break;
   884 			}
   885 		case RTestResMan::EDeRegisterClientLevelFromResource:	
   886 			{
   887 				r = PowerResourceManager::DeRegisterClientLevelFromResource((TUint)a1, (TUint)a2);
   888 				break;
   889 			} 
   890 		case RTestResMan::ECancelNotification:
   891 			{
   892 			r = KErrNotFound;
   893 			if(ptr.iPtr2) //Check for notification in conditional list if it is true.
   894 				{ 
   895 				for(SNotificationList* pN=iCondList; pN != NULL; pN=pN->iNext)
   896 					{
   897 					if((pN->iClientId == ptr.iClientId) && (pN->iResourceId == (TUint)ptr.iPtr1))
   898 						{
   899 						r = PowerResourceManager::CancelNotification(pN->iClientId, pN->iResourceId, *pN->iNoti);
   900 						LIST_REMOVE(iCondList, pN, iNext, SNotificationList);
   901 						delete pN->iNoti;
   902 						delete pN;
   903 						break;
   904 						}
   905 					}
   906 				}
   907 			else //Check for notification in unconditional list.
   908 				{
   909 				for(SNotificationList* pN=iUnCondList; pN != NULL; pN=pN->iNext)
   910 					{
   911 					if((pN->iClientId == ptr.iClientId) && (pN->iResourceId == (TUint)ptr.iPtr1))
   912 						{
   913 						r = PowerResourceManager::CancelNotification(pN->iClientId, pN->iResourceId, *pN->iNoti);
   914 						LIST_REMOVE(iUnCondList, pN, iNext, SNotificationList);
   915 						delete pN->iNoti;
   916 						delete pN;
   917 						break;
   918 						}
   919 					}
   920 				}
   921 			break;
   922 			}
   923 		case RTestResMan::ECheckNotifications:
   924 			{
   925 			NKern::Sleep(NKern::TimerTicks(300)); //This is required as sometimes check is done before callback is called.
   926 			TUint countCond = 0, countUncond = 0;
   927 			SNotificationList* pN; 
   928 			//Get the conditional notification callback functions called for the resource id.
   929 			for(pN=iCondList; pN != NULL; pN=pN->iNext)
   930 				{
   931 				if(pN->iResourceId == (TUint)ptr.iPtr1)
   932 					{
   933 					countCond = pN->iCount;
   934 					pN->iCount = 0;
   935 					break;
   936 					}
   937 				}
   938 			//Get the unconditional notification callback functions called for the resource id.
   939 			for(pN=iUnCondList; pN != NULL; pN=pN->iNext)
   940 				{
   941 				if(pN->iResourceId == (TUint)ptr.iPtr1)
   942 					{
   943 					countUncond = pN->iCount;
   944 					pN->iCount = 0;
   945 					break;
   946 					}
   947 				}
   948 			//If the notifications count is not as expected return error.
   949 			if((countCond != (TUint)ptr.iPtr3) || (countUncond != (TUint)ptr.iPtr2))
   950 				r = KErrUnderflow;
   951 			break;
   952 			}
   953 		case RTestResMan::ERegisterForIdleResourcesInfo:
   954 			{	
   955 			if(pBuf)
   956 				{
   957 				r = KErrAlreadyExists;
   958 				break;
   959 				}
   960 			NKern::ThreadEnterCS();
   961 			pBuf = HBuf::New((TUint)ptr.iPtr1 * sizeof(SIdleResourceInfo)); //Allocate buffer for requested resources
   962 			NKern::ThreadLeaveCS();
   963 			if(!pBuf)
   964 				return KErrNoMemory;
   965 			r = Kern::ThreadRawRead(iClientThreadPtr, ptr.iPtr2, (TAny*)pBuf->Ptr(), (TUint)ptr.iPtr1 * sizeof(SIdleResourceInfo));
   966 			if(r != KErrNone)
   967 				{
   968 				Kern::Printf("RTestResMan::ERegisterForIdleResourceInfo threadRawRead failed with %d\n", r);
   969 				break;
   970 				}
   971 			//Below function calls RegisterForResourceIdle resource controller virtual function, 
   972 			//This is for testing purposes only.
   973 
   974 			r =DSimulatedPowerResourceController::CaptureIdleResourcesInfo((TUint)ptr.iClientId, (TUint)ptr.iPtr1, (TPtr*)pBuf);
   975 			if( r == KErrInUse)
   976 			   delete pBuf;
   977 			break;
   978 			}
   979 		case RTestResMan::EGetIdleResourcesInfo:
   980 			{
   981 			//Pass the buffer for comparision
   982 			if(!pBuf)
   983 				{
   984 				r = KErrNotFound;
   985 				break;
   986 				}
   987 			pBuf->SetLength(sizeof(SIdleResourceInfo) * (TUint)a1);
   988 			r = Kern::ThreadDesWrite(iClientThreadPtr, a2, (const TDesC8&)*pBuf, 0);
   989 			break;
   990 			}
   991 		case RTestResMan::ECheckPostBootLevelNotifications:
   992 			{
   993 				if(DTestResManLddFactory::iPostBootNotiCount != EXPECTED_POST_NOTI_COUNT)
   994 				{
   995 				r = KErrUnderflow;
   996 				break;
   997 				}
   998 			r = KErrNone;
   999 			break;
  1000 			}
  1001 		case RTestResMan::EGetControllerVersion:
  1002 			{
  1003 			TUint Version;
  1004 			r = PowerResourceManager::GetResourceControllerVersion((TUint)a1, Version);
  1005 			if(r == KErrNone)
  1006 				{
  1007 				r = Kern::ThreadRawWrite(iClientThreadPtr, a2, &Version, sizeof(TUint));
  1008 				if(r != KErrNone)
  1009 					Kern::Printf("RTestResMan::EGetControllerVersion ThreadRawWrite failed with %d", r);
  1010 				}
  1011 			break;
  1012 			}
  1013 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1014 		case RTestResMan::ERegisterDynamicResource:
  1015 			{
  1016 			TUint resId;
  1017 			r = Kern::ThreadRawRead(iClientThreadPtr, a2, (TAny*)&resId, sizeof(TUint));
  1018 			if(r != KErrNone)
  1019 				{
  1020 				Kern::Printf("RTestResMan::RegisterDynamicResource ThreadRawRead failed with %d", r);
  1021 				break;
  1022 				}			
  1023 			DDynamicPowerResource* pDR = NULL;
  1024 			switch(resId) //Create the dynamic resource
  1025 				{
  1026 				case 1:
  1027 					pDR = new (DBIGISSPDynamicResource);
  1028 					break;
  1029 				case 2:
  1030 					pDR = new (DMLIGLSSHNDynamicResource);
  1031 					break;
  1032 				case 3: 
  1033 					pDR = new (DBLGLSSHNDynamicResource);
  1034 					break;
  1035 				case 4:
  1036 					pDR = new (DMLLGLSSHPDynamicResource);
  1037 					break;
  1038 				case 5:
  1039 					pDR = (DDynamicPowerResource*) new (DDynamicResourceD01);
  1040 					break;
  1041 				case 6:
  1042 					pDR = (DDynamicPowerResource*) new (DDynamicResourceD02);
  1043 					break;
  1044 				case 7:
  1045 					pDR = (DDynamicPowerResource*) new (DDynamicResourceD03);
  1046 					break;
  1047 				case 8:
  1048 					pDR = (DDynamicPowerResource*) new (DDynamicResourceD04);
  1049 					break;
  1050 				}
  1051 			if(!pDR)
  1052 				return KErrNoMemory;
  1053 			iDynamicArray.Append(pDR);
  1054 			r = PowerResourceManager::RegisterDynamicResource((TUint)a1, pDR, resId);
  1055 			if(r == KErrNone)
  1056 				{
  1057 				r = Kern::ThreadRawWrite(iClientThreadPtr, a2, (TAny*)&resId, sizeof(TUint));
  1058 				if(r != KErrNone)
  1059 					Kern::Printf("RTestResMan::RegisterDynamicResource ThreadRawWrite failed with %d", r);
  1060 				}
  1061 			break;
  1062 			}
  1063 		case RTestResMan::EDeRegisterDynamicResource: //Deregister dynamic resource
  1064 			{
  1065 			if(ptr.iPtr2)
  1066 				{
  1067 				TInt level;
  1068 				r = Kern::ThreadRawRead(iClientThreadPtr, ptr.iPtr2, &level, sizeof(TInt));
  1069 				if(r != KErrNone)
  1070 					{
  1071 					Kern::Printf("RTestResMan::DeRegisterDynamicResource ThreadRawRead failed with %d", r);
  1072 					break;
  1073 					}	
  1074 				r = PowerResourceManager::DeRegisterDynamicResource(ptr.iClientId, (TUint)ptr.iPtr1, &level);
  1075 				}
  1076 			else
  1077 				r = PowerResourceManager::DeRegisterDynamicResource(ptr.iClientId, (TUint)ptr.iPtr1, NULL);
  1078 			break;
  1079 			}
  1080 		case RTestResMan::ERegisterResourceDependency: //Register resource dependency
  1081 			{
  1082 			SResourceDependencyInfo info1, info2;
  1083 			r = Kern::ThreadRawRead(iClientThreadPtr, ptr.iPtr1, &info1, sizeof(SResourceDependencyInfo));
  1084 			if(r != KErrNone)
  1085 				{
  1086 				Kern::Printf("RTestResMan::RegisterResourceDependency ThreadRawRead failed with %d", r);
  1087 				break;
  1088 				}
  1089 			r = Kern::ThreadRawRead(iClientThreadPtr, ptr.iPtr2, &info2, sizeof(SResourceDependencyInfo));
  1090 			if(r != KErrNone)
  1091 				{
  1092 				Kern::Printf("RTestResMan::RegisterResourceDependency ThreadRawRead failed with %d", r);
  1093 				break;
  1094 				}
  1095 			r = PowerResourceManager::RegisterResourceDependency(ptr.iClientId, &info1, &info2);
  1096 			break;
  1097 			}
  1098 		case RTestResMan::EDeRegisterResourceDependency: //Deregister resource dependency
  1099 			{
  1100 			r = PowerResourceManager::DeRegisterResourceDependency(ptr.iClientId, (TUint)ptr.iPtr1, (TUint)ptr.iPtr2);
  1101 			break;
  1102 			}
  1103 		case RTestResMan::EGetNumDependentsForResource:
  1104 			{
  1105 			TUint numDepResources;
  1106 			r = PowerResourceManager::GetNumDependentsForResource(ptr.iClientId, (TUint)ptr.iPtr1, numDepResources);
  1107 			if(r == KErrNone)
  1108 				{
  1109 				r = Kern::ThreadRawWrite(iClientThreadPtr, ptr.iPtr2, (TAny*)&numDepResources, sizeof(TUint));
  1110 				if(r != KErrNone)
  1111 					Kern::Printf("RTestResMan::RegisterDynamicResource ThreadRawWrite failed with %d", r);
  1112 				}
  1113 			break;
  1114 			}
  1115 		case RTestResMan::EGetDependentsIdForResource:
  1116 			{
  1117 			TUint numDepResources;
  1118 			HBuf* sResDepInfo = NULL;
  1119 			r = Kern::ThreadRawRead(iClientThreadPtr, ptr.iPtr3, (TAny*)&numDepResources, sizeof(TUint));
  1120 			if(r != KErrNone)
  1121 				{
  1122 				Kern::Printf("RTestResMan::GetDependentsIdForResource ThreadRawRead failed with %d", r);
  1123 				break;
  1124 				}
  1125 			if(ptr.iPtr2 != NULL)
  1126 				{
  1127 				NKern::ThreadEnterCS();
  1128 				sResDepInfo = HBuf::New(numDepResources * sizeof(SResourceDependencyInfo));
  1129 				NKern::ThreadLeaveCS();
  1130 				if(!sResDepInfo)
  1131 					return KErrNoMemory;
  1132 				}
  1133 			
  1134 			r = PowerResourceManager::GetDependentsIdForResource(ptr.iClientId, (TUint)ptr.iPtr1, (TAny*)sResDepInfo, numDepResources);
  1135 			if(r == KErrNone)
  1136 				{
  1137 				if(ptr.iPtr2)
  1138 					r = Kern::ThreadDesWrite(iClientThreadPtr, ptr.iPtr2, (const TDesC8&)*sResDepInfo, 0);
  1139 				if(r != KErrNone)
  1140 					{
  1141 					Kern::Printf("RTestResMan::GetDepedentsIdForResource ThreadDesWrite failed with %d", r);
  1142 					Kern::Free(sResDepInfo);
  1143 					break;
  1144 					}
  1145 				r = Kern::ThreadRawWrite(iClientThreadPtr, ptr.iPtr3, (TAny*)&numDepResources, sizeof(TUint));
  1146 				if(r != KErrNone)
  1147 					{
  1148 					Kern::Printf("RTestResMan::GetDependentsIdForResource ThreadRawWrite failed with %d", r);
  1149 					Kern::Free(sResDepInfo);
  1150 					break;
  1151 					}
  1152 				}
  1153 			Kern::Free(sResDepInfo);
  1154 			break;
  1155 			}
  1156 
  1157 #endif
  1158 		default:
  1159 			r = KErrNotSupported;
  1160 			break;
  1161 		}
  1162 	return r;
  1163 	}
  1164 
  1165 TInt DTestResManLdd::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* /*a2*/)
  1166 	{
  1167 	TInt r = KErrNone;
  1168 	TParameterListInfo ptr;
  1169 	r = Kern::ThreadRawRead(iClientThreadPtr, (TParameterListInfo*)a1, &ptr, sizeof(TParameterListInfo));
  1170 	if(r != KErrNone)
  1171 		Kern::RequestComplete(iClientThreadPtr, aStatus, r);
  1172 	switch(aReqNo)
  1173 		{
  1174 		case RTestResMan::EChangeResourceStateAsync:
  1175 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1176 		case RTestResMan::EChangeResStateAndDeregisterDynamicRes:
  1177 		case RTestResMan::ECheckParallelExecutionForChangeResState:
  1178 #endif
  1179 			SNotificationList* pN; 
  1180 			//Zero the conditional notification count for the resource id.
  1181 			for(pN=iCondList; pN != NULL; pN=pN->iNext)
  1182 				{
  1183 				if(pN->iResourceId == (TUint)ptr.iPtr1)
  1184 					{
  1185 					pN->iCount = 0;
  1186 					break;
  1187 					}
  1188 				}
  1189 			//Zero the unconditional notification count for the resource id.
  1190 			for(pN=iUnCondList; pN != NULL; pN=pN->iNext)
  1191 				{
  1192 				if(pN->iResourceId == (TUint)ptr.iPtr1)
  1193 					{
  1194 					pN->iCount = 0;
  1195 					break;
  1196 					}
  1197 				}
  1198 			iLevelOwnerIdPtr = NULL;
  1199 			iStatePtr = (TInt*)ptr.iPtr2;
  1200 			TInt state;
  1201 			r = Kern::ThreadRawRead(iClientThreadPtr, iStatePtr, &state, sizeof(TInt)); 
  1202 			if(r != KErrNone)
  1203 				Kern::RequestComplete(iClientThreadPtr, aStatus, r);
  1204 			iStatus = aStatus;
  1205 			iClientId = ptr.iClientId;
  1206 			iResourceId = (TUint)ptr.iPtr1;
  1207 			iCallbackCancel = EFalse;
  1208 			r = PowerResourceManager::ChangeResourceState(ptr.iClientId, (TUint)ptr.iPtr1, state, &iAsyncResourceCallback);
  1209 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1210 			if(aReqNo == RTestResMan::EChangeResStateAndDeregisterDynamicRes) //Try to delete the dynamic while resource change
  1211 				{
  1212 				r = PowerResourceManager::DeRegisterDynamicResource(ptr.iClientId, (TUint)ptr.iPtr1, NULL);
  1213 				if(r == KErrInUse) //Wait for the request to complete
  1214 					r = KErrNone; 
  1215 				break;
  1216 				}
  1217 			if(aReqNo == RTestResMan::ECheckParallelExecutionForChangeResState)
  1218 				{
  1219 				r = PowerResourceManager::ChangeResourceState(ptr.iClientId, (TUint)ptr.iPtr3, (TInt)ptr.iPtr4, &iAsyncTestParallelCallback);
  1220 				iTestParallelResourceId = (TUint)ptr.iPtr3;
  1221 				iValidateCallbackReceived = ETrue;
  1222 				break;
  1223 				}
  1224 #endif
  1225 			if(ptr.iPtr3) //Cancel the asynchronous operation if true.
  1226 				{
  1227 				r = PowerResourceManager::CancelAsyncRequestCallBack(ptr.iClientId, (TUint)ptr.iPtr1, iAsyncResourceCallback);
  1228 				if(r == KErrInUse) //Wait for the request to complete
  1229 					r = KErrNone;
  1230 				else
  1231 					iCallbackCancel = ETrue;
  1232 				}
  1233 			break;
  1234 		case RTestResMan::EGetResourceStateAsync:
  1235 			iStatus = aStatus;
  1236 			iCallbackCancel = EFalse;
  1237 			iClientId = ptr.iClientId;
  1238 			iResourceId = (TUint)ptr.iPtr1;
  1239 			iStatePtr = (TInt*)ptr.iPtr4;
  1240 			iLevelOwnerIdPtr = (TInt*)ptr.iPtr5;
  1241 			r = PowerResourceManager::GetResourceState(ptr.iClientId, (TUint)ptr.iPtr1, (TBool)ptr.iPtr2, iAsyncResourceCallback);
  1242 			if(ptr.iPtr3) //Cancel the asynchronous operation if true.
  1243 				{
  1244 				r = PowerResourceManager::CancelAsyncRequestCallBack(ptr.iClientId, (TUint)ptr.iPtr1, iAsyncResourceCallback);
  1245 				if(r == KErrInUse)
  1246 					r = KErrNone;
  1247 				else 
  1248 					iCallbackCancel = ETrue;
  1249 				}
  1250 			break;
  1251 		}
  1252 	return r;
  1253 	}
  1254 
  1255 //Function called on Asynchronous operation
  1256 void DTestResManLdd::CallbackFunc(TUint aClientId, TUint aResId, TInt aLevel, TInt aLevelOwnerId, TInt aResult, TAny* aParam)
  1257 	{
  1258 	TInt r;
  1259 	DTestResManLdd *pC = (DTestResManLdd*)aParam;
  1260 	//Check for correctnes of clientId and resourceId
  1261 	if((TUint)pC->iClientId != aClientId || pC->iResourceId != aResId)
  1262 		Kern::RequestComplete(pC->iClientThreadPtr, pC->iStatus, KErrCorrupt);
  1263 	if(!pC->iCallbackCancel)
  1264 		{
  1265 		if(pC->iStatePtr) 
  1266 			{
  1267 			r = Kern::ThreadRawWrite(pC->iClientThreadPtr, pC->iStatePtr, (TAny*)&aLevel, sizeof(TInt));
  1268 			if(r != KErrNone)
  1269 				Kern::Printf("RTestResManLdd::CallbackFunc ThreadRawWrite failed with %d", r);
  1270 			}
  1271 		if(pC->iLevelOwnerIdPtr)
  1272 			{
  1273 			r = Kern::ThreadRawWrite(pC->iClientThreadPtr, pC->iLevelOwnerIdPtr, (TAny*)&aLevelOwnerId, sizeof(TInt));
  1274 			if(r != KErrNone)
  1275 				Kern::Printf("RTestResManLdd::CallbackFunc ThreadRawWrite failed with %d", r);
  1276 			}
  1277 		#ifdef PRM_ENABLE_EXTENDED_VERSION
  1278 		if(pC->iValidateCallbackReceived)
  1279 			{
  1280 			if(!pC->iCallbackReceived)
  1281 				aResult = KErrCompletion;
  1282 			}
  1283 		#endif
  1284 		Kern::RequestComplete(pC->iClientThreadPtr, pC->iStatus, aResult);
  1285 		}
  1286 	pC->iCallbackCancel = EFalse;
  1287 	pC->iStatus = NULL;
  1288 	}
  1289 
  1290 #ifdef PRM_ENABLE_EXTENDED_VERSION
  1291 //Function called on completion of asynchronous long latency resource, used only to check parallel execution of DFC's
  1292 void DTestResManLdd::TestParallelExecutionCallback(TUint aClientId, TUint aResId, TInt /*aLevel*/, TInt /*aLevelOwnerId*/, TInt /*aResult*/, TAny* aParam)
  1293 	{
  1294 	Kern::Printf("DTestResManLdd::TestParallelExecutionCallback:: called");
  1295 	DTestResManLdd *pC = (DTestResManLdd*)aParam;
  1296 	//Check for correctness of clientId and resourceId
  1297 	if((TUint)pC->iClientId == aClientId && pC->iTestParallelResourceId == aResId)
  1298 		{
  1299 		pC->iCallbackReceived = ETrue;
  1300 		}
  1301 	}
  1302 #endif
  1303 
  1304 //Function called on Conditional notification
  1305 void DTestResManLdd::CondNotificationFunc(TUint /*aClientId*/, TUint aResId, TInt /*aLevel*/, TInt /*aLevelOwnerId*/, TInt /*aResult*/, TAny* aParam)
  1306 	{
  1307 	DTestResManLdd *pC = (DTestResManLdd*)aParam;
  1308 	for(SNotificationList *pN = pC->iCondList; pN!= NULL; pN=pN->iNext)
  1309 		{
  1310 		if((pN->iResourceId == aResId))
  1311 			{
  1312 			pN->iCount++; //Increment the count, as same callback function for all conditioanl notifications.
  1313 			break;
  1314 			}
  1315 		}
  1316 	}
  1317 
  1318 //Function called on UnConditional notification
  1319 void DTestResManLdd::UnCondNotificationFunc(TUint /*aClientId*/, TUint aResId, TInt /*aLevel*/, TInt /*aLevelOwnerId*/, TInt /*aResult*/, TAny* aParam)
  1320 	{
  1321 	DTestResManLdd *pC = (DTestResManLdd*)aParam;
  1322 	for(SNotificationList *pN = pC->iUnCondList; pN!= NULL; pN=pN->iNext)
  1323 		{
  1324 		if((pN->iResourceId == aResId) && (pC->iCallbackCancel == EFalse))
  1325 			{
  1326 			pN->iCount++; //Increment the count as same callback function for all unconditioanl notifications.
  1327 			break;
  1328 			}
  1329 		}
  1330 	}
  1331 
  1332 //Function called on postbootvalueset. 
  1333 void DTestResManLddFactory::PostBootNotificationFunc(TUint /*aClientId*/, TUint aResId, TInt /*aLevel*/, TInt /*aLevelOwnerId*/, TInt /*aResult*/, TAny* aParam)
  1334 	{
  1335 	iPostBootNotiCount++;
  1336 	DPowerResourceNotification *ptr = (DPowerResourceNotification*)aParam;
  1337 	TInt r = PowerResourceManager::CancelNotification(iClient.iClientId, aResId, *ptr);
  1338 	if(r == KErrNone)
  1339 		delete ptr;
  1340 	}