diff options
| author | Ronghua Wu <ronghuawu@google.com> | 2015-07-07 16:47:42 -0700 | 
|---|---|---|
| committer | Ronghua Wu <ronghuawu@google.com> | 2015-07-13 15:18:12 -0700 | 
| commit | 05d89f1c6452b2fce0b9f1315240f8cace69a88d (patch) | |
| tree | 32ceb479a4e3f113bf8a08d564535cb4f09383b0 /services/mediaresourcemanager | |
| parent | dfad5454e0caf46f8732f1415d3b9a76f2a1242e (diff) | |
| download | frameworks_av-05d89f1c6452b2fce0b9f1315240f8cace69a88d.zip frameworks_av-05d89f1c6452b2fce0b9f1315240f8cace69a88d.tar.gz frameworks_av-05d89f1c6452b2fce0b9f1315240f8cace69a88d.tar.bz2  | |
mediaresourcemanager: handle the case when there's no client holding resource with the same type
Bug: 21171205
Change-Id: Id4aa6ccc7ee7daba25fd295399235c5b463ccd83
Diffstat (limited to 'services/mediaresourcemanager')
3 files changed, 128 insertions, 103 deletions
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<sp<IResourceManagerClient>> *clients) { +    if (res == NULL) { +        return; +    } +    sp<IResourceManagerClient> client; +    if (getLowestPriorityBiggestClient_l(callingPid, res->mType, &client)) { +        clients->push_back(client); +    } +} +  bool ResourceManagerService::reclaimResource(          int callingPid, const Vector<MediaResource> &resources) {      String8 log = String8::format("reclaimResource(callingPid %d, resources %s)", @@ -213,54 +224,61 @@ bool ResourceManagerService::reclaimResource(      Vector<sp<IResourceManagerClient>> 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<IResourceManagerClient> 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<IResourceManagerClient> 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<MediaResource> &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<sp<IResourceManagerClient>> *clients); +      mutable Mutex mLock;      sp<ProcessInfoInterface> mProcessInfo;      sp<ServiceLog> 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<sp<IResourceManagerClient> > 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<MediaResource> 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<MediaResource> 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<IResourceManagerClient> 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.  | 
