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