blob: 6a384278b880da1961146477a15bba32e8e8c884 [file] [log] [blame]
Yin-Chia Yeh8dfe4642020-06-01 11:57:45 -07001/*
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
23using namespace android::resource_policy;
24
25struct TestClient {
26 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
39using TestClientDescriptor = ClientDescriptor<int, TestClient>;
40using TestDescriptorPtr = std::shared_ptr<TestClientDescriptor>;
41
42TestDescriptorPtr 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
47class TestClientManager : public ClientManager<int, TestClient> {
48public:
49 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.
58TEST(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