• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_NDEBUG 0
18 #define LOG_TAG "ClientManagerTest"
19 
20 #include "../utils/ClientManager.h"
21 #include <gtest/gtest.h>
22 
23 using namespace android::resource_policy;
24 
25 struct TestClient {
TestClientTestClient26     TestClient(int id, int32_t cost, const std::set<int>& conflictingKeys, int32_t ownerId,
27             int32_t score, int32_t state, bool isVendorClient) :
28             mId(id), mCost(cost), mConflictingKeys(conflictingKeys),
29             mOwnerId(ownerId), mScore(score), mState(state), mIsVendorClient(isVendorClient) {};
30     int mId;
31     int32_t mCost;    // Int 0..100
32     std::set<int> mConflictingKeys;
33     int32_t mOwnerId; // PID
34     int32_t mScore;   // Priority
35     int32_t mState;   // Foreground/background etc
36     bool mIsVendorClient;
37 };
38 
39 using TestClientDescriptor = ClientDescriptor<int, TestClient>;
40 using TestDescriptorPtr = std::shared_ptr<TestClientDescriptor>;
41 
makeDescFromTestClient(const TestClient & tc)42 TestDescriptorPtr makeDescFromTestClient(const TestClient& tc) {
43     return std::make_shared<TestClientDescriptor>(/*ID*/tc.mId, tc, tc.mCost, tc.mConflictingKeys,
44             tc.mScore, tc.mOwnerId, tc.mState, tc.mIsVendorClient);
45 }
46 
47 class TestClientManager : public ClientManager<int, TestClient> {
48 public:
TestClientManager()49     TestClientManager() {}
~TestClientManager()50     virtual ~TestClientManager() {}
51 };
52 
53 
54 // Test ClientMager behavior when there is only one single owner
55 // The expected behavior is that if one owner (application or vendor) is trying
56 // to open second camera, it may succeed or not, but the first opened camera
57 // should never be evicted.
TEST(ClientManagerTest,SingleOwnerMultipleCamera)58 TEST(ClientManagerTest, SingleOwnerMultipleCamera) {
59 
60     TestClientManager cm;
61     TestClient cam0Client(/*ID*/0, /*cost*/100, /*conflicts*/{1},
62             /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false);
63     auto cam0Desc = makeDescFromTestClient(cam0Client);
64     auto evicted = cm.addAndEvict(cam0Desc);
65     ASSERT_EQ(evicted.size(), 0u) << "Evicted list must be empty";
66 
67     TestClient cam1Client(/*ID*/1, /*cost*/100, /*conflicts*/{0},
68             /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false);
69     auto cam1Desc = makeDescFromTestClient(cam1Client);
70 
71     // 1. Check with conflicting devices, new client would be evicted
72     auto wouldBeEvicted = cm.wouldEvict(cam1Desc);
73     ASSERT_EQ(wouldBeEvicted.size(), 1u) << "Evicted list length must be 1";
74     ASSERT_EQ(wouldBeEvicted[0]->getKey(), cam1Desc->getKey()) << "cam1 must be evicted";
75 
76     cm.removeAll();
77 
78     TestClient cam2Client(/*ID*/2, /*cost*/100, /*conflicts*/{},
79             /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false);
80     auto cam2Desc = makeDescFromTestClient(cam2Client);
81     evicted = cm.addAndEvict(cam2Desc);
82     ASSERT_EQ(evicted.size(), 0u) << "Evicted list must be empty";
83 
84     TestClient cam3Client(/*ID*/3, /*cost*/100, /*conflicts*/{},
85             /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false);
86     auto cam3Desc = makeDescFromTestClient(cam3Client);
87 
88     // 2. Check without conflicting devices, the pre-existing client won't be evicted
89     // In this case, the new client would be granted, but could later be rejected by HAL due to
90     // resource cost.
91     wouldBeEvicted = cm.wouldEvict(cam3Desc);
92     ASSERT_EQ(wouldBeEvicted.size(), 0u) << "Evicted list must be empty";
93 
94     cm.removeAll();
95 
96     evicted = cm.addAndEvict(cam0Desc);
97     ASSERT_EQ(evicted.size(), 0u) << "Evicted list must be empty";
98 
99     TestClient cam0ClientNew(/*ID*/0, /*cost*/100, /*conflicts*/{1},
100             /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false);
101     auto cam0DescNew = makeDescFromTestClient(cam0ClientNew);
102     wouldBeEvicted = cm.wouldEvict(cam0DescNew);
103 
104     // 3. Check opening the same camera twice will evict the older client
105     ASSERT_EQ(wouldBeEvicted.size(), 1u) << "Evicted list length must be 1";
106     ASSERT_EQ(wouldBeEvicted[0], cam0Desc) << "cam0 (old) must be evicted";
107 }
108 
109