| /* |
| * 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::kHwVideoCodec, amount); |
| } |
| |
| static MediaResource createNonSecureVideoCodecResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kNonSecureCodec, |
| MediaResource::SubType::kHwVideoCodec, amount); |
| } |
| |
| static MediaResource createSecureAudioCodecResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kSecureCodec, |
| MediaResource::SubType::kHwAudioCodec, amount); |
| } |
| |
| static MediaResource createNonSecureAudioCodecResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kNonSecureCodec, |
| MediaResource::SubType::kHwAudioCodec, amount); |
| } |
| |
| static MediaResource createSecureImageCodecResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kSecureCodec, |
| MediaResource::SubType::kHwImageCodec, amount); |
| } |
| |
| static MediaResource createNonSecureImageCodecResource(int amount = 1) { |
| return MediaResource(MediaResource::Type::kNonSecureCodec, |
| MediaResource::SubType::kHwImageCodec, 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)); |
| ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(mTestClient1), |
| .name = "none"}; |
| mService->addResource(client1Info, mTestClient1, resources1); |
| resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200)); |
| std::vector<MediaResourceParcel> resources11; |
| resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200)); |
| mService->addResource(client1Info, mTestClient1, resources11); |
| |
| // kTestPid2 mTestClient2 |
| std::vector<MediaResourceParcel> resources2; |
| resources2.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1)); |
| resources2.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300)); |
| ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(mTestClient2), |
| .name = "none"}; |
| mService->addResource(client2Info, mTestClient2, resources2); |
| |
| // kTestPid2 mTestClient3 |
| std::vector<MediaResourceParcel> resources3; |
| ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(mTestClient3), |
| .name = "none"}; |
| mService->addResource(client3Info, mTestClient3, resources3); |
| resources3.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| resources3.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100)); |
| mService->addResource(client3Info, mTestClient3, resources3); |
| |
| const PidResourceInfosMap &map = mService->mMap; |
| EXPECT_EQ(2u, map.size()); |
| const auto& mapIndex1 = map.find(kTestPid1); |
| EXPECT_TRUE(mapIndex1 != map.end()); |
| const ResourceInfos &infos1 = mapIndex1->second; |
| EXPECT_EQ(1u, infos1.size()); |
| expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, resources1); |
| |
| const auto& mapIndex2 = map.find(kTestPid2); |
| EXPECT_TRUE(mapIndex2 != map.end()); |
| const ResourceInfos &infos2 = mapIndex2->second; |
| EXPECT_EQ(2u, infos2.size()); |
| expectEqResourceInfo(infos2.at(getId(mTestClient2)), kTestUid2, mTestClient2, resources2); |
| expectEqResourceInfo(infos2.at(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)); |
| ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(mTestClient1), |
| .name = "none"}; |
| mService->addResource(client1Info, 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()); |
| const auto& mapIndex1 = map.find(kTestPid1); |
| EXPECT_TRUE(mapIndex1 != map.end()); |
| const ResourceInfos &infos1 = mapIndex1->second; |
| EXPECT_EQ(1u, infos1.size()); |
| std::vector<MediaResourceParcel> expected; |
| expectEqResourceInfo(infos1.at(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(client1Info, mTestClient1, resources1); |
| resources1.clear(); |
| resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, 10)); |
| resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 10)); |
| mService->addResource(client1Info, 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.at(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(client1Info, 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.at(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(client1Info, 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.at(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)); |
| ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(mTestClient1), |
| .name = "none"}; |
| mService->addResource(client1Info, mTestClient1, resources1); |
| |
| std::vector<MediaResourceParcel> resources11; |
| resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200)); |
| mService->addResource(client1Info, mTestClient1, resources11); |
| |
| const PidResourceInfosMap &map = mService->mMap; |
| EXPECT_EQ(1u, map.size()); |
| const auto& mapIndex1 = map.find(kTestPid1); |
| EXPECT_TRUE(mapIndex1 != map.end()); |
| const ResourceInfos &infos1 = mapIndex1->second; |
| EXPECT_EQ(1u, infos1.size()); |
| |
| // test adding existing types to combine values |
| resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100)); |
| mService->addResource(client1Info, mTestClient1, resources1); |
| |
| std::vector<MediaResourceParcel> expected; |
| expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2)); |
| expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300)); |
| expectEqResourceInfo(infos1.at(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::kHwVideoCodec, 1)); |
| mService->addResource(client1Info, 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::kHwVideoCodec, 1)); |
| expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 500)); |
| expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| } |
| |
| void testRemoveResource() { |
| // kTestPid1 mTestClient1 |
| std::vector<MediaResourceParcel> resources1; |
| resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(mTestClient1), |
| .name = "none"}; |
| mService->addResource(client1Info, mTestClient1, resources1); |
| |
| std::vector<MediaResourceParcel> resources11; |
| resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200)); |
| mService->addResource(client1Info, mTestClient1, resources11); |
| |
| const PidResourceInfosMap &map = mService->mMap; |
| EXPECT_EQ(1u, map.size()); |
| const auto& mapIndex1 = map.find(kTestPid1); |
| EXPECT_TRUE(mapIndex1 != map.end()); |
| const ResourceInfos &infos1 = mapIndex1->second; |
| EXPECT_EQ(1u, infos1.size()); |
| |
| // test partial removal |
| resources11[0].value = 100; |
| mService->removeResource(client1Info, resources11); |
| |
| std::vector<MediaResourceParcel> expected; |
| expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100)); |
| expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| |
| // test removal request with negative value, should be ignored |
| resources11[0].value = -10000; |
| mService->removeResource(client1Info, resources11); |
| |
| expectEqResourceInfo(infos1.at(getId(mTestClient1)), kTestUid1, mTestClient1, expected); |
| |
| // test complete removal with overshoot value |
| resources11[0].value = 1000; |
| mService->removeResource(client1Info, resources11); |
| |
| expected.clear(); |
| expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| expectEqResourceInfo(infos1.at(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 |
| ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(kLowPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = 0, |
| .name = "none"}; |
| CHECK_STATUS_FALSE(mService->reclaimResource(clientInfo, resources, &result)); |
| |
| // override Low Priority Pid with High Priority Pid |
| mService->overridePid(kLowPriorityPid, kHighPriorityPid); |
| CHECK_STATUS_TRUE(mService->reclaimResource(clientInfo, resources, &result)); |
| |
| // restore Low Priority Pid |
| mService->overridePid(kLowPriorityPid, -1); |
| CHECK_STATUS_FALSE(mService->reclaimResource(clientInfo, resources, &result)); |
| } |
| } |
| |
| void testMarkClientForPendingRemoval() { |
| ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(mTestClient1), |
| .name = "none"}; |
| ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(mTestClient2), |
| .name = "none"}; |
| ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(mTestClient3), |
| .name = "none"}; |
| { |
| addResource(); |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1)); |
| |
| // Remove low priority clients |
| mService->removeClient(client1Info); |
| |
| // no lower priority client |
| CHECK_STATUS_FALSE(mService->reclaimResource(client2Info, resources, &result)); |
| EXPECT_EQ(false, toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_EQ(false, toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| mService->markClientForPendingRemoval(client2Info); |
| |
| // client marked for pending removal from the same process got reclaimed |
| CHECK_STATUS_TRUE(mService->reclaimResource(client2Info, 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(client3Info); |
| } |
| |
| { |
| addResource(); |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1)); |
| |
| mService->markClientForPendingRemoval(client2Info); |
| |
| // client marked for pending removal from the same process got reclaimed |
| // first, even though there are lower priority process |
| CHECK_STATUS_TRUE(mService->reclaimResource(client2Info, 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(client2Info, 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(client3Info); |
| } |
| |
| { |
| addResource(); |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| mService->markClientForPendingRemoval(client2Info); |
| |
| // 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(client3Info); |
| |
| // 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(client1Info); |
| } |
| } |
| |
| void testRemoveClient() { |
| addResource(); |
| |
| ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(mTestClient2), |
| .name = "none"}; |
| mService->removeClient(client2Info); |
| |
| const PidResourceInfosMap &map = mService->mMap; |
| EXPECT_EQ(2u, map.size()); |
| const ResourceInfos &infos1 = map.at(kTestPid1); |
| const ResourceInfos &infos2 = map.at(kTestPid2); |
| EXPECT_EQ(1u, infos1.size()); |
| EXPECT_EQ(1u, infos2.size()); |
| // mTestClient2 has been removed. |
| EXPECT_EQ(mTestClient3, infos2.at(getId(mTestClient3)).client); |
| } |
| |
| void testGetAllClients() { |
| addResource(); |
| |
| std::vector<ClientInfo> targetClients; |
| MediaResource resource(MediaResource::Type::kSecureCodec, |
| MediaResource::SubType::kUnspecifiedSubType, |
| 1); |
| ResourceRequestInfo requestInfoHigh { kHighPriorityPid, &resource}; |
| ResourceRequestInfo requestInfoMid { kMidPriorityPid, &resource}; |
| ResourceRequestInfo requestInfoLow { kLowPriorityPid, &resource}; |
| |
| EXPECT_FALSE(mService->getAllClients_l(requestInfoLow, targetClients)); |
| // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l |
| // will fail. |
| EXPECT_FALSE(mService->getAllClients_l(requestInfoMid, targetClients)); |
| EXPECT_TRUE(mService->getAllClients_l(requestInfoHigh, targetClients)); |
| |
| EXPECT_EQ(2u, targetClients.size()); |
| // (OK to require ordering in clients[], as the pid map is sorted) |
| EXPECT_EQ(getId(mTestClient3), targetClients[0].mClientId); |
| EXPECT_EQ(getId(mTestClient1), targetClients[1].mClientId); |
| } |
| |
| void testReclaimResourceSecure() { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1)); |
| resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150)); |
| |
| ClientInfoParcel lowPriorityClient{.pid = static_cast<int32_t>(kLowPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = 0, |
| .name = "none"}; |
| ClientInfoParcel midPriorityClient{.pid = static_cast<int32_t>(kMidPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = 0, |
| .name = "none"}; |
| ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = 0, |
| .name = "none"}; |
| |
| // ### 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(lowPriorityClient, resources, &result)); |
| CHECK_STATUS_FALSE(mService->reclaimResource(midPriorityClient, resources, &result)); |
| |
| // reclaim all secure codecs |
| CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, 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(highPriorityClient, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, 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(lowPriorityClient, resources, &result)); |
| CHECK_STATUS_FALSE(mService->reclaimResource(midPriorityClient, resources, &result)); |
| |
| // reclaim all secure and non-secure codecs |
| CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, resources, &result)); |
| EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, 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(lowPriorityClient, resources, &result)); |
| CHECK_STATUS_FALSE(mService->reclaimResource(midPriorityClient, resources, &result)); |
| |
| // reclaim all non-secure codecs |
| CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, 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(highPriorityClient, 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(highPriorityClient, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, 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(lowPriorityClient, resources, &result)); |
| |
| CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, 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(highPriorityClient, 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(highPriorityClient, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, 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(highPriorityClient, 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(highPriorityClient, 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(highPriorityClient, 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)); |
| |
| ClientInfoParcel lowPriorityClient{.pid = static_cast<int32_t>(kLowPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = 0, |
| .name = "none"}; |
| ClientInfoParcel midPriorityClient{.pid = static_cast<int32_t>(kMidPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = 0, |
| .name = "none"}; |
| ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = 0, |
| .name = "none"}; |
| |
| // ### secure codec can't coexist with non-secure codec ### |
| { |
| addResource(); |
| mService->mSupportsSecureWithNonSecureCodec = false; |
| |
| // priority too low |
| CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result)); |
| CHECK_STATUS_FALSE(mService->reclaimResource(midPriorityClient, resources, &result)); |
| |
| // reclaim all secure codecs |
| CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, 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(highPriorityClient, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, resources, &result)); |
| } |
| |
| |
| // ### secure codec can coexist with non-secure codec ### |
| { |
| addResource(); |
| mService->mSupportsSecureWithNonSecureCodec = true; |
| |
| // priority too low |
| CHECK_STATUS_FALSE(mService->reclaimResource(lowPriorityClient, resources, &result)); |
| |
| CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, 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(highPriorityClient, 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(highPriorityClient, resources, &result)); |
| EXPECT_FALSE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_TRUE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // nothing left |
| CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, 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(highPriorityClient, 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(highPriorityClient, resources, &result)); |
| EXPECT_TRUE(toTestClient(mTestClient1)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient2)->checkIfReclaimedAndReset()); |
| EXPECT_FALSE(toTestClient(mTestClient3)->checkIfReclaimedAndReset()); |
| |
| // clean up client 3 which still left |
| ClientInfoParcel clientInfo{.pid = static_cast<int32_t>(kTestPid2), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(mTestClient3), |
| .name = "none"}; |
| mService->removeClient(clientInfo); |
| } |
| } |
| |
| void testGetLowestPriorityBiggestClient() { |
| ClientInfo clientInfo; |
| MediaResource resource(MediaResource::Type::kGraphicMemory, |
| MediaResource::SubType::kUnspecifiedSubType, |
| 1); |
| ResourceRequestInfo requestInfoHigh { kHighPriorityPid, &resource}; |
| ResourceRequestInfo requestInfoLow { kLowPriorityPid, &resource}; |
| EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(requestInfoHigh, clientInfo)); |
| |
| addResource(); |
| |
| EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(requestInfoLow, clientInfo)); |
| EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(requestInfoHigh, clientInfo)); |
| |
| // kTestPid1 is the lowest priority process with MediaResource::Type::kGraphicMemory. |
| // mTestClient1 has the largest MediaResource::Type::kGraphicMemory within kTestPid1. |
| EXPECT_EQ(getId(mTestClient1), clientInfo.mClientId); |
| } |
| |
| 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::kHwVideoCodec, 1)); |
| ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(mTestClient1), |
| .name = "none"}; |
| mService->addResource(client1Info, 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(client1Info, 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::kHwVideoCodec, 2)); |
| ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(mTestClient2), |
| .name = "none"}; |
| mService->addResource(client2Info, 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(client1Info, 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(client1Info, 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(client2Info); |
| 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)); |
| ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(mTestClient1), |
| .name = "none"}; |
| mService->addResource(client1Info, mTestClient1, resources1); |
| EXPECT_EQ(2u, mSystemCB->eventCount()); |
| EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType()); |
| |
| // each client should only cause 1 CPUSET_ENABLE |
| mService->addResource(client1Info, 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)); |
| ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(mTestClient2), |
| .name = "none"}; |
| mService->addResource(client2Info, 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(client2Info); |
| EXPECT_EQ(3u, mSystemCB->eventCount()); |
| |
| // remove 1 cpuboost from mTestClient1, should not be CPUSET_DISABLE (still 1 left) |
| mService->removeResource(client1Info, 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(client1Info, 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()); |
| ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kLowPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(audioImageTestClient), |
| .name = "none"}; |
| mService->addResource(client1Info, audioImageTestClient, audioImageResources); |
| |
| // Fail to reclaim a video codec resource |
| std::vector<MediaResourceParcel> reclaimResources; |
| reclaimResources.push_back(createNonSecureVideoCodecResource()); |
| ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = 0, |
| .name = "none"}; |
| CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result)); |
| |
| // Now add a video codec resource |
| std::vector<MediaResourceParcel> videoResources; |
| videoResources.push_back(createNonSecureVideoCodecResource()); |
| ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kLowPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(videoTestClient), |
| .name = "none"}; |
| mService->addResource(client2Info, videoTestClient, videoResources); |
| |
| // Verify that the newly-created video codec resource can be reclaimed |
| CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, 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()); |
| ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kLowPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(videoImageTestClient), |
| .name = "none"}; |
| mService->addResource(client1Info, videoImageTestClient, videoImageResources); |
| |
| // Fail to reclaim an audio codec resource |
| std::vector<MediaResourceParcel> reclaimResources; |
| reclaimResources.push_back(createNonSecureAudioCodecResource()); |
| ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = 0, |
| .name = "none"}; |
| CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result)); |
| |
| // Now add an audio codec resource |
| std::vector<MediaResourceParcel> audioResources; |
| audioResources.push_back(createNonSecureAudioCodecResource()); |
| ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kLowPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(audioTestClient), |
| .name = "none"}; |
| mService->addResource(client2Info, audioTestClient, audioResources); |
| |
| // Verify that the newly-created audio codec resource can be reclaimed |
| CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, 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()); |
| ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kLowPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(videoAudioTestClient), |
| .name = "none"}; |
| mService->addResource(client1Info, videoAudioTestClient, videoAudioResources); |
| |
| // Fail to reclaim an image codec resource |
| std::vector<MediaResourceParcel> reclaimResources; |
| reclaimResources.push_back(createNonSecureImageCodecResource()); |
| ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = 0, |
| .name = "none"}; |
| CHECK_STATUS_FALSE(mService->reclaimResource(highPriorityClient, reclaimResources, &result)); |
| |
| // Now add an image codec resource |
| std::vector<MediaResourceParcel> imageResources; |
| imageResources.push_back(createNonSecureImageCodecResource()); |
| ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kLowPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(imageTestClient), |
| .name = "none"}; |
| mService->addResource(client2Info, imageTestClient, imageResources); |
| |
| // Verify that the newly-created image codec resource can be reclaimed |
| CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, 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, onlyUid); |
| |
| std::vector<MediaResourceParcel> ownedResources; |
| ownedResources.push_back(createNonSecureVideoCodecResource()); |
| ownedResources.push_back(createGraphicMemoryResource(100)); |
| ClientInfoParcel onlyClientInfo{.pid = static_cast<int32_t>(kLowPriorityPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(onlyClient), |
| .name = "none"}; |
| mService->addResource(onlyClientInfo, 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)); |
| ClientInfoParcel highPriorityClient{.pid = static_cast<int32_t>(kHighPriorityPid), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = 0, |
| .name = "none"}; |
| CHECK_STATUS_TRUE(mService->reclaimResource(highPriorityClient, 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, onlyUid); |
| const auto largeSecureVideoMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largestSecureVideoActiveClient = createTestClient(onlyPid, onlyUid); |
| ClientInfoParcel clientA{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(smallSecureVideoMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientB{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largeSecureVideoMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientC{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largestSecureVideoActiveClient), |
| .name = "none"}; |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createSecureVideoCodecResource(1)); |
| mService->addResource(clientA, smallSecureVideoMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureVideoCodecResource(2)); |
| mService->addResource(clientB, largeSecureVideoMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureVideoCodecResource(3)); |
| mService->addResource(clientC, largestSecureVideoActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(clientA); |
| mService->markClientForPendingRemoval(clientB); |
| // don't mark the largest client |
| |
| // non-secure video codec |
| const auto smallNonSecureVideoMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largeNonSecureVideoMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largestNonSecureVideoActiveClient = createTestClient(onlyPid, onlyUid); |
| ClientInfoParcel clientD{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(smallNonSecureVideoMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientE{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largeNonSecureVideoMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientF{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largestNonSecureVideoActiveClient), |
| .name = "none"}; |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createNonSecureVideoCodecResource(1)); |
| mService->addResource(clientD, smallNonSecureVideoMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureVideoCodecResource(2)); |
| mService->addResource(clientE, largeNonSecureVideoMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureVideoCodecResource(3)); |
| mService->addResource(clientF, largestNonSecureVideoActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(clientD); |
| mService->markClientForPendingRemoval(clientE); |
| // don't mark the largest client |
| |
| // secure audio codec |
| const auto smallSecureAudioMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largeSecureAudioMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largestSecureAudioActiveClient = createTestClient(onlyPid, onlyUid); |
| ClientInfoParcel clientG{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(smallSecureAudioMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientH{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largeSecureAudioMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientI{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largestSecureVideoActiveClient), |
| .name = "none"}; |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createSecureAudioCodecResource(1)); |
| mService->addResource(clientG, smallSecureAudioMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureAudioCodecResource(2)); |
| mService->addResource(clientH, largeSecureAudioMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureAudioCodecResource(3)); |
| mService->addResource(clientI, largestSecureVideoActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(clientG); |
| mService->markClientForPendingRemoval(clientH); |
| // don't mark the largest client |
| |
| // non-secure audio codec |
| const auto smallNonSecureAudioMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largeNonSecureAudioMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largestNonSecureAudioActiveClient = createTestClient(onlyPid, onlyUid); |
| ClientInfoParcel clientJ{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(smallNonSecureAudioMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientK{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largeNonSecureAudioMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientL{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largestNonSecureAudioActiveClient), |
| .name = "none"}; |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createNonSecureAudioCodecResource(1)); |
| mService->addResource(clientJ, smallNonSecureAudioMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureAudioCodecResource(2)); |
| mService->addResource(clientK, largeNonSecureAudioMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureAudioCodecResource(3)); |
| mService->addResource(clientL, largestNonSecureAudioActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(clientJ); |
| mService->markClientForPendingRemoval(clientK); |
| // don't mark the largest client |
| |
| // secure image codec |
| const auto smallSecureImageMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largeSecureImageMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largestSecureImageActiveClient = createTestClient(onlyPid, onlyUid); |
| ClientInfoParcel clientM{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(smallSecureImageMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientN{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largeSecureImageMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientO{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largestSecureImageActiveClient), |
| .name = "none"}; |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createSecureImageCodecResource(1)); |
| mService->addResource(clientM, smallSecureImageMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureImageCodecResource(2)); |
| mService->addResource(clientN, largeSecureImageMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createSecureImageCodecResource(3)); |
| mService->addResource(clientO, largestSecureImageActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(clientM); |
| mService->markClientForPendingRemoval(clientN); |
| // don't mark the largest client |
| |
| // non-secure image codec |
| const auto smallNonSecureImageMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largeNonSecureImageMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largestNonSecureImageActiveClient = createTestClient(onlyPid, onlyUid); |
| ClientInfoParcel clientP{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(smallNonSecureImageMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientQ{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largeNonSecureImageMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientR{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largestNonSecureImageActiveClient), |
| .name = "none"}; |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createNonSecureImageCodecResource(1)); |
| mService->addResource(clientP, smallNonSecureImageMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureImageCodecResource(2)); |
| mService->addResource(clientQ, largeNonSecureImageMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createNonSecureImageCodecResource(3)); |
| mService->addResource(clientR, largestNonSecureImageActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(clientP); |
| mService->markClientForPendingRemoval(clientQ); |
| // don't mark the largest client |
| |
| // graphic memory |
| const auto smallGraphicMemoryMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largeGraphicMemoryMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largestGraphicMemoryActiveClient = createTestClient(onlyPid, onlyUid); |
| ClientInfoParcel clientS{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(smallGraphicMemoryMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientT{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largeGraphicMemoryMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientU{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largestGraphicMemoryActiveClient), |
| .name = "none"}; |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createGraphicMemoryResource(100)); |
| mService->addResource(clientS, smallGraphicMemoryMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createGraphicMemoryResource(200)); |
| mService->addResource(clientT, largeGraphicMemoryMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createGraphicMemoryResource(300)); |
| mService->addResource(clientU, largestGraphicMemoryActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(clientS); |
| mService->markClientForPendingRemoval(clientT); |
| // don't mark the largest client |
| |
| // DRM session |
| const auto smallDrmSessionMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largeDrmSessionMarkedClient = createTestClient(onlyPid, onlyUid); |
| const auto largestDrmSessionActiveClient = createTestClient(onlyPid, onlyUid); |
| ClientInfoParcel clientV{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(smallDrmSessionMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientW{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largeDrmSessionMarkedClient), |
| .name = "none"}; |
| ClientInfoParcel clientX{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(largestDrmSessionActiveClient), |
| .name = "none"}; |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createDrmSessionResource(1)); |
| mService->addResource(clientV, smallDrmSessionMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createDrmSessionResource(2)); |
| mService->addResource(clientW, largeDrmSessionMarkedClient, resources); |
| resources.clear(); |
| resources.push_back(createDrmSessionResource(3)); |
| mService->addResource(clientX, largestDrmSessionActiveClient, resources); |
| } |
| mService->markClientForPendingRemoval(clientV); |
| mService->markClientForPendingRemoval(clientW); |
| // don't mark the largest client |
| |
| // battery |
| const auto batteryMarkedClient = createTestClient(onlyPid, onlyUid); |
| ClientInfoParcel clientY{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(batteryMarkedClient), |
| .name = "none"}; |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createBatteryResource()); |
| mService->addResource(clientY, batteryMarkedClient, resources); |
| } |
| mService->markClientForPendingRemoval(clientY); |
| |
| // CPU boost |
| const auto cpuBoostMarkedClient = createTestClient(onlyPid, onlyUid); |
| ClientInfoParcel clientZ{.pid = static_cast<int32_t>(onlyPid), |
| .uid = static_cast<int32_t>(onlyUid), |
| .id = getId(cpuBoostMarkedClient), |
| .name = "none"}; |
| { |
| std::vector<MediaResourceParcel> resources; |
| resources.push_back(createCpuBoostResource()); |
| mService->addResource(clientZ, cpuBoostMarkedClient, resources); |
| } |
| mService->markClientForPendingRemoval(clientZ); |
| |
| // 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()); |
| } |
| |
| inline void initClientConfigParcel(bool encoder, bool hw, |
| int32_t width, int32_t height, |
| int64_t id, |
| const ClientInfoParcel& clientInfo, |
| ClientConfigParcel& clientConfig) { |
| clientConfig.codecType = hw? MediaResource::SubType::kHwVideoCodec : |
| MediaResource::SubType::kSwVideoCodec; |
| clientConfig.isEncoder = encoder; |
| clientConfig.width = width; |
| clientConfig.height = height; |
| clientConfig.timeStamp = systemTime(SYSTEM_TIME_MONOTONIC) / 1000LL; |
| clientConfig.id = id; |
| clientConfig.clientInfo = clientInfo; |
| } |
| |
| void testConcurrentCodecs() { |
| std::shared_ptr<IResourceManagerClient> testClient4 = |
| createTestClient(kTestPid1, kTestUid1); |
| ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(mTestClient1), |
| .name = "none"}; |
| ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(mTestClient2), |
| .name = "none"}; |
| ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2), |
| .uid = static_cast<int32_t>(kTestUid2), |
| .id = getId(mTestClient3), |
| .name = "none"}; |
| ClientInfoParcel client4Info{.pid = static_cast<int32_t>(kTestPid1), |
| .uid = static_cast<int32_t>(kTestUid1), |
| .id = getId(testClient4), |
| .name = "none"}; |
| ClientConfigParcel client1Config; |
| ClientConfigParcel client2Config; |
| ClientConfigParcel client3Config; |
| ClientConfigParcel client4Config; |
| |
| // HW Video Encoder @ 1080P. |
| initClientConfigParcel(true, true, 1920, 1080, 11111111, |
| client1Info, client1Config); |
| // HW Video Decoder @ 4K. |
| initClientConfigParcel(true, true, 2160, 3840, 22222222, |
| client2Info, client2Config); |
| // SW Video Encoder @ 1080P. |
| initClientConfigParcel(true, true, 1920, 1080, 33333333, |
| client3Info, client3Config); |
| // SW Video Decoder @ 4K. |
| initClientConfigParcel(true, true, 2160, 3840, 44444444, |
| client4Info, client4Config); |
| |
| // Start client1 at 1080P. |
| mService->notifyClientStarted(client1Config); |
| long peakPixelCountP1 = mService->getPeakConcurrentPixelCount(kTestPid1); |
| long currentPixelCountP1 = mService->getCurrentConcurrentPixelCount(kTestPid1); |
| EXPECT_TRUE(peakPixelCountP1 = client1Config.width * client1Config.height); |
| EXPECT_TRUE(currentPixelCountP1 = client1Config.width * client1Config.height); |
| |
| // Stop client1. |
| mService->notifyClientStopped(client1Config); |
| peakPixelCountP1 = mService->getPeakConcurrentPixelCount(kTestPid1); |
| currentPixelCountP1 = mService->getCurrentConcurrentPixelCount(kTestPid1); |
| EXPECT_TRUE(peakPixelCountP1 == client1Config.width * client1Config.height); |
| EXPECT_TRUE(currentPixelCountP1 == 0); |
| |
| // Start client1 at 1080P. |
| mService->notifyClientStarted(client1Config); |
| // Start client2 at 4K. |
| mService->notifyClientStarted(client2Config); |
| |
| // Verify the Peak and Current Concurrent pixel count for both the process |
| // (kTestPid1, kTestPid2) |
| peakPixelCountP1 = mService->getPeakConcurrentPixelCount(kTestPid1); |
| currentPixelCountP1 = mService->getCurrentConcurrentPixelCount(kTestPid1); |
| long peakPixelCountP2 = mService->getPeakConcurrentPixelCount(kTestPid2); |
| long currentPixelCountP2 = mService->getCurrentConcurrentPixelCount(kTestPid2); |
| EXPECT_TRUE(peakPixelCountP1 == client1Config.width * client1Config.height); |
| EXPECT_TRUE(currentPixelCountP1 == client1Config.width * client1Config.height); |
| EXPECT_TRUE(peakPixelCountP2 == client2Config.width * client2Config.height); |
| EXPECT_TRUE(currentPixelCountP2 == client2Config.width * client2Config.height); |
| |
| // Start client3 at 1080P. |
| mService->notifyClientStarted(client3Config); |
| // Start client4 at 4K. |
| mService->notifyClientStarted(client4Config); |
| |
| // Verify the Peak and Current Concurrent pixel count for both the process |
| // (kTestPid1, kTestPid2) |
| peakPixelCountP1 = mService->getPeakConcurrentPixelCount(kTestPid1); |
| currentPixelCountP1 = mService->getCurrentConcurrentPixelCount(kTestPid1); |
| peakPixelCountP2 = mService->getPeakConcurrentPixelCount(kTestPid2); |
| currentPixelCountP2 = mService->getCurrentConcurrentPixelCount(kTestPid2); |
| EXPECT_TRUE(peakPixelCountP1 == |
| (client1Config.width * client1Config.height + |
| client4Config.width * client4Config.height)); |
| EXPECT_TRUE(currentPixelCountP1 == |
| (client1Config.width * client1Config.height + |
| client4Config.width * client4Config.height)); |
| EXPECT_TRUE(peakPixelCountP2 == |
| (client2Config.width * client2Config.height + |
| client3Config.width * client3Config.height)); |
| EXPECT_TRUE(currentPixelCountP2 == |
| (client2Config.width * client2Config.height + |
| client3Config.width * client3Config.height)); |
| |
| // Stop client4 |
| mService->notifyClientStopped(client4Config); |
| currentPixelCountP1 = mService->getCurrentConcurrentPixelCount(kTestPid1); |
| EXPECT_TRUE(currentPixelCountP1 == client1Config.width * client1Config.height); |
| |
| // Stop client1 |
| mService->notifyClientStopped(client1Config); |
| |
| // Stop client2 |
| mService->notifyClientStopped(client2Config); |
| currentPixelCountP2 = mService->getCurrentConcurrentPixelCount(kTestPid2); |
| EXPECT_TRUE(currentPixelCountP2 == client3Config.width * client3Config.height); |
| // Stop client3 |
| mService->notifyClientStopped(client3Config); |
| |
| // Verify the Peak and Current Concurrent pixel count for both the process |
| // (kTestPid1, kTestPid2) |
| peakPixelCountP1 = mService->getPeakConcurrentPixelCount(kTestPid1); |
| currentPixelCountP1 = mService->getCurrentConcurrentPixelCount(kTestPid1); |
| peakPixelCountP2 = mService->getPeakConcurrentPixelCount(kTestPid2); |
| currentPixelCountP2 = mService->getCurrentConcurrentPixelCount(kTestPid2); |
| EXPECT_TRUE(peakPixelCountP1 == |
| (client1Config.width * client1Config.height + |
| client4Config.width * client4Config.height)); |
| EXPECT_TRUE(currentPixelCountP1 == 0); |
| EXPECT_TRUE(peakPixelCountP2 == |
| (client2Config.width * client2Config.height + |
| client3Config.width * client3Config.height)); |
| EXPECT_TRUE(currentPixelCountP2 == 0); |
| } |
| }; |
| |
| 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(); |
| } |
| |
| TEST_F(ResourceManagerServiceTest, concurrentCodecs) { |
| testConcurrentCodecs(); |
| } |
| |
| } // namespace android |