From 05d89f1c6452b2fce0b9f1315240f8cace69a88d Mon Sep 17 00:00:00 2001 From: Ronghua Wu Date: Tue, 7 Jul 2015 16:47:42 -0700 Subject: mediaresourcemanager: handle the case when there's no client holding resource with the same type Bug: 21171205 Change-Id: Id4aa6ccc7ee7daba25fd295399235c5b463ccd83 --- .../ResourceManagerService.cpp | 86 ++++++++----- .../mediaresourcemanager/ResourceManagerService.h | 8 ++ .../test/ResourceManagerService_test.cpp | 137 ++++++++++----------- 3 files changed, 128 insertions(+), 103 deletions(-) (limited to 'services/mediaresourcemanager') diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp index e2b6695..61147ff 100644 --- a/services/mediaresourcemanager/ResourceManagerService.cpp +++ b/services/mediaresourcemanager/ResourceManagerService.cpp @@ -204,6 +204,17 @@ void ResourceManagerService::removeResource(int64_t clientId) { } } +void ResourceManagerService::getClientForResource_l( + int callingPid, const MediaResource *res, Vector> *clients) { + if (res == NULL) { + return; + } + sp client; + if (getLowestPriorityBiggestClient_l(callingPid, res->mType, &client)) { + clients->push_back(client); + } +} + bool ResourceManagerService::reclaimResource( int callingPid, const Vector &resources) { String8 log = String8::format("reclaimResource(callingPid %d, resources %s)", @@ -213,54 +224,61 @@ bool ResourceManagerService::reclaimResource( Vector> clients; { Mutex::Autolock lock(mLock); - // first pass to handle secure/non-secure codec conflict + const MediaResource *secureCodec = NULL; + const MediaResource *nonSecureCodec = NULL; + const MediaResource *graphicMemory = NULL; for (size_t i = 0; i < resources.size(); ++i) { String8 type = resources[i].mType; - if (type == kResourceSecureCodec) { - if (!mSupportsMultipleSecureCodecs) { - if (!getAllClients_l(callingPid, String8(kResourceSecureCodec), &clients)) { - return false; - } + if (resources[i].mType == kResourceSecureCodec) { + secureCodec = &resources[i]; + } else if (type == kResourceNonSecureCodec) { + nonSecureCodec = &resources[i]; + } else if (type == kResourceGraphicMemory) { + graphicMemory = &resources[i]; + } + } + + // first pass to handle secure/non-secure codec conflict + if (secureCodec != NULL) { + if (!mSupportsMultipleSecureCodecs) { + if (!getAllClients_l(callingPid, String8(kResourceSecureCodec), &clients)) { + return false; } - if (!mSupportsSecureWithNonSecureCodec) { - if (!getAllClients_l(callingPid, String8(kResourceNonSecureCodec), &clients)) { - return false; - } + } + if (!mSupportsSecureWithNonSecureCodec) { + if (!getAllClients_l(callingPid, String8(kResourceNonSecureCodec), &clients)) { + return false; } - } else if (type == kResourceNonSecureCodec) { - if (!mSupportsSecureWithNonSecureCodec) { - if (!getAllClients_l(callingPid, String8(kResourceSecureCodec), &clients)) { - return false; - } + } + } + if (nonSecureCodec != NULL) { + if (!mSupportsSecureWithNonSecureCodec) { + if (!getAllClients_l(callingPid, String8(kResourceSecureCodec), &clients)) { + return false; } } } if (clients.size() == 0) { // if no secure/non-secure codec conflict, run second pass to handle other resources. - for (size_t i = 0; i < resources.size(); ++i) { - String8 type = resources[i].mType; - if (type == kResourceGraphicMemory) { - sp client; - if (!getLowestPriorityBiggestClient_l(callingPid, type, &client)) { - return false; - } - clients.push_back(client); - } - } + getClientForResource_l(callingPid, graphicMemory, &clients); } if (clients.size() == 0) { // if we are here, run the third pass to free one codec with the same type. - for (size_t i = 0; i < resources.size(); ++i) { - String8 type = resources[i].mType; - if (type == kResourceSecureCodec || type == kResourceNonSecureCodec) { - sp client; - if (!getLowestPriorityBiggestClient_l(callingPid, type, &client)) { - return false; - } - clients.push_back(client); - } + getClientForResource_l(callingPid, secureCodec, &clients); + getClientForResource_l(callingPid, nonSecureCodec, &clients); + } + + if (clients.size() == 0) { + // if we are here, run the fourth pass to free one codec with the different type. + if (secureCodec != NULL) { + MediaResource temp(String8(kResourceNonSecureCodec), 1); + getClientForResource_l(callingPid, &temp, &clients); + } + if (nonSecureCodec != NULL) { + MediaResource temp(String8(kResourceSecureCodec), 1); + getClientForResource_l(callingPid, &temp, &clients); } } } diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h index 0d9d878..ca218fc 100644 --- a/services/mediaresourcemanager/ResourceManagerService.h +++ b/services/mediaresourcemanager/ResourceManagerService.h @@ -65,6 +65,9 @@ public: virtual void removeResource(int64_t clientId); + // Tries to reclaim resource from processes with lower priority than the calling process + // according to the requested resources. + // Returns true if any resource has been reclaimed, otherwise returns false. virtual bool reclaimResource(int callingPid, const Vector &resources); protected: @@ -95,6 +98,11 @@ private: bool isCallingPriorityHigher_l(int callingPid, int pid); + // A helper function basically calls getLowestPriorityBiggestClient_l and add the result client + // to the given Vector. + void getClientForResource_l( + int callingPid, const MediaResource *res, Vector> *clients); + mutable Mutex mLock; sp mProcessInfo; sp mServiceLog; diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp index 3d53f1f..8ae6a55 100644 --- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp +++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp @@ -79,6 +79,10 @@ private: static const int kTestPid1 = 30; static const int kTestPid2 = 20; +static const int kLowPriorityPid = 40; +static const int kMidPriorityPid = 25; +static const int kHighPriorityPid = 10; + class ResourceManagerServiceTest : public ::testing::Test { public: ResourceManagerServiceTest() @@ -227,15 +231,12 @@ protected: String8 type = String8(kResourceSecureCodec); String8 unknowType = String8("unknowType"); Vector > clients; - int lowPriorityPid = 100; - EXPECT_FALSE(mService->getAllClients_l(lowPriorityPid, type, &clients)); - int midPriorityPid = 25; + EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, &clients)); // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l // will fail. - EXPECT_FALSE(mService->getAllClients_l(midPriorityPid, type, &clients)); - int highPriorityPid = 10; - EXPECT_TRUE(mService->getAllClients_l(highPriorityPid, unknowType, &clients)); - EXPECT_TRUE(mService->getAllClients_l(highPriorityPid, type, &clients)); + EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, &clients)); + EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, unknowType, &clients)); + EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, &clients)); EXPECT_EQ(2u, clients.size()); EXPECT_EQ(mTestClient3, clients[0]); @@ -254,19 +255,19 @@ protected: mService->mSupportsSecureWithNonSecureCodec = true; // priority too low - EXPECT_FALSE(mService->reclaimResource(40, resources)); - EXPECT_FALSE(mService->reclaimResource(25, resources)); + EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); + EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources)); // reclaim all secure codecs - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(true, false, true); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(true /* c1 */, false /* c2 */, true /* c3 */); // call again should reclaim one largest graphic memory from lowest process - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(false, true, false); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); // nothing left - EXPECT_FALSE(mService->reclaimResource(10, resources)); + EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ### @@ -276,15 +277,15 @@ protected: mService->mSupportsSecureWithNonSecureCodec = false; // priority too low - EXPECT_FALSE(mService->reclaimResource(40, resources)); - EXPECT_FALSE(mService->reclaimResource(25, resources)); + EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); + EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources)); // reclaim all secure and non-secure codecs - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(true, true, true); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(true /* c1 */, true /* c2 */, true /* c3 */); // nothing left - EXPECT_FALSE(mService->reclaimResource(10, resources)); + EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } @@ -295,23 +296,23 @@ protected: mService->mSupportsSecureWithNonSecureCodec = false; // priority too low - EXPECT_FALSE(mService->reclaimResource(40, resources)); - EXPECT_FALSE(mService->reclaimResource(25, resources)); + EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); + EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources)); // reclaim all non-secure codecs - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(false, true, false); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); // call again should reclaim one largest graphic memory from lowest process - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(true, false, false); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(true /* c1 */, false /* c2 */, false /* c3 */); // call again should reclaim another largest graphic memory from lowest process - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(false, false, true); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(false /* c1 */, false /* c2 */, true /* c3 */); // nothing left - EXPECT_FALSE(mService->reclaimResource(10, resources)); + EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } // ### secure codecs can coexist and secure codec can coexist with non-secure codec ### @@ -321,22 +322,22 @@ protected: mService->mSupportsSecureWithNonSecureCodec = true; // priority too low - EXPECT_FALSE(mService->reclaimResource(40, resources)); + EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); - EXPECT_TRUE(mService->reclaimResource(10, resources)); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); // one largest graphic memory from lowest process got reclaimed - verifyClients(true, false, false); + verifyClients(true /* c1 */, false /* c2 */, false /* c3 */); // call again should reclaim another graphic memory from lowest process - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(false, true, false); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); // call again should reclaim another graphic memory from lowest process - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(false, false, true); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(false /* c1 */, false /* c2 */, true /* c3 */); // nothing left - EXPECT_FALSE(mService->reclaimResource(10, resources)); + EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } // ### secure codecs can coexist and secure codec can coexist with non-secure codec ### @@ -348,19 +349,17 @@ protected: Vector resources; resources.push_back(MediaResource(String8(kResourceSecureCodec), 1)); - EXPECT_TRUE(mService->reclaimResource(10, resources)); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); // secure codec from lowest process got reclaimed - verifyClients(true, false, false); + verifyClients(true /* c1 */, false /* c2 */, false /* c3 */); // call again should reclaim another secure codec from lowest process - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(false, false, true); - - // nothing left - EXPECT_FALSE(mService->reclaimResource(10, resources)); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(false /* c1 */, false /* c2 */, true /* c3 */); - // clean up client 2 which still has non secure codec left - mService->removeResource((int64_t) mTestClient2.get()); + // no more secure codec, non-secure codec will be reclaimed. + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); } } @@ -375,19 +374,19 @@ protected: mService->mSupportsSecureWithNonSecureCodec = false; // priority too low - EXPECT_FALSE(mService->reclaimResource(40, resources)); - EXPECT_FALSE(mService->reclaimResource(25, resources)); + EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); + EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources)); // reclaim all secure codecs - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(true, false, true); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(true /* c1 */, false /* c2 */, true /* c3 */); // call again should reclaim one graphic memory from lowest process - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(false, true, false); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); // nothing left - EXPECT_FALSE(mService->reclaimResource(10, resources)); + EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } @@ -397,22 +396,22 @@ protected: mService->mSupportsSecureWithNonSecureCodec = true; // priority too low - EXPECT_FALSE(mService->reclaimResource(40, resources)); + EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); - EXPECT_TRUE(mService->reclaimResource(10, resources)); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); // one largest graphic memory from lowest process got reclaimed - verifyClients(true, false, false); + verifyClients(true /* c1 */, false /* c2 */, false /* c3 */); // call again should reclaim another graphic memory from lowest process - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(false, true, false); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); // call again should reclaim another graphic memory from lowest process - EXPECT_TRUE(mService->reclaimResource(10, resources)); - verifyClients(false, false, true); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(false /* c1 */, false /* c2 */, true /* c3 */); // nothing left - EXPECT_FALSE(mService->reclaimResource(10, resources)); + EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } // ### secure codec can coexist with non-secure codec ### @@ -423,15 +422,15 @@ protected: Vector resources; resources.push_back(MediaResource(String8(kResourceNonSecureCodec), 1)); - EXPECT_TRUE(mService->reclaimResource(10, resources)); + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); // one non secure codec from lowest process got reclaimed - verifyClients(false, true, false); + verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); - // nothing left - EXPECT_FALSE(mService->reclaimResource(10, resources)); + // no more non-secure codec, secure codec from lowest priority process will be reclaimed + EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); + verifyClients(true /* c1 */, false /* c2 */, false /* c3 */); - // clean up client 1 and 3 which still have secure codec left - mService->removeResource((int64_t) mTestClient1.get()); + // clean up client 3 which still left mService->removeResource((int64_t) mTestClient3.get()); } } @@ -439,12 +438,12 @@ protected: void testGetLowestPriorityBiggestClient() { String8 type = String8(kResourceGraphicMemory); sp client; - EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(10, type, &client)); + EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client)); addResource(); - EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(100, type, &client)); - EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(10, type, &client)); + EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, &client)); + EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client)); // kTestPid1 is the lowest priority process with kResourceGraphicMemory. // mTestClient1 has the largest kResourceGraphicMemory within kTestPid1. -- cgit v1.1