blob: 3d53f1f59cf5c68f5a9aa38793c3fec12f23428e [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
32struct TestProcessInfo : public ProcessInfoInterface {
33 TestProcessInfo() {}
34 virtual ~TestProcessInfo() {}
35
36 virtual bool getPriority(int pid, int *priority) {
37 // For testing, use pid as priority.
38 // Lower the value higher the priority.
39 *priority = pid;
40 return true;
41 }
42
43private:
44 DISALLOW_EVIL_CONSTRUCTORS(TestProcessInfo);
45};
46
47struct TestClient : public BnResourceManagerClient {
48 TestClient(sp<ResourceManagerService> service)
49 : mReclaimed(false), mService(service) {}
50
51 virtual bool reclaimResource() {
52 sp<IResourceManagerClient> client(this);
53 mService->removeResource((int64_t) client.get());
54 mReclaimed = true;
55 return true;
56 }
57
Ronghua Wu8f9dd872015-04-23 15:24:25 -070058 virtual String8 getName() {
59 return String8("test_client");
60 }
61
Ronghua Wu231c3d12015-03-11 15:10:32 -070062 bool reclaimed() const {
63 return mReclaimed;
64 }
65
66 void reset() {
67 mReclaimed = false;
68 }
69
70protected:
71 virtual ~TestClient() {}
72
73private:
74 bool mReclaimed;
75 sp<ResourceManagerService> mService;
76 DISALLOW_EVIL_CONSTRUCTORS(TestClient);
77};
78
79static const int kTestPid1 = 30;
80static const int kTestPid2 = 20;
81
82class ResourceManagerServiceTest : public ::testing::Test {
83public:
84 ResourceManagerServiceTest()
85 : mService(new ResourceManagerService(new TestProcessInfo)),
86 mTestClient1(new TestClient(mService)),
87 mTestClient2(new TestClient(mService)),
88 mTestClient3(new TestClient(mService)) {
89 }
90
91protected:
92 static bool isEqualResources(const Vector<MediaResource> &resources1,
93 const Vector<MediaResource> &resources2) {
94 if (resources1.size() != resources2.size()) {
95 return false;
96 }
97 for (size_t i = 0; i < resources1.size(); ++i) {
98 if (resources1[i] != resources2[i]) {
99 return false;
100 }
101 }
102 return true;
103 }
104
105 static void expectEqResourceInfo(const ResourceInfo &info, sp<IResourceManagerClient> client,
106 const Vector<MediaResource> &resources) {
107 EXPECT_EQ(client, info.client);
108 EXPECT_TRUE(isEqualResources(resources, info.resources));
109 }
110
111 void verifyClients(bool c1, bool c2, bool c3) {
112 TestClient *client1 = static_cast<TestClient*>(mTestClient1.get());
113 TestClient *client2 = static_cast<TestClient*>(mTestClient2.get());
114 TestClient *client3 = static_cast<TestClient*>(mTestClient3.get());
115
116 EXPECT_EQ(c1, client1->reclaimed());
117 EXPECT_EQ(c2, client2->reclaimed());
118 EXPECT_EQ(c3, client3->reclaimed());
119
120 client1->reset();
121 client2->reset();
122 client3->reset();
123 }
124
Ronghua Wu67e7f542015-03-13 10:47:08 -0700125 // test set up
126 // ---------------------------------------------------------------------------------
127 // pid priority client type number
128 // ---------------------------------------------------------------------------------
129 // kTestPid1(30) 30 mTestClient1 secure codec 1
130 // graphic memory 200
131 // graphic memory 200
132 // ---------------------------------------------------------------------------------
133 // kTestPid2(20) 20 mTestClient2 non-secure codec 1
134 // graphic memory 300
135 // -------------------------------------------
136 // mTestClient3 secure codec 1
137 // graphic memory 100
138 // ---------------------------------------------------------------------------------
Ronghua Wu231c3d12015-03-11 15:10:32 -0700139 void addResource() {
140 // kTestPid1 mTestClient1
141 Vector<MediaResource> resources1;
142 resources1.push_back(MediaResource(String8(kResourceSecureCodec), 1));
143 mService->addResource(kTestPid1, (int64_t) mTestClient1.get(), mTestClient1, resources1);
144 resources1.push_back(MediaResource(String8(kResourceGraphicMemory), 200));
145 Vector<MediaResource> resources11;
146 resources11.push_back(MediaResource(String8(kResourceGraphicMemory), 200));
147 mService->addResource(kTestPid1, (int64_t) mTestClient1.get(), mTestClient1, resources11);
148
149 // kTestPid2 mTestClient2
150 Vector<MediaResource> resources2;
151 resources2.push_back(MediaResource(String8(kResourceNonSecureCodec), 1));
152 resources2.push_back(MediaResource(String8(kResourceGraphicMemory), 300));
153 mService->addResource(kTestPid2, (int64_t) mTestClient2.get(), mTestClient2, resources2);
154
155 // kTestPid2 mTestClient3
156 Vector<MediaResource> resources3;
157 mService->addResource(kTestPid2, (int64_t) mTestClient3.get(), mTestClient3, resources3);
158 resources3.push_back(MediaResource(String8(kResourceSecureCodec), 1));
159 resources3.push_back(MediaResource(String8(kResourceGraphicMemory), 100));
160 mService->addResource(kTestPid2, (int64_t) mTestClient3.get(), mTestClient3, resources3);
161
162 const PidResourceInfosMap &map = mService->mMap;
163 EXPECT_EQ(2u, map.size());
164 ssize_t index1 = map.indexOfKey(kTestPid1);
165 ASSERT_GE(index1, 0);
166 const ResourceInfos &infos1 = map[index1];
167 EXPECT_EQ(1u, infos1.size());
168 expectEqResourceInfo(infos1[0], mTestClient1, resources1);
169
170 ssize_t index2 = map.indexOfKey(kTestPid2);
171 ASSERT_GE(index2, 0);
172 const ResourceInfos &infos2 = map[index2];
173 EXPECT_EQ(2u, infos2.size());
174 expectEqResourceInfo(infos2[0], mTestClient2, resources2);
175 expectEqResourceInfo(infos2[1], mTestClient3, resources3);
176 }
177
178 void testConfig() {
179 EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
180 EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
181
182 Vector<MediaResourcePolicy> policies1;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700183 policies1.push_back(
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700184 MediaResourcePolicy(
185 String8(kPolicySupportsMultipleSecureCodecs),
186 String8("true")));
187 policies1.push_back(
188 MediaResourcePolicy(
189 String8(kPolicySupportsSecureWithNonSecureCodec),
190 String8("false")));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700191 mService->config(policies1);
192 EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
193 EXPECT_FALSE(mService->mSupportsSecureWithNonSecureCodec);
194
195 Vector<MediaResourcePolicy> policies2;
Ronghua Wu231c3d12015-03-11 15:10:32 -0700196 policies2.push_back(
Ronghua Wu9ba21b92015-04-21 14:23:06 -0700197 MediaResourcePolicy(
198 String8(kPolicySupportsMultipleSecureCodecs),
199 String8("false")));
200 policies2.push_back(
201 MediaResourcePolicy(
202 String8(kPolicySupportsSecureWithNonSecureCodec),
203 String8("true")));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700204 mService->config(policies2);
205 EXPECT_FALSE(mService->mSupportsMultipleSecureCodecs);
206 EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
207 }
208
209 void testRemoveResource() {
210 addResource();
211
212 mService->removeResource((int64_t) mTestClient2.get());
213
214 const PidResourceInfosMap &map = mService->mMap;
215 EXPECT_EQ(2u, map.size());
216 const ResourceInfos &infos1 = map.valueFor(kTestPid1);
217 const ResourceInfos &infos2 = map.valueFor(kTestPid2);
218 EXPECT_EQ(1u, infos1.size());
219 EXPECT_EQ(1u, infos2.size());
220 // mTestClient2 has been removed.
221 EXPECT_EQ(mTestClient3, infos2[0].client);
222 }
223
224 void testGetAllClients() {
225 addResource();
226
227 String8 type = String8(kResourceSecureCodec);
228 String8 unknowType = String8("unknowType");
229 Vector<sp<IResourceManagerClient> > clients;
230 int lowPriorityPid = 100;
231 EXPECT_FALSE(mService->getAllClients_l(lowPriorityPid, type, &clients));
232 int midPriorityPid = 25;
Ronghua Wu67e7f542015-03-13 10:47:08 -0700233 // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
234 // will fail.
235 EXPECT_FALSE(mService->getAllClients_l(midPriorityPid, type, &clients));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700236 int highPriorityPid = 10;
Ronghua Wu67e7f542015-03-13 10:47:08 -0700237 EXPECT_TRUE(mService->getAllClients_l(highPriorityPid, unknowType, &clients));
238 EXPECT_TRUE(mService->getAllClients_l(highPriorityPid, type, &clients));
Ronghua Wu231c3d12015-03-11 15:10:32 -0700239
240 EXPECT_EQ(2u, clients.size());
241 EXPECT_EQ(mTestClient3, clients[0]);
242 EXPECT_EQ(mTestClient1, clients[1]);
243 }
244
245 void testReclaimResourceSecure() {
246 Vector<MediaResource> resources;
247 resources.push_back(MediaResource(String8(kResourceSecureCodec), 1));
248 resources.push_back(MediaResource(String8(kResourceGraphicMemory), 150));
249
250 // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
251 {
252 addResource();
253 mService->mSupportsMultipleSecureCodecs = false;
254 mService->mSupportsSecureWithNonSecureCodec = true;
255
256 // priority too low
257 EXPECT_FALSE(mService->reclaimResource(40, resources));
258 EXPECT_FALSE(mService->reclaimResource(25, resources));
259
260 // reclaim all secure codecs
261 EXPECT_TRUE(mService->reclaimResource(10, resources));
262 verifyClients(true, false, true);
263
264 // call again should reclaim one largest graphic memory from lowest process
265 EXPECT_TRUE(mService->reclaimResource(10, resources));
266 verifyClients(false, true, false);
267
268 // nothing left
269 EXPECT_FALSE(mService->reclaimResource(10, resources));
270 }
271
272 // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
273 {
274 addResource();
275 mService->mSupportsMultipleSecureCodecs = false;
276 mService->mSupportsSecureWithNonSecureCodec = false;
277
278 // priority too low
279 EXPECT_FALSE(mService->reclaimResource(40, resources));
280 EXPECT_FALSE(mService->reclaimResource(25, resources));
281
282 // reclaim all secure and non-secure codecs
283 EXPECT_TRUE(mService->reclaimResource(10, resources));
284 verifyClients(true, true, true);
285
286 // nothing left
287 EXPECT_FALSE(mService->reclaimResource(10, resources));
288 }
289
290
291 // ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
292 {
293 addResource();
294 mService->mSupportsMultipleSecureCodecs = true;
295 mService->mSupportsSecureWithNonSecureCodec = false;
296
297 // priority too low
298 EXPECT_FALSE(mService->reclaimResource(40, resources));
299 EXPECT_FALSE(mService->reclaimResource(25, resources));
300
301 // reclaim all non-secure codecs
302 EXPECT_TRUE(mService->reclaimResource(10, resources));
303 verifyClients(false, true, false);
304
305 // call again should reclaim one largest graphic memory from lowest process
306 EXPECT_TRUE(mService->reclaimResource(10, resources));
307 verifyClients(true, false, false);
308
309 // call again should reclaim another largest graphic memory from lowest process
310 EXPECT_TRUE(mService->reclaimResource(10, resources));
311 verifyClients(false, false, true);
312
313 // nothing left
314 EXPECT_FALSE(mService->reclaimResource(10, resources));
315 }
316
317 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
318 {
319 addResource();
320 mService->mSupportsMultipleSecureCodecs = true;
321 mService->mSupportsSecureWithNonSecureCodec = true;
322
323 // priority too low
324 EXPECT_FALSE(mService->reclaimResource(40, resources));
325
326 EXPECT_TRUE(mService->reclaimResource(10, resources));
327 // one largest graphic memory from lowest process got reclaimed
328 verifyClients(true, false, false);
329
330 // call again should reclaim another graphic memory from lowest process
331 EXPECT_TRUE(mService->reclaimResource(10, resources));
332 verifyClients(false, true, false);
333
334 // call again should reclaim another graphic memory from lowest process
335 EXPECT_TRUE(mService->reclaimResource(10, resources));
336 verifyClients(false, false, true);
337
338 // nothing left
339 EXPECT_FALSE(mService->reclaimResource(10, resources));
340 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700341
342 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
343 {
344 addResource();
345 mService->mSupportsMultipleSecureCodecs = true;
346 mService->mSupportsSecureWithNonSecureCodec = true;
347
348 Vector<MediaResource> resources;
349 resources.push_back(MediaResource(String8(kResourceSecureCodec), 1));
350
351 EXPECT_TRUE(mService->reclaimResource(10, resources));
352 // secure codec from lowest process got reclaimed
353 verifyClients(true, false, false);
354
355 // call again should reclaim another secure codec from lowest process
356 EXPECT_TRUE(mService->reclaimResource(10, resources));
357 verifyClients(false, false, true);
358
359 // nothing left
360 EXPECT_FALSE(mService->reclaimResource(10, resources));
361
362 // clean up client 2 which still has non secure codec left
363 mService->removeResource((int64_t) mTestClient2.get());
364 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700365 }
366
367 void testReclaimResourceNonSecure() {
368 Vector<MediaResource> resources;
369 resources.push_back(MediaResource(String8(kResourceNonSecureCodec), 1));
370 resources.push_back(MediaResource(String8(kResourceGraphicMemory), 150));
371
372 // ### secure codec can't coexist with non-secure codec ###
373 {
374 addResource();
375 mService->mSupportsSecureWithNonSecureCodec = false;
376
377 // priority too low
378 EXPECT_FALSE(mService->reclaimResource(40, resources));
379 EXPECT_FALSE(mService->reclaimResource(25, resources));
380
381 // reclaim all secure codecs
382 EXPECT_TRUE(mService->reclaimResource(10, resources));
383 verifyClients(true, false, true);
384
385 // call again should reclaim one graphic memory from lowest process
386 EXPECT_TRUE(mService->reclaimResource(10, resources));
387 verifyClients(false, true, false);
388
389 // nothing left
390 EXPECT_FALSE(mService->reclaimResource(10, resources));
391 }
392
393
394 // ### secure codec can coexist with non-secure codec ###
395 {
396 addResource();
397 mService->mSupportsSecureWithNonSecureCodec = true;
398
399 // priority too low
400 EXPECT_FALSE(mService->reclaimResource(40, resources));
401
402 EXPECT_TRUE(mService->reclaimResource(10, resources));
403 // one largest graphic memory from lowest process got reclaimed
404 verifyClients(true, false, false);
405
406 // call again should reclaim another graphic memory from lowest process
407 EXPECT_TRUE(mService->reclaimResource(10, resources));
408 verifyClients(false, true, false);
409
410 // call again should reclaim another graphic memory from lowest process
411 EXPECT_TRUE(mService->reclaimResource(10, resources));
412 verifyClients(false, false, true);
413
414 // nothing left
415 EXPECT_FALSE(mService->reclaimResource(10, resources));
416 }
Ronghua Wu67e7f542015-03-13 10:47:08 -0700417
418 // ### secure codec can coexist with non-secure codec ###
419 {
420 addResource();
421 mService->mSupportsSecureWithNonSecureCodec = true;
422
423 Vector<MediaResource> resources;
424 resources.push_back(MediaResource(String8(kResourceNonSecureCodec), 1));
425
426 EXPECT_TRUE(mService->reclaimResource(10, resources));
427 // one non secure codec from lowest process got reclaimed
428 verifyClients(false, true, false);
429
430 // nothing left
431 EXPECT_FALSE(mService->reclaimResource(10, resources));
432
433 // clean up client 1 and 3 which still have secure codec left
434 mService->removeResource((int64_t) mTestClient1.get());
435 mService->removeResource((int64_t) mTestClient3.get());
436 }
Ronghua Wu231c3d12015-03-11 15:10:32 -0700437 }
438
439 void testGetLowestPriorityBiggestClient() {
440 String8 type = String8(kResourceGraphicMemory);
441 sp<IResourceManagerClient> client;
442 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(10, type, &client));
443
444 addResource();
445
446 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(100, type, &client));
447 EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(10, type, &client));
448
449 // kTestPid1 is the lowest priority process with kResourceGraphicMemory.
450 // mTestClient1 has the largest kResourceGraphicMemory within kTestPid1.
451 EXPECT_EQ(mTestClient1, client);
452 }
453
454 void testGetLowestPriorityPid() {
455 int pid;
456 int priority;
457 TestProcessInfo processInfo;
458
459 String8 type = String8(kResourceGraphicMemory);
460 EXPECT_FALSE(mService->getLowestPriorityPid_l(type, &pid, &priority));
461
462 addResource();
463
464 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
465 EXPECT_EQ(kTestPid1, pid);
466 int priority1;
467 processInfo.getPriority(kTestPid1, &priority1);
468 EXPECT_EQ(priority1, priority);
469
470 type = String8(kResourceNonSecureCodec);
471 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
472 EXPECT_EQ(kTestPid2, pid);
473 int priority2;
474 processInfo.getPriority(kTestPid2, &priority2);
475 EXPECT_EQ(priority2, priority);
476 }
477
478 void testGetBiggestClient() {
479 String8 type = String8(kResourceGraphicMemory);
480 sp<IResourceManagerClient> client;
481 EXPECT_FALSE(mService->getBiggestClient_l(kTestPid2, type, &client));
482
483 addResource();
484
485 EXPECT_TRUE(mService->getBiggestClient_l(kTestPid2, type, &client));
486 EXPECT_EQ(mTestClient2, client);
487 }
488
489 void testIsCallingPriorityHigher() {
490 EXPECT_FALSE(mService->isCallingPriorityHigher_l(101, 100));
491 EXPECT_FALSE(mService->isCallingPriorityHigher_l(100, 100));
492 EXPECT_TRUE(mService->isCallingPriorityHigher_l(99, 100));
493 }
494
495 sp<ResourceManagerService> mService;
496 sp<IResourceManagerClient> mTestClient1;
497 sp<IResourceManagerClient> mTestClient2;
498 sp<IResourceManagerClient> mTestClient3;
499};
500
501TEST_F(ResourceManagerServiceTest, config) {
502 testConfig();
503}
504
505TEST_F(ResourceManagerServiceTest, addResource) {
506 addResource();
507}
508
509TEST_F(ResourceManagerServiceTest, removeResource) {
510 testRemoveResource();
511}
512
513TEST_F(ResourceManagerServiceTest, reclaimResource) {
514 testReclaimResourceSecure();
515 testReclaimResourceNonSecure();
516}
517
518TEST_F(ResourceManagerServiceTest, getAllClients_l) {
519 testGetAllClients();
520}
521
522TEST_F(ResourceManagerServiceTest, getLowestPriorityBiggestClient_l) {
523 testGetLowestPriorityBiggestClient();
524}
525
526TEST_F(ResourceManagerServiceTest, getLowestPriorityPid_l) {
527 testGetLowestPriorityPid();
528}
529
530TEST_F(ResourceManagerServiceTest, getBiggestClient_l) {
531 testGetBiggestClient();
532}
533
534TEST_F(ResourceManagerServiceTest, isCallingPriorityHigher_l) {
535 testIsCallingPriorityHigher();
536}
537
538} // namespace android