blob: be592f537a1e8798d5f6db3cb5b5fae56d9bbc9c [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"
24#include <media/IResourceManagerService.h>
25#include <media/MediaResource.h>
26#include <media/MediaResourcePolicy.h>
27#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/ProcessInfoInterface.h>
29
30namespace android {
31
Chih-Hung Hsieh51873d82016-08-09 14:18:51 -070032static int64_t getId(const sp<IResourceManagerClient>& client) {
Ronghua Wu37c89242015-07-15 12:23:48 -070033 return (int64_t) client.get();
34}
35
Ronghua Wu231c3d12015-03-11 15:10:32 -070036struct TestProcessInfo : public ProcessInfoInterface {
37 TestProcessInfo() {}
38 virtual ~TestProcessInfo() {}
39
40 virtual bool getPriority(int pid, int *priority) {
41 // For testing, use pid as priority.
42 // Lower the value higher the priority.
43 *priority = pid;
44 return true;
45 }
46
Ronghua Wud11c43a2016-01-27 16:26:12 -080047 virtual bool isValidPid(int /* pid */) {
48 return true;
49 }
50
Ronghua Wu231c3d12015-03-11 15:10:32 -070051private:
52 DISALLOW_EVIL_CONSTRUCTORS(TestProcessInfo);
53};
54
55struct TestClient : public BnResourceManagerClient {
Ronghua Wu37c89242015-07-15 12:23:48 -070056 TestClient(int pid, sp<ResourceManagerService> service)
57 : mReclaimed(false), mPid(pid), mService(service) {}
Ronghua Wu231c3d12015-03-11 15:10:32 -070058
59 virtual bool reclaimResource() {
60 sp<IResourceManagerClient> client(this);
Chong Zhangfb092d32019-08-12 09:45:44 -070061 mService->removeClient(mPid, (int64_t) client.get());
Ronghua Wu231c3d12015-03-11 15:10:32 -070062 mReclaimed = true;
63 return true;
64 }
65
Ronghua Wu8f9dd872015-04-23 15:24:25 -070066 virtual String8 getName() {
67 return String8("test_client");
68 }
69
Ronghua Wu231c3d12015-03-11 15:10:32 -070070 bool reclaimed() const {
71 return mReclaimed;
72 }
73
74 void reset() {
75 mReclaimed = false;
76 }
77
78protected:
79 virtual ~TestClient() {}
80
81private:
82 bool mReclaimed;
Ronghua Wu37c89242015-07-15 12:23:48 -070083 int mPid;
Ronghua Wu231c3d12015-03-11 15:10:32 -070084 sp<ResourceManagerService> mService;
85 DISALLOW_EVIL_CONSTRUCTORS(TestClient);
86};
87
88static const int kTestPid1 = 30;
Chong Zhangee33d642019-08-08 14:26:43 -070089static const int kTestUid1 = 1010;
90
Ronghua Wu231c3d12015-03-11 15:10:32 -070091static const int kTestPid2 = 20;
Chong Zhangee33d642019-08-08 14:26:43 -070092static const int kTestUid2 = 1011;
Ronghua Wu231c3d12015-03-11 15:10:32 -070093
Ronghua Wu05d89f12015-07-07 16:47:42 -070094static const int kLowPriorityPid = 40;
95static const int kMidPriorityPid = 25;
96static const int kHighPriorityPid = 10;
97
Ronghua Wu231c3d12015-03-11 15:10:32 -070098class ResourceManagerServiceTest : public ::testing::Test {
99public:
100 ResourceManagerServiceTest()
101 : mService(new ResourceManagerService(new TestProcessInfo)),
Ronghua Wu37c89242015-07-15 12:23:48 -0700102 mTestClient1(new TestClient(kTestPid1, mService)),
103 mTestClient2(new TestClient(kTestPid2, mService)),
104 mTestClient3(new TestClient(kTestPid2, mService)) {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700105 }
106
107protected:
108 static bool isEqualResources(const Vector<MediaResource> &resources1,
Chong Zhangfb092d32019-08-12 09:45:44 -0700109 const ResourceList &resources2) {
110 // convert resource1 to ResourceList
111 ResourceList r1;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700112 for (size_t i = 0; i < resources1.size(); ++i) {
Chong Zhangfb092d32019-08-12 09:45:44 -0700113 const auto resType = std::make_pair(resources1[i].mType, resources1[i].mSubType);
114 r1[resType] = resources1[i];
Ronghua Wu231c3d12015-03-11 15:10:32 -0700115 }
Chong Zhangfb092d32019-08-12 09:45:44 -0700116 return r1 == resources2;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700117 }
118
Chong Zhangee33d642019-08-08 14:26:43 -0700119 static void expectEqResourceInfo(const ResourceInfo &info,
120 int uid,
121 sp<IResourceManagerClient> client,
Ronghua Wu231c3d12015-03-11 15:10:32 -0700122 const Vector<MediaResource> &resources) {
Chong Zhangee33d642019-08-08 14:26:43 -0700123 EXPECT_EQ(uid, info.uid);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700124 EXPECT_EQ(client, info.client);
125 EXPECT_TRUE(isEqualResources(resources, info.resources));
126 }
127
128 void verifyClients(bool c1, bool c2, bool c3) {
129 TestClient *client1 = static_cast<TestClient*>(mTestClient1.get());
130 TestClient *client2 = static_cast<TestClient*>(mTestClient2.get());
131 TestClient *client3 = static_cast<TestClient*>(mTestClient3.get());
132
133 EXPECT_EQ(c1, client1->reclaimed());
134 EXPECT_EQ(c2, client2->reclaimed());
135 EXPECT_EQ(c3, client3->reclaimed());
136
137 client1->reset();
138 client2->reset();
139 client3->reset();
140 }
141
Ronghua Wu67e7f542015-03-13 10:47:08 -0700142 // test set up
143 // ---------------------------------------------------------------------------------
144 // pid priority client type number
145 // ---------------------------------------------------------------------------------
146 // kTestPid1(30) 30 mTestClient1 secure codec 1
147 // graphic memory 200
148 // graphic memory 200
149 // ---------------------------------------------------------------------------------
150 // kTestPid2(20) 20 mTestClient2 non-secure codec 1
151 // graphic memory 300
152 // -------------------------------------------
153 // mTestClient3 secure codec 1
154 // graphic memory 100
155 // ---------------------------------------------------------------------------------
Ronghua Wu231c3d12015-03-11 15:10:32 -0700156 void addResource() {
157 // kTestPid1 mTestClient1
158 Vector<MediaResource> resources1;
Ronghua Wuea15fd22016-03-03 13:35:05 -0800159 resources1.push_back(MediaResource(MediaResource::kSecureCodec, 1));
Chong Zhangee33d642019-08-08 14:26:43 -0700160 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
Ronghua Wuea15fd22016-03-03 13:35:05 -0800161 resources1.push_back(MediaResource(MediaResource::kGraphicMemory, 200));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700162 Vector<MediaResource> resources11;
Ronghua Wuea15fd22016-03-03 13:35:05 -0800163 resources11.push_back(MediaResource(MediaResource::kGraphicMemory, 200));
Chong Zhangee33d642019-08-08 14:26:43 -0700164 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700165
166 // kTestPid2 mTestClient2
167 Vector<MediaResource> resources2;
Ronghua Wuea15fd22016-03-03 13:35:05 -0800168 resources2.push_back(MediaResource(MediaResource::kNonSecureCodec, 1));
169 resources2.push_back(MediaResource(MediaResource::kGraphicMemory, 300));
Chong Zhangee33d642019-08-08 14:26:43 -0700170 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources2);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700171
172 // kTestPid2 mTestClient3
173 Vector<MediaResource> resources3;
Chong Zhangee33d642019-08-08 14:26:43 -0700174 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
Ronghua Wuea15fd22016-03-03 13:35:05 -0800175 resources3.push_back(MediaResource(MediaResource::kSecureCodec, 1));
176 resources3.push_back(MediaResource(MediaResource::kGraphicMemory, 100));
Chong Zhangee33d642019-08-08 14:26:43 -0700177 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources3);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700178
179 const PidResourceInfosMap &map = mService->mMap;
180 EXPECT_EQ(2u, map.size());
181 ssize_t index1 = map.indexOfKey(kTestPid1);
182 ASSERT_GE(index1, 0);
183 const ResourceInfos &infos1 = map[index1];
184 EXPECT_EQ(1u, infos1.size());
Chong Zhangfb092d32019-08-12 09:45:44 -0700185 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, resources1);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700186
187 ssize_t index2 = map.indexOfKey(kTestPid2);
188 ASSERT_GE(index2, 0);
189 const ResourceInfos &infos2 = map[index2];
190 EXPECT_EQ(2u, infos2.size());
Chong Zhangfb092d32019-08-12 09:45:44 -0700191 expectEqResourceInfo(infos2.valueFor(getId(mTestClient2)), kTestUid2, mTestClient2, resources2);
192 expectEqResourceInfo(infos2.valueFor(getId(mTestClient3)), kTestUid2, mTestClient3, resources3);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700193 }
194
195 void testConfig() {
196 EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
197 EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
198
199 Vector<MediaResourcePolicy> policies1;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700200 policies1.push_back(
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700201 MediaResourcePolicy(
202 String8(kPolicySupportsMultipleSecureCodecs),
203 String8("true")));
204 policies1.push_back(
205 MediaResourcePolicy(
206 String8(kPolicySupportsSecureWithNonSecureCodec),
207 String8("false")));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700208 mService->config(policies1);
209 EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
210 EXPECT_FALSE(mService->mSupportsSecureWithNonSecureCodec);
211
212 Vector<MediaResourcePolicy> policies2;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700213 policies2.push_back(
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700214 MediaResourcePolicy(
215 String8(kPolicySupportsMultipleSecureCodecs),
216 String8("false")));
217 policies2.push_back(
218 MediaResourcePolicy(
219 String8(kPolicySupportsSecureWithNonSecureCodec),
220 String8("true")));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700221 mService->config(policies2);
222 EXPECT_FALSE(mService->mSupportsMultipleSecureCodecs);
223 EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
224 }
225
Chong Zhangfb092d32019-08-12 09:45:44 -0700226 void testCombineResource() {
227 // kTestPid1 mTestClient1
228 Vector<MediaResource> resources1;
229 resources1.push_back(MediaResource(MediaResource::kSecureCodec, 1));
230 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
231
232 Vector<MediaResource> resources11;
233 resources11.push_back(MediaResource(MediaResource::kGraphicMemory, 200));
234 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
235
236 const PidResourceInfosMap &map = mService->mMap;
237 EXPECT_EQ(1u, map.size());
238 ssize_t index1 = map.indexOfKey(kTestPid1);
239 ASSERT_GE(index1, 0);
240 const ResourceInfos &infos1 = map[index1];
241 EXPECT_EQ(1u, infos1.size());
242
243 // test adding existing types to combine values
244 resources1.push_back(MediaResource(MediaResource::kGraphicMemory, 100));
245 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
246
247 Vector<MediaResource> expected;
248 expected.push_back(MediaResource(MediaResource::kSecureCodec, 2));
249 expected.push_back(MediaResource(MediaResource::kGraphicMemory, 300));
250 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
251
252 // test adding new types (including types that differs only in subType)
253 resources11.push_back(MediaResource(MediaResource::kNonSecureCodec, 1));
254 resources11.push_back(MediaResource(MediaResource::kSecureCodec, MediaResource::kVideoCodec, 1));
255 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
256
257 expected.clear();
258 expected.push_back(MediaResource(MediaResource::kSecureCodec, 2));
259 expected.push_back(MediaResource(MediaResource::kNonSecureCodec, 1));
260 expected.push_back(MediaResource(MediaResource::kSecureCodec, MediaResource::kVideoCodec, 1));
261 expected.push_back(MediaResource(MediaResource::kGraphicMemory, 500));
262 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
263 }
264
Ronghua Wu231c3d12015-03-11 15:10:32 -0700265 void testRemoveResource() {
Chong Zhangfb092d32019-08-12 09:45:44 -0700266 // kTestPid1 mTestClient1
267 Vector<MediaResource> resources1;
268 resources1.push_back(MediaResource(MediaResource::kSecureCodec, 1));
269 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources1);
270
271 Vector<MediaResource> resources11;
272 resources11.push_back(MediaResource(MediaResource::kGraphicMemory, 200));
273 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources11);
274
275 const PidResourceInfosMap &map = mService->mMap;
276 EXPECT_EQ(1u, map.size());
277 ssize_t index1 = map.indexOfKey(kTestPid1);
278 ASSERT_GE(index1, 0);
279 const ResourceInfos &infos1 = map[index1];
280 EXPECT_EQ(1u, infos1.size());
281
282 // test partial removal
283 resources11.editItemAt(0).mValue = 100;
284 mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
285
286 Vector<MediaResource> expected;
287 expected.push_back(MediaResource(MediaResource::kSecureCodec, 1));
288 expected.push_back(MediaResource(MediaResource::kGraphicMemory, 100));
289 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
290
291 // test complete removal with overshoot value
292 resources11.editItemAt(0).mValue = 1000;
293 mService->removeResource(kTestPid1, getId(mTestClient1), resources11);
294
295 expected.clear();
296 expected.push_back(MediaResource(MediaResource::kSecureCodec, 1));
297 expectEqResourceInfo(infos1.valueFor(getId(mTestClient1)), kTestUid1, mTestClient1, expected);
298 }
299
300 void testRemoveClient() {
Ronghua Wu231c3d12015-03-11 15:10:32 -0700301 addResource();
302
Chong Zhangfb092d32019-08-12 09:45:44 -0700303 mService->removeClient(kTestPid2, getId(mTestClient2));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700304
305 const PidResourceInfosMap &map = mService->mMap;
306 EXPECT_EQ(2u, map.size());
307 const ResourceInfos &infos1 = map.valueFor(kTestPid1);
308 const ResourceInfos &infos2 = map.valueFor(kTestPid2);
309 EXPECT_EQ(1u, infos1.size());
310 EXPECT_EQ(1u, infos2.size());
311 // mTestClient2 has been removed.
Chong Zhangfb092d32019-08-12 09:45:44 -0700312 // (OK to use infos2[0] as there is only 1 entry)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700313 EXPECT_EQ(mTestClient3, infos2[0].client);
314 }
315
316 void testGetAllClients() {
317 addResource();
318
Ronghua Wuea15fd22016-03-03 13:35:05 -0800319 MediaResource::Type type = MediaResource::kSecureCodec;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700320 Vector<sp<IResourceManagerClient> > clients;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700321 EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, &clients));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700322 // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
323 // will fail.
Ronghua Wu05d89f12015-07-07 16:47:42 -0700324 EXPECT_FALSE(mService->getAllClients_l(kMidPriorityPid, type, &clients));
Ronghua Wu05d89f12015-07-07 16:47:42 -0700325 EXPECT_TRUE(mService->getAllClients_l(kHighPriorityPid, type, &clients));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700326
327 EXPECT_EQ(2u, clients.size());
Chong Zhangfb092d32019-08-12 09:45:44 -0700328 // (OK to require ordering in clients[], as the pid map is sorted)
Ronghua Wu231c3d12015-03-11 15:10:32 -0700329 EXPECT_EQ(mTestClient3, clients[0]);
330 EXPECT_EQ(mTestClient1, clients[1]);
331 }
332
333 void testReclaimResourceSecure() {
334 Vector<MediaResource> resources;
Ronghua Wuea15fd22016-03-03 13:35:05 -0800335 resources.push_back(MediaResource(MediaResource::kSecureCodec, 1));
336 resources.push_back(MediaResource(MediaResource::kGraphicMemory, 150));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700337
338 // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
339 {
340 addResource();
341 mService->mSupportsMultipleSecureCodecs = false;
342 mService->mSupportsSecureWithNonSecureCodec = true;
343
344 // priority too low
Ronghua Wu05d89f12015-07-07 16:47:42 -0700345 EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
346 EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700347
348 // reclaim all secure codecs
Ronghua Wu05d89f12015-07-07 16:47:42 -0700349 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
350 verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700351
352 // call again should reclaim one largest graphic memory from lowest process
Ronghua Wu05d89f12015-07-07 16:47:42 -0700353 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
354 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700355
356 // nothing left
Ronghua Wu05d89f12015-07-07 16:47:42 -0700357 EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700358 }
359
360 // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
361 {
362 addResource();
363 mService->mSupportsMultipleSecureCodecs = false;
364 mService->mSupportsSecureWithNonSecureCodec = false;
365
366 // priority too low
Ronghua Wu05d89f12015-07-07 16:47:42 -0700367 EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
368 EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700369
370 // reclaim all secure and non-secure codecs
Ronghua Wu05d89f12015-07-07 16:47:42 -0700371 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
372 verifyClients(true /* c1 */, true /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700373
374 // nothing left
Ronghua Wu05d89f12015-07-07 16:47:42 -0700375 EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700376 }
377
378
379 // ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
380 {
381 addResource();
382 mService->mSupportsMultipleSecureCodecs = true;
383 mService->mSupportsSecureWithNonSecureCodec = false;
384
385 // priority too low
Ronghua Wu05d89f12015-07-07 16:47:42 -0700386 EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
387 EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700388
389 // reclaim all non-secure codecs
Ronghua Wu05d89f12015-07-07 16:47:42 -0700390 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
391 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700392
393 // call again should reclaim one largest graphic memory from lowest process
Ronghua Wu05d89f12015-07-07 16:47:42 -0700394 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
395 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700396
397 // call again should reclaim another largest graphic memory from lowest process
Ronghua Wu05d89f12015-07-07 16:47:42 -0700398 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
399 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700400
401 // nothing left
Ronghua Wu05d89f12015-07-07 16:47:42 -0700402 EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700403 }
404
405 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
406 {
407 addResource();
408 mService->mSupportsMultipleSecureCodecs = true;
409 mService->mSupportsSecureWithNonSecureCodec = true;
410
411 // priority too low
Ronghua Wu05d89f12015-07-07 16:47:42 -0700412 EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700413
Ronghua Wu05d89f12015-07-07 16:47:42 -0700414 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700415 // one largest graphic memory from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700416 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700417
418 // call again should reclaim another graphic memory from lowest process
Ronghua Wu05d89f12015-07-07 16:47:42 -0700419 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
420 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700421
422 // call again should reclaim another graphic memory from lowest process
Ronghua Wu05d89f12015-07-07 16:47:42 -0700423 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
424 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700425
426 // nothing left
Ronghua Wu05d89f12015-07-07 16:47:42 -0700427 EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700428 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700429
430 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
431 {
432 addResource();
433 mService->mSupportsMultipleSecureCodecs = true;
434 mService->mSupportsSecureWithNonSecureCodec = true;
435
436 Vector<MediaResource> resources;
Ronghua Wuea15fd22016-03-03 13:35:05 -0800437 resources.push_back(MediaResource(MediaResource::kSecureCodec, 1));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700438
Ronghua Wu05d89f12015-07-07 16:47:42 -0700439 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700440 // secure codec from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700441 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700442
443 // call again should reclaim another secure codec from lowest process
Ronghua Wu05d89f12015-07-07 16:47:42 -0700444 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
445 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700446
Ronghua Wu05d89f12015-07-07 16:47:42 -0700447 // no more secure codec, non-secure codec will be reclaimed.
448 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
449 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700450 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700451 }
452
453 void testReclaimResourceNonSecure() {
454 Vector<MediaResource> resources;
Ronghua Wuea15fd22016-03-03 13:35:05 -0800455 resources.push_back(MediaResource(MediaResource::kNonSecureCodec, 1));
456 resources.push_back(MediaResource(MediaResource::kGraphicMemory, 150));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700457
458 // ### secure codec can't coexist with non-secure codec ###
459 {
460 addResource();
461 mService->mSupportsSecureWithNonSecureCodec = false;
462
463 // priority too low
Ronghua Wu05d89f12015-07-07 16:47:42 -0700464 EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
465 EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700466
467 // reclaim all secure codecs
Ronghua Wu05d89f12015-07-07 16:47:42 -0700468 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
469 verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700470
471 // call again should reclaim one graphic memory from lowest process
Ronghua Wu05d89f12015-07-07 16:47:42 -0700472 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
473 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700474
475 // nothing left
Ronghua Wu05d89f12015-07-07 16:47:42 -0700476 EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700477 }
478
479
480 // ### secure codec can coexist with non-secure codec ###
481 {
482 addResource();
483 mService->mSupportsSecureWithNonSecureCodec = true;
484
485 // priority too low
Ronghua Wu05d89f12015-07-07 16:47:42 -0700486 EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700487
Ronghua Wu05d89f12015-07-07 16:47:42 -0700488 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700489 // one largest graphic memory from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700490 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700491
492 // call again should reclaim another graphic memory from lowest process
Ronghua Wu05d89f12015-07-07 16:47:42 -0700493 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
494 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700495
496 // call again should reclaim another graphic memory from lowest process
Ronghua Wu05d89f12015-07-07 16:47:42 -0700497 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
498 verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);
Ronghua Wu231c3d12015-03-11 15:10:32 -0700499
500 // nothing left
Ronghua Wu05d89f12015-07-07 16:47:42 -0700501 EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700502 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700503
504 // ### secure codec can coexist with non-secure codec ###
505 {
506 addResource();
507 mService->mSupportsSecureWithNonSecureCodec = true;
508
509 Vector<MediaResource> resources;
Ronghua Wuea15fd22016-03-03 13:35:05 -0800510 resources.push_back(MediaResource(MediaResource::kNonSecureCodec, 1));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700511
Ronghua Wu05d89f12015-07-07 16:47:42 -0700512 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700513 // one non secure codec from lowest process got reclaimed
Ronghua Wu05d89f12015-07-07 16:47:42 -0700514 verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700515
Ronghua Wu05d89f12015-07-07 16:47:42 -0700516 // no more non-secure codec, secure codec from lowest priority process will be reclaimed
517 EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
518 verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);
Ronghua Wu67e7f542015-03-13 10:47:08 -0700519
Ronghua Wu05d89f12015-07-07 16:47:42 -0700520 // clean up client 3 which still left
Chong Zhangfb092d32019-08-12 09:45:44 -0700521 mService->removeClient(kTestPid2, getId(mTestClient3));
Ronghua Wu67e7f542015-03-13 10:47:08 -0700522 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700523 }
524
525 void testGetLowestPriorityBiggestClient() {
Ronghua Wuea15fd22016-03-03 13:35:05 -0800526 MediaResource::Type type = MediaResource::kGraphicMemory;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700527 sp<IResourceManagerClient> client;
Ronghua Wu05d89f12015-07-07 16:47:42 -0700528 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700529
530 addResource();
531
Ronghua Wu05d89f12015-07-07 16:47:42 -0700532 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kLowPriorityPid, type, &client));
533 EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700534
Ronghua Wuea15fd22016-03-03 13:35:05 -0800535 // kTestPid1 is the lowest priority process with MediaResource::kGraphicMemory.
536 // mTestClient1 has the largest MediaResource::kGraphicMemory within kTestPid1.
Ronghua Wu231c3d12015-03-11 15:10:32 -0700537 EXPECT_EQ(mTestClient1, client);
538 }
539
540 void testGetLowestPriorityPid() {
541 int pid;
542 int priority;
543 TestProcessInfo processInfo;
544
Ronghua Wuea15fd22016-03-03 13:35:05 -0800545 MediaResource::Type type = MediaResource::kGraphicMemory;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700546 EXPECT_FALSE(mService->getLowestPriorityPid_l(type, &pid, &priority));
547
548 addResource();
549
550 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
551 EXPECT_EQ(kTestPid1, pid);
552 int priority1;
553 processInfo.getPriority(kTestPid1, &priority1);
554 EXPECT_EQ(priority1, priority);
555
Ronghua Wuea15fd22016-03-03 13:35:05 -0800556 type = MediaResource::kNonSecureCodec;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700557 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
558 EXPECT_EQ(kTestPid2, pid);
559 int priority2;
560 processInfo.getPriority(kTestPid2, &priority2);
561 EXPECT_EQ(priority2, priority);
562 }
563
564 void testGetBiggestClient() {
Ronghua Wuea15fd22016-03-03 13:35:05 -0800565 MediaResource::Type type = MediaResource::kGraphicMemory;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700566 sp<IResourceManagerClient> client;
567 EXPECT_FALSE(mService->getBiggestClient_l(kTestPid2, type, &client));
568
569 addResource();
570
571 EXPECT_TRUE(mService->getBiggestClient_l(kTestPid2, type, &client));
572 EXPECT_EQ(mTestClient2, client);
573 }
574
575 void testIsCallingPriorityHigher() {
576 EXPECT_FALSE(mService->isCallingPriorityHigher_l(101, 100));
577 EXPECT_FALSE(mService->isCallingPriorityHigher_l(100, 100));
578 EXPECT_TRUE(mService->isCallingPriorityHigher_l(99, 100));
579 }
580
581 sp<ResourceManagerService> mService;
582 sp<IResourceManagerClient> mTestClient1;
583 sp<IResourceManagerClient> mTestClient2;
584 sp<IResourceManagerClient> mTestClient3;
585};
586
587TEST_F(ResourceManagerServiceTest, config) {
588 testConfig();
589}
590
591TEST_F(ResourceManagerServiceTest, addResource) {
592 addResource();
593}
594
Chong Zhangfb092d32019-08-12 09:45:44 -0700595TEST_F(ResourceManagerServiceTest, combineResource) {
596 testCombineResource();
597}
598
Ronghua Wu231c3d12015-03-11 15:10:32 -0700599TEST_F(ResourceManagerServiceTest, removeResource) {
600 testRemoveResource();
601}
602
Chong Zhangfb092d32019-08-12 09:45:44 -0700603TEST_F(ResourceManagerServiceTest, removeClient) {
604 testRemoveClient();
605}
606
Ronghua Wu231c3d12015-03-11 15:10:32 -0700607TEST_F(ResourceManagerServiceTest, reclaimResource) {
608 testReclaimResourceSecure();
609 testReclaimResourceNonSecure();
610}
611
612TEST_F(ResourceManagerServiceTest, getAllClients_l) {
613 testGetAllClients();
614}
615
616TEST_F(ResourceManagerServiceTest, getLowestPriorityBiggestClient_l) {
617 testGetLowestPriorityBiggestClient();
618}
619
620TEST_F(ResourceManagerServiceTest, getLowestPriorityPid_l) {
621 testGetLowestPriorityPid();
622}
623
624TEST_F(ResourceManagerServiceTest, getBiggestClient_l) {
625 testGetBiggestClient();
626}
627
628TEST_F(ResourceManagerServiceTest, isCallingPriorityHigher_l) {
629 testIsCallingPriorityHigher();
630}
631
632} // namespace android