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