blob: 3a45dcf88f3324d0216d31a337b7078011beacdc [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 android {
Ronghua Wu231c3d12015-03-11 15:10:32 -070031
Chong Zhangfdd512a2019-11-22 11:03:14 -080032using Status = ::ndk::ScopedAStatus;
33using ::aidl::android::media::BnResourceManagerClient;
34using ::aidl::android::media::IResourceManagerService;
35using ::aidl::android::media::IResourceManagerClient;
36
37static int64_t getId(const std::shared_ptr<IResourceManagerClient>& client) {
Ronghua Wu37c89242015-07-15 12:23:48 -070038 return (int64_t) client.get();
39}
40
Ronghua Wu231c3d12015-03-11 15:10:32 -070041struct TestProcessInfo : public ProcessInfoInterface {
42 TestProcessInfo() {}
43 virtual ~TestProcessInfo() {}
44
45 virtual bool getPriority(int pid, int *priority) {
46 // For testing, use pid as priority.
47 // Lower the value higher the priority.
48 *priority = pid;
49 return true;
50 }
51
Ronghua Wud11c43a2016-01-27 16:26:12 -080052 virtual bool isValidPid(int /* pid */) {
53 return true;
54 }
55
Ronghua Wu231c3d12015-03-11 15:10:32 -070056private:
57 DISALLOW_EVIL_CONSTRUCTORS(TestProcessInfo);
58};
59
Chong Zhangdd726802019-08-21 17:24:13 -070060struct TestSystemCallback :
61 public ResourceManagerService::SystemCallbackInterface {
62 TestSystemCallback() :
63 mLastEvent({EventType::INVALID, 0}), mEventCount(0) {}
64
65 enum EventType {
66 INVALID = -1,
67 VIDEO_ON = 0,
68 VIDEO_OFF = 1,
69 VIDEO_RESET = 2,
70 CPUSET_ENABLE = 3,
71 CPUSET_DISABLE = 4,
72 };
73
74 struct EventEntry {
75 EventType type;
76 int arg;
77 };
78
79 virtual void noteStartVideo(int uid) override {
80 mLastEvent = {EventType::VIDEO_ON, uid};
81 mEventCount++;
82 }
83
84 virtual void noteStopVideo(int uid) override {
85 mLastEvent = {EventType::VIDEO_OFF, uid};
86 mEventCount++;
87 }
88
89 virtual void noteResetVideo() override {
90 mLastEvent = {EventType::VIDEO_RESET, 0};
91 mEventCount++;
92 }
93
Chong Zhangfdd512a2019-11-22 11:03:14 -080094 virtual bool requestCpusetBoost(bool enable) override {
Chong Zhangdd726802019-08-21 17:24:13 -070095 mLastEvent = {enable ? EventType::CPUSET_ENABLE : EventType::CPUSET_DISABLE, 0};
96 mEventCount++;
97 return true;
98 }
99
100 size_t eventCount() { return mEventCount; }
101 EventType lastEventType() { return mLastEvent.type; }
102 EventEntry lastEvent() { return mLastEvent; }
103
104protected:
105 virtual ~TestSystemCallback() {}
106
107private:
108 EventEntry mLastEvent;
109 size_t mEventCount;
110
111 DISALLOW_EVIL_CONSTRUCTORS(TestSystemCallback);
112};
113
114
Ronghua Wu231c3d12015-03-11 15:10:32 -0700115struct TestClient : public BnResourceManagerClient {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800116 TestClient(int pid, const std::shared_ptr<ResourceManagerService> &service)
Ronghua Wu37c89242015-07-15 12:23:48 -0700117 : mReclaimed(false), mPid(pid), mService(service) {}
Ronghua Wu231c3d12015-03-11 15:10:32 -0700118
Chong Zhang181e6952019-10-09 13:23:39 -0700119 Status reclaimResource(bool* _aidl_return) override {
Chong Zhangfdd512a2019-11-22 11:03:14 -0800120 mService->removeClient(mPid, getId(ref<TestClient>()));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700121 mReclaimed = true;
Chong Zhang181e6952019-10-09 13:23:39 -0700122 *_aidl_return = true;
123 return Status::ok();
Ronghua Wu231c3d12015-03-11 15:10:32 -0700124 }
125
Chong Zhang181e6952019-10-09 13:23:39 -0700126 Status getName(::std::string* _aidl_return) override {
127 *_aidl_return = "test_client";
128 return Status::ok();
Ronghua Wu8f9dd872015-04-23 15:24:25 -0700129 }
130
Ronghua Wu231c3d12015-03-11 15:10:32 -0700131 bool reclaimed() const {
132 return mReclaimed;
133 }
134
135 void reset() {
136 mReclaimed = false;
137 }
138
Ronghua Wu231c3d12015-03-11 15:10:32 -0700139 virtual ~TestClient() {}
140
141private:
142 bool mReclaimed;
Ronghua Wu37c89242015-07-15 12:23:48 -0700143 int mPid;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800144 std::shared_ptr<ResourceManagerService> mService;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700145 DISALLOW_EVIL_CONSTRUCTORS(TestClient);
146};
147
148static const int kTestPid1 = 30;
Chong Zhangee33d642019-08-08 14:26:43 -0700149static const int kTestUid1 = 1010;
150
Ronghua Wu231c3d12015-03-11 15:10:32 -0700151static const int kTestPid2 = 20;
Chong Zhangee33d642019-08-08 14:26:43 -0700152static const int kTestUid2 = 1011;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700153
Ronghua Wu05d89f12015-07-07 16:47:42 -0700154static const int kLowPriorityPid = 40;
155static const int kMidPriorityPid = 25;
156static const int kHighPriorityPid = 10;
157
Chong Zhangdd726802019-08-21 17:24:13 -0700158using EventType = TestSystemCallback::EventType;
159using EventEntry = TestSystemCallback::EventEntry;
160bool operator== (const EventEntry& lhs, const EventEntry& rhs) {
161 return lhs.type == rhs.type && lhs.arg == rhs.arg;
162}
163
Chong Zhang181e6952019-10-09 13:23:39 -0700164#define CHECK_STATUS_TRUE(condition) \
165 EXPECT_TRUE((condition).isOk() && (result))
166
167#define CHECK_STATUS_FALSE(condition) \
168 EXPECT_TRUE((condition).isOk() && !(result))
169
Ronghua Wu231c3d12015-03-11 15:10:32 -0700170class ResourceManagerServiceTest : public ::testing::Test {
171public:
172 ResourceManagerServiceTest()
Chong Zhangdd726802019-08-21 17:24:13 -0700173 : mSystemCB(new TestSystemCallback()),
Chong Zhangfdd512a2019-11-22 11:03:14 -0800174 mService(::ndk::SharedRefBase::make<ResourceManagerService>(
175 new TestProcessInfo, mSystemCB)),
176 mTestClient1(::ndk::SharedRefBase::make<TestClient>(kTestPid1, mService)),
177 mTestClient2(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)),
178 mTestClient3(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700179 }
180
181protected:
Chong Zhang181e6952019-10-09 13:23:39 -0700182 static bool isEqualResources(const std::vector<MediaResourceParcel> &resources1,
Chong Zhangfb092d32019-08-12 09:45:44 -0700183 const ResourceList &resources2) {
184 // convert resource1 to ResourceList
185 ResourceList r1;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700186 for (size_t i = 0; i < resources1.size(); ++i) {
Robert Shihc3af31b2019-09-20 21:45:01 -0700187 const auto &res = resources1[i];
Chong Zhang181e6952019-10-09 13:23:39 -0700188 const auto resType = std::tuple(res.type, res.subType, res.id);
Robert Shihc3af31b2019-09-20 21:45:01 -0700189 r1[resType] = res;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700190 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700191 return r1 == resources2;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700192 }
193
Chong Zhangee33d642019-08-08 14:26:43 -0700194 static void expectEqResourceInfo(const ResourceInfo &info,
195 int uid,
Chong Zhangfdd512a2019-11-22 11:03:14 -0800196 std::shared_ptr<IResourceManagerClient> client,
Chong Zhang181e6952019-10-09 13:23:39 -0700197 const std::vector<MediaResourceParcel> &resources) {
Chong Zhangee33d642019-08-08 14:26:43 -0700198 EXPECT_EQ(uid, info.uid);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700199 EXPECT_EQ(client, info.client);
200 EXPECT_TRUE(isEqualResources(resources, info.resources));
201 }
202
203 void verifyClients(bool c1, bool c2, bool c3) {
204 TestClient *client1 = static_cast<TestClient*>(mTestClient1.get());
205 TestClient *client2 = static_cast<TestClient*>(mTestClient2.get());
206 TestClient *client3 = static_cast<TestClient*>(mTestClient3.get());
207
208 EXPECT_EQ(c1, client1->reclaimed());
209 EXPECT_EQ(c2, client2->reclaimed());
210 EXPECT_EQ(c3, client3->reclaimed());
211
212 client1->reset();
213 client2->reset();
214 client3->reset();
215 }
216
Ronghua Wu67e7f542015-03-13 10:47:08 -0700217 // test set up
218 // ---------------------------------------------------------------------------------
219 // pid priority client type number
220 // ---------------------------------------------------------------------------------
221 // kTestPid1(30) 30 mTestClient1 secure codec 1
222 // graphic memory 200
223 // graphic memory 200
224 // ---------------------------------------------------------------------------------
225 // kTestPid2(20) 20 mTestClient2 non-secure codec 1
226 // graphic memory 300
227 // -------------------------------------------
228 // mTestClient3 secure codec 1
229 // graphic memory 100
230 // ---------------------------------------------------------------------------------
Ronghua Wu231c3d12015-03-11 15:10:32 -0700231 void addResource() {
232 // kTestPid1 mTestClient1
Chong Zhang181e6952019-10-09 13:23:39 -0700233 std::vector<MediaResourceParcel> resources1;
234 resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
Chong Zhangee33d642019-08-08 14:26:43 -0700235 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
Chong Zhang181e6952019-10-09 13:23:39 -0700236 resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
237 std::vector<MediaResourceParcel> resources11;
238 resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
Chong Zhangee33d642019-08-08 14:26:43 -0700239 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700240
241 // kTestPid2 mTestClient2
Chong Zhang181e6952019-10-09 13:23:39 -0700242 std::vector<MediaResourceParcel> resources2;
243 resources2.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
244 resources2.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300));
Chong Zhangee33d642019-08-08 14:26:43 -0700245 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700246
247 // kTestPid2 mTestClient3
Chong Zhang181e6952019-10-09 13:23:39 -0700248 std::vector<MediaResourceParcel> resources3;
Chong Zhangee33d642019-08-08 14:26:43 -0700249 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
Chong Zhang181e6952019-10-09 13:23:39 -0700250 resources3.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
251 resources3.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
Chong Zhangee33d642019-08-08 14:26:43 -0700252 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700253
254 const PidResourceInfosMap &map = mService->mMap;
255 EXPECT_EQ(2u, map.size());
256 ssize_t index1 = map.indexOfKey(kTestPid1);
257 ASSERT_GE(index1, 0);
258 const ResourceInfos &infos1 = map[index1];
259 EXPECT_EQ(1u, infos1.size());
Chong Zhangfb092d32019-08-12 09:45:44 -0700260 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, resources1);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700261
262 ssize_t index2 = map.indexOfKey(kTestPid2);
263 ASSERT_GE(index2, 0);
264 const ResourceInfos &infos2 = map[index2];
265 EXPECT_EQ(2u, infos2.size());
Chong Zhangfb092d32019-08-12 09:45:44 -0700266 expectEqResourceInfo(infos2.valueFor(getId(mTestClient2)), kTestUid2, mTestClient2, resources2);
267 expectEqResourceInfo(infos2.valueFor(getId(mTestClient3)), kTestUid2, mTestClient3, resources3);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700268 }
269
Chong Zhang181e6952019-10-09 13:23:39 -0700270 void testCombineResourceWithNegativeValues() {
271 // kTestPid1 mTestClient1
272 std::vector<MediaResourceParcel> resources1;
273 resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, -100));
274 resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, -100));
275 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
276
277 // Expected result:
278 // 1) the client should have been added;
279 // 2) both resource entries should have been rejected, resource list should be empty.
280 const PidResourceInfosMap &map = mService->mMap;
281 EXPECT_EQ(1u, map.size());
282 ssize_t index1 = map.indexOfKey(kTestPid1);
283 ASSERT_GE(index1, 0);
284 const ResourceInfos &infos1 = map[index1];
285 EXPECT_EQ(1u, infos1.size());
286 std::vector<MediaResourceParcel> expected;
287 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
288
289 resources1.clear();
290 resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX));
291 resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
292 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
293 resources1.clear();
294 resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, 10));
295 resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 10));
296 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
297
298 // Expected result:
299 // Both values should saturate to INT64_MAX
300 expected.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX));
301 expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
302 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
303
304 resources1.clear();
305 resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, -10));
306 resources1.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, -10));
307 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
308
309 // Expected result:
310 // 1) DrmSession resource should allow negative value addition, and value should drop accordingly
311 // 2) Non-drm session resource should ignore negative value addition.
312 expected.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MAX - 10));
313 expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
314 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
315
316 resources1.clear();
317 resources1.push_back(MediaResource(MediaResource::Type::kDrmSession, INT64_MIN));
318 expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MIN));
319 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
320
321 // Expected result:
322 // 1) DrmSession resource value should drop to 0, but the entry shouldn't be removed.
323 // 2) Non-drm session resource should ignore negative value addition.
324 expected.clear();
325 expected.push_back(MediaResource(MediaResource::Type::kDrmSession, 0));
326 expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, INT64_MAX));
327 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
328 }
329
Ronghua Wu231c3d12015-03-11 15:10:32 -0700330 void testConfig() {
331 EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
332 EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
333
Chong Zhang181e6952019-10-09 13:23:39 -0700334 std::vector<MediaResourcePolicyParcel> policies1;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700335 policies1.push_back(
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700336 MediaResourcePolicy(
Chong Zhangfdd512a2019-11-22 11:03:14 -0800337 IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
Chong Zhang181e6952019-10-09 13:23:39 -0700338 "true"));
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700339 policies1.push_back(
340 MediaResourcePolicy(
Chong Zhangfdd512a2019-11-22 11:03:14 -0800341 IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
Chong Zhang181e6952019-10-09 13:23:39 -0700342 "false"));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700343 mService->config(policies1);
344 EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
345 EXPECT_FALSE(mService->mSupportsSecureWithNonSecureCodec);
346
Chong Zhang181e6952019-10-09 13:23:39 -0700347 std::vector<MediaResourcePolicyParcel> policies2;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700348 policies2.push_back(
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700349 MediaResourcePolicy(
Chong Zhangfdd512a2019-11-22 11:03:14 -0800350 IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
Chong Zhang181e6952019-10-09 13:23:39 -0700351 "false"));
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700352 policies2.push_back(
353 MediaResourcePolicy(
Chong Zhangfdd512a2019-11-22 11:03:14 -0800354 IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
Chong Zhang181e6952019-10-09 13:23:39 -0700355 "true"));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700356 mService->config(policies2);
357 EXPECT_FALSE(mService->mSupportsMultipleSecureCodecs);
358 EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
359 }
360
Chong Zhangfb092d32019-08-12 09:45:44 -0700361 void testCombineResource() {
362 // kTestPid1 mTestClient1
Chong Zhang181e6952019-10-09 13:23:39 -0700363 std::vector<MediaResourceParcel> resources1;
364 resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
Chong Zhangfb092d32019-08-12 09:45:44 -0700365 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
366
Chong Zhang181e6952019-10-09 13:23:39 -0700367 std::vector<MediaResourceParcel> resources11;
368 resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
Chong Zhangfb092d32019-08-12 09:45:44 -0700369 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
370
371 const PidResourceInfosMap &map = mService->mMap;
372 EXPECT_EQ(1u, map.size());
373 ssize_t index1 = map.indexOfKey(kTestPid1);
374 ASSERT_GE(index1, 0);
375 const ResourceInfos &infos1 = map[index1];
376 EXPECT_EQ(1u, infos1.size());
377
378 // test adding existing types to combine values
Chong Zhang181e6952019-10-09 13:23:39 -0700379 resources1.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
Chong Zhangfb092d32019-08-12 09:45:44 -0700380 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
381
Chong Zhang181e6952019-10-09 13:23:39 -0700382 std::vector<MediaResourceParcel> expected;
383 expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2));
384 expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 300));
Chong Zhangfb092d32019-08-12 09:45:44 -0700385 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
386
387 // test adding new types (including types that differs only in subType)
Chong Zhang181e6952019-10-09 13:23:39 -0700388 resources11.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
389 resources11.push_back(MediaResource(MediaResource::Type::kSecureCodec, MediaResource::SubType::kVideoCodec, 1));
Chong Zhangfb092d32019-08-12 09:45:44 -0700390 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
391
392 expected.clear();
Chong Zhang181e6952019-10-09 13:23:39 -0700393 expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 2));
394 expected.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
395 expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, MediaResource::SubType::kVideoCodec, 1));
396 expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 500));
Chong Zhangfb092d32019-08-12 09:45:44 -0700397 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
398 }
399
Ronghua Wu231c3d12015-03-11 15:10:32 -0700400 void testRemoveResource() {
Chong Zhangfb092d32019-08-12 09:45:44 -0700401 // kTestPid1 mTestClient1
Chong Zhang181e6952019-10-09 13:23:39 -0700402 std::vector<MediaResourceParcel> resources1;
403 resources1.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
Chong Zhangfb092d32019-08-12 09:45:44 -0700404 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
405
Chong Zhang181e6952019-10-09 13:23:39 -0700406 std::vector<MediaResourceParcel> resources11;
407 resources11.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 200));
Chong Zhangfb092d32019-08-12 09:45:44 -0700408 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
409
410 const PidResourceInfosMap &map = mService->mMap;
411 EXPECT_EQ(1u, map.size());
412 ssize_t index1 = map.indexOfKey(kTestPid1);
413 ASSERT_GE(index1, 0);
414 const ResourceInfos &infos1 = map[index1];
415 EXPECT_EQ(1u, infos1.size());
416
417 // test partial removal
Chong Zhang181e6952019-10-09 13:23:39 -0700418 resources11[0].value = 100;
Chong Zhangfb092d32019-08-12 09:45:44 -0700419 mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
420
Chong Zhang181e6952019-10-09 13:23:39 -0700421 std::vector<MediaResourceParcel> expected;
422 expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
423 expected.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 100));
424 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
425
426 // test removal request with negative value, should be ignored
427 resources11[0].value = -10000;
428 mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
429
Chong Zhangfb092d32019-08-12 09:45:44 -0700430 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
431
432 // test complete removal with overshoot value
Chong Zhang181e6952019-10-09 13:23:39 -0700433 resources11[0].value = 1000;
Chong Zhangfb092d32019-08-12 09:45:44 -0700434 mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
435
436 expected.clear();
Chong Zhang181e6952019-10-09 13:23:39 -0700437 expected.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
Chong Zhangfb092d32019-08-12 09:45:44 -0700438 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
439 }
440
Henry Fang32762922020-01-28 18:40:39 -0800441 void testOverridePid() {
442
443 bool result;
444 std::vector<MediaResourceParcel> resources;
445 resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
446 resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
447
448 // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
449 {
450 addResource();
451 mService->mSupportsMultipleSecureCodecs = false;
452 mService->mSupportsSecureWithNonSecureCodec = true;
453
454 // priority too low to reclaim resource
455 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
456
457 // override Low Priority Pid with High Priority Pid
458 mService->overridePid(kLowPriorityPid, kHighPriorityPid);
459 CHECK_STATUS_TRUE(mService->reclaimResource(kLowPriorityPid, resources, &result));
460
461 // restore Low Priority Pid
462 mService->overridePid(kLowPriorityPid, -1);
463 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
464 }
465 }
466
Wonsik Kimd20e9362020-04-28 10:42:57 -0700467 void testMarkClientForPendingRemoval() {
468 bool result;
469
470 {
471 addResource();
472 mService->mSupportsSecureWithNonSecureCodec = true;
473
474 std::vector<MediaResourceParcel> resources;
475 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
476
477 // Remove low priority clients
478 mService->removeClient(kTestPid1, getId(mTestClient1));
479
480 // no lower priority client
481 CHECK_STATUS_FALSE(mService->reclaimResource(kTestPid2, resources, &result));
482 verifyClients(false /* c1 */, false /* c2 */, false /* c3 */);
483
484 mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
485
486 // client marked for pending removal from the same process got reclaimed
487 CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
488 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
489
490 // clean up client 3 which still left
491 mService->removeClient(kTestPid2, getId(mTestClient3));
492 }
493
494 {
495 addResource();
496 mService->mSupportsSecureWithNonSecureCodec = true;
497
498 std::vector<MediaResourceParcel> resources;
499 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
500
501 mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
502
503 // client marked for pending removal from the same process got reclaimed
504 // first, even though there are lower priority process
505 CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
506 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
507
508 // lower priority client got reclaimed
509 CHECK_STATUS_TRUE(mService->reclaimResource(kTestPid2, resources, &result));
510 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
511
512 // clean up client 3 which still left
513 mService->removeClient(kTestPid2, getId(mTestClient3));
514 }
Wonsik Kim271429d2020-10-01 10:12:56 -0700515
516 {
517 addResource();
518 mService->mSupportsSecureWithNonSecureCodec = true;
519
520 mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient2));
521
522 // client marked for pending removal got reclaimed
523 EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk());
524 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
525
526 // No more clients marked for removal
527 EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk());
528 verifyClients(false /* c1 */, false /* c2 */, false /* c3 */);
529
530 mService->markClientForPendingRemoval(kTestPid2, getId(mTestClient3));
531
532 // client marked for pending removal got reclaimed
533 EXPECT_TRUE(mService->reclaimResourcesFromClientsPendingRemoval(kTestPid2).isOk());
534 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
535
536 // clean up client 1 which still left
537 mService->removeClient(kTestPid1, getId(mTestClient1));
538 }
Wonsik Kimd20e9362020-04-28 10:42:57 -0700539 }
540
Chong Zhangfb092d32019-08-12 09:45:44 -0700541 void testRemoveClient() {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700542 addResource();
543
Chong Zhangfb092d32019-08-12 09:45:44 -0700544 mService->removeClient(kTestPid2, getId(mTestClient2));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700545
546 const PidResourceInfosMap &map = mService->mMap;
547 EXPECT_EQ(2u, map.size());
548 const ResourceInfos &infos1 = map.valueFor(kTestPid1);
549 const ResourceInfos &infos2 = map.valueFor(kTestPid2);
550 EXPECT_EQ(1u, infos1.size());
551 EXPECT_EQ(1u, infos2.size());
552 // mTestClient2 has been removed.
Chong Zhangfb092d32019-08-12 09:45:44 -0700553 // (OK to use infos2[0] as there is only 1 entry)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700554 EXPECT_EQ(mTestClient3, infos2[0].client);
555 }
556
557 void testGetAllClients() {
558 addResource();
559
Chong Zhang181e6952019-10-09 13:23:39 -0700560 MediaResource::Type type = MediaResource::Type::kSecureCodec;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800561 Vector<std::shared_ptr<IResourceManagerClient> > clients;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700562 EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, &clients));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700563 // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
564 // will fail.
Ronghua Wu05d89f12015-07-07 16:47:42 -0700565 EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, &clients));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700566 EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, &clients));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700567
568 EXPECT_EQ(2u, clients.size());
Chong Zhangfb092d32019-08-12 09:45:44 -0700569 // (OK to require ordering in clients[], as the pid map is sorted)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700570 EXPECT_EQ(mTestClient3, clients[0]);
571 EXPECT_EQ(mTestClient1, clients[1]);
572 }
573
574 void testReclaimResourceSecure() {
Chong Zhang181e6952019-10-09 13:23:39 -0700575 bool result;
576 std::vector<MediaResourceParcel> resources;
577 resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
578 resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700579
580 // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
581 {
582 addResource();
583 mService->mSupportsMultipleSecureCodecs = false;
584 mService->mSupportsSecureWithNonSecureCodec = true;
585
586 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700587 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
588 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700589
590 // reclaim all secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700591 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700592 verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700593
594 // call again should reclaim one largest graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700595 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700596 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700597
598 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700599 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700600 }
601
602 // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
603 {
604 addResource();
605 mService->mSupportsMultipleSecureCodecs = false;
606 mService->mSupportsSecureWithNonSecureCodec = false;
607
608 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700609 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
610 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700611
612 // reclaim all secure and non-secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700613 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700614 verifyClients(true /* c1 */, true /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700615
616 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700617 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700618 }
619
620
621 // ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
622 {
623 addResource();
624 mService->mSupportsMultipleSecureCodecs = true;
625 mService->mSupportsSecureWithNonSecureCodec = false;
626
627 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700628 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
629 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700630
631 // reclaim all non-secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700632 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700633 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700634
635 // call again should reclaim one largest graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700636 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700637 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700638
639 // call again should reclaim another largest graphic memory from lowest process
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 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700642
643 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700644 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700645 }
646
647 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
648 {
649 addResource();
650 mService->mSupportsMultipleSecureCodecs = true;
651 mService->mSupportsSecureWithNonSecureCodec = true;
652
653 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700654 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700655
Chong Zhang181e6952019-10-09 13:23:39 -0700656 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700657 // one largest graphic memory from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700658 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700659
660 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700661 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700662 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700663
664 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700665 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700666 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700667
668 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700669 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700670 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700671
672 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
673 {
674 addResource();
675 mService->mSupportsMultipleSecureCodecs = true;
676 mService->mSupportsSecureWithNonSecureCodec = true;
677
Chong Zhang181e6952019-10-09 13:23:39 -0700678 std::vector<MediaResourceParcel> resources;
679 resources.push_back(MediaResource(MediaResource::Type::kSecureCodec, 1));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700680
Chong Zhang181e6952019-10-09 13:23:39 -0700681 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700682 // secure codec from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700683 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700684
685 // call again should reclaim another secure codec from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700686 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700687 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700688
Ronghua Wu05d89f12015-07-07 16:47:42 -0700689 // no more secure codec, non-secure codec will be reclaimed.
Chong Zhang181e6952019-10-09 13:23:39 -0700690 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700691 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700692 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700693 }
694
695 void testReclaimResourceNonSecure() {
Chong Zhang181e6952019-10-09 13:23:39 -0700696 bool result;
697 std::vector<MediaResourceParcel> resources;
698 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
699 resources.push_back(MediaResource(MediaResource::Type::kGraphicMemory, 150));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700700
701 // ### secure codec can't coexist with non-secure codec ###
702 {
703 addResource();
704 mService->mSupportsSecureWithNonSecureCodec = false;
705
706 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700707 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
708 CHECK_STATUS_FALSE(mService->reclaimResource(kMidPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700709
710 // reclaim all secure codecs
Chong Zhang181e6952019-10-09 13:23:39 -0700711 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700712 verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700713
714 // call again should reclaim one graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700715 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700716 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700717
718 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700719 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700720 }
721
722
723 // ### secure codec can coexist with non-secure codec ###
724 {
725 addResource();
726 mService->mSupportsSecureWithNonSecureCodec = true;
727
728 // priority too low
Chong Zhang181e6952019-10-09 13:23:39 -0700729 CHECK_STATUS_FALSE(mService->reclaimResource(kLowPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700730
Chong Zhang181e6952019-10-09 13:23:39 -0700731 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700732 // one largest graphic memory from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700733 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700734
735 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700736 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700737 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700738
739 // call again should reclaim another graphic memory from lowest process
Chong Zhang181e6952019-10-09 13:23:39 -0700740 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700741 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700742
743 // nothing left
Chong Zhang181e6952019-10-09 13:23:39 -0700744 CHECK_STATUS_FALSE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700745 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700746
747 // ### secure codec can coexist with non-secure codec ###
748 {
749 addResource();
750 mService->mSupportsSecureWithNonSecureCodec = true;
751
Chong Zhang181e6952019-10-09 13:23:39 -0700752 std::vector<MediaResourceParcel> resources;
753 resources.push_back(MediaResource(MediaResource::Type::kNonSecureCodec, 1));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700754
Chong Zhang181e6952019-10-09 13:23:39 -0700755 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700756 // one non secure codec from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700757 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700758
Ronghua Wu05d89f12015-07-07 16:47:42 -0700759 // no more non-secure codec, secure codec from lowest priority process will be reclaimed
Chong Zhang181e6952019-10-09 13:23:39 -0700760 CHECK_STATUS_TRUE(mService->reclaimResource(kHighPriorityPid, resources, &result));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700761 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700762
Ronghua Wu05d89f12015-07-07 16:47:42 -0700763 // clean up client 3 which still left
Chong Zhangfb092d32019-08-12 09:45:44 -0700764 mService->removeClient(kTestPid2, getId(mTestClient3));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700765 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700766 }
767
768 void testGetLowestPriorityBiggestClient() {
Chong Zhang181e6952019-10-09 13:23:39 -0700769 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800770 std::shared_ptr<IResourceManagerClient> client;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700771 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700772
773 addResource();
774
Ronghua Wu05d89f12015-07-07 16:47:42 -0700775 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, &client));
776 EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700777
Chong Zhang181e6952019-10-09 13:23:39 -0700778 // kTestPid1 is the lowest priority process with MediaResource::Type::kGraphicMemory.
779 // mTestClient1 has the largest MediaResource::Type::kGraphicMemory within kTestPid1.
Ronghua Wu231c3d12015-03-11 15:10:32 -0700780 EXPECT_EQ(mTestClient1, client);
781 }
782
783 void testGetLowestPriorityPid() {
784 int pid;
785 int priority;
786 TestProcessInfo processInfo;
787
Chong Zhang181e6952019-10-09 13:23:39 -0700788 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700789 EXPECT_FALSE(mService->getLowestPriorityPid_l(type, &pid, &priority));
790
791 addResource();
792
793 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
794 EXPECT_EQ(kTestPid1, pid);
795 int priority1;
796 processInfo.getPriority(kTestPid1, &priority1);
797 EXPECT_EQ(priority1, priority);
798
Chong Zhang181e6952019-10-09 13:23:39 -0700799 type = MediaResource::Type::kNonSecureCodec;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700800 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
801 EXPECT_EQ(kTestPid2, pid);
802 int priority2;
803 processInfo.getPriority(kTestPid2, &priority2);
804 EXPECT_EQ(priority2, priority);
805 }
806
807 void testGetBiggestClient() {
Chong Zhang181e6952019-10-09 13:23:39 -0700808 MediaResource::Type type = MediaResource::Type::kGraphicMemory;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800809 std::shared_ptr<IResourceManagerClient> client;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700810 EXPECT_FALSE(mService->getBiggestClient_l(kTestPid2, type, &client));
811
812 addResource();
813
814 EXPECT_TRUE(mService->getBiggestClient_l(kTestPid2, type, &client));
815 EXPECT_EQ(mTestClient2, client);
816 }
817
818 void testIsCallingPriorityHigher() {
819 EXPECT_FALSE(mService->isCallingPriorityHigher_l(101, 100));
820 EXPECT_FALSE(mService->isCallingPriorityHigher_l(100, 100));
821 EXPECT_TRUE(mService->isCallingPriorityHigher_l(99, 100));
822 }
823
Chong Zhangdd726802019-08-21 17:24:13 -0700824 void testBatteryStats() {
825 // reset should always be called when ResourceManagerService is created (restarted)
826 EXPECT_EQ(1u, mSystemCB->eventCount());
827 EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType());
828
829 // new client request should cause VIDEO_ON
Chong Zhang181e6952019-10-09 13:23:39 -0700830 std::vector<MediaResourceParcel> resources1;
831 resources1.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 1));
Chong Zhangdd726802019-08-21 17:24:13 -0700832 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
833 EXPECT_EQ(2u, mSystemCB->eventCount());
834 EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid1}), mSystemCB->lastEvent());
835
836 // each client should only cause 1 VIDEO_ON
837 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
838 EXPECT_EQ(2u, mSystemCB->eventCount());
839
840 // new client request should cause VIDEO_ON
Chong Zhang181e6952019-10-09 13:23:39 -0700841 std::vector<MediaResourceParcel> resources2;
842 resources2.push_back(MediaResource(MediaResource::Type::kBattery, MediaResource::SubType::kVideoCodec, 2));
Chong Zhangdd726802019-08-21 17:24:13 -0700843 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
844 EXPECT_EQ(3u, mSystemCB->eventCount());
845 EXPECT_EQ(EventEntry({EventType::VIDEO_ON, kTestUid2}), mSystemCB->lastEvent());
846
847 // partially remove mTestClient1's request, shouldn't be any VIDEO_OFF
848 mService->removeResource(kTestPid1, getId(mTestClient1), resources1);
849 EXPECT_EQ(3u, mSystemCB->eventCount());
850
851 // remove mTestClient1's request, should be VIDEO_OFF for kTestUid1
852 // (use resource2 to test removing more instances than previously requested)
853 mService->removeResource(kTestPid1, getId(mTestClient1), resources2);
854 EXPECT_EQ(4u, mSystemCB->eventCount());
855 EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid1}), mSystemCB->lastEvent());
856
857 // remove mTestClient2, should be VIDEO_OFF for kTestUid2
858 mService->removeClient(kTestPid2, getId(mTestClient2));
859 EXPECT_EQ(5u, mSystemCB->eventCount());
860 EXPECT_EQ(EventEntry({EventType::VIDEO_OFF, kTestUid2}), mSystemCB->lastEvent());
861 }
862
863 void testCpusetBoost() {
864 // reset should always be called when ResourceManagerService is created (restarted)
865 EXPECT_EQ(1u, mSystemCB->eventCount());
866 EXPECT_EQ(EventType::VIDEO_RESET, mSystemCB->lastEventType());
867
868 // new client request should cause CPUSET_ENABLE
Chong Zhang181e6952019-10-09 13:23:39 -0700869 std::vector<MediaResourceParcel> resources1;
870 resources1.push_back(MediaResource(MediaResource::Type::kCpuBoost, 1));
Chong Zhangdd726802019-08-21 17:24:13 -0700871 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
872 EXPECT_EQ(2u, mSystemCB->eventCount());
873 EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
874
875 // each client should only cause 1 CPUSET_ENABLE
876 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
877 EXPECT_EQ(2u, mSystemCB->eventCount());
878
879 // new client request should cause CPUSET_ENABLE
Chong Zhang181e6952019-10-09 13:23:39 -0700880 std::vector<MediaResourceParcel> resources2;
881 resources2.push_back(MediaResource(MediaResource::Type::kCpuBoost, 2));
Chong Zhangdd726802019-08-21 17:24:13 -0700882 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
883 EXPECT_EQ(3u, mSystemCB->eventCount());
884 EXPECT_EQ(EventType::CPUSET_ENABLE, mSystemCB->lastEventType());
885
886 // remove mTestClient2 should not cause CPUSET_DISABLE, mTestClient1 still active
887 mService->removeClient(kTestPid2, getId(mTestClient2));
888 EXPECT_EQ(3u, mSystemCB->eventCount());
889
890 // remove 1 cpuboost from mTestClient1, should not be CPUSET_DISABLE (still 1 left)
891 mService->removeResource(kTestPid1, getId(mTestClient1), resources1);
892 EXPECT_EQ(3u, mSystemCB->eventCount());
893
894 // remove 2 cpuboost from mTestClient1, should be CPUSET_DISABLE
895 // (use resource2 to test removing more than previously requested)
896 mService->removeResource(kTestPid1, getId(mTestClient1), resources2);
897 EXPECT_EQ(4u, mSystemCB->eventCount());
898 EXPECT_EQ(EventType::CPUSET_DISABLE, mSystemCB->lastEventType());
899 }
900
901 sp<TestSystemCallback> mSystemCB;
Chong Zhangfdd512a2019-11-22 11:03:14 -0800902 std::shared_ptr<ResourceManagerService> mService;
903 std::shared_ptr<IResourceManagerClient> mTestClient1;
904 std::shared_ptr<IResourceManagerClient> mTestClient2;
905 std::shared_ptr<IResourceManagerClient> mTestClient3;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700906};
907
908TEST_F(ResourceManagerServiceTest, config) {
909 testConfig();
910}
911
912TEST_F(ResourceManagerServiceTest, addResource) {
913 addResource();
914}
915
Chong Zhangfb092d32019-08-12 09:45:44 -0700916TEST_F(ResourceManagerServiceTest, combineResource) {
917 testCombineResource();
918}
919
Chong Zhang181e6952019-10-09 13:23:39 -0700920TEST_F(ResourceManagerServiceTest, combineResourceNegative) {
921 testCombineResourceWithNegativeValues();
922}
923
Ronghua Wu231c3d12015-03-11 15:10:32 -0700924TEST_F(ResourceManagerServiceTest, removeResource) {
925 testRemoveResource();
926}
927
Chong Zhangfb092d32019-08-12 09:45:44 -0700928TEST_F(ResourceManagerServiceTest, removeClient) {
929 testRemoveClient();
930}
931
Ronghua Wu231c3d12015-03-11 15:10:32 -0700932TEST_F(ResourceManagerServiceTest, reclaimResource) {
933 testReclaimResourceSecure();
934 testReclaimResourceNonSecure();
935}
936
937TEST_F(ResourceManagerServiceTest, getAllClients_l) {
938 testGetAllClients();
939}
940
941TEST_F(ResourceManagerServiceTest, getLowestPriorityBiggestClient_l) {
942 testGetLowestPriorityBiggestClient();
943}
944
945TEST_F(ResourceManagerServiceTest, getLowestPriorityPid_l) {
946 testGetLowestPriorityPid();
947}
948
949TEST_F(ResourceManagerServiceTest, getBiggestClient_l) {
950 testGetBiggestClient();
951}
952
953TEST_F(ResourceManagerServiceTest, isCallingPriorityHigher_l) {
954 testIsCallingPriorityHigher();
955}
956
Chong Zhangdd726802019-08-21 17:24:13 -0700957TEST_F(ResourceManagerServiceTest, testBatteryStats) {
958 testBatteryStats();
959}
960
961TEST_F(ResourceManagerServiceTest, testCpusetBoost) {
962 testCpusetBoost();
963}
964
Henry Fang32762922020-01-28 18:40:39 -0800965TEST_F(ResourceManagerServiceTest, overridePid) {
966 testOverridePid();
967}
968
Wonsik Kimd20e9362020-04-28 10:42:57 -0700969TEST_F(ResourceManagerServiceTest, markClientForPendingRemoval) {
970 testMarkClientForPendingRemoval();
971}
972
Ronghua Wu231c3d12015-03-11 15:10:32 -0700973} // namespace android