blob: e3d3e781a0e4721ab1d92634919c121ada9ad19c [file] [log] [blame]
Chong Zhanga9d45c72020-09-09 12:41:17 -07001/*
2 * Copyright 2020 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 "ResourceObserverService_test"
19
20#include <iostream>
21#include <list>
22
23#include <aidl/android/media/BnResourceObserver.h>
24#include <utils/Log.h>
25#include "ResourceObserverService.h"
26#include "ResourceManagerServiceTestUtils.h"
27
Chong Zhanga9d45c72020-09-09 12:41:17 -070028namespace android {
29
30using ::aidl::android::media::BnResourceObserver;
31using ::aidl::android::media::MediaObservableParcel;
32using ::aidl::android::media::MediaObservableType;
33
34#define BUSY ::aidl::android::media::MediaObservableEvent::kBusy
35#define IDLE ::aidl::android::media::MediaObservableEvent::kIdle
36#define ALL ::aidl::android::media::MediaObservableEvent::kAll
37
38struct EventTracker {
39 struct Event {
40 enum { NoEvent, Busy, Idle } type = NoEvent;
41 int uid = 0;
42 int pid = 0;
43 std::vector<MediaObservableParcel> observables;
44 };
45
46 static const Event NoEvent;
47
48 static std::string toString(const MediaObservableParcel& observable) {
49 return "{" + ::aidl::android::media::toString(observable.type)
50 + ", " + std::to_string(observable.value) + "}";
51 }
52 static std::string toString(const Event& event) {
53 std::string eventStr;
54 switch (event.type) {
55 case Event::Busy:
56 eventStr = "Busy";
57 break;
58 case Event::Idle:
59 eventStr = "Idle";
60 break;
61 default:
62 return "NoEvent";
63 }
64 std::string observableStr;
65 for (auto &observable : event.observables) {
66 if (!observableStr.empty()) {
67 observableStr += ", ";
68 }
69 observableStr += toString(observable);
70 }
71 return "{" + eventStr + ", " + std::to_string(event.uid) + ", "
72 + std::to_string(event.pid) + ", {" + observableStr + "}}";
73 }
74
75 static Event Busy(int uid, int pid, const std::vector<MediaObservableParcel>& observables) {
76 return { Event::Busy, uid, pid, observables };
77 }
78 static Event Idle(int uid, int pid, const std::vector<MediaObservableParcel>& observables) {
79 return { Event::Idle, uid, pid, observables };
80 }
81
82 // Pop 1 event from front, wait for up to timeoutUs if empty.
83 const Event& pop(int64_t timeoutUs = 0) {
84 std::unique_lock lock(mLock);
85
86 if (mEventQueue.empty() && timeoutUs > 0) {
87 mCondition.wait_for(lock, std::chrono::microseconds(timeoutUs));
88 }
89
90 if (mEventQueue.empty()) {
91 mPoppedEvent = NoEvent;
92 } else {
93 mPoppedEvent = *mEventQueue.begin();
94 mEventQueue.pop_front();
95 }
96
97 return mPoppedEvent;
98 }
99
100 // Push 1 event to back.
101 void append(const Event& event) {
102 ALOGD("%s", toString(event).c_str());
103
104 std::unique_lock lock(mLock);
105
106 mEventQueue.push_back(event);
107 mCondition.notify_one();
108 }
109
110private:
111 std::mutex mLock;
112 std::condition_variable mCondition;
113 Event mPoppedEvent;
114 std::list<Event> mEventQueue;
115};
116
117const EventTracker::Event EventTracker::NoEvent;
118
119// Operators for GTest macros.
120bool operator==(const EventTracker::Event& lhs, const EventTracker::Event& rhs) {
121 return lhs.type == rhs.type && lhs.uid == rhs.uid && lhs.pid == rhs.pid &&
122 lhs.observables == rhs.observables;
123}
124
125std::ostream& operator<<(std::ostream& str, const EventTracker::Event& v) {
126 str << EventTracker::toString(v);
127 return str;
128}
129
130struct TestObserver : public BnResourceObserver, public EventTracker {
131 TestObserver(const char *name) : mName(name) {}
132 ~TestObserver() = default;
133 Status onStatusChanged(MediaObservableEvent event, int32_t uid, int32_t pid,
134 const std::vector<MediaObservableParcel>& observables) override {
135 ALOGD("%s: %s", mName.c_str(), __FUNCTION__);
136 if (event == MediaObservableEvent::kBusy) {
137 append(Busy(uid, pid, observables));
138 } else {
139 append(Idle(uid, pid, observables));
140 }
141
142 return Status::ok();
143 }
144 std::string mName;
145};
146
147class ResourceObserverServiceTest : public ResourceManagerServiceTestBase {
148public:
149 ResourceObserverServiceTest() : ResourceManagerServiceTestBase(),
150 mObserverService(::ndk::SharedRefBase::make<ResourceObserverService>()),
151 mTestObserver1(::ndk::SharedRefBase::make<TestObserver>("observer1")),
152 mTestObserver2(::ndk::SharedRefBase::make<TestObserver>("observer2")),
153 mTestObserver3(::ndk::SharedRefBase::make<TestObserver>("observer3")) {
154 mService->setObserverService(mObserverService);
155 }
156
157 void registerObservers(MediaObservableEvent filter = ALL) {
158 std::vector<MediaObservableFilter> filters1, filters2, filters3;
159 filters1 = {{MediaObservableType::kVideoSecureCodec, filter}};
160 filters2 = {{MediaObservableType::kVideoNonSecureCodec, filter}};
161 filters3 = {{MediaObservableType::kVideoSecureCodec, filter},
162 {MediaObservableType::kVideoNonSecureCodec, filter}};
163
164 // mTestObserver1 monitors secure video codecs.
165 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
166
167 // mTestObserver2 monitors non-secure video codecs.
168 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver2, filters2).isOk());
169
170 // mTestObserver3 monitors both secure & non-secure video codecs.
171 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver3, filters3).isOk());
172 }
173
174protected:
175 std::shared_ptr<ResourceObserverService> mObserverService;
176 std::shared_ptr<TestObserver> mTestObserver1;
177 std::shared_ptr<TestObserver> mTestObserver2;
178 std::shared_ptr<TestObserver> mTestObserver3;
179};
180
181TEST_F(ResourceObserverServiceTest, testRegisterObserver) {
182 std::vector<MediaObservableFilter> filters1;
183 Status status;
184
185 // Register with empty observables should fail.
186 status = mObserverService->registerObserver(mTestObserver1, filters1);
187 EXPECT_FALSE(status.isOk());
188 EXPECT_EQ(status.getServiceSpecificError(), BAD_VALUE);
189
190 // mTestObserver1 monitors secure video codecs.
191 filters1 = {{MediaObservableType::kVideoSecureCodec, ALL}};
192 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
193
194 // Register duplicates should fail.
195 status = mObserverService->registerObserver(mTestObserver1, filters1);
196 EXPECT_FALSE(status.isOk());
197 EXPECT_EQ(status.getServiceSpecificError(), ALREADY_EXISTS);
198}
199
200TEST_F(ResourceObserverServiceTest, testUnregisterObserver) {
201 std::vector<MediaObservableFilter> filters1;
202 Status status;
203
204 // Unregister without registering first should fail.
205 status = mObserverService->unregisterObserver(mTestObserver1);
206 EXPECT_FALSE(status.isOk());
207 EXPECT_EQ(status.getServiceSpecificError(), NAME_NOT_FOUND);
208
209 // mTestObserver1 monitors secure video codecs.
210 filters1 = {{MediaObservableType::kVideoSecureCodec, ALL}};
211 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
212 EXPECT_TRUE(mObserverService->unregisterObserver(mTestObserver1).isOk());
213
214 // Unregister again should fail.
215 status = mObserverService->unregisterObserver(mTestObserver1);
216 EXPECT_FALSE(status.isOk());
217 EXPECT_EQ(status.getServiceSpecificError(), NAME_NOT_FOUND);
218}
219
220TEST_F(ResourceObserverServiceTest, testAddResourceBasic) {
221 registerObservers();
222
223 std::vector<MediaObservableParcel> observables1, observables2, observables3;
224 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
225 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
226 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
227 {MediaObservableType::kVideoNonSecureCodec, 1}};
228
229 std::vector<MediaResourceParcel> resources;
230 // Add secure video codec.
231 resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/)};
232 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
233 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
234 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
235 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
236
237 // Add non-secure video codec.
238 resources = {MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
239 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources);
240 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
241 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
242 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
243
244 // Add secure & non-secure video codecs.
245 resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
246 MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
247 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
248 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
249 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
250 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
251
252 // Add additional audio codecs, should be ignored.
253 resources.push_back(MediaResource::CodecResource(1 /*secure*/, 0 /*video*/));
254 resources.push_back(MediaResource::CodecResource(0 /*secure*/, 0 /*video*/));
255 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
256 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
257 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables2));
258 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables3));
259}
260
261TEST_F(ResourceObserverServiceTest, testAddResourceMultiple) {
262 registerObservers();
263
264 std::vector<MediaObservableParcel> observables1, observables2, observables3;
265 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
266 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
267 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
268 {MediaObservableType::kVideoNonSecureCodec, 1}};
269
270 std::vector<MediaResourceParcel> resources;
271
272 // Add multiple secure & non-secure video codecs.
273 // Multiple entries of the same type should be merged, count should be propagated correctly.
274 resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
275 MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
276 MediaResource::CodecResource(0 /*secure*/, 1 /*video*/, 3 /*count*/)};
277 observables1 = {{MediaObservableType::kVideoSecureCodec, 2}};
278 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 3}};
279 observables3 = {{MediaObservableType::kVideoSecureCodec, 2},
280 {MediaObservableType::kVideoNonSecureCodec, 3}};
281 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
282 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
283 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
284 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
285}
286
287TEST_F(ResourceObserverServiceTest, testRemoveResourceBasic) {
288 registerObservers();
289
290 std::vector<MediaObservableParcel> observables1, observables2, observables3;
291 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
292 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
293 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
294 {MediaObservableType::kVideoNonSecureCodec, 1}};
295
296 std::vector<MediaResourceParcel> resources;
297 // Add secure video codec to client1.
298 resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/)};
299 mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
300 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
301 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
302 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
303 // Remove secure video codec. observer 1&3 should receive updates.
304 mService->removeResource(kTestPid1, getId(mTestClient1), resources);
305 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid1, kTestPid1, observables1));
306 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
307 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid1, kTestPid1, observables1));
308 // Remove secure video codec again, should have no event.
309 mService->removeResource(kTestPid1, getId(mTestClient1), resources);
310 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
311 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
312 EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
313 // Remove client1, should have no event.
314 mService->removeClient(kTestPid1, getId(mTestClient1));
315 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
316 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
317 EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
318
319 // Add non-secure video codec to client2.
320 resources = {MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
321 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources);
322 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
323 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
324 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
325 // Remove client2, observer 2&3 should receive updates.
326 mService->removeClient(kTestPid2, getId(mTestClient2));
327 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
328 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
329 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
330 // Remove non-secure codec after client2 removed, should have no event.
331 mService->removeResource(kTestPid2, getId(mTestClient2), resources);
332 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
333 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
334 EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
335 // Remove client2 again, should have no event.
336 mService->removeClient(kTestPid2, getId(mTestClient2));
337 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
338 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
339 EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
340
341 // Add secure & non-secure video codecs, plus audio codecs (that's ignored).
342 resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
343 MediaResource::CodecResource(0 /*secure*/, 1 /*video*/),
344 MediaResource::CodecResource(1 /*secure*/, 0 /*video*/),
345 MediaResource::CodecResource(0 /*secure*/, 0 /*video*/)};
346 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
347 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
348 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
349 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
350 // Remove one audio codec, should have no event.
351 resources = {MediaResource::CodecResource(1 /*secure*/, 0 /*video*/)};
352 mService->removeResource(kTestPid2, getId(mTestClient3), resources);
353 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
354 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
355 EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
356 // Remove the other audio codec and the secure video codec, only secure video codec
357 // removal should be reported.
358 resources = {MediaResource::CodecResource(0 /*secure*/, 0 /*video*/),
359 MediaResource::CodecResource(1 /*secure*/, 1 /*video*/)};
360 mService->removeResource(kTestPid2, getId(mTestClient3), resources);
361 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
362 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
363 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
364 // Remove client3 entirely. Non-secure video codec removal should be reported.
365 mService->removeClient(kTestPid2, getId(mTestClient3));
366 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
367 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
368 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
369}
370
371TEST_F(ResourceObserverServiceTest, testRemoveResourceMultiple) {
372 registerObservers();
373
374 std::vector<MediaObservableParcel> observables1, observables2, observables3;
375 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
376 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
377 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
378 {MediaObservableType::kVideoNonSecureCodec, 1}};
379
380 std::vector<MediaResourceParcel> resources;
381
382 // Add multiple secure & non-secure video codecs, plus audio codecs (that's ignored).
383 // (ResourceManager will merge these internally.)
384 resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
385 MediaResource::CodecResource(0 /*secure*/, 1 /*video*/, 4 /*count*/),
386 MediaResource::CodecResource(1 /*secure*/, 0 /*video*/),
387 MediaResource::CodecResource(0 /*secure*/, 0 /*video*/)};
388 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
389 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
390 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 4}};
391 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
392 {MediaObservableType::kVideoNonSecureCodec, 4}};
393 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
394 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
395 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
396 // Remove one audio codec, 2 secure video codecs and 2 non-secure video codecs.
397 // 1 secure video codec removal and 2 non-secure video codec removals should be reported.
398 resources = {MediaResource::CodecResource(0 /*secure*/, 0 /*video*/),
399 MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
400 MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
401 MediaResource::CodecResource(0 /*secure*/, 1 /*video*/, 2 /*count*/)};
402 mService->removeResource(kTestPid2, getId(mTestClient3), resources);
403 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
404 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 2}};
405 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
406 {MediaObservableType::kVideoNonSecureCodec, 2}};
407 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
408 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
409 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables3));
410 // Remove client3 entirely. 2 non-secure video codecs removal should be reported.
411 mService->removeClient(kTestPid2, getId(mTestClient3));
412 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
413 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
414 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
415}
416
417TEST_F(ResourceObserverServiceTest, testEventFilters) {
418 // Register observers with different event filters.
419 std::vector<MediaObservableFilter> filters1, filters2, filters3;
420 filters1 = {{MediaObservableType::kVideoSecureCodec, BUSY}};
421 filters2 = {{MediaObservableType::kVideoNonSecureCodec, IDLE}};
422 filters3 = {{MediaObservableType::kVideoSecureCodec, IDLE},
423 {MediaObservableType::kVideoNonSecureCodec, BUSY}};
424
425 // mTestObserver1 monitors secure video codecs.
426 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
427
428 // mTestObserver2 monitors non-secure video codecs.
429 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver2, filters2).isOk());
430
431 // mTestObserver3 monitors both secure & non-secure video codecs.
432 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver3, filters3).isOk());
433
434 std::vector<MediaObservableParcel> observables1, observables2;
435 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
436 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
437
438 std::vector<MediaResourceParcel> resources;
439
440 // Add secure & non-secure video codecs.
441 resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
442 MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
443 mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
444 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
445 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
446 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
447
448 // Remove secure & non-secure video codecs.
449 mService->removeResource(kTestPid2, getId(mTestClient3), resources);
450 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
451 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
452 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
453}
454
455} // namespace android