blob: a6ecc09effbc4084671436a7ca9c9303a8f5f0c6 [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 }
Wonsik Kimcf325ba2020-10-01 10:12:56 -0700523
524 {
525 addResource();
526 mService->mSupportsSecureWithNonSecureCodec = true;
527
528 mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
529
530 // client marked for pending removal got reclaimed
531 EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk());
532 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
533
534 // No more clients marked for removal
535 EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk());
536 verifyClients(false /* c1 */, false /* c2 */, false /* c3 */);
537
538 mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient3));
539
540 // client marked for pending removal got reclaimed
541 EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk());
542 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
543
544 // clean up client 1 which still left
545 mService->removeClient(kTestPid1, getId(mTestClient1));
546 }
Wonsik Kimd20e9362020-04-28 10:42:57 -0700547 }
548
Chong Zhangfb092d32019-08-12 09:45:44 -0700549 void testRemoveClient() {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700550 addResource();
551
Chong Zhangfb092d32019-08-12 09:45:44 -0700552 mService->removeClient(kTestPid2, getId(mTestClient2));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700553
554 const PidResourceInfosMap &map = mService->mMap;
555 EXPECT_EQ(2u, map.size());
556 const ResourceInfos &infos1 = map.valueFor(kTestPid1);
557 const ResourceInfos &infos2 = map.valueFor(kTestPid2);
558 EXPECT_EQ(1u, infos1.size());
559 EXPECT_EQ(1u, infos2.size());
560 // mTestClient2 has been removed.
Chong Zhangfb092d32019-08-12 09:45:44 -0700561 // (OK to use infos2[0] as there is only 1 entry)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700562 EXPECT_EQ(mTestClient3, infos2[0].client);
563 }
564
565 void testGetAllClients() {
566 addResource();
567
Chong Zhang181e6952019-10-09 13:23:39 -0700568 MediaResource::Type type = MediaResource::Type::kSecureCodec;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800569 Vector<std::shared_ptr<IResourceManagerClient> > clients;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700570 EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, &clients));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700571 // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
572 // will fail.
Ronghua Wu05d89f12015-07-07 16:47:42 -0700573 EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, &clients));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700574 EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, &clients));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700575
576 EXPECT_EQ(2u, clients.size());
Chong Zhangfb092d32019-08-12 09:45:44 -0700577 // (OK to require ordering in clients[], as the pid map is sorted)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700578 EXPECT_EQ(mTestClient3, clients[0]);
579 EXPECT_EQ(mTestClient1, clients[1]);
580 }
581
582 void testReclaimResourceSecure() {
Chong Zhang181e6952019-10-09 13:23:39 -0700583 bool result;
584 std::vector<MediaResourceParcel> resources;
585 resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
586 resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700587
588 // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
589 {
590 addResource();
591 mService->mSupportsMultipleSecureCodecs = false;
592 mService->mSupportsSecureWithNonSecureCodec = true;
593
594 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700595 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
596 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700597
598 // reclaim all secure codecs
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(true /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700601
602 // call again should reclaim one largest graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700603 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700604 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700605
606 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700607 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700608 }
609
610 // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
611 {
612 addResource();
613 mService->mSupportsMultipleSecureCodecs = false;
614 mService->mSupportsSecureWithNonSecureCodec = false;
615
616 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700617 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
618 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700619
620 // reclaim all secure and non-secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700621 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700622 verifyClients(true /* c1 */, true /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700623
624 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700625 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700626 }
627
628
629 // ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
630 {
631 addResource();
632 mService->mSupportsMultipleSecureCodecs = true;
633 mService->mSupportsSecureWithNonSecureCodec = false;
634
635 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700636 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
637 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700638
639 // reclaim all non-secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700640 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700641 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700642
643 // call again should reclaim one largest graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700644 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700645 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700646
647 // call again should reclaim another largest graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700648 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700649 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700650
651 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700652 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700653 }
654
655 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
656 {
657 addResource();
658 mService->mSupportsMultipleSecureCodecs = true;
659 mService->mSupportsSecureWithNonSecureCodec = true;
660
661 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700662 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700663
Chong Zhang181e6952019-10-09 13:23:39 -0700664 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700665 // one largest graphic memory from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700666 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700667
668 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700669 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700670 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700671
672 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700673 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700674 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700675
676 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700677 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700678 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700679
680 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
681 {
682 addResource();
683 mService->mSupportsMultipleSecureCodecs = true;
684 mService->mSupportsSecureWithNonSecureCodec = true;
685
Chong Zhang181e6952019-10-09 13:23:39 -0700686 std::vector<MediaResourceParcel> resources;
687 resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 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 // secure codec from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700691 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700692
693 // call again should reclaim another secure codec from lowest process
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(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700696
Ronghua Wu05d89f12015-07-07 16:47:42 -0700697 // no more secure codec, non-secure codec will be reclaimed.
Chong Zhang181e6952019-10-09 13:23:39 -0700698 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700699 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700700 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700701 }
702
703 void testReclaimResourceNonSecure() {
Chong Zhang181e6952019-10-09 13:23:39 -0700704 bool result;
705 std::vector<MediaResourceParcel> resources;
706 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
707 resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700708
709 // ### secure codec can't coexist with non-secure codec ###
710 {
711 addResource();
712 mService->mSupportsSecureWithNonSecureCodec = false;
713
714 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700715 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
716 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700717
718 // reclaim all secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700719 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700720 verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700721
722 // call again should reclaim one graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700723 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700724 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700725
726 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700727 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700728 }
729
730
731 // ### secure codec can coexist with non-secure codec ###
732 {
733 addResource();
734 mService->mSupportsSecureWithNonSecureCodec = true;
735
736 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700737 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700738
Chong Zhang181e6952019-10-09 13:23:39 -0700739 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700740 // one largest graphic memory from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700741 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700742
743 // call again should reclaim another graphic memory from lowest process
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(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700746
747 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700748 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700749 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700750
751 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700752 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700753 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700754
755 // ### secure codec can coexist with non-secure codec ###
756 {
757 addResource();
758 mService->mSupportsSecureWithNonSecureCodec = true;
759
Chong Zhang181e6952019-10-09 13:23:39 -0700760 std::vector<MediaResourceParcel> resources;
761 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700762
Chong Zhang181e6952019-10-09 13:23:39 -0700763 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700764 // one non secure codec from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700765 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700766
Ronghua Wu05d89f12015-07-07 16:47:42 -0700767 // no more non-secure codec, secure codec from lowest priority process will be reclaimed
Chong Zhang181e6952019-10-09 13:23:39 -0700768 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700769 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700770
Ronghua Wu05d89f12015-07-07 16:47:42 -0700771 // clean up client 3 which still left
Chong Zhangfb092d32019-08-12 09:45:44 -0700772 mService->removeClient(kTestPid2, getId(mTestClient3));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700773 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700774 }
775
776 void testGetLowestPriorityBiggestClient() {
Chong Zhang181e6952019-10-09 13:23:39 -0700777 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800778 std::shared_ptr<IResourceManagerClient> client;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700779 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700780
781 addResource();
782
Ronghua Wu05d89f12015-07-07 16:47:42 -0700783 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, &client));
784 EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700785
Chong Zhang181e6952019-10-09 13:23:39 -0700786 // kTestPid1 is the lowest priority process with MediaResource::Type::kGraphicMemory.
787 // mTestClient1 has the largest MediaResource::Type::kGraphicMemory within kTestPid1.
Ronghua Wu231c3d12015-03-11 15:10:32 -0700788 EXPECT_EQ(mTestClient1, client);
789 }
790
791 void testGetLowestPriorityPid() {
792 int pid;
793 int priority;
794 TestProcessInfo processInfo;
795
Chong Zhang181e6952019-10-09 13:23:39 -0700796 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700797 EXPECT_FALSE(mService->getLowestPriorityPid_l(type, &pid, &priority));
798
799 addResource();
800
801 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
802 EXPECT_EQ(kTestPid1, pid);
803 int priority1;
804 processInfo.getPriority(kTestPid1, &priority1);
805 EXPECT_EQ(priority1, priority);
806
Chong Zhang181e6952019-10-09 13:23:39 -0700807 type = MediaResource::Type::kNonSecureCodec;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700808 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
809 EXPECT_EQ(kTestPid2, pid);
810 int priority2;
811 processInfo.getPriority(kTestPid2, &priority2);
812 EXPECT_EQ(priority2, priority);
813 }
814
815 void testGetBiggestClient() {
Chong Zhang181e6952019-10-09 13:23:39 -0700816 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800817 std::shared_ptr<IResourceManagerClient> client;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700818 EXPECT_FALSE(mService->getBiggestClient_l(kTestPid2, type, &client));
819
820 addResource();
821
822 EXPECT_TRUE(mService->getBiggestClient_l(kTestPid2, type, &client));
823 EXPECT_EQ(mTestClient2, client);
824 }
825
826 void testIsCallingPriorityHigher() {
827 EXPECT_FALSE(mService->isCallingPriorityHigher_l(101, 100));
828 EXPECT_FALSE(mService->isCallingPriorityHigher_l(100, 100));
829 EXPECT_TRUE(mService->isCallingPriorityHigher_l(99, 100));
830 }
831
Chong Zhangdd726802019-08-21 17:24:13 -0700832 void testBatteryStats() {
833 // reset should always be called when ResourceManagerService is created (restarted)
834 EXPECT_EQ(1u, mSystemCB->eventCount());
835 EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType());
836
837 // new client request should cause VIDEO_ON
Chong Zhang181e6952019-10-09 13:23:39 -0700838 std::vector<MediaResourceParcel> resources1;
839 resources1.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 1));
Chong Zhangdd726802019-08-21 17:24:13 -0700840 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
841 EXPECT_EQ(2u, mSystemCB->eventCount());
842 EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid1}), mSystemCB->lastEvent());
843
844 // each client should only cause 1 VIDEO_ON
845 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
846 EXPECT_EQ(2u, mSystemCB->eventCount());
847
848 // new client request should cause VIDEO_ON
Chong Zhang181e6952019-10-09 13:23:39 -0700849 std::vector<MediaResourceParcel> resources2;
850 resources2.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 2));
Chong Zhangdd726802019-08-21 17:24:13 -0700851 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
852 EXPECT_EQ(3u, mSystemCB->eventCount());
853 EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid2}), mSystemCB->lastEvent());
854
855 // partially remove mTestClient1's request, shouldn't be any VIDEO_OFF
856 mService->removeResource(kTestPid1, getId(mTestClient1), resources1);
857 EXPECT_EQ(3u, mSystemCB->eventCount());
858
859 // remove mTestClient1's request, should be VIDEO_OFF for kTestUid1
860 // (use resource2 to test removing more instances than previously requested)
861 mService->removeResource(kTestPid1, getId(mTestClient1), resources2);
862 EXPECT_EQ(4u, mSystemCB->eventCount());
863 EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid1}), mSystemCB->lastEvent());
864
865 // remove mTestClient2, should be VIDEO_OFF for kTestUid2
866 mService->removeClient(kTestPid2, getId(mTestClient2));
867 EXPECT_EQ(5u, mSystemCB->eventCount());
868 EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid2}), mSystemCB->lastEvent());
869 }
870
871 void testCpusetBoost() {
872 // reset should always be called when ResourceManagerService is created (restarted)
873 EXPECT_EQ(1u, mSystemCB->eventCount());
874 EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType());
875
876 // new client request should cause CPUSET_ENABLE
Chong Zhang181e6952019-10-09 13:23:39 -0700877 std::vector<MediaResourceParcel> resources1;
878 resources1.push_back(MediaResource(MediaResource::Type::kCpuBoost, 1));
Chong Zhangdd726802019-08-21 17:24:13 -0700879 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
880 EXPECT_EQ(2u, mSystemCB->eventCount());
881 EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
882
883 // each client should only cause 1 CPUSET_ENABLE
884 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
885 EXPECT_EQ(2u, mSystemCB->eventCount());
886
887 // new client request should cause CPUSET_ENABLE
Chong Zhang181e6952019-10-09 13:23:39 -0700888 std::vector<MediaResourceParcel> resources2;
889 resources2.push_back(MediaResource(MediaResource::Type::kCpuBoost, 2));
Chong Zhangdd726802019-08-21 17:24:13 -0700890 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
891 EXPECT_EQ(3u, mSystemCB->eventCount());
892 EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
893
894 // remove mTestClient2 should not cause CPUSET_DISABLE, mTestClient1 still active
895 mService->removeClient(kTestPid2, getId(mTestClient2));
896 EXPECT_EQ(3u, mSystemCB->eventCount());
897
898 // remove 1 cpuboost from mTestClient1, should not be CPUSET_DISABLE (still 1 left)
899 mService->removeResource(kTestPid1, getId(mTestClient1), resources1);
900 EXPECT_EQ(3u, mSystemCB->eventCount());
901
902 // remove 2 cpuboost from mTestClient1, should be CPUSET_DISABLE
903 // (use resource2 to test removing more than previously requested)
904 mService->removeResource(kTestPid1, getId(mTestClient1), resources2);
905 EXPECT_EQ(4u, mSystemCB->eventCount());
906 EXPECT_EQ(EventType::CPUSET_DISABLE, mSystemCB->lastEventType());
907 }
908
909 sp<TestSystemCallback> mSystemCB;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800910 std::shared_ptr<ResourceManagerService> mService;
911 std::shared_ptr<IResourceManagerClient> mTestClient1;
912 std::shared_ptr<IResourceManagerClient> mTestClient2;
913 std::shared_ptr<IResourceManagerClient> mTestClient3;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700914};
915
916TEST_F(ResourceManagerServiceTest, config) {
917 testConfig();
918}
919
920TEST_F(ResourceManagerServiceTest, addResource) {
921 addResource();
922}
923
Chong Zhangfb092d32019-08-12 09:45:44 -0700924TEST_F(ResourceManagerServiceTest, combineResource) {
925 testCombineResource();
926}
927
Chong Zhang181e6952019-10-09 13:23:39 -0700928TEST_F(ResourceManagerServiceTest, combineResourceNegative) {
929 testCombineResourceWithNegativeValues();
930}
931
Ronghua Wu231c3d12015-03-11 15:10:32 -0700932TEST_F(ResourceManagerServiceTest, removeResource) {
933 testRemoveResource();
934}
935
Chong Zhangfb092d32019-08-12 09:45:44 -0700936TEST_F(ResourceManagerServiceTest, removeClient) {
937 testRemoveClient();
938}
939
Ronghua Wu231c3d12015-03-11 15:10:32 -0700940TEST_F(ResourceManagerServiceTest, reclaimResource) {
941 testReclaimResourceSecure();
942 testReclaimResourceNonSecure();
943}
944
945TEST_F(ResourceManagerServiceTest, getAllClients_l) {
946 testGetAllClients();
947}
948
949TEST_F(ResourceManagerServiceTest, getLowestPriorityBiggestClient_l) {
950 testGetLowestPriorityBiggestClient();
951}
952
953TEST_F(ResourceManagerServiceTest, getLowestPriorityPid_l) {
954 testGetLowestPriorityPid();
955}
956
957TEST_F(ResourceManagerServiceTest, getBiggestClient_l) {
958 testGetBiggestClient();
959}
960
961TEST_F(ResourceManagerServiceTest, isCallingPriorityHigher_l) {
962 testIsCallingPriorityHigher();
963}
964
Chong Zhangdd726802019-08-21 17:24:13 -0700965TEST_F(ResourceManagerServiceTest, testBatteryStats) {
966 testBatteryStats();
967}
968
969TEST_F(ResourceManagerServiceTest, testCpusetBoost) {
970 testCpusetBoost();
971}
972
Henry Fang32762922020-01-28 18:40:39 -0800973TEST_F(ResourceManagerServiceTest, overridePid) {
974 testOverridePid();
975}
976
Wonsik Kimd20e9362020-04-28 10:42:57 -0700977TEST_F(ResourceManagerServiceTest, markClientForPendingRemoval) {
978 testMarkClientForPendingRemoval();
979}
980
Ronghua Wu231c3d12015-03-11 15:10:32 -0700981} // namespace android