blob: b73e1bc9975c1fc3e62d31897cb28a042f8935b7 [file] [log] [blame]
Ronghua Wu231c3d12015-03-11 15:10:32 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
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
121 void addResource() {
122 // kTestPid1 mTestClient1
123 Vector<MediaResource> resources1;
124 resources1.push_back(MediaResource(String8(kResourceSecureCodec), 1));
125 mService->addResource(kTestPid1, (int64_t) mTestClient1.get(), mTestClient1, resources1);
126 resources1.push_back(MediaResource(String8(kResourceGraphicMemory), 200));
127 Vector<MediaResource> resources11;
128 resources11.push_back(MediaResource(String8(kResourceGraphicMemory), 200));
129 mService->addResource(kTestPid1, (int64_t) mTestClient1.get(), mTestClient1, resources11);
130
131 // kTestPid2 mTestClient2
132 Vector<MediaResource> resources2;
133 resources2.push_back(MediaResource(String8(kResourceNonSecureCodec), 1));
134 resources2.push_back(MediaResource(String8(kResourceGraphicMemory), 300));
135 mService->addResource(kTestPid2, (int64_t) mTestClient2.get(), mTestClient2, resources2);
136
137 // kTestPid2 mTestClient3
138 Vector<MediaResource> resources3;
139 mService->addResource(kTestPid2, (int64_t) mTestClient3.get(), mTestClient3, resources3);
140 resources3.push_back(MediaResource(String8(kResourceSecureCodec), 1));
141 resources3.push_back(MediaResource(String8(kResourceGraphicMemory), 100));
142 mService->addResource(kTestPid2, (int64_t) mTestClient3.get(), mTestClient3, resources3);
143
144 const PidResourceInfosMap &map = mService->mMap;
145 EXPECT_EQ(2u, map.size());
146 ssize_t index1 = map.indexOfKey(kTestPid1);
147 ASSERT_GE(index1, 0);
148 const ResourceInfos &infos1 = map[index1];
149 EXPECT_EQ(1u, infos1.size());
150 expectEqResourceInfo(infos1[0], mTestClient1, resources1);
151
152 ssize_t index2 = map.indexOfKey(kTestPid2);
153 ASSERT_GE(index2, 0);
154 const ResourceInfos &infos2 = map[index2];
155 EXPECT_EQ(2u, infos2.size());
156 expectEqResourceInfo(infos2[0], mTestClient2, resources2);
157 expectEqResourceInfo(infos2[1], mTestClient3, resources3);
158 }
159
160 void testConfig() {
161 EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
162 EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
163
164 Vector<MediaResourcePolicy> policies1;
165 policies1.push_back(MediaResourcePolicy(String8(kPolicySupportsMultipleSecureCodecs), 1));
166 policies1.push_back(
167 MediaResourcePolicy(String8(kPolicySupportsSecureWithNonSecureCodec), 0));
168 mService->config(policies1);
169 EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
170 EXPECT_FALSE(mService->mSupportsSecureWithNonSecureCodec);
171
172 Vector<MediaResourcePolicy> policies2;
173 policies2.push_back(MediaResourcePolicy(String8(kPolicySupportsMultipleSecureCodecs), 0));
174 policies2.push_back(
175 MediaResourcePolicy(String8(kPolicySupportsSecureWithNonSecureCodec), 1));
176 mService->config(policies2);
177 EXPECT_FALSE(mService->mSupportsMultipleSecureCodecs);
178 EXPECT_TRUE(mService->mSupportsSecureWithNonSecureCodec);
179 }
180
181 void testRemoveResource() {
182 addResource();
183
184 mService->removeResource((int64_t) mTestClient2.get());
185
186 const PidResourceInfosMap &map = mService->mMap;
187 EXPECT_EQ(2u, map.size());
188 const ResourceInfos &infos1 = map.valueFor(kTestPid1);
189 const ResourceInfos &infos2 = map.valueFor(kTestPid2);
190 EXPECT_EQ(1u, infos1.size());
191 EXPECT_EQ(1u, infos2.size());
192 // mTestClient2 has been removed.
193 EXPECT_EQ(mTestClient3, infos2[0].client);
194 }
195
196 void testGetAllClients() {
197 addResource();
198
199 String8 type = String8(kResourceSecureCodec);
200 String8 unknowType = String8("unknowType");
201 Vector<sp<IResourceManagerClient> > clients;
202 int lowPriorityPid = 100;
203 EXPECT_FALSE(mService->getAllClients_l(lowPriorityPid, type, &clients));
204 int midPriorityPid = 25;
205 EXPECT_FALSE(mService->getAllClients_l(lowPriorityPid, type, &clients));
206 int highPriorityPid = 10;
207 EXPECT_TRUE(mService->getAllClients_l(10, unknowType, &clients));
208 EXPECT_TRUE(mService->getAllClients_l(10, type, &clients));
209
210 EXPECT_EQ(2u, clients.size());
211 EXPECT_EQ(mTestClient3, clients[0]);
212 EXPECT_EQ(mTestClient1, clients[1]);
213 }
214
215 void testReclaimResourceSecure() {
216 Vector<MediaResource> resources;
217 resources.push_back(MediaResource(String8(kResourceSecureCodec), 1));
218 resources.push_back(MediaResource(String8(kResourceGraphicMemory), 150));
219
220 // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
221 {
222 addResource();
223 mService->mSupportsMultipleSecureCodecs = false;
224 mService->mSupportsSecureWithNonSecureCodec = true;
225
226 // priority too low
227 EXPECT_FALSE(mService->reclaimResource(40, resources));
228 EXPECT_FALSE(mService->reclaimResource(25, resources));
229
230 // reclaim all secure codecs
231 EXPECT_TRUE(mService->reclaimResource(10, resources));
232 verifyClients(true, false, true);
233
234 // call again should reclaim one largest graphic memory from lowest process
235 EXPECT_TRUE(mService->reclaimResource(10, resources));
236 verifyClients(false, true, false);
237
238 // nothing left
239 EXPECT_FALSE(mService->reclaimResource(10, resources));
240 }
241
242 // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
243 {
244 addResource();
245 mService->mSupportsMultipleSecureCodecs = false;
246 mService->mSupportsSecureWithNonSecureCodec = false;
247
248 // priority too low
249 EXPECT_FALSE(mService->reclaimResource(40, resources));
250 EXPECT_FALSE(mService->reclaimResource(25, resources));
251
252 // reclaim all secure and non-secure codecs
253 EXPECT_TRUE(mService->reclaimResource(10, resources));
254 verifyClients(true, true, true);
255
256 // nothing left
257 EXPECT_FALSE(mService->reclaimResource(10, resources));
258 }
259
260
261 // ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
262 {
263 addResource();
264 mService->mSupportsMultipleSecureCodecs = true;
265 mService->mSupportsSecureWithNonSecureCodec = false;
266
267 // priority too low
268 EXPECT_FALSE(mService->reclaimResource(40, resources));
269 EXPECT_FALSE(mService->reclaimResource(25, resources));
270
271 // reclaim all non-secure codecs
272 EXPECT_TRUE(mService->reclaimResource(10, resources));
273 verifyClients(false, true, false);
274
275 // call again should reclaim one largest graphic memory from lowest process
276 EXPECT_TRUE(mService->reclaimResource(10, resources));
277 verifyClients(true, false, false);
278
279 // call again should reclaim another largest graphic memory from lowest process
280 EXPECT_TRUE(mService->reclaimResource(10, resources));
281 verifyClients(false, false, true);
282
283 // nothing left
284 EXPECT_FALSE(mService->reclaimResource(10, resources));
285 }
286
287 // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
288 {
289 addResource();
290 mService->mSupportsMultipleSecureCodecs = true;
291 mService->mSupportsSecureWithNonSecureCodec = true;
292
293 // priority too low
294 EXPECT_FALSE(mService->reclaimResource(40, resources));
295
296 EXPECT_TRUE(mService->reclaimResource(10, resources));
297 // one largest graphic memory from lowest process got reclaimed
298 verifyClients(true, false, false);
299
300 // call again should reclaim another graphic memory from lowest process
301 EXPECT_TRUE(mService->reclaimResource(10, resources));
302 verifyClients(false, true, false);
303
304 // call again should reclaim another graphic memory from lowest process
305 EXPECT_TRUE(mService->reclaimResource(10, resources));
306 verifyClients(false, false, true);
307
308 // nothing left
309 EXPECT_FALSE(mService->reclaimResource(10, resources));
310 }
311 }
312
313 void testReclaimResourceNonSecure() {
314 Vector<MediaResource> resources;
315 resources.push_back(MediaResource(String8(kResourceNonSecureCodec), 1));
316 resources.push_back(MediaResource(String8(kResourceGraphicMemory), 150));
317
318 // ### secure codec can't coexist with non-secure codec ###
319 {
320 addResource();
321 mService->mSupportsSecureWithNonSecureCodec = false;
322
323 // priority too low
324 EXPECT_FALSE(mService->reclaimResource(40, resources));
325 EXPECT_FALSE(mService->reclaimResource(25, resources));
326
327 // reclaim all secure codecs
328 EXPECT_TRUE(mService->reclaimResource(10, resources));
329 verifyClients(true, false, true);
330
331 // call again should reclaim one graphic memory from lowest process
332 EXPECT_TRUE(mService->reclaimResource(10, resources));
333 verifyClients(false, true, false);
334
335 // nothing left
336 EXPECT_FALSE(mService->reclaimResource(10, resources));
337 }
338
339
340 // ### secure codec can coexist with non-secure codec ###
341 {
342 addResource();
343 mService->mSupportsSecureWithNonSecureCodec = true;
344
345 // priority too low
346 EXPECT_FALSE(mService->reclaimResource(40, resources));
347
348 EXPECT_TRUE(mService->reclaimResource(10, resources));
349 // one largest graphic memory from lowest process got reclaimed
350 verifyClients(true, false, false);
351
352 // call again should reclaim another graphic memory from lowest process
353 EXPECT_TRUE(mService->reclaimResource(10, resources));
354 verifyClients(false, true, false);
355
356 // call again should reclaim another graphic memory from lowest process
357 EXPECT_TRUE(mService->reclaimResource(10, resources));
358 verifyClients(false, false, true);
359
360 // nothing left
361 EXPECT_FALSE(mService->reclaimResource(10, resources));
362 }
363 }
364
365 void testGetLowestPriorityBiggestClient() {
366 String8 type = String8(kResourceGraphicMemory);
367 sp<IResourceManagerClient> client;
368 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(10, type, &client));
369
370 addResource();
371
372 EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(100, type, &client));
373 EXPECT_TRUE(mService->getLowestPriorityBiggestClient_l(10, type, &client));
374
375 // kTestPid1 is the lowest priority process with kResourceGraphicMemory.
376 // mTestClient1 has the largest kResourceGraphicMemory within kTestPid1.
377 EXPECT_EQ(mTestClient1, client);
378 }
379
380 void testGetLowestPriorityPid() {
381 int pid;
382 int priority;
383 TestProcessInfo processInfo;
384
385 String8 type = String8(kResourceGraphicMemory);
386 EXPECT_FALSE(mService->getLowestPriorityPid_l(type, &pid, &priority));
387
388 addResource();
389
390 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
391 EXPECT_EQ(kTestPid1, pid);
392 int priority1;
393 processInfo.getPriority(kTestPid1, &priority1);
394 EXPECT_EQ(priority1, priority);
395
396 type = String8(kResourceNonSecureCodec);
397 EXPECT_TRUE(mService->getLowestPriorityPid_l(type, &pid, &priority));
398 EXPECT_EQ(kTestPid2, pid);
399 int priority2;
400 processInfo.getPriority(kTestPid2, &priority2);
401 EXPECT_EQ(priority2, priority);
402 }
403
404 void testGetBiggestClient() {
405 String8 type = String8(kResourceGraphicMemory);
406 sp<IResourceManagerClient> client;
407 EXPECT_FALSE(mService->getBiggestClient_l(kTestPid2, type, &client));
408
409 addResource();
410
411 EXPECT_TRUE(mService->getBiggestClient_l(kTestPid2, type, &client));
412 EXPECT_EQ(mTestClient2, client);
413 }
414
415 void testIsCallingPriorityHigher() {
416 EXPECT_FALSE(mService->isCallingPriorityHigher_l(101, 100));
417 EXPECT_FALSE(mService->isCallingPriorityHigher_l(100, 100));
418 EXPECT_TRUE(mService->isCallingPriorityHigher_l(99, 100));
419 }
420
421 sp<ResourceManagerService> mService;
422 sp<IResourceManagerClient> mTestClient1;
423 sp<IResourceManagerClient> mTestClient2;
424 sp<IResourceManagerClient> mTestClient3;
425};
426
427TEST_F(ResourceManagerServiceTest, config) {
428 testConfig();
429}
430
431TEST_F(ResourceManagerServiceTest, addResource) {
432 addResource();
433}
434
435TEST_F(ResourceManagerServiceTest, removeResource) {
436 testRemoveResource();
437}
438
439TEST_F(ResourceManagerServiceTest, reclaimResource) {
440 testReclaimResourceSecure();
441 testReclaimResourceNonSecure();
442}
443
444TEST_F(ResourceManagerServiceTest, getAllClients_l) {
445 testGetAllClients();
446}
447
448TEST_F(ResourceManagerServiceTest, getLowestPriorityBiggestClient_l) {
449 testGetLowestPriorityBiggestClient();
450}
451
452TEST_F(ResourceManagerServiceTest, getLowestPriorityPid_l) {
453 testGetLowestPriorityPid();
454}
455
456TEST_F(ResourceManagerServiceTest, getBiggestClient_l) {
457 testGetBiggestClient();
458}
459
460TEST_F(ResourceManagerServiceTest, isCallingPriorityHigher_l) {
461 testIsCallingPriorityHigher();
462}
463
464} // namespace android