sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include "d_prmacctst.h" sl@0: #ifdef RESOURCE_MANAGER_SIMULATED_PSL sl@0: #include "../resourceman_psl/rescontrol_psl.h" sl@0: #endif // RESOURCE_MANAGER_SIMULATED_PSL sl@0: sl@0: #define TEST_KERRNONE(x) { TInt _r = (x); if (_r != KErrNone) \ sl@0: Kern::Printf("Test failed: %s line %d error %d", __FILE__, __LINE__, _r); } sl@0: #define TEST(x) { if (!(x)) Kern::Printf("Test failed: %s line %d", __FILE__, __LINE__); } sl@0: sl@0: _LIT(KTestDfcQueBaseName, "PrmIfDfc"); sl@0: const TInt KTestDfcQuePrority = KMaxDfcPriority - 1; sl@0: sl@0: //--------------------------------------------------------------------------- sl@0: sl@0: class DPrmIfDevice : public DLogicalDevice sl@0: { sl@0: public: sl@0: DPrmIfDevice(); sl@0: virtual TInt Install(); sl@0: virtual void GetCaps(TDes8& aDes) const; sl@0: virtual TInt Create(DLogicalChannelBase*& aChannel); sl@0: }; sl@0: sl@0: //--------------------------------------------------------------------------- sl@0: sl@0: class DPrmIfChannel : public DLogicalChannel sl@0: { sl@0: public: sl@0: DPrmIfChannel(); sl@0: ~DPrmIfChannel(); sl@0: protected: sl@0: virtual void HandleMsg(TMessageBase* aMsg); sl@0: virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: private: sl@0: TInt DoControl(TInt aReqNo, TAny *a1, TAny *a2); sl@0: TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny *a1, TAny *a2); sl@0: void Shutdown(); sl@0: sl@0: public: sl@0: static TUint KernelExtensionClientId; sl@0: private: sl@0: DThread* iUserThread; sl@0: TUint iClientId; sl@0: HBuf* iClientName; sl@0: }; sl@0: sl@0: TUint DPrmIfChannel::KernelExtensionClientId = 0; sl@0: sl@0: void TestCallbackFunction(TUint /* aClientId */, sl@0: TUint /* aResourceId */, sl@0: TInt /* aLevel */, sl@0: TInt /* aLevelOwnerId */, sl@0: TInt /* aResult */, sl@0: TAny* aSem); sl@0: sl@0: //--------------------------------------------------------------------------- sl@0: sl@0: DPrmIfDevice::DPrmIfDevice() sl@0: { sl@0: } sl@0: sl@0: TInt DPrmIfDevice::Install() sl@0: { sl@0: return SetName(&KPrmIfLddName); sl@0: } sl@0: sl@0: void DPrmIfDevice::GetCaps(TDes8& /* aDes */) const sl@0: { sl@0: // Not used but required as DLogicalDevice::GetCaps is pure virtual sl@0: } sl@0: sl@0: TInt DPrmIfDevice::Create(DLogicalChannelBase*& aChannel) sl@0: { sl@0: aChannel = new DPrmIfChannel; sl@0: return aChannel ? KErrNone : KErrNoMemory; sl@0: } sl@0: sl@0: //--------------------------------------------------------------------------- sl@0: sl@0: DPrmIfChannel::DPrmIfChannel() sl@0: { sl@0: iUserThread = &Kern::CurrentThread(); sl@0: ((DObject*) iUserThread)->Open(); sl@0: } sl@0: sl@0: DPrmIfChannel::~DPrmIfChannel() sl@0: { sl@0: if(iDfcQ) sl@0: ((TDynamicDfcQue*)iDfcQ)->Destroy(); sl@0: // Close our reference on the client thread sl@0: Kern::SafeClose((DObject*&)iUserThread,NULL); sl@0: } sl@0: sl@0: void DPrmIfChannel::HandleMsg(TMessageBase *aMsg) sl@0: { sl@0: TThreadMessage& m = *(TThreadMessage*) aMsg; sl@0: TInt id = m.iValue; sl@0: sl@0: if (id == (TInt) ECloseMsg) sl@0: { sl@0: m.Complete(KErrNone, EFalse); sl@0: return; sl@0: } sl@0: else if (id == KMaxTInt) sl@0: { sl@0: // DoCancel sl@0: m.Complete(KErrNone, ETrue); sl@0: return; sl@0: } sl@0: else if (id < 0) sl@0: { sl@0: // DoRequest sl@0: TRequestStatus* pS = (TRequestStatus*) m.Ptr0(); sl@0: TInt r = DoRequest(~id, pS, m.Ptr1(), m.Ptr2()); sl@0: if (r != KErrNone) sl@0: { sl@0: Kern::RequestComplete(iUserThread, pS, r); sl@0: } sl@0: m.Complete(KErrNone, ETrue); sl@0: } sl@0: else sl@0: { sl@0: // DoControl sl@0: TInt r = DoControl(id, m.Ptr0(), m.Ptr1()); sl@0: if(r != KErrCompletion) sl@0: { sl@0: m.Complete(r, ETrue); sl@0: } sl@0: } sl@0: } sl@0: sl@0: TInt DPrmIfChannel::DoCreate(TInt /* aUnit */, const TDesC8* /* aInfo */, const TVersion& /* aVer */) sl@0: { sl@0: TDynamicDfcQue* dfcQ; sl@0: TInt r = Kern::DynamicDfcQCreate(dfcQ, KTestDfcQuePrority, KTestDfcQueBaseName); sl@0: TEST_KERRNONE(r); sl@0: iDfcQ = dfcQ; sl@0: if (r != KErrNone) sl@0: { sl@0: return r; sl@0: } sl@0: SetDfcQ(iDfcQ); sl@0: iMsgQ.Receive(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DPrmIfChannel::DoControl(TInt aReqNo, TAny *a1, TAny *a2) sl@0: { sl@0: TInt r = KErrNotSupported; sl@0: switch (aReqNo) sl@0: { sl@0: case RPrmIf::EControlOpenClient: sl@0: { sl@0: if (iClientId) sl@0: { sl@0: return KErrAlreadyExists; sl@0: } sl@0: TBuf8<80> clientName; sl@0: r = PowerResourceManager::GetClientName((TUint) a1, (TUint) a1, clientName); sl@0: TEST_KERRNONE(r); sl@0: if (r == KErrNone) sl@0: iClientId = (TUint) a1; sl@0: break; sl@0: } sl@0: sl@0: case RPrmIf::EControlGetKernelExtClientId: sl@0: { sl@0: r = Kern::ThreadRawWrite(iUserThread, a1, &KernelExtensionClientId, sizeof(TUint)); sl@0: TEST_KERRNONE(r); sl@0: break; sl@0: } sl@0: sl@0: case RPrmIf::EControlRegisterClient: sl@0: { sl@0: if (iClientId) sl@0: { sl@0: return KErrAlreadyExists; sl@0: } sl@0: iClientName = HBuf::New(KNameMaxLength); sl@0: r = Kern::ThreadDesRead(iUserThread, a1, *iClientName, 0); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: r = PowerResourceManager::RegisterClient(iClientId, *iClientName); sl@0: TEST_KERRNONE(r); sl@0: break; sl@0: } sl@0: sl@0: case RPrmIf::EControlDeRegisterClient: sl@0: { sl@0: if (!iClientId) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: r = PowerResourceManager::DeRegisterClient(iClientId); sl@0: if (r == KErrNone) sl@0: { sl@0: if (iClientId == KernelExtensionClientId) sl@0: { sl@0: // Set it to 0 so it cannot be re-opened sl@0: KernelExtensionClientId = 0; sl@0: } sl@0: delete iClientName; sl@0: iClientId = 0; sl@0: } sl@0: break; sl@0: } sl@0: sl@0: case RPrmIf::EControlGetInfoOnResourcesInUseByClient: sl@0: { sl@0: if (!iClientId) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: TUint nores; sl@0: r = PowerResourceManager::GetNumResourcesInUseByClient(iClientId, (TUint) a1, nores); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: if (nores > 0) sl@0: { sl@0: HBuf* resinfo; sl@0: resinfo = HBuf::New(nores * sizeof(TResInfo)); sl@0: TEST(resinfo != NULL); sl@0: if (resinfo == NULL) sl@0: { sl@0: return KErrNoMemory; sl@0: } sl@0: r = PowerResourceManager::GetInfoOnResourcesInUseByClient(iClientId, (TUint) a1, nores, (TAny*) resinfo); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: delete resinfo; sl@0: return r; sl@0: } sl@0: r = Kern::ThreadDesWrite(iUserThread, a2, *resinfo, 0); sl@0: TEST_KERRNONE(r); sl@0: delete resinfo; sl@0: } sl@0: break; sl@0: } sl@0: sl@0: case RPrmIf::EControlChangeResourceState: sl@0: { sl@0: if (!iClientId) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: r = PowerResourceManager::ChangeResourceState(iClientId, (TUint) a1, (TInt) a2); sl@0: break; sl@0: } sl@0: sl@0: case RPrmIf::EControlGetResourceState: sl@0: { sl@0: if (!iClientId) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: TInt state; sl@0: TInt levelowner; sl@0: r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, EFalse, state, levelowner); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt)); sl@0: TEST_KERRNONE(r); sl@0: break; sl@0: } sl@0: sl@0: case RPrmIf::EControlGetResourceStateCached: sl@0: { sl@0: if (!iClientId) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: TInt state; sl@0: TInt levelowner; sl@0: r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, ETrue, state, levelowner); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt)); sl@0: TEST_KERRNONE(r); sl@0: break; sl@0: } sl@0: sl@0: case RPrmIf::EControlGetLevelOwner: sl@0: { sl@0: if (!iClientId) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: TInt state; sl@0: TInt levelowner; sl@0: r = PowerResourceManager::GetResourceState(iClientId, (TUint) a1, EFalse, state, levelowner); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &levelowner, sizeof(TInt)); sl@0: TEST_KERRNONE(r); sl@0: break; sl@0: } sl@0: sl@0: case RPrmIf::EControlGetTotalNumberOfResources: sl@0: { sl@0: if (!iClientId) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: TUint nores; sl@0: r = PowerResourceManager::GetNumResourcesInUseByClient(iClientId, 0, nores); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: r = Kern::ThreadRawWrite(iUserThread, a1, (TAny*) &nores, sizeof(TUint)); sl@0: TEST_KERRNONE(r); sl@0: break; sl@0: } sl@0: sl@0: #ifdef PRM_ENABLE_EXTENDED_VERSION sl@0: case RPrmIf::EControlGetResourceDependencies: sl@0: { sl@0: if (!iClientId) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: // Get the resource information from the PRM sl@0: TUint numres; sl@0: r = PowerResourceManager::GetNumDependentsForResource(iClientId, (TUint) a1, numres); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: sl@0: // Create a descriptor with the list of dependencies sl@0: HBuf* depdes; sl@0: depdes = HBuf::New(sizeof(SResourceDependencyInfo) * numres); sl@0: TEST(depdes != NULL); sl@0: if (depdes == NULL) sl@0: { sl@0: return KErrNoMemory; sl@0: } sl@0: sl@0: TUint numres2 = numres; sl@0: r = PowerResourceManager::GetDependentsIdForResource(iClientId, (TUint) a1, (TAny*) depdes, numres2); sl@0: TEST_KERRNONE(r); sl@0: TEST(numres == numres2); sl@0: sl@0: // Copy the descriptor contents to the user-side descriptor sl@0: r = Kern::ThreadDesWrite(iUserThread, a2, *depdes, 0); sl@0: TEST_KERRNONE(r); sl@0: delete depdes; sl@0: break; sl@0: } sl@0: #endif // PRM_ENABLE_EXTENDED_VERSION sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: TInt DPrmIfChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny *a1, TAny *a2) sl@0: { sl@0: TInt r = KErrNotSupported; sl@0: switch (aReqNo) sl@0: { sl@0: case RPrmIf::ERequestChangeResourceStateAndGetState: sl@0: { sl@0: if (!iClientId) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: TTestResourceStateBuf args; sl@0: r = Kern::ThreadDesRead(iUserThread, a1, args, 0); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: NFastSemaphore sem; sl@0: NKern::FSSetOwner(&sem, (NThreadBase*) NKern::CurrentThread()); sl@0: TPowerResourceCb cbfn(&TestCallbackFunction, (TAny*) &sem, /*iDfcQ*/ Kern::DfcQue0(), KMaxDfcPriority - 2); sl@0: // Change the state of the resource (asynchronous call) sl@0: r = PowerResourceManager::ChangeResourceState(iClientId, args().iResourceId, args().iNewState, &cbfn); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: // Retrieve the intermediate state of the resource sl@0: TInt state; sl@0: TInt levelowner; sl@0: r = PowerResourceManager::GetResourceState(iClientId, args().iResourceId, EFalse, state, levelowner); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: r = Kern::ThreadRawWrite(iUserThread, a2, (TAny*) &state, sizeof(TInt)); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: // Wait for the callback function sl@0: NKern::FSWait(&sem); sl@0: Kern::RequestComplete(iUserThread, aStatus, r); sl@0: break; sl@0: } sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: //--------------------------------------------------------------------------- sl@0: sl@0: // sl@0: // Callback function for Latency Tests sl@0: // sl@0: void TestCallbackFunction(TUint /* aClientId */, sl@0: TUint /* aResourceId */, sl@0: TInt /* aLevel */, sl@0: TInt /* aLevelOwnerId */, sl@0: TInt /* aResult */, sl@0: TAny* aSem) sl@0: { sl@0: if (!aSem) sl@0: { sl@0: return; sl@0: } sl@0: NKern::FSSignal((NFastSemaphore*) aSem); sl@0: } sl@0: sl@0: // sl@0: // This function is called during kernel initialisation. It registers a client sl@0: // on the PRM in order to take ownership of the Single-User resources before sl@0: // anyone else does. sl@0: // sl@0: static void InitExtension(TAny*) sl@0: { sl@0: TInt r; sl@0: sl@0: // Get the overall number of resources sl@0: TUint nores; sl@0: r = PowerResourceManager::GetNumResourcesInUseByClient(DPrmIfChannel::KernelExtensionClientId, 0, nores); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return; sl@0: } sl@0: sl@0: // Get hold of all of the resources by setting their state to the default level sl@0: TInt i; sl@0: for (i = 0; i < (TInt) nores; i++) sl@0: { sl@0: TPowerResourceInfoBuf01 res; sl@0: res.Zero(); sl@0: r = PowerResourceManager::GetResourceInfo(DPrmIfChannel::KernelExtensionClientId, i + 1, (TAny*) &res); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return; sl@0: } sl@0: r = PowerResourceManager::ChangeResourceState(DPrmIfChannel::KernelExtensionClientId, i + 1, res().iDefaultLevel); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return; sl@0: } sl@0: } sl@0: TUint resinuse; sl@0: r = PowerResourceManager::GetNumResourcesInUseByClient(DPrmIfChannel::KernelExtensionClientId, DPrmIfChannel::KernelExtensionClientId, resinuse); sl@0: TEST_KERRNONE(r); sl@0: TEST(resinuse == nores); sl@0: } sl@0: sl@0: static TDfc InitExtensionDfc(&InitExtension, NULL, Kern::SvMsgQue(), KMaxDfcPriority - 2); // Priority lower than the Resource Controller (KMaxDfcPriority - 1) sl@0: sl@0: #ifndef RESOURCE_MANAGER_SIMULATED_PSL sl@0: _LIT8(KTestKExtClientName, "KEXTC"); sl@0: DECLARE_STANDARD_EXTENSION() sl@0: { sl@0: // Register the initial PRM client (kernel will crash if this fails) sl@0: TUint clientid; sl@0: TInt r = PowerResourceManager::RegisterClient(clientid, KTestKExtClientName); sl@0: TEST_KERRNONE(r); sl@0: if (r) sl@0: { sl@0: return r; sl@0: } sl@0: DPrmIfChannel::KernelExtensionClientId = clientid; sl@0: // Queue the DFC call to take control of all the resources sl@0: InitExtensionDfc.Enque(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: DECLARE_EXTENSION_LDD() sl@0: { sl@0: return new DPrmIfDevice; sl@0: } sl@0: #else sl@0: DECLARE_STANDARD_LDD() sl@0: { sl@0: TInt r = DSimulatedPowerResourceController::CompleteResourceControllerInitialisation(); sl@0: if (r != KErrNone) sl@0: { sl@0: return NULL; sl@0: } sl@0: return new DPrmIfDevice; sl@0: } sl@0: #endif