blob: 702935d25b30de50abb669fef6632e6f899c7604 [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
Wonsik Kimd20e9362020-04-28 10:42:57 -0700475 void testMarkClientForPendingRemoval() {
476 bool result;
477
478 {
479 addResource();
480 mService->mSupportsSecureWithNonSecureCodec = true;
481
482 std::vector<MediaResourceParcel> resources;
483 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
484
485 // Remove low priority clients
486 mService->removeClient(kTestPid1, getId(mTestClient1));
487
488 // no lower priority client
489 CHECK_STATUS_FALSE(mService->reclaimResource(kTestPid2, resources, &result));
490 verifyClients(false /* c1 */, false /* c2 */, false /* c3 */);
491
492 mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
493
494 // client marked for pending removal from the same process got reclaimed
495 CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
496 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
497
498 // clean up client 3 which still left
499 mService->removeClient(kTestPid2, getId(mTestClient3));
500 }
501
502 {
503 addResource();
504 mService->mSupportsSecureWithNonSecureCodec = true;
505
506 std::vector<MediaResourceParcel> resources;
507 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
508
509 mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
510
511 // client marked for pending removal from the same process got reclaimed
512 // first, even though there are lower priority process
513 CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
514 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
515
516 // lower priority client got reclaimed
517 CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
518 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
519
520 // clean up client 3 which still left
521 mService->removeClient(kTestPid2, getId(mTestClient3));
522 }
523 }
524
Chong Zhangfb092d32019-08-12 09:45:44 -0700525 void testRemoveClient() {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700526 addResource();
527
Chong Zhangfb092d32019-08-12 09:45:44 -0700528 mService->removeClient(kTestPid2, getId(mTestClient2));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700529
530 const PidResourceInfosMap &map = mService->mMap;
531 EXPECT_EQ(2u, map.size());
532 const ResourceInfos &infos1 = map.valueFor(kTestPid1);
533 const ResourceInfos &infos2 = map.valueFor(kTestPid2);
534 EXPECT_EQ(1u, infos1.size());
535 EXPECT_EQ(1u, infos2.size());
536 // mTestClient2 has been removed.
Chong Zhangfb092d32019-08-12 09:45:44 -0700537 // (OK to use infos2[0] as there is only 1 entry)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700538 EXPECT_EQ(mTestClient3, infos2[0].client);
539 }
540
541 void testGetAllClients() {
542 addResource();
543
Chong Zhang181e6952019-10-09 13:23:39 -0700544 MediaResource::Type type = MediaResource::Type::kSecureCodec;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800545 Vector<std::shared_ptr<IResourceManagerClient> > clients;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700546 EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, &clients));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700547 // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
548 // will fail.
Ronghua Wu05d89f12015-07-07 16:47:42 -0700549 EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, &clients));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700550 EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, &clients));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700551
552 EXPECT_EQ(2u, clients.size());
Chong Zhangfb092d32019-08-12 09:45:44 -0700553 // (OK to require ordering in clients[], as the pid map is sorted)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700554 EXPECT_EQ(mTestClient3, clients[0]);
555 EXPECT_EQ(mTestClient1, clients[1]);
556 }
557
558 void testReclaimResourceSecure() {
Chong Zhang181e6952019-10-09 13:23:39 -0700559 bool result;
560 std::vector<MediaResourceParcel> resources;
561 resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
562 resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700563
564 // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
565 {
566 addResource();
567 mService->mSupportsMultipleSecureCodecs = false;
568 mService->mSupportsSecureWithNonSecureCodec = true;
569
570 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700571 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
572 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700573
574 // reclaim all secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700575 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700576 verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700577
578 // call again should reclaim one largest graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700579 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700580 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700581
582 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700583 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700584 }
585
586 // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
587 {
588 addResource();
589 mService->mSupportsMultipleSecureCodecs = false;
590 mService->mSupportsSecureWithNonSecureCodec = false;
591
592 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700593 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
594 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700595
596 // reclaim all secure and non-secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700597 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700598 verifyClients(true /* c1 */, true /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700599
600 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700601 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700602 }
603
604
605 // ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
606 {
607 addResource();
608 mService->mSupportsMultipleSecureCodecs = true;
609 mService->mSupportsSecureWithNonSecureCodec = false;
610
611 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700612 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
613 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700614
615 // reclaim all non-secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700616 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700617 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700618
619 // call again should reclaim one largest graphic memory 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(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700622
623 // call again should reclaim another largest graphic memory from lowest process
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 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700626
627 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700628 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700629 }
630
631 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
632 {
633 addResource();
634 mService->mSupportsMultipleSecureCodecs = true;
635 mService->mSupportsSecureWithNonSecureCodec = true;
636
637 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700638 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700639
Chong Zhang181e6952019-10-09 13:23:39 -0700640 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700641 // one largest graphic memory from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700642 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700643
644 // call again should reclaim another graphic memory from lowest process
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(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700647
648 // call again should reclaim another 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 */, false /* c2 */, true /* 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 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700655
656 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
657 {
658 addResource();
659 mService->mSupportsMultipleSecureCodecs = true;
660 mService->mSupportsSecureWithNonSecureCodec = true;
661
Chong Zhang181e6952019-10-09 13:23:39 -0700662 std::vector<MediaResourceParcel> resources;
663 resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700664
Chong Zhang181e6952019-10-09 13:23:39 -0700665 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700666 // secure codec from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700667 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700668
669 // call again should reclaim another secure codec 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 */, false /* c2 */, true /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700672
Ronghua Wu05d89f12015-07-07 16:47:42 -0700673 // no more secure codec, non-secure codec will be reclaimed.
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 */, true /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700676 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700677 }
678
679 void testReclaimResourceNonSecure() {
Chong Zhang181e6952019-10-09 13:23:39 -0700680 bool result;
681 std::vector<MediaResourceParcel> resources;
682 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
683 resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700684
685 // ### secure codec can't coexist with non-secure codec ###
686 {
687 addResource();
688 mService->mSupportsSecureWithNonSecureCodec = false;
689
690 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700691 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
692 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700693
694 // reclaim all secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700695 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700696 verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700697
698 // call again should reclaim one graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700699 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700700 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700701
702 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700703 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700704 }
705
706
707 // ### secure codec can coexist with non-secure codec ###
708 {
709 addResource();
710 mService->mSupportsSecureWithNonSecureCodec = true;
711
712 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700713 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700714
Chong Zhang181e6952019-10-09 13:23:39 -0700715 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700716 // one largest graphic memory from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700717 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700718
719 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700720 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700721 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700722
723 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700724 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700725 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700726
727 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700728 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700729 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700730
731 // ### secure codec can coexist with non-secure codec ###
732 {
733 addResource();
734 mService->mSupportsSecureWithNonSecureCodec = true;
735
Chong Zhang181e6952019-10-09 13:23:39 -0700736 std::vector<MediaResourceParcel> resources;
737 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700738
Chong Zhang181e6952019-10-09 13:23:39 -0700739 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700740 // one non secure codec from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700741 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700742
Ronghua Wu05d89f12015-07-07 16:47:42 -0700743 // no more non-secure codec, secure codec from lowest priority process will be reclaimed
Chong Zhang181e6952019-10-09 13:23:39 -0700744 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700745 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700746
Ronghua Wu05d89f12015-07-07 16:47:42 -0700747 // clean up client 3 which still left
Chong Zhangfb092d32019-08-12 09:45:44 -0700748 mService->removeClient(kTestPid2, getId(mTestClient3));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700749 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700750 }
751
752 void testGetLowestPriorityBiggestClient() {
Chong Zhang181e6952019-10-09 13:23:39 -0700753 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800754 std::shared_ptr<IResourceManagerClient> client;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700755 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700756
757 addResource();
758
Ronghua Wu05d89f12015-07-07 16:47:42 -0700759 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, &client));
760 EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700761
Chong Zhang181e6952019-10-09 13:23:39 -0700762 // kTestPid1 is the lowest priority process with MediaResource::Type::kGraphicMemory.
763 // mTestClient1 has the largest MediaResource::Type::kGraphicMemory within kTestPid1.
Ronghua Wu231c3d12015-03-11 15:10:32 -0700764 EXPECT_EQ(mTestClient1, client);
765 }
766
767 void testGetLowestPriorityPid() {
768 int pid;
769 int priority;
770 TestProcessInfo processInfo;
771
Chong Zhang181e6952019-10-09 13:23:39 -0700772 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700773 EXPECT_FALSE(mService->getLowestPriorityPid_l(type, &pid, &priority));
774
775 addResource();
776
777 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
778 EXPECT_EQ(kTestPid1, pid);
779 int priority1;
780 processInfo.getPriority(kTestPid1, &priority1);
781 EXPECT_EQ(priority1, priority);
782
Chong Zhang181e6952019-10-09 13:23:39 -0700783 type = MediaResource::Type::kNonSecureCodec;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700784 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
785 EXPECT_EQ(kTestPid2, pid);
786 int priority2;
787 processInfo.getPriority(kTestPid2, &priority2);
788 EXPECT_EQ(priority2, priority);
789 }
790
791 void testGetBiggestClient() {
Chong Zhang181e6952019-10-09 13:23:39 -0700792 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800793 std::shared_ptr<IResourceManagerClient> client;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700794 EXPECT_FALSE(mService->getBiggestClient_l(kTestPid2, type, &client));
795
796 addResource();
797
798 EXPECT_TRUE(mService->getBiggestClient_l(kTestPid2, type, &client));
799 EXPECT_EQ(mTestClient2, client);
800 }
801
802 void testIsCallingPriorityHigher() {
803 EXPECT_FALSE(mService->isCallingPriorityHigher_l(101, 100));
804 EXPECT_FALSE(mService->isCallingPriorityHigher_l(100, 100));
805 EXPECT_TRUE(mService->isCallingPriorityHigher_l(99, 100));
806 }
807
Chong Zhangdd726802019-08-21 17:24:13 -0700808 void testBatteryStats() {
809 // reset should always be called when ResourceManagerService is created (restarted)
810 EXPECT_EQ(1u, mSystemCB->eventCount());
811 EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType());
812
813 // new client request should cause VIDEO_ON
Chong Zhang181e6952019-10-09 13:23:39 -0700814 std::vector<MediaResourceParcel> resources1;
815 resources1.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 1));
Chong Zhangdd726802019-08-21 17:24:13 -0700816 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
817 EXPECT_EQ(2u, mSystemCB->eventCount());
818 EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid1}), mSystemCB->lastEvent());
819
820 // each client should only cause 1 VIDEO_ON
821 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
822 EXPECT_EQ(2u, mSystemCB->eventCount());
823
824 // new client request should cause VIDEO_ON
Chong Zhang181e6952019-10-09 13:23:39 -0700825 std::vector<MediaResourceParcel> resources2;
826 resources2.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 2));
Chong Zhangdd726802019-08-21 17:24:13 -0700827 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
828 EXPECT_EQ(3u, mSystemCB->eventCount());
829 EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid2}), mSystemCB->lastEvent());
830
831 // partially remove mTestClient1's request, shouldn't be any VIDEO_OFF
832 mService->removeResource(kTestPid1, getId(mTestClient1), resources1);
833 EXPECT_EQ(3u, mSystemCB->eventCount());
834
835 // remove mTestClient1's request, should be VIDEO_OFF for kTestUid1
836 // (use resource2 to test removing more instances than previously requested)
837 mService->removeResource(kTestPid1, getId(mTestClient1), resources2);
838 EXPECT_EQ(4u, mSystemCB->eventCount());
839 EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid1}), mSystemCB->lastEvent());
840
841 // remove mTestClient2, should be VIDEO_OFF for kTestUid2
842 mService->removeClient(kTestPid2, getId(mTestClient2));
843 EXPECT_EQ(5u, mSystemCB->eventCount());
844 EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid2}), mSystemCB->lastEvent());
845 }
846
847 void testCpusetBoost() {
848 // reset should always be called when ResourceManagerService is created (restarted)
849 EXPECT_EQ(1u, mSystemCB->eventCount());
850 EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType());
851
852 // new client request should cause CPUSET_ENABLE
Chong Zhang181e6952019-10-09 13:23:39 -0700853 std::vector<MediaResourceParcel> resources1;
854 resources1.push_back(MediaResource(MediaResource::Type::kCpuBoost, 1));
Chong Zhangdd726802019-08-21 17:24:13 -0700855 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
856 EXPECT_EQ(2u, mSystemCB->eventCount());
857 EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
858
859 // each client should only cause 1 CPUSET_ENABLE
860 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
861 EXPECT_EQ(2u, mSystemCB->eventCount());
862
863 // new client request should cause CPUSET_ENABLE
Chong Zhang181e6952019-10-09 13:23:39 -0700864 std::vector<MediaResourceParcel> resources2;
865 resources2.push_back(MediaResource(MediaResource::Type::kCpuBoost, 2));
Chong Zhangdd726802019-08-21 17:24:13 -0700866 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
867 EXPECT_EQ(3u, mSystemCB->eventCount());
868 EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
869
870 // remove mTestClient2 should not cause CPUSET_DISABLE, mTestClient1 still active
871 mService->removeClient(kTestPid2, getId(mTestClient2));
872 EXPECT_EQ(3u, mSystemCB->eventCount());
873
874 // remove 1 cpuboost from mTestClient1, should not be CPUSET_DISABLE (still 1 left)
875 mService->removeResource(kTestPid1, getId(mTestClient1), resources1);
876 EXPECT_EQ(3u, mSystemCB->eventCount());
877
878 // remove 2 cpuboost from mTestClient1, should be CPUSET_DISABLE
879 // (use resource2 to test removing more than previously requested)
880 mService->removeResource(kTestPid1, getId(mTestClient1), resources2);
881 EXPECT_EQ(4u, mSystemCB->eventCount());
882 EXPECT_EQ(EventType::CPUSET_DISABLE, mSystemCB->lastEventType());
883 }
884
885 sp<TestSystemCallback> mSystemCB;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800886 std::shared_ptr<ResourceManagerService> mService;
887 std::shared_ptr<IResourceManagerClient> mTestClient1;
888 std::shared_ptr<IResourceManagerClient> mTestClient2;
889 std::shared_ptr<IResourceManagerClient> mTestClient3;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700890};
891
892TEST_F(ResourceManagerServiceTest, config) {
893 testConfig();
894}
895
896TEST_F(ResourceManagerServiceTest, addResource) {
897 addResource();
898}
899
Chong Zhangfb092d32019-08-12 09:45:44 -0700900TEST_F(ResourceManagerServiceTest, combineResource) {
901 testCombineResource();
902}
903
Chong Zhang181e6952019-10-09 13:23:39 -0700904TEST_F(ResourceManagerServiceTest, combineResourceNegative) {
905 testCombineResourceWithNegativeValues();
906}
907
Ronghua Wu231c3d12015-03-11 15:10:32 -0700908TEST_F(ResourceManagerServiceTest, removeResource) {
909 testRemoveResource();
910}
911
Chong Zhangfb092d32019-08-12 09:45:44 -0700912TEST_F(ResourceManagerServiceTest, removeClient) {
913 testRemoveClient();
914}
915
Ronghua Wu231c3d12015-03-11 15:10:32 -0700916TEST_F(ResourceManagerServiceTest, reclaimResource) {
917 testReclaimResourceSecure();
918 testReclaimResourceNonSecure();
919}
920
921TEST_F(ResourceManagerServiceTest, getAllClients_l) {
922 testGetAllClients();
923}
924
925TEST_F(ResourceManagerServiceTest, getLowestPriorityBiggestClient_l) {
926 testGetLowestPriorityBiggestClient();
927}
928
929TEST_F(ResourceManagerServiceTest, getLowestPriorityPid_l) {
930 testGetLowestPriorityPid();
931}
932
933TEST_F(ResourceManagerServiceTest, getBiggestClient_l) {
934 testGetBiggestClient();
935}
936
937TEST_F(ResourceManagerServiceTest, isCallingPriorityHigher_l) {
938 testIsCallingPriorityHigher();
939}
940
Chong Zhangdd726802019-08-21 17:24:13 -0700941TEST_F(ResourceManagerServiceTest, testBatteryStats) {
942 testBatteryStats();
943}
944
945TEST_F(ResourceManagerServiceTest, testCpusetBoost) {
946 testCpusetBoost();
947}
948
Henry Fang32762922020-01-28 18:40:39 -0800949TEST_F(ResourceManagerServiceTest, overridePid) {
950 testOverridePid();
951}
952
Wonsik Kimd20e9362020-04-28 10:42:57 -0700953TEST_F(ResourceManagerServiceTest, markClientForPendingRemoval) {
954 testMarkClientForPendingRemoval();
955}
956
Ronghua Wu231c3d12015-03-11 15:10:32 -0700957} // namespace android