| /* |
| * Copyright 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| //#define LOG_NDEBUG 0 |
| #define LOG_TAG "ResourceManagerService_test" |
| |
| #include <utils/Log.h> |
| |
| #include "ResourceManagerServiceTestUtils.h" |
| #include "ResourceManagerService.h" |
| |
| namespace android { |
| |
| class ResourceManagerServiceTest : public ResourceManagerServiceTestBase { |
| private: |
| static MediaResource createSecureVideoCodecResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kSecureCodec, |
| MediaResource::SubType::kVideoCodec, amount); |
| } |
| |
| static MediaResource createNonSecureVideoCodecResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kNonSecureCodec, |
| MediaResource::SubType::kVideoCodec, amount); |
| } |
| |
| static MediaResource createSecureAudioCodecResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kSecureCodec, |
| MediaResource::SubType::kAudioCodec, amount); |
| } |
| |
| static MediaResource createNonSecureAudioCodecResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kNonSecureCodec, |
| MediaResource::SubType::kAudioCodec, amount); |
| } |
| |
| static MediaResource createSecureImageCodecResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kSecureCodec, |
| MediaResource::SubType::kImageCodec, amount); |
| } |
| |
| static MediaResource createNonSecureImageCodecResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kNonSecureCodec, |
| MediaResource::SubType::kImageCodec, amount); |
| } |
| |
| static MediaResource createGraphicMemoryResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kGraphicMemory, |
| MediaResource::SubType::kUnspecifiedSubType, amount); |
| } |
| |
| static MediaResource createDrmSessionResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kDrmSession, |
| MediaResource::SubType::kUnspecifiedSubType, amount); |
| } |
| |
| static MediaResource createBatteryResource() { |
| return MediaResource(MediaResource::Type::kBattery, |
| MediaResource::SubType::kUnspecifiedSubType, 1); |
| } |
| |
| static MediaResource createCpuBoostResource() { |
| return MediaResource(MediaResource::Type::kCpuBoost, |
| MediaResource::SubType::kUnspecifiedSubType, 1); |
| } |
| |
| public: |
| ResourceManagerServiceTest() : ResourceManagerServiceTestBase() {} |
| |
| |
| // test set up |
| // --------------------------------------------------------------------------------- |
| // pid priority client type number |
| // --------------------------------------------------------------------------------- |
| // kTestPid1(30) 30 mTestClient1 secure codec 1 |
| // graphic memory 200 |
| // graphic memory 200 |
| // --------------------------------------------------------------------------------- |
| // kTestPid2(20) 20 mTestClient2 non-secure codec 1 |
| // graphic memory 300 |
| // ------------------------------------------- |
| // mTestClient3 secure codec 1 |
| // graphic memory 100 |
| // --------------------------------------------------------------------------------- |
| void addResource() { |
| // kTestPid1 mTestClient1 |
| std::vector<MediaResourceParcel> resources1; |
| resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200)); |
| std::vector<MediaResourceParcel> resources11; |
| resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11); |
| |
| // kTestPid2 mTestClient2 |
| std::vector<MediaResourceParcel> resources2; |
| resources2.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1)); |
| resources2.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300)); |
| mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2); |
| |
| // kTestPid2 mTestClient3 |
| std::vector<MediaResourceParcel> resources3; |
| mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3); |
| resources3.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| resources3.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100)); |
| mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3); |
| |
| const PidResourceInfosMap &map = mService->mMap; |
| EXPECT_EQ(2u, map.size()); |
| ssize_t index1 = map.indexOfKey(kTestPid1); |
| ASSERT_GE(index1, 0); |
| const ResourceInfos &infos1 = map[index1]; |
| EXPECT_EQ(1u, infos1.size()); |
| expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, resources1); |
| |
| ssize_t index2 = map.indexOfKey(kTestPid2); |
| ASSERT_GE(index2, 0); |
| const ResourceInfos &infos2 = map[index2]; |
| EXPECT_EQ(2u, infos2.size()); |
| expectEqResourceInfo(infos2.valueFor(getId(mTestClient2)), kTestUid2, mTestClient2, resources2); |
| expectEqResourceInfo(infos2.valueFor(getId(mTestClient3)), kTestUid2, mTestClient3, resources3); |
| } |
| |
| void testCombineResourceWithNegativeValues() { |
| // kTestPid1 mTestClient1 |
| std::vector<MediaResourceParcel> resources1; |
| resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, -100)); |
| resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, -100)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| |
| // Expected result: |
| // 1) the client should have been added; |
| // 2) both resource entries should have been rejected, resource list should be empty. |
| const PidResourceInfosMap &map = mService->mMap; |
| EXPECT_EQ(1u, map.size()); |
| ssize_t index1 = map.indexOfKey(kTestPid1); |
| ASSERT_GE(index1, 0); |
| const ResourceInfos &infos1 = map[index1]; |
| EXPECT_EQ(1u, infos1.size()); |
| std::vector<MediaResourceParcel> expected; |
| expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| |
| resources1.clear(); |
| resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX)); |
| resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| resources1.clear(); |
| resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, 10)); |
| resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 10)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| |
| // Expected result: |
| // Both values should saturate to INT64_MAX |
| expected.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX)); |
| expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX)); |
| expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| |
| resources1.clear(); |
| resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, -10)); |
| resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, -10)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| |
| // Expected result: |
| // 1) DrmSession resource should allow negative value addition, and value should drop accordingly |
| // 2) Non-drm session resource should ignore negative value addition. |
| expected.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX - 10)); |
| expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX)); |
| expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| |
| resources1.clear(); |
| resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MIN)); |
| expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MIN)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| |
| // Expected result: |
| // 1) DrmSession resource value should drop to 0, but the entry shouldn't be removed. |
| // 2) Non-drm session resource should ignore negative value addition. |
| expected.clear(); |
| expected.push_back(MediaResource(MediaResource::Type::kDrmSession, 0)); |
| expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX)); |
| expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| } |
| |
| void testConfig() { |
| EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs); |
| EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec); |
| |
| std::vector<MediaResourcePolicyParcel> policies1; |
| policies1.push_back( |
| MediaResourcePolicy( |
| IResourceManagerService::kPolicySupportsMultipleSecureCodecs, |
| "true")); |
| policies1.push_back( |
| MediaResourcePolicy( |
| IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec, |
| "false")); |
| mService->config(policies1); |
| EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs); |
| EXPECT_FALSE(mService->mSupportsSecureWithNonSecureCodec); |
| |
| std::vector<MediaResourcePolicyParcel> policies2; |
| policies2.push_back( |
| MediaResourcePolicy( |
| IResourceManagerService::kPolicySupportsMultipleSecureCodecs, |
| "false")); |
| policies2.push_back( |
| MediaResourcePolicy( |
| IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec, |
| "true")); |
| mService->config(policies2); |
| EXPECT_FALSE(mService->mSupportsMultipleSecureCodecs); |
| EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec); |
| } |
| |
| void testCombineResource() { |
| // kTestPid1 mTestClient1 |
| std::vector<MediaResourceParcel> resources1; |
| resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| |
| std::vector<MediaResourceParcel> resources11; |
| resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11); |
| |
| const PidResourceInfosMap &map = mService->mMap; |
| EXPECT_EQ(1u, map.size()); |
| ssize_t index1 = map.indexOfKey(kTestPid1); |
| ASSERT_GE(index1, 0); |
| const ResourceInfos &infos1 = map[index1]; |
| EXPECT_EQ(1u, infos1.size()); |
| |
| // test adding existing types to combine values |
| resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| |
| std::vector<MediaResourceParcel> expected; |
| expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2)); |
| expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300)); |
| expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| |
| // test adding new types (including types that differs only in subType) |
| resources11.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1)); |
| resources11.push_back(MediaResource(MediaResource::Type::kSecureCodec, MediaResource::SubType::kVideoCodec, 1)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11); |
| |
| expected.clear(); |
| expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2)); |
| expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1)); |
| expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, MediaResource::SubType::kVideoCodec, 1)); |
| expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 500)); |
| expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| } |
| |
| void testRemoveResource() { |
| // kTestPid1 mTestClient1 |
| std::vector<MediaResourceParcel> resources1; |
| resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| |
| std::vector<MediaResourceParcel> resources11; |
| resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11); |
| |
| const PidResourceInfosMap &map = mService->mMap; |
| EXPECT_EQ(1u, map.size()); |
| ssize_t index1 = map.indexOfKey(kTestPid1); |
| ASSERT_GE(index1, 0); |
| const ResourceInfos &infos1 = map[index1]; |
| EXPECT_EQ(1u, infos1.size()); |
| |
| // test partial removal |
| resources11[0].value = 100; |
| mService->removeResource(kTestPid1, getId(mTestClient1), resources11); |
| |
| std::vector<MediaResourceParcel> expected; |
| expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100)); |
| expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| |
| // test removal request with negative value, should be ignored |
| resources11[0].value = -10000; |
| mService->removeResource(kTestPid1, getId(mTestClient1), resources11); |
| |
| expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| |
| // test complete removal with overshoot value |
| resources11[0].value = 1000; |
| mService->removeResource(kTestPid1, getId(mTestClient1), resources11); |
| |
| expected.clear(); |
| expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| } |
| |
| void testOverridePid() { |
| |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150)); |
| |
| // ### secure codec can't coexist and secure codec can coexist with non-secure codec ### |
| { |
| addResource(); |
| mService->mSupportsMultipleSecureCodecs = false; |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| // priority too low to reclaim resource |
| CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result)); |
| |
| // override Low Priority Pid with High Priority Pid |
| mService->overridePid(kLowPriorityPid, kHighPriorityPid); |
| CHECK_STATUS_TRUE(mService->reclaimResource(kLowPriorityPid, resources, &result)); |
| |
| // restore Low Priority Pid |
| mService->overridePid(kLowPriorityPid, -1); |
| CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result)); |
| } |
| } |
| |
| void testMarkClientForPendingRemoval() { |
| { |
| addResource(); |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1)); |
| |
| // Remove low priority clients |
| mService->removeClient(kTestPid1, getId(mTestClient1)); |
| |
| // no lower priority client |
| CHECK_STATUS_FALSE(mService->reclaimResource(kTestPid2, resources, &result)); |
| EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2)); |
| |
| // client marked for pending removal from the same process got reclaimed |
| CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result)); |
| EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(true, toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // clean up client 3 which still left |
| mService->removeClient(kTestPid2, getId(mTestClient3)); |
| } |
| |
| { |
| addResource(); |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1)); |
| |
| mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2)); |
| |
| // client marked for pending removal from the same process got reclaimed |
| // first, even though there are lower priority process |
| CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result)); |
| EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(true, toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // lower priority client got reclaimed |
| CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result)); |
| EXPECT_EQ(true, toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // clean up client 3 which still left |
| mService->removeClient(kTestPid2, getId(mTestClient3)); |
| } |
| |
| { |
| addResource(); |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2)); |
| |
| // client marked for pending removal got reclaimed |
| EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk()); |
| EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(true, toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // No more clients marked for removal |
| EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk()); |
| EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient3)); |
| |
| // client marked for pending removal got reclaimed |
| EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk()); |
| EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(true, toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // clean up client 1 which still left |
| mService->removeClient(kTestPid1, getId(mTestClient1)); |
| } |
| } |
| |
| void testRemoveClient() { |
| addResource(); |
| |
| mService->removeClient(kTestPid2, getId(mTestClient2)); |
| |
| const PidResourceInfosMap &map = mService->mMap; |
| EXPECT_EQ(2u, map.size()); |
| const ResourceInfos &infos1 = map.valueFor(kTestPid1); |
| const ResourceInfos &infos2 = map.valueFor(kTestPid2); |
| EXPECT_EQ(1u, infos1.size()); |
| EXPECT_EQ(1u, infos2.size()); |
| // mTestClient2 has been removed. |
| // (OK to use infos2[0] as there is only 1 entry) |
| EXPECT_EQ(mTestClient3, infos2[0].client); |
| } |
| |
| void testGetAllClients() { |
| addResource(); |
| MediaResource::Type type = MediaResource::Type::kSecureCodec; |
| MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType; |
| |
| Vector<std::shared_ptr<IResourceManagerClient> > clients; |
| EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, subType, &clients)); |
| // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l |
| // will fail. |
| EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, subType, &clients)); |
| EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, subType, &clients)); |
| |
| EXPECT_EQ(2u, clients.size()); |
| // (OK to require ordering in clients[], as the pid map is sorted) |
| EXPECT_EQ(mTestClient3, clients[0]); |
| EXPECT_EQ(mTestClient1, clients[1]); |
| } |
| |
| void testReclaimResourceSecure() { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150)); |
| |
| // ### secure codec can't coexist and secure codec can coexist with non-secure codec ### |
| { |
| addResource(); |
| mService->mSupportsMultipleSecureCodecs = false; |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| // priority too low |
| CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result)); |
| CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result)); |
| |
| // reclaim all secure codecs |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // call again should reclaim one largest graphic memory from lowest process |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| } |
| |
| // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ### |
| { |
| addResource(); |
| mService->mSupportsMultipleSecureCodecs = false; |
| mService->mSupportsSecureWithNonSecureCodec = false; |
| |
| // priority too low |
| CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result)); |
| CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result)); |
| |
| // reclaim all secure and non-secure codecs |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| } |
| |
| |
| // ### secure codecs can coexist but secure codec can't coexist with non-secure codec ### |
| { |
| addResource(); |
| mService->mSupportsMultipleSecureCodecs = true; |
| mService->mSupportsSecureWithNonSecureCodec = false; |
| |
| // priority too low |
| CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result)); |
| CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result)); |
| |
| // reclaim all non-secure codecs |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // call again should reclaim one largest graphic memory from lowest process |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // call again should reclaim another largest graphic memory from lowest process |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| } |
| |
| // ### secure codecs can coexist and secure codec can coexist with non-secure codec ### |
| { |
| addResource(); |
| mService->mSupportsMultipleSecureCodecs = true; |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| // priority too low |
| CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result)); |
| |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| // one largest graphic memory from lowest process got reclaimed |
| EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // call again should reclaim another graphic memory from lowest process |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // call again should reclaim another graphic memory from lowest process |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| } |
| |
| // ### secure codecs can coexist and secure codec can coexist with non-secure codec ### |
| { |
| addResource(); |
| mService->mSupportsMultipleSecureCodecs = true; |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| // secure codec from lowest process got reclaimed |
| EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // call again should reclaim another secure codec from lowest process |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // no more secure codec, non-secure codec will be reclaimed. |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| } |
| } |
| |
| void testReclaimResourceNonSecure() { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1)); |
| resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150)); |
| |
| // ### secure codec can't coexist with non-secure codec ### |
| { |
| addResource(); |
| mService->mSupportsSecureWithNonSecureCodec = false; |
| |
| // priority too low |
| CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result)); |
| CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result)); |
| |
| // reclaim all secure codecs |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // call again should reclaim one graphic memory from lowest process |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| } |
| |
| |
| // ### secure codec can coexist with non-secure codec ### |
| { |
| addResource(); |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| // priority too low |
| CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result)); |
| |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| // one largest graphic memory from lowest process got reclaimed |
| EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // call again should reclaim another graphic memory from lowest process |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // call again should reclaim another graphic memory from lowest process |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| } |
| |
| // ### secure codec can coexist with non-secure codec ### |
| { |
| addResource(); |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1)); |
| |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| // one non secure codec from lowest process got reclaimed |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // no more non-secure codec, secure codec from lowest priority process will be reclaimed |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result)); |
| EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // clean up client 3 which still left |
| mService->removeClient(kTestPid2, getId(mTestClient3)); |
| } |
| } |
| |
| void testGetLowestPriorityBiggestClient() { |
| MediaResource::Type type = MediaResource::Type::kGraphicMemory; |
| MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType; |
| std::shared_ptr<IResourceManagerClient> client; |
| EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, subType, |
| &client)); |
| |
| addResource(); |
| |
| EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, subType, |
| &client)); |
| EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, subType, |
| &client)); |
| |
| // kTestPid1 is the lowest priority process with MediaResource::Type::kGraphicMemory. |
| // mTestClient1 has the largest MediaResource::Type::kGraphicMemory within kTestPid1. |
| EXPECT_EQ(mTestClient1, client); |
| } |
| |
| void testGetLowestPriorityPid() { |
| int pid; |
| int priority; |
| TestProcessInfo processInfo; |
| |
| MediaResource::Type type = MediaResource::Type::kGraphicMemory; |
| MediaResource::SubType subType = MediaResource::SubType::kUnspecifiedSubType; |
| EXPECT_FALSE(mService->getLowestPriorityPid_l(type, subType, &pid, &priority)); |
| |
| addResource(); |
| |
| EXPECT_TRUE(mService->getLowestPriorityPid_l(type, subType, &pid, &priority)); |
| EXPECT_EQ(kTestPid1, pid); |
| int priority1; |
| processInfo.getPriority(kTestPid1, &priority1); |
| EXPECT_EQ(priority1, priority); |
| |
| type = MediaResource::Type::kNonSecureCodec; |
| EXPECT_TRUE(mService->getLowestPriorityPid_l(type, subType, &pid, &priority)); |
| EXPECT_EQ(kTestPid2, pid); |
| int priority2; |
| processInfo.getPriority(kTestPid2, &priority2); |
| EXPECT_EQ(priority2, priority); |
| } |
| |
| void testIsCallingPriorityHigher() { |
| EXPECT_FALSE(mService->isCallingPriorityHigher_l(101, 100)); |
| EXPECT_FALSE(mService->isCallingPriorityHigher_l(100, 100)); |
| EXPECT_TRUE(mService->isCallingPriorityHigher_l(99, 100)); |
| } |
| |
| void testBatteryStats() { |
| // reset should always be called when ResourceManagerService is created (restarted) |
| EXPECT_EQ(1u, mSystemCB->eventCount()); |
| EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType()); |
| |
| // new client request should cause VIDEO_ON |
| std::vector<MediaResourceParcel> resources1; |
| resources1.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 1)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| EXPECT_EQ(2u, mSystemCB->eventCount()); |
| EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid1}), mSystemCB->lastEvent()); |
| |
| // each client should only cause 1 VIDEO_ON |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| EXPECT_EQ(2u, mSystemCB->eventCount()); |
| |
| // new client request should cause VIDEO_ON |
| std::vector<MediaResourceParcel> resources2; |
| resources2.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 2)); |
| mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2); |
| EXPECT_EQ(3u, mSystemCB->eventCount()); |
| EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid2}), mSystemCB->lastEvent()); |
| |
| // partially remove mTestClient1's request, shouldn't be any VIDEO_OFF |
| mService->removeResource(kTestPid1, getId(mTestClient1), resources1); |
| EXPECT_EQ(3u, mSystemCB->eventCount()); |
| |
| // remove mTestClient1's request, should be VIDEO_OFF for kTestUid1 |
| // (use resource2 to test removing more instances than previously requested) |
| mService->removeResource(kTestPid1, getId(mTestClient1), resources2); |
| EXPECT_EQ(4u, mSystemCB->eventCount()); |
| EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid1}), mSystemCB->lastEvent()); |
| |
| // remove mTestClient2, should be VIDEO_OFF for kTestUid2 |
| mService->removeClient(kTestPid2, getId(mTestClient2)); |
| EXPECT_EQ(5u, mSystemCB->eventCount()); |
| EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid2}), mSystemCB->lastEvent()); |
| } |
| |
| void testCpusetBoost() { |
| // reset should always be called when ResourceManagerService is created (restarted) |
| EXPECT_EQ(1u, mSystemCB->eventCount()); |
| EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType()); |
| |
| // new client request should cause CPUSET_ENABLE |
| std::vector<MediaResourceParcel> resources1; |
| resources1.push_back(MediaResource(MediaResource::Type::kCpuBoost, 1)); |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| EXPECT_EQ(2u, mSystemCB->eventCount()); |
| EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType()); |
| |
| // each client should only cause 1 CPUSET_ENABLE |
| mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1); |
| EXPECT_EQ(2u, mSystemCB->eventCount()); |
| |
| // new client request should cause CPUSET_ENABLE |
| std::vector<MediaResourceParcel> resources2; |
| resources2.push_back(MediaResource(MediaResource::Type::kCpuBoost, 2)); |
| mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2); |
| EXPECT_EQ(3u, mSystemCB->eventCount()); |
| EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType()); |
| |
| // remove mTestClient2 should not cause CPUSET_DISABLE, mTestClient1 still active |
| mService->removeClient(kTestPid2, getId(mTestClient2)); |
| EXPECT_EQ(3u, mSystemCB->eventCount()); |
| |
| // remove 1 cpuboost from mTestClient1, should not be CPUSET_DISABLE (still 1 left) |
| mService->removeResource(kTestPid1, getId(mTestClient1), resources1); |
| EXPECT_EQ(3u, mSystemCB->eventCount()); |
| |
| // remove 2 cpuboost from mTestClient1, should be CPUSET_DISABLE |
| // (use resource2 to test removing more than previously requested) |
| mService->removeResource(kTestPid1, getId(mTestClient1), resources2); |
| EXPECT_EQ(4u, mSystemCB->eventCount()); |
| EXPECT_EQ(EventType::CPUSET_DISABLE, mSystemCB->lastEventType()); |
| } |
| |
| void testReclaimResources_withVideoCodec_reclaimsOnlyVideoCodec() { |
| const std::shared_ptr<IResourceManagerClient>& audioImageTestClient = mTestClient1; |
| const std::shared_ptr<IResourceManagerClient>& videoTestClient = mTestClient2; |
| |
| // Create an audio and image codec resource |
| std::vector<MediaResourceParcel> audioImageResources; |
| audioImageResources.push_back(createNonSecureAudioCodecResource()); |
| audioImageResources.push_back(createNonSecureImageCodecResource()); |
| mService->addResource(kLowPriorityPid, kTestUid1, getId(audioImageTestClient), |
| audioImageTestClient, audioImageResources); |
| |
| // Fail to reclaim a video codec resource |
| std::vector<MediaResourceParcel> reclaimResources; |
| reclaimResources.push_back(createNonSecureVideoCodecResource()); |
| CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result)); |
| |
| // Now add a video codec resource |
| std::vector<MediaResourceParcel> videoResources; |
| videoResources.push_back(createNonSecureVideoCodecResource()); |
| mService->addResource(kLowPriorityPid, kTestUid1, getId(videoTestClient), videoTestClient, |
| videoResources); |
| |
| // Verify that the newly-created video codec resource can be reclaimed |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result)); |
| |
| // Verify that the audio and image resources are untouched |
| EXPECT_FALSE(toTestClient(audioImageTestClient)->checkIfReclaimedAndReset()); |
| // But the video resource was reclaimed |
| EXPECT_TRUE(toTestClient(videoTestClient)->checkIfReclaimedAndReset()); |
| } |
| |
| void testReclaimResources_withAudioCodec_reclaimsOnlyAudioCodec() { |
| const auto & videoImageTestClient = mTestClient1; |
| const auto & audioTestClient = mTestClient2; |
| |
| // Create a video and audio codec resource |
| std::vector<MediaResourceParcel> videoImageResources; |
| videoImageResources.push_back(createNonSecureVideoCodecResource()); |
| videoImageResources.push_back(createNonSecureImageCodecResource()); |
| mService->addResource(kLowPriorityPid, kTestUid1, getId(videoImageTestClient), |
| videoImageTestClient, videoImageResources); |
| |
| // Fail to reclaim an audio codec resource |
| std::vector<MediaResourceParcel> reclaimResources; |
| reclaimResources.push_back(createNonSecureAudioCodecResource()); |
| CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result)); |
| |
| // Now add an audio codec resource |
| std::vector<MediaResourceParcel> audioResources; |
| audioResources.push_back(createNonSecureAudioCodecResource()); |
| mService->addResource(kLowPriorityPid, kTestUid2, getId(audioTestClient), audioTestClient, |
| audioResources); |
| |
| // Verify that the newly-created audio codec resource can be reclaimed |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result)); |
| |
| // Verify that the video and image resources are untouched |
| EXPECT_FALSE(toTestClient(videoImageTestClient)->checkIfReclaimedAndReset()); |
| // But the audio resource was reclaimed |
| EXPECT_TRUE(toTestClient(audioTestClient)->checkIfReclaimedAndReset()); |
| } |
| |
| void testReclaimResources_withImageCodec_reclaimsOnlyImageCodec() { |
| const auto & videoAudioTestClient = mTestClient1; |
| const auto & imageTestClient = mTestClient2; |
| |
| // Create a video and audio codec resource |
| std::vector<MediaResourceParcel> videoAudioResources; |
| videoAudioResources.push_back(createNonSecureVideoCodecResource()); |
| videoAudioResources.push_back(createNonSecureAudioCodecResource()); |
| mService->addResource(kLowPriorityPid, kTestUid1, getId(videoAudioTestClient), |
| videoAudioTestClient, videoAudioResources); |
| |
| // Fail to reclaim an image codec resource |
| std::vector<MediaResourceParcel> reclaimResources; |
| reclaimResources.push_back(createNonSecureImageCodecResource()); |
| CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result)); |
| |
| // Now add an image codec resource |
| std::vector<MediaResourceParcel> imageResources; |
| imageResources.push_back(createNonSecureImageCodecResource()); |
| mService->addResource(kLowPriorityPid, kTestUid2, getId(imageTestClient), imageTestClient, |
| imageResources); |
| |
| // Verify that the newly-created image codec resource can be reclaimed |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result)); |
| |
| // Verify that the video and audio resources are untouched |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| // But the image resource was reclaimed |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| } |
| |
| void testReclaimResources_whenPartialResourceMatch_reclaims() { |
| const int onlyUid = kTestUid1; |
| const auto onlyClient = createTestClient(kLowPriorityPid); |
| |
| std::vector<MediaResourceParcel> ownedResources; |
| ownedResources.push_back(createNonSecureVideoCodecResource()); |
| ownedResources.push_back(createGraphicMemoryResource(100)); |
| mService->addResource(kLowPriorityPid, onlyUid, getId(onlyClient), onlyClient, |
| ownedResources); |
| |
| // Reclaim an image codec instead of the video codec that is owned, but also reclaim |
| // graphics memory, which will trigger the reclaim. |
| std::vector<MediaResourceParcel> reclaimResources; |
| reclaimResources.push_back(createNonSecureImageCodecResource()); |
| reclaimResources.push_back(createGraphicMemoryResource(100)); |
| CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, reclaimResources, &result)); |
| |
| // Verify that the video codec resources (including the needed graphic memory) is reclaimed |
| EXPECT_TRUE(toTestClient(onlyClient)->checkIfReclaimedAndReset()); |
| } |
| |
| void testReclaimResourcesFromMarkedClients_removesBiggestMarkedClientForSomeResources() { |
| // this test only uses one pid and one uid |
| const int onlyPid = kTestPid1; |
| const int onlyUid = kTestUid1; |
| |
| // secure video codec |
| const auto smallSecureVideoMarkedClient = createTestClient(onlyPid); |
| const auto largeSecureVideoMarkedClient = createTestClient(onlyPid); |
| const auto largestSecureVideoActiveClient = createTestClient(onlyPid); |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createSecureVideoCodecResource(1)); |
| mService->addResource(onlyPid, onlyUid, getId(smallSecureVideoMarkedClient), |
| smallSecureVideoMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureVideoCodecResource(2)); |
| mService->addResource(onlyPid, onlyUid, getId(largeSecureVideoMarkedClient), |
| largeSecureVideoMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureVideoCodecResource(3)); |
| mService->addResource(onlyPid, onlyUid, getId(largestSecureVideoActiveClient), |
| largestSecureVideoActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(onlyPid, getId(smallSecureVideoMarkedClient)); |
| mService->markClientForPendingRemoval(onlyPid, getId(largeSecureVideoMarkedClient)); |
| // don't mark the largest client |
| |
| // non-secure video codec |
| const auto smallNonSecureVideoMarkedClient = createTestClient(onlyPid); |
| const auto largeNonSecureVideoMarkedClient = createTestClient(onlyPid); |
| const auto largestNonSecureVideoActiveClient = createTestClient(onlyPid); |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createNonSecureVideoCodecResource(1)); |
| mService->addResource(onlyPid, onlyUid, getId(smallNonSecureVideoMarkedClient), |
| smallNonSecureVideoMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureVideoCodecResource(2)); |
| mService->addResource(onlyPid, onlyUid, getId(largeNonSecureVideoMarkedClient), |
| largeNonSecureVideoMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureVideoCodecResource(3)); |
| mService->addResource(onlyPid, onlyUid, getId(largestNonSecureVideoActiveClient), |
| largestNonSecureVideoActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(onlyPid, getId(smallNonSecureVideoMarkedClient)); |
| mService->markClientForPendingRemoval(onlyPid, getId(largeNonSecureVideoMarkedClient)); |
| // don't mark the largest client |
| |
| // secure audio codec |
| const auto smallSecureAudioMarkedClient = createTestClient(onlyPid); |
| const auto largeSecureAudioMarkedClient = createTestClient(onlyPid); |
| const auto largestSecureAudioActiveClient = createTestClient(onlyPid); |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createSecureAudioCodecResource(1)); |
| mService->addResource(onlyPid, onlyUid, getId(smallSecureAudioMarkedClient), |
| smallSecureAudioMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureAudioCodecResource(2)); |
| mService->addResource(onlyPid, onlyUid, getId(largeSecureAudioMarkedClient), |
| largeSecureAudioMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureAudioCodecResource(3)); |
| mService->addResource(onlyPid, onlyUid, getId(largestSecureVideoActiveClient), |
| largestSecureVideoActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(onlyPid, getId(smallSecureAudioMarkedClient)); |
| mService->markClientForPendingRemoval(onlyPid, getId(largeSecureAudioMarkedClient)); |
| // don't mark the largest client |
| |
| // non-secure audio codec |
| const auto smallNonSecureAudioMarkedClient = createTestClient(onlyPid); |
| const auto largeNonSecureAudioMarkedClient = createTestClient(onlyPid); |
| const auto largestNonSecureAudioActiveClient = createTestClient(onlyPid); |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createNonSecureAudioCodecResource(1)); |
| mService->addResource(onlyPid, onlyUid, getId(smallNonSecureAudioMarkedClient), |
| smallNonSecureAudioMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureAudioCodecResource(2)); |
| mService->addResource(onlyPid, onlyUid, getId(largeNonSecureAudioMarkedClient), |
| largeNonSecureAudioMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureAudioCodecResource(3)); |
| mService->addResource(onlyPid, onlyUid, getId(largestNonSecureAudioActiveClient), |
| largestNonSecureAudioActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(onlyPid, getId(smallNonSecureAudioMarkedClient)); |
| mService->markClientForPendingRemoval(onlyPid, getId(largeNonSecureAudioMarkedClient)); |
| // don't mark the largest client |
| |
| // secure image codec |
| const auto smallSecureImageMarkedClient = createTestClient(onlyPid); |
| const auto largeSecureImageMarkedClient = createTestClient(onlyPid); |
| const auto largestSecureImageActiveClient = createTestClient(onlyPid); |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createSecureImageCodecResource(1)); |
| mService->addResource(onlyPid, onlyUid, getId(smallSecureImageMarkedClient), |
| smallSecureImageMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureImageCodecResource(2)); |
| mService->addResource(onlyPid, onlyUid, getId(largeSecureImageMarkedClient), |
| largeSecureImageMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureImageCodecResource(3)); |
| mService->addResource(onlyPid, onlyUid, getId(largestSecureImageActiveClient), |
| largestSecureImageActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(onlyPid, getId(smallSecureImageMarkedClient)); |
| mService->markClientForPendingRemoval(onlyPid, getId(largeSecureImageMarkedClient)); |
| // don't mark the largest client |
| |
| // non-secure image codec |
| const auto smallNonSecureImageMarkedClient = createTestClient(onlyPid); |
| const auto largeNonSecureImageMarkedClient = createTestClient(onlyPid); |
| const auto largestNonSecureImageActiveClient = createTestClient(onlyPid); |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createNonSecureImageCodecResource(1)); |
| mService->addResource(onlyPid, onlyUid, getId(smallNonSecureImageMarkedClient), |
| smallNonSecureImageMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureImageCodecResource(2)); |
| mService->addResource(onlyPid, onlyUid, getId(largeNonSecureImageMarkedClient), |
| largeNonSecureImageMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureImageCodecResource(3)); |
| mService->addResource(onlyPid, onlyUid, getId(largestNonSecureImageActiveClient), |
| largestNonSecureImageActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(onlyPid, getId(smallNonSecureImageMarkedClient)); |
| mService->markClientForPendingRemoval(onlyPid, getId(largeNonSecureImageMarkedClient)); |
| // don't mark the largest client |
| |
| // graphic memory |
| const auto smallGraphicMemoryMarkedClient = createTestClient(onlyPid); |
| const auto largeGraphicMemoryMarkedClient = createTestClient(onlyPid); |
| const auto largestGraphicMemoryActiveClient = createTestClient(onlyPid); |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createGraphicMemoryResource(100)); |
| mService->addResource(onlyPid, onlyUid, getId(smallGraphicMemoryMarkedClient), |
| smallGraphicMemoryMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createGraphicMemoryResource(200)); |
| mService->addResource(onlyPid, onlyUid, getId(largeGraphicMemoryMarkedClient), |
| largeGraphicMemoryMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createGraphicMemoryResource(300)); |
| mService->addResource(onlyPid, onlyUid, getId(largestGraphicMemoryActiveClient), |
| largestGraphicMemoryActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(onlyPid, getId(smallGraphicMemoryMarkedClient)); |
| mService->markClientForPendingRemoval(onlyPid, getId(largeGraphicMemoryMarkedClient)); |
| // don't mark the largest client |
| |
| // DRM session |
| const auto smallDrmSessionMarkedClient = createTestClient(onlyPid); |
| const auto largeDrmSessionMarkedClient = createTestClient(onlyPid); |
| const auto largestDrmSessionActiveClient = createTestClient(onlyPid); |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createDrmSessionResource(1)); |
| mService->addResource(onlyPid, onlyUid, getId(smallDrmSessionMarkedClient), |
| smallDrmSessionMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createDrmSessionResource(2)); |
| mService->addResource(onlyPid, onlyUid, getId(largeDrmSessionMarkedClient), |
| largeDrmSessionMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createDrmSessionResource(3)); |
| mService->addResource(onlyPid, onlyUid, getId(largestDrmSessionActiveClient), |
| largestDrmSessionActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(onlyPid, getId(smallDrmSessionMarkedClient)); |
| mService->markClientForPendingRemoval(onlyPid, getId(largeDrmSessionMarkedClient)); |
| // don't mark the largest client |
| |
| // battery |
| const auto batteryMarkedClient = createTestClient(onlyPid); |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createBatteryResource()); |
| mService->addResource(onlyPid, onlyUid, getId(batteryMarkedClient), |
| batteryMarkedClient, resources); |
| } |
| mService->markClientForPendingRemoval(onlyPid, getId(batteryMarkedClient)); |
| |
| // CPU boost |
| const auto cpuBoostMarkedClient = createTestClient(onlyPid); |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createCpuBoostResource()); |
| mService->addResource(onlyPid, onlyUid, getId(cpuBoostMarkedClient), |
| cpuBoostMarkedClient, resources); |
| } |
| mService->markClientForPendingRemoval(onlyPid, getId(cpuBoostMarkedClient)); |
| |
| // now we expect that we only reclaim resources from the biggest marked client |
| EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(onlyPid).isOk()); |
| // secure video codec |
| EXPECT_FALSE(toTestClient(smallSecureVideoMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(largeSecureVideoMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(largestSecureVideoActiveClient)->checkIfReclaimedAndReset()); |
| // non-secure video codec |
| EXPECT_FALSE(toTestClient(smallNonSecureVideoMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(largeNonSecureVideoMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(largestNonSecureVideoActiveClient)->checkIfReclaimedAndReset()); |
| // secure audio codec |
| EXPECT_FALSE(toTestClient(smallSecureAudioMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(largeSecureAudioMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(largestSecureAudioActiveClient)->checkIfReclaimedAndReset()); |
| // non-secure audio codec |
| EXPECT_FALSE(toTestClient(smallNonSecureAudioMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(largeNonSecureAudioMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(largestNonSecureAudioActiveClient)->checkIfReclaimedAndReset()); |
| // secure image codec |
| EXPECT_FALSE(toTestClient(smallSecureImageMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(largeSecureImageMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(largestSecureImageActiveClient)->checkIfReclaimedAndReset()); |
| // non-secure image codec |
| EXPECT_FALSE(toTestClient(smallNonSecureImageMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(largeNonSecureImageMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(largestNonSecureImageActiveClient)->checkIfReclaimedAndReset()); |
| // graphic memory |
| EXPECT_FALSE(toTestClient(smallGraphicMemoryMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(largeGraphicMemoryMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(largestGraphicMemoryActiveClient)->checkIfReclaimedAndReset()); |
| // DRM session |
| EXPECT_FALSE(toTestClient(smallDrmSessionMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(largeDrmSessionMarkedClient)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(largestDrmSessionActiveClient)->checkIfReclaimedAndReset()); |
| // battery is not expected to be reclaimed when marked as pending removal |
| EXPECT_FALSE(toTestClient(batteryMarkedClient)->checkIfReclaimedAndReset()); |
| // CPU boost is not expected to be reclaimed when marked as pending removal |
| EXPECT_FALSE(toTestClient(cpuBoostMarkedClient)->checkIfReclaimedAndReset()); |
| } |
| }; |
| |
| TEST_F(ResourceManagerServiceTest, config) { |
| testConfig(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, addResource) { |
| addResource(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, combineResource) { |
| testCombineResource(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, combineResourceNegative) { |
| testCombineResourceWithNegativeValues(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, removeResource) { |
| testRemoveResource(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, removeClient) { |
| testRemoveClient(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, reclaimResource) { |
| testReclaimResourceSecure(); |
| testReclaimResourceNonSecure(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, getAllClients_l) { |
| testGetAllClients(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, getLowestPriorityBiggestClient_l) { |
| testGetLowestPriorityBiggestClient(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, getLowestPriorityPid_l) { |
| testGetLowestPriorityPid(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, isCallingPriorityHigher_l) { |
| testIsCallingPriorityHigher(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, batteryStats) { |
| testBatteryStats(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, cpusetBoost) { |
| testCpusetBoost(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, overridePid) { |
| testOverridePid(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, markClientForPendingRemoval) { |
| testMarkClientForPendingRemoval(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, reclaimResources_withVideoCodec_reclaimsOnlyVideoCodec) { |
| testReclaimResources_withVideoCodec_reclaimsOnlyVideoCodec(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, reclaimResources_withAudioCodec_reclaimsOnlyAudioCodec) { |
| testReclaimResources_withAudioCodec_reclaimsOnlyAudioCodec(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, reclaimResources_withImageCodec_reclaimsOnlyImageCodec) { |
| testReclaimResources_withImageCodec_reclaimsOnlyImageCodec(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, reclaimResources_whenPartialResourceMatch_reclaims) { |
| testReclaimResources_whenPartialResourceMatch_reclaims(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, |
| reclaimResourcesFromMarkedClients_removesBiggestMarkedClientForSomeResources) { |
| testReclaimResourcesFromMarkedClients_removesBiggestMarkedClientForSomeResources(); |
| } |
| |
| } // namespace android |