blob: 5d839fa062c491acec9e9b581b2009f3a66c0308 [file] [log] [blame]
Ronghua Wu231c3d12015-03-11 15:10:32 -07001/*
Ronghua Wu67e7f542015-03-13 10:47:08 -07002 * Copyright 2015 The Android Open Source Project
Ronghua Wu231c3d12015-03-11 15:10:32 -07003 *
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 "ResourceManagerService_test"
19#include <utils/Log.h>
20
21#include <gtest/gtest.h>
22
23#include "ResourceManagerService.h"
Chong Zhangfdd512a2019-11-22 11:03:14 -080024#include <aidl/android/media/BnResourceManagerClient.h>
Ronghua Wu231c3d12015-03-11 15:10:32 -070025#include <media/MediaResource.h>
26#include <media/MediaResourcePolicy.h>
27#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/ProcessInfoInterface.h>
29
Chong Zhangfdd512a2019-11-22 11:03:14 -080030namespace aidl {
Ronghua Wu231c3d12015-03-11 15:10:32 -070031namespace android {
Chong Zhang181e6952019-10-09 13:23:39 -070032namespace media {
Chong Zhangfdd512a2019-11-22 11:03:14 -080033bool operator== (const MediaResourceParcel& lhs, const MediaResourceParcel& rhs) {
34 return lhs.type == rhs.type && lhs.subType == rhs.subType &&
35 lhs.id == rhs.id && lhs.value == rhs.value;
36}}}}
Chong Zhang181e6952019-10-09 13:23:39 -070037
Chong Zhangfdd512a2019-11-22 11:03:14 -080038namespace android {
Ronghua Wu231c3d12015-03-11 15:10:32 -070039
Chong Zhangfdd512a2019-11-22 11:03:14 -080040using Status = ::ndk::ScopedAStatus;
41using ::aidl::android::media::BnResourceManagerClient;
42using ::aidl::android::media::IResourceManagerService;
43using ::aidl::android::media::IResourceManagerClient;
44
45static int64_t getId(const std::shared_ptr<IResourceManagerClient>& client) {
Ronghua Wu37c89242015-07-15 12:23:48 -070046 return (int64_t) client.get();
47}
48
Ronghua Wu231c3d12015-03-11 15:10:32 -070049struct TestProcessInfo : public ProcessInfoInterface {
50 TestProcessInfo() {}
51 virtual ~TestProcessInfo() {}
52
53 virtual bool getPriority(int pid, int *priority) {
54 // For testing, use pid as priority.
55 // Lower the value higher the priority.
56 *priority = pid;
57 return true;
58 }
59
Ronghua Wud11c43a2016-01-27 16:26:12 -080060 virtual bool isValidPid(int /* pid */) {
61 return true;
62 }
63
Ronghua Wu231c3d12015-03-11 15:10:32 -070064private:
65 DISALLOW_EVIL_CONSTRUCTORS(TestProcessInfo);
66};
67
Chong Zhangdd726802019-08-21 17:24:13 -070068struct TestSystemCallback :
69 public ResourceManagerService::SystemCallbackInterface {
70 TestSystemCallback() :
71 mLastEvent({EventType::INVALID, 0}), mEventCount(0) {}
72
73 enum EventType {
74 INVALID = -1,
75 VIDEO_ON = 0,
76 VIDEO_OFF = 1,
77 VIDEO_RESET = 2,
78 CPUSET_ENABLE = 3,
79 CPUSET_DISABLE = 4,
80 };
81
82 struct EventEntry {
83 EventType type;
84 int arg;
85 };
86
87 virtual void noteStartVideo(int uid) override {
88 mLastEvent = {EventType::VIDEO_ON, uid};
89 mEventCount++;
90 }
91
92 virtual void noteStopVideo(int uid) override {
93 mLastEvent = {EventType::VIDEO_OFF, uid};
94 mEventCount++;
95 }
96
97 virtual void noteResetVideo() override {
98 mLastEvent = {EventType::VIDEO_RESET, 0};
99 mEventCount++;
100 }
101
Chong Zhangfdd512a2019-11-22 11:03:14 -0800102 virtual bool requestCpusetBoost(bool enable) override {
Chong Zhangdd726802019-08-21 17:24:13 -0700103 mLastEvent = {enable ? EventType::CPUSET_ENABLE : EventType::CPUSET_DISABLE, 0};
104 mEventCount++;
105 return true;
106 }
107
108 size_t eventCount() { return mEventCount; }
109 EventType lastEventType() { return mLastEvent.type; }
110 EventEntry lastEvent() { return mLastEvent; }
111
112protected:
113 virtual ~TestSystemCallback() {}
114
115private:
116 EventEntry mLastEvent;
117 size_t mEventCount;
118
119 DISALLOW_EVIL_CONSTRUCTORS(TestSystemCallback);
120};
121
122
Ronghua Wu231c3d12015-03-11 15:10:32 -0700123struct TestClient : public BnResourceManagerClient {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800124 TestClient(int pid, const std::shared_ptr<ResourceManagerService> &service)
Ronghua Wu37c89242015-07-15 12:23:48 -0700125 : mReclaimed(false), mPid(pid), mService(service) {}
Ronghua Wu231c3d12015-03-11 15:10:32 -0700126
Chong Zhang181e6952019-10-09 13:23:39 -0700127 Status reclaimResource(bool* _aidl_return) override {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800128 mService->removeClient(mPid, getId(ref<TestClient>()));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700129 mReclaimed = true;
Chong Zhang181e6952019-10-09 13:23:39 -0700130 *_aidl_return = true;
131 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700132 }
133
Chong Zhang181e6952019-10-09 13:23:39 -0700134 Status getName(::std::string* _aidl_return) override {
135 *_aidl_return = "test_client";
136 return Status::ok();
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700137 }
138
Ronghua Wu231c3d12015-03-11 15:10:32 -0700139 bool reclaimed() const {
140 return mReclaimed;
141 }
142
143 void reset() {
144 mReclaimed = false;
145 }
146
Ronghua Wu231c3d12015-03-11 15:10:32 -0700147 virtual ~TestClient() {}
148
149private:
150 bool mReclaimed;
Ronghua Wu37c89242015-07-15 12:23:48 -0700151 int mPid;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800152 std::shared_ptr<ResourceManagerService> mService;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700153 DISALLOW_EVIL_CONSTRUCTORS(TestClient);
154};
155
156static const int kTestPid1 = 30;
Chong Zhangee33d642019-08-08 14:26:43 -0700157static const int kTestUid1 = 1010;
158
Ronghua Wu231c3d12015-03-11 15:10:32 -0700159static const int kTestPid2 = 20;
Chong Zhangee33d642019-08-08 14:26:43 -0700160static const int kTestUid2 = 1011;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700161
Ronghua Wu05d89f12015-07-07 16:47:42 -0700162static const int kLowPriorityPid = 40;
163static const int kMidPriorityPid = 25;
164static const int kHighPriorityPid = 10;
165
Chong Zhangdd726802019-08-21 17:24:13 -0700166using EventType = TestSystemCallback::EventType;
167using EventEntry = TestSystemCallback::EventEntry;
168bool operator== (const EventEntry& lhs, const EventEntry& rhs) {
169 return lhs.type == rhs.type && lhs.arg == rhs.arg;
170}
171
Chong Zhang181e6952019-10-09 13:23:39 -0700172#define CHECK_STATUS_TRUE(condition) \
173 EXPECT_TRUE((condition).isOk() && (result))
174
175#define CHECK_STATUS_FALSE(condition) \
176 EXPECT_TRUE((condition).isOk() && !(result))
177
Ronghua Wu231c3d12015-03-11 15:10:32 -0700178class ResourceManagerServiceTest : public ::testing::Test {
179public:
180 ResourceManagerServiceTest()
Chong Zhangdd726802019-08-21 17:24:13 -0700181 : mSystemCB(new TestSystemCallback()),
Chong Zhangfdd512a2019-11-22 11:03:14 -0800182 mService(::ndk::SharedRefBase::make<ResourceManagerService>(
183 new TestProcessInfo, mSystemCB)),
184 mTestClient1(::ndk::SharedRefBase::make<TestClient>(kTestPid1, mService)),
185 mTestClient2(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)),
186 mTestClient3(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700187 }
188
189protected:
Chong Zhang181e6952019-10-09 13:23:39 -0700190 static bool isEqualResources(const std::vector<MediaResourceParcel> &resources1,
Chong Zhangfb092d32019-08-12 09:45:44 -0700191 const ResourceList &resources2) {
192 // convert resource1 to ResourceList
193 ResourceList r1;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700194 for (size_t i = 0; i < resources1.size(); ++i) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700195 const auto &res = resources1[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700196 const auto resType = std::tuple(res.type, res.subType, res.id);
Robert Shihc3af31b2019-09-20 21:45:01 -0700197 r1[resType] = res;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700198 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700199 return r1 == resources2;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700200 }
201
Chong Zhangee33d642019-08-08 14:26:43 -0700202 static void expectEqResourceInfo(const ResourceInfo &info,
203 int uid,
Chong Zhangfdd512a2019-11-22 11:03:14 -0800204 std::shared_ptr<IResourceManagerClient> client,
Chong Zhang181e6952019-10-09 13:23:39 -0700205 const std::vector<MediaResourceParcel> &resources) {
Chong Zhangee33d642019-08-08 14:26:43 -0700206 EXPECT_EQ(uid, info.uid);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700207 EXPECT_EQ(client, info.client);
208 EXPECT_TRUE(isEqualResources(resources, info.resources));
209 }
210
211 void verifyClients(bool c1, bool c2, bool c3) {
212 TestClient *client1 = static_cast<TestClient*>(mTestClient1.get());
213 TestClient *client2 = static_cast<TestClient*>(mTestClient2.get());
214 TestClient *client3 = static_cast<TestClient*>(mTestClient3.get());
215
216 EXPECT_EQ(c1, client1->reclaimed());
217 EXPECT_EQ(c2, client2->reclaimed());
218 EXPECT_EQ(c3, client3->reclaimed());
219
220 client1->reset();
221 client2->reset();
222 client3->reset();
223 }
224
Ronghua Wu67e7f542015-03-13 10:47:08 -0700225 // test set up
226 // ---------------------------------------------------------------------------------
227 // pid priority client type number
228 // ---------------------------------------------------------------------------------
229 // kTestPid1(30) 30 mTestClient1 secure codec 1
230 // graphic memory 200
231 // graphic memory 200
232 // ---------------------------------------------------------------------------------
233 // kTestPid2(20) 20 mTestClient2 non-secure codec 1
234 // graphic memory 300
235 // -------------------------------------------
236 // mTestClient3 secure codec 1
237 // graphic memory 100
238 // ---------------------------------------------------------------------------------
Ronghua Wu231c3d12015-03-11 15:10:32 -0700239 void addResource() {
240 // kTestPid1 mTestClient1
Chong Zhang181e6952019-10-09 13:23:39 -0700241 std::vector<MediaResourceParcel> resources1;
242 resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
Chong Zhangee33d642019-08-08 14:26:43 -0700243 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
Chong Zhang181e6952019-10-09 13:23:39 -0700244 resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
245 std::vector<MediaResourceParcel> resources11;
246 resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
Chong Zhangee33d642019-08-08 14:26:43 -0700247 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700248
249 // kTestPid2 mTestClient2
Chong Zhang181e6952019-10-09 13:23:39 -0700250 std::vector<MediaResourceParcel> resources2;
251 resources2.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
252 resources2.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300));
Chong Zhangee33d642019-08-08 14:26:43 -0700253 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700254
255 // kTestPid2 mTestClient3
Chong Zhang181e6952019-10-09 13:23:39 -0700256 std::vector<MediaResourceParcel> resources3;
Chong Zhangee33d642019-08-08 14:26:43 -0700257 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
Chong Zhang181e6952019-10-09 13:23:39 -0700258 resources3.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
259 resources3.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
Chong Zhangee33d642019-08-08 14:26:43 -0700260 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700261
262 const PidResourceInfosMap &map = mService->mMap;
263 EXPECT_EQ(2u, map.size());
264 ssize_t index1 = map.indexOfKey(kTestPid1);
265 ASSERT_GE(index1, 0);
266 const ResourceInfos &infos1 = map[index1];
267 EXPECT_EQ(1u, infos1.size());
Chong Zhangfb092d32019-08-12 09:45:44 -0700268 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, resources1);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700269
270 ssize_t index2 = map.indexOfKey(kTestPid2);
271 ASSERT_GE(index2, 0);
272 const ResourceInfos &infos2 = map[index2];
273 EXPECT_EQ(2u, infos2.size());
Chong Zhangfb092d32019-08-12 09:45:44 -0700274 expectEqResourceInfo(infos2.valueFor(getId(mTestClient2)), kTestUid2, mTestClient2, resources2);
275 expectEqResourceInfo(infos2.valueFor(getId(mTestClient3)), kTestUid2, mTestClient3, resources3);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700276 }
277
Chong Zhang181e6952019-10-09 13:23:39 -0700278 void testCombineResourceWithNegativeValues() {
279 // kTestPid1 mTestClient1
280 std::vector<MediaResourceParcel> resources1;
281 resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, -100));
282 resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, -100));
283 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
284
285 // Expected result:
286 // 1) the client should have been added;
287 // 2) both resource entries should have been rejected, resource list should be empty.
288 const PidResourceInfosMap &map = mService->mMap;
289 EXPECT_EQ(1u, map.size());
290 ssize_t index1 = map.indexOfKey(kTestPid1);
291 ASSERT_GE(index1, 0);
292 const ResourceInfos &infos1 = map[index1];
293 EXPECT_EQ(1u, infos1.size());
294 std::vector<MediaResourceParcel> expected;
295 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
296
297 resources1.clear();
298 resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX));
299 resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
300 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
301 resources1.clear();
302 resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, 10));
303 resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 10));
304 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
305
306 // Expected result:
307 // Both values should saturate to INT64_MAX
308 expected.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX));
309 expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
310 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
311
312 resources1.clear();
313 resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, -10));
314 resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, -10));
315 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
316
317 // Expected result:
318 // 1) DrmSession resource should allow negative value addition, and value should drop accordingly
319 // 2) Non-drm session resource should ignore negative value addition.
320 expected.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX - 10));
321 expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
322 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
323
324 resources1.clear();
325 resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MIN));
326 expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MIN));
327 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
328
329 // Expected result:
330 // 1) DrmSession resource value should drop to 0, but the entry shouldn't be removed.
331 // 2) Non-drm session resource should ignore negative value addition.
332 expected.clear();
333 expected.push_back(MediaResource(MediaResource::Type::kDrmSession, 0));
334 expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
335 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
336 }
337
Ronghua Wu231c3d12015-03-11 15:10:32 -0700338 void testConfig() {
339 EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
340 EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
341
Chong Zhang181e6952019-10-09 13:23:39 -0700342 std::vector<MediaResourcePolicyParcel> policies1;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700343 policies1.push_back(
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700344 MediaResourcePolicy(
Chong Zhangfdd512a2019-11-22 11:03:14 -0800345 IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
Chong Zhang181e6952019-10-09 13:23:39 -0700346 "true"));
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700347 policies1.push_back(
348 MediaResourcePolicy(
Chong Zhangfdd512a2019-11-22 11:03:14 -0800349 IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
Chong Zhang181e6952019-10-09 13:23:39 -0700350 "false"));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700351 mService->config(policies1);
352 EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
353 EXPECT_FALSE(mService->mSupportsSecureWithNonSecureCodec);
354
Chong Zhang181e6952019-10-09 13:23:39 -0700355 std::vector<MediaResourcePolicyParcel> policies2;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700356 policies2.push_back(
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700357 MediaResourcePolicy(
Chong Zhangfdd512a2019-11-22 11:03:14 -0800358 IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
Chong Zhang181e6952019-10-09 13:23:39 -0700359 "false"));
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700360 policies2.push_back(
361 MediaResourcePolicy(
Chong Zhangfdd512a2019-11-22 11:03:14 -0800362 IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
Chong Zhang181e6952019-10-09 13:23:39 -0700363 "true"));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700364 mService->config(policies2);
365 EXPECT_FALSE(mService->mSupportsMultipleSecureCodecs);
366 EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
367 }
368
Chong Zhangfb092d32019-08-12 09:45:44 -0700369 void testCombineResource() {
370 // kTestPid1 mTestClient1
Chong Zhang181e6952019-10-09 13:23:39 -0700371 std::vector<MediaResourceParcel> resources1;
372 resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
Chong Zhangfb092d32019-08-12 09:45:44 -0700373 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
374
Chong Zhang181e6952019-10-09 13:23:39 -0700375 std::vector<MediaResourceParcel> resources11;
376 resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
Chong Zhangfb092d32019-08-12 09:45:44 -0700377 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
378
379 const PidResourceInfosMap &map = mService->mMap;
380 EXPECT_EQ(1u, map.size());
381 ssize_t index1 = map.indexOfKey(kTestPid1);
382 ASSERT_GE(index1, 0);
383 const ResourceInfos &infos1 = map[index1];
384 EXPECT_EQ(1u, infos1.size());
385
386 // test adding existing types to combine values
Chong Zhang181e6952019-10-09 13:23:39 -0700387 resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
Chong Zhangfb092d32019-08-12 09:45:44 -0700388 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
389
Chong Zhang181e6952019-10-09 13:23:39 -0700390 std::vector<MediaResourceParcel> expected;
391 expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2));
392 expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300));
Chong Zhangfb092d32019-08-12 09:45:44 -0700393 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
394
395 // test adding new types (including types that differs only in subType)
Chong Zhang181e6952019-10-09 13:23:39 -0700396 resources11.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
397 resources11.push_back(MediaResource(MediaResource::Type::kSecureCodec, MediaResource::SubType::kVideoCodec, 1));
Chong Zhangfb092d32019-08-12 09:45:44 -0700398 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
399
400 expected.clear();
Chong Zhang181e6952019-10-09 13:23:39 -0700401 expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2));
402 expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
403 expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, MediaResource::SubType::kVideoCodec, 1));
404 expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 500));
Chong Zhangfb092d32019-08-12 09:45:44 -0700405 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
406 }
407
Ronghua Wu231c3d12015-03-11 15:10:32 -0700408 void testRemoveResource() {
Chong Zhangfb092d32019-08-12 09:45:44 -0700409 // kTestPid1 mTestClient1
Chong Zhang181e6952019-10-09 13:23:39 -0700410 std::vector<MediaResourceParcel> resources1;
411 resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
Chong Zhangfb092d32019-08-12 09:45:44 -0700412 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
413
Chong Zhang181e6952019-10-09 13:23:39 -0700414 std::vector<MediaResourceParcel> resources11;
415 resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
Chong Zhangfb092d32019-08-12 09:45:44 -0700416 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
417
418 const PidResourceInfosMap &map = mService->mMap;
419 EXPECT_EQ(1u, map.size());
420 ssize_t index1 = map.indexOfKey(kTestPid1);
421 ASSERT_GE(index1, 0);
422 const ResourceInfos &infos1 = map[index1];
423 EXPECT_EQ(1u, infos1.size());
424
425 // test partial removal
Chong Zhang181e6952019-10-09 13:23:39 -0700426 resources11[0].value = 100;
Chong Zhangfb092d32019-08-12 09:45:44 -0700427 mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
428
Chong Zhang181e6952019-10-09 13:23:39 -0700429 std::vector<MediaResourceParcel> expected;
430 expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
431 expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
432 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
433
434 // test removal request with negative value, should be ignored
435 resources11[0].value = -10000;
436 mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
437
Chong Zhangfb092d32019-08-12 09:45:44 -0700438 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
439
440 // test complete removal with overshoot value
Chong Zhang181e6952019-10-09 13:23:39 -0700441 resources11[0].value = 1000;
Chong Zhangfb092d32019-08-12 09:45:44 -0700442 mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
443
444 expected.clear();
Chong Zhang181e6952019-10-09 13:23:39 -0700445 expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
Chong Zhangfb092d32019-08-12 09:45:44 -0700446 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
447 }
448
Henry Fang32762922020-01-28 18:40:39 -0800449 void testOverridePid() {
450
451 bool result;
452 std::vector<MediaResourceParcel> resources;
453 resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
454 resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
455
456 // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
457 {
458 addResource();
459 mService->mSupportsMultipleSecureCodecs = false;
460 mService->mSupportsSecureWithNonSecureCodec = true;
461
462 // priority too low to reclaim resource
463 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
464
465 // override Low Priority Pid with High Priority Pid
466 mService->overridePid(kLowPriorityPid, kHighPriorityPid);
467 CHECK_STATUS_TRUE(mService->reclaimResource(kLowPriorityPid, resources, &result));
468
469 // restore Low Priority Pid
470 mService->overridePid(kLowPriorityPid, -1);
471 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
472 }
473 }
474
Chong Zhangfb092d32019-08-12 09:45:44 -0700475 void testRemoveClient() {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700476 addResource();
477
Chong Zhangfb092d32019-08-12 09:45:44 -0700478 mService->removeClient(kTestPid2, getId(mTestClient2));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700479
480 const PidResourceInfosMap &map = mService->mMap;
481 EXPECT_EQ(2u, map.size());
482 const ResourceInfos &infos1 = map.valueFor(kTestPid1);
483 const ResourceInfos &infos2 = map.valueFor(kTestPid2);
484 EXPECT_EQ(1u, infos1.size());
485 EXPECT_EQ(1u, infos2.size());
486 // mTestClient2 has been removed.
Chong Zhangfb092d32019-08-12 09:45:44 -0700487 // (OK to use infos2[0] as there is only 1 entry)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700488 EXPECT_EQ(mTestClient3, infos2[0].client);
489 }
490
491 void testGetAllClients() {
492 addResource();
493
Chong Zhang181e6952019-10-09 13:23:39 -0700494 MediaResource::Type type = MediaResource::Type::kSecureCodec;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800495 Vector<std::shared_ptr<IResourceManagerClient> > clients;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700496 EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, &clients));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700497 // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
498 // will fail.
Ronghua Wu05d89f12015-07-07 16:47:42 -0700499 EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, &clients));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700500 EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, &clients));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700501
502 EXPECT_EQ(2u, clients.size());
Chong Zhangfb092d32019-08-12 09:45:44 -0700503 // (OK to require ordering in clients[], as the pid map is sorted)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700504 EXPECT_EQ(mTestClient3, clients[0]);
505 EXPECT_EQ(mTestClient1, clients[1]);
506 }
507
508 void testReclaimResourceSecure() {
Chong Zhang181e6952019-10-09 13:23:39 -0700509 bool result;
510 std::vector<MediaResourceParcel> resources;
511 resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
512 resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700513
514 // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
515 {
516 addResource();
517 mService->mSupportsMultipleSecureCodecs = false;
518 mService->mSupportsSecureWithNonSecureCodec = true;
519
520 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700521 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
522 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700523
524 // reclaim all secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700525 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700526 verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700527
528 // call again should reclaim one largest graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700529 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700530 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700531
532 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700533 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700534 }
535
536 // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
537 {
538 addResource();
539 mService->mSupportsMultipleSecureCodecs = false;
540 mService->mSupportsSecureWithNonSecureCodec = false;
541
542 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700543 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
544 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700545
546 // reclaim all secure and non-secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700547 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700548 verifyClients(true /* c1 */, true /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700549
550 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700551 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700552 }
553
554
555 // ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
556 {
557 addResource();
558 mService->mSupportsMultipleSecureCodecs = true;
559 mService->mSupportsSecureWithNonSecureCodec = false;
560
561 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700562 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
563 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700564
565 // reclaim all non-secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700566 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700567 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700568
569 // call again should reclaim one largest graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700570 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700571 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700572
573 // call again should reclaim another largest graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700574 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700575 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700576
577 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700578 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700579 }
580
581 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
582 {
583 addResource();
584 mService->mSupportsMultipleSecureCodecs = true;
585 mService->mSupportsSecureWithNonSecureCodec = true;
586
587 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700588 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700589
Chong Zhang181e6952019-10-09 13:23:39 -0700590 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700591 // one largest graphic memory from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700592 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700593
594 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700595 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700596 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700597
598 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700599 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700600 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700601
602 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700603 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700604 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700605
606 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
607 {
608 addResource();
609 mService->mSupportsMultipleSecureCodecs = true;
610 mService->mSupportsSecureWithNonSecureCodec = true;
611
Chong Zhang181e6952019-10-09 13:23:39 -0700612 std::vector<MediaResourceParcel> resources;
613 resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700614
Chong Zhang181e6952019-10-09 13:23:39 -0700615 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700616 // secure codec from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700617 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700618
619 // call again should reclaim another secure codec from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700620 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700621 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700622
Ronghua Wu05d89f12015-07-07 16:47:42 -0700623 // no more secure codec, non-secure codec will be reclaimed.
Chong Zhang181e6952019-10-09 13:23:39 -0700624 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700625 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700626 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700627 }
628
629 void testReclaimResourceNonSecure() {
Chong Zhang181e6952019-10-09 13:23:39 -0700630 bool result;
631 std::vector<MediaResourceParcel> resources;
632 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
633 resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700634
635 // ### secure codec can't coexist with non-secure codec ###
636 {
637 addResource();
638 mService->mSupportsSecureWithNonSecureCodec = false;
639
640 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700641 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
642 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700643
644 // reclaim all secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700645 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700646 verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700647
648 // call again should reclaim one graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700649 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700650 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700651
652 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700653 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700654 }
655
656
657 // ### secure codec can coexist with non-secure codec ###
658 {
659 addResource();
660 mService->mSupportsSecureWithNonSecureCodec = true;
661
662 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700663 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700664
Chong Zhang181e6952019-10-09 13:23:39 -0700665 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700666 // one largest graphic memory from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700667 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700668
669 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700670 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700671 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700672
673 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700674 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700675 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700676
677 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700678 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700679 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700680
681 // ### secure codec can coexist with non-secure codec ###
682 {
683 addResource();
684 mService->mSupportsSecureWithNonSecureCodec = true;
685
Chong Zhang181e6952019-10-09 13:23:39 -0700686 std::vector<MediaResourceParcel> resources;
687 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700688
Chong Zhang181e6952019-10-09 13:23:39 -0700689 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700690 // one non secure codec from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700691 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700692
Ronghua Wu05d89f12015-07-07 16:47:42 -0700693 // no more non-secure codec, secure codec from lowest priority process will be reclaimed
Chong Zhang181e6952019-10-09 13:23:39 -0700694 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700695 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700696
Ronghua Wu05d89f12015-07-07 16:47:42 -0700697 // clean up client 3 which still left
Chong Zhangfb092d32019-08-12 09:45:44 -0700698 mService->removeClient(kTestPid2, getId(mTestClient3));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700699 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700700 }
701
702 void testGetLowestPriorityBiggestClient() {
Chong Zhang181e6952019-10-09 13:23:39 -0700703 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800704 std::shared_ptr<IResourceManagerClient> client;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700705 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700706
707 addResource();
708
Ronghua Wu05d89f12015-07-07 16:47:42 -0700709 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, &client));
710 EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700711
Chong Zhang181e6952019-10-09 13:23:39 -0700712 // kTestPid1 is the lowest priority process with MediaResource::Type::kGraphicMemory.
713 // mTestClient1 has the largest MediaResource::Type::kGraphicMemory within kTestPid1.
Ronghua Wu231c3d12015-03-11 15:10:32 -0700714 EXPECT_EQ(mTestClient1, client);
715 }
716
717 void testGetLowestPriorityPid() {
718 int pid;
719 int priority;
720 TestProcessInfo processInfo;
721
Chong Zhang181e6952019-10-09 13:23:39 -0700722 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700723 EXPECT_FALSE(mService->getLowestPriorityPid_l(type, &pid, &priority));
724
725 addResource();
726
727 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
728 EXPECT_EQ(kTestPid1, pid);
729 int priority1;
730 processInfo.getPriority(kTestPid1, &priority1);
731 EXPECT_EQ(priority1, priority);
732
Chong Zhang181e6952019-10-09 13:23:39 -0700733 type = MediaResource::Type::kNonSecureCodec;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700734 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
735 EXPECT_EQ(kTestPid2, pid);
736 int priority2;
737 processInfo.getPriority(kTestPid2, &priority2);
738 EXPECT_EQ(priority2, priority);
739 }
740
741 void testGetBiggestClient() {
Chong Zhang181e6952019-10-09 13:23:39 -0700742 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800743 std::shared_ptr<IResourceManagerClient> client;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700744 EXPECT_FALSE(mService->getBiggestClient_l(kTestPid2, type, &client));
745
746 addResource();
747
748 EXPECT_TRUE(mService->getBiggestClient_l(kTestPid2, type, &client));
749 EXPECT_EQ(mTestClient2, client);
750 }
751
752 void testIsCallingPriorityHigher() {
753 EXPECT_FALSE(mService->isCallingPriorityHigher_l(101, 100));
754 EXPECT_FALSE(mService->isCallingPriorityHigher_l(100, 100));
755 EXPECT_TRUE(mService->isCallingPriorityHigher_l(99, 100));
756 }
757
Chong Zhangdd726802019-08-21 17:24:13 -0700758 void testBatteryStats() {
759 // reset should always be called when ResourceManagerService is created (restarted)
760 EXPECT_EQ(1u, mSystemCB->eventCount());
761 EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType());
762
763 // new client request should cause VIDEO_ON
Chong Zhang181e6952019-10-09 13:23:39 -0700764 std::vector<MediaResourceParcel> resources1;
765 resources1.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 1));
Chong Zhangdd726802019-08-21 17:24:13 -0700766 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
767 EXPECT_EQ(2u, mSystemCB->eventCount());
768 EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid1}), mSystemCB->lastEvent());
769
770 // each client should only cause 1 VIDEO_ON
771 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
772 EXPECT_EQ(2u, mSystemCB->eventCount());
773
774 // new client request should cause VIDEO_ON
Chong Zhang181e6952019-10-09 13:23:39 -0700775 std::vector<MediaResourceParcel> resources2;
776 resources2.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 2));
Chong Zhangdd726802019-08-21 17:24:13 -0700777 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
778 EXPECT_EQ(3u, mSystemCB->eventCount());
779 EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid2}), mSystemCB->lastEvent());
780
781 // partially remove mTestClient1's request, shouldn't be any VIDEO_OFF
782 mService->removeResource(kTestPid1, getId(mTestClient1), resources1);
783 EXPECT_EQ(3u, mSystemCB->eventCount());
784
785 // remove mTestClient1's request, should be VIDEO_OFF for kTestUid1
786 // (use resource2 to test removing more instances than previously requested)
787 mService->removeResource(kTestPid1, getId(mTestClient1), resources2);
788 EXPECT_EQ(4u, mSystemCB->eventCount());
789 EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid1}), mSystemCB->lastEvent());
790
791 // remove mTestClient2, should be VIDEO_OFF for kTestUid2
792 mService->removeClient(kTestPid2, getId(mTestClient2));
793 EXPECT_EQ(5u, mSystemCB->eventCount());
794 EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid2}), mSystemCB->lastEvent());
795 }
796
797 void testCpusetBoost() {
798 // reset should always be called when ResourceManagerService is created (restarted)
799 EXPECT_EQ(1u, mSystemCB->eventCount());
800 EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType());
801
802 // new client request should cause CPUSET_ENABLE
Chong Zhang181e6952019-10-09 13:23:39 -0700803 std::vector<MediaResourceParcel> resources1;
804 resources1.push_back(MediaResource(MediaResource::Type::kCpuBoost, 1));
Chong Zhangdd726802019-08-21 17:24:13 -0700805 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
806 EXPECT_EQ(2u, mSystemCB->eventCount());
807 EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
808
809 // each client should only cause 1 CPUSET_ENABLE
810 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
811 EXPECT_EQ(2u, mSystemCB->eventCount());
812
813 // new client request should cause CPUSET_ENABLE
Chong Zhang181e6952019-10-09 13:23:39 -0700814 std::vector<MediaResourceParcel> resources2;
815 resources2.push_back(MediaResource(MediaResource::Type::kCpuBoost, 2));
Chong Zhangdd726802019-08-21 17:24:13 -0700816 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
817 EXPECT_EQ(3u, mSystemCB->eventCount());
818 EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
819
820 // remove mTestClient2 should not cause CPUSET_DISABLE, mTestClient1 still active
821 mService->removeClient(kTestPid2, getId(mTestClient2));
822 EXPECT_EQ(3u, mSystemCB->eventCount());
823
824 // remove 1 cpuboost from mTestClient1, should not be CPUSET_DISABLE (still 1 left)
825 mService->removeResource(kTestPid1, getId(mTestClient1), resources1);
826 EXPECT_EQ(3u, mSystemCB->eventCount());
827
828 // remove 2 cpuboost from mTestClient1, should be CPUSET_DISABLE
829 // (use resource2 to test removing more than previously requested)
830 mService->removeResource(kTestPid1, getId(mTestClient1), resources2);
831 EXPECT_EQ(4u, mSystemCB->eventCount());
832 EXPECT_EQ(EventType::CPUSET_DISABLE, mSystemCB->lastEventType());
833 }
834
835 sp<TestSystemCallback> mSystemCB;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800836 std::shared_ptr<ResourceManagerService> mService;
837 std::shared_ptr<IResourceManagerClient> mTestClient1;
838 std::shared_ptr<IResourceManagerClient> mTestClient2;
839 std::shared_ptr<IResourceManagerClient> mTestClient3;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700840};
841
842TEST_F(ResourceManagerServiceTest, config) {
843 testConfig();
844}
845
846TEST_F(ResourceManagerServiceTest, addResource) {
847 addResource();
848}
849
Chong Zhangfb092d32019-08-12 09:45:44 -0700850TEST_F(ResourceManagerServiceTest, combineResource) {
851 testCombineResource();
852}
853
Chong Zhang181e6952019-10-09 13:23:39 -0700854TEST_F(ResourceManagerServiceTest, combineResourceNegative) {
855 testCombineResourceWithNegativeValues();
856}
857
Ronghua Wu231c3d12015-03-11 15:10:32 -0700858TEST_F(ResourceManagerServiceTest, removeResource) {
859 testRemoveResource();
860}
861
Chong Zhangfb092d32019-08-12 09:45:44 -0700862TEST_F(ResourceManagerServiceTest, removeClient) {
863 testRemoveClient();
864}
865
Ronghua Wu231c3d12015-03-11 15:10:32 -0700866TEST_F(ResourceManagerServiceTest, reclaimResource) {
867 testReclaimResourceSecure();
868 testReclaimResourceNonSecure();
869}
870
871TEST_F(ResourceManagerServiceTest, getAllClients_l) {
872 testGetAllClients();
873}
874
875TEST_F(ResourceManagerServiceTest, getLowestPriorityBiggestClient_l) {
876 testGetLowestPriorityBiggestClient();
877}
878
879TEST_F(ResourceManagerServiceTest, getLowestPriorityPid_l) {
880 testGetLowestPriorityPid();
881}
882
883TEST_F(ResourceManagerServiceTest, getBiggestClient_l) {
884 testGetBiggestClient();
885}
886
887TEST_F(ResourceManagerServiceTest, isCallingPriorityHigher_l) {
888 testIsCallingPriorityHigher();
889}
890
Chong Zhangdd726802019-08-21 17:24:13 -0700891TEST_F(ResourceManagerServiceTest, testBatteryStats) {
892 testBatteryStats();
893}
894
895TEST_F(ResourceManagerServiceTest, testCpusetBoost) {
896 testCpusetBoost();
897}
898
Henry Fang32762922020-01-28 18:40:39 -0800899TEST_F(ResourceManagerServiceTest, overridePid) {
900 testOverridePid();
901}
902
Ronghua Wu231c3d12015-03-11 15:10:32 -0700903} // namespace android