1 /*
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 
28 namespace android {
29 
30 using ::aidl::android::media::BnResourceObserver;
31 using ::aidl::android::media::MediaObservableParcel;
32 using ::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 
38 struct 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 
toStringandroid::EventTracker48     static std::string toString(const MediaObservableParcel& observable) {
49         return "{" + ::aidl::android::media::toString(observable.type)
50         + ", " + std::to_string(observable.value) + "}";
51     }
toStringandroid::EventTracker52     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 
Busyandroid::EventTracker75     static Event Busy(int uid, int pid, const std::vector<MediaObservableParcel>& observables) {
76         return { Event::Busy, uid, pid, observables };
77     }
Idleandroid::EventTracker78     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.
popandroid::EventTracker83     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.
appendandroid::EventTracker101     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 
110 private:
111     std::mutex mLock;
112     std::condition_variable mCondition;
113     Event mPoppedEvent;
114     std::list<Event> mEventQueue;
115 };
116 
117 const EventTracker::Event EventTracker::NoEvent;
118 
119 // Operators for GTest macros.
operator ==(const EventTracker::Event & lhs,const EventTracker::Event & rhs)120 bool 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 
operator <<(std::ostream & str,const EventTracker::Event & v)125 std::ostream& operator<<(std::ostream& str, const EventTracker::Event& v) {
126     str << EventTracker::toString(v);
127     return str;
128 }
129 
130 struct TestObserver : public BnResourceObserver, public EventTracker {
TestObserverandroid::TestObserver131     TestObserver(const char *name) : mName(name) {}
132     ~TestObserver() = default;
onStatusChangedandroid::TestObserver133     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 
147 class ResourceObserverServiceTest : public ResourceManagerServiceTestBase {
148 public:
ResourceObserverServiceTest()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 
registerObservers(MediaObservableEvent filter=ALL)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 
174 protected:
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 
TEST_F(ResourceObserverServiceTest,testRegisterObserver)181 TEST_F(ResourceObserverServiceTest, testRegisterObserver) {
182     std::vector<MediaObservableFilter> filters1;
183     Status status;
184 
185     // Register with null observer should fail.
186     status = mObserverService->registerObserver(nullptr, filters1);
187     EXPECT_FALSE(status.isOk());
188     EXPECT_EQ(status.getServiceSpecificError(), BAD_VALUE);
189 
190     // Register with empty observables should fail.
191     status = mObserverService->registerObserver(mTestObserver1, filters1);
192     EXPECT_FALSE(status.isOk());
193     EXPECT_EQ(status.getServiceSpecificError(), BAD_VALUE);
194 
195     // mTestObserver1 monitors secure video codecs.
196     filters1 = {{MediaObservableType::kVideoSecureCodec, ALL}};
197     EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
198 
199     // Register duplicates should fail.
200     status = mObserverService->registerObserver(mTestObserver1, filters1);
201     EXPECT_FALSE(status.isOk());
202     EXPECT_EQ(status.getServiceSpecificError(), ALREADY_EXISTS);
203 }
204 
TEST_F(ResourceObserverServiceTest,testUnregisterObserver)205 TEST_F(ResourceObserverServiceTest, testUnregisterObserver) {
206     std::vector<MediaObservableFilter> filters1;
207     Status status;
208 
209     // Unregister without registering first should fail.
210     status = mObserverService->unregisterObserver(mTestObserver1);
211     EXPECT_FALSE(status.isOk());
212     EXPECT_EQ(status.getServiceSpecificError(), NAME_NOT_FOUND);
213 
214     // mTestObserver1 monitors secure video codecs.
215     filters1 = {{MediaObservableType::kVideoSecureCodec, ALL}};
216     EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
217     EXPECT_TRUE(mObserverService->unregisterObserver(mTestObserver1).isOk());
218 
219     // Unregister again should fail.
220     status = mObserverService->unregisterObserver(mTestObserver1);
221     EXPECT_FALSE(status.isOk());
222     EXPECT_EQ(status.getServiceSpecificError(), NAME_NOT_FOUND);
223 }
224 
TEST_F(ResourceObserverServiceTest,testAddResourceBasic)225 TEST_F(ResourceObserverServiceTest, testAddResourceBasic) {
226     registerObservers();
227 
228     std::vector<MediaObservableParcel> observables1, observables2, observables3;
229     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
230     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
231     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
232                    {MediaObservableType::kVideoNonSecureCodec, 1}};
233 
234     std::vector<MediaResourceParcel> resources;
235     // Add secure video codec.
236     resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/)};
237     mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
238     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
239     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
240     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
241 
242     // Add non-secure video codec.
243     resources = {MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
244     mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources);
245     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
246     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
247     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
248 
249     // Add secure & non-secure video codecs.
250     resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
251                  MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
252     mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
253     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
254     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
255     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
256 
257     // Add additional audio codecs, should be ignored.
258     resources.push_back(MediaResource::CodecResource(1 /*secure*/, 0 /*video*/));
259     resources.push_back(MediaResource::CodecResource(0 /*secure*/, 0 /*video*/));
260     mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
261     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
262     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables2));
263     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables3));
264 }
265 
TEST_F(ResourceObserverServiceTest,testAddResourceMultiple)266 TEST_F(ResourceObserverServiceTest, testAddResourceMultiple) {
267     registerObservers();
268 
269     std::vector<MediaObservableParcel> observables1, observables2, observables3;
270     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
271     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
272     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
273                    {MediaObservableType::kVideoNonSecureCodec, 1}};
274 
275     std::vector<MediaResourceParcel> resources;
276 
277     // Add multiple secure & non-secure video codecs.
278     // Multiple entries of the same type should be merged, count should be propagated correctly.
279     resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
280                  MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
281                  MediaResource::CodecResource(0 /*secure*/, 1 /*video*/, 3 /*count*/)};
282     observables1 = {{MediaObservableType::kVideoSecureCodec, 2}};
283     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 3}};
284     observables3 = {{MediaObservableType::kVideoSecureCodec, 2},
285                    {MediaObservableType::kVideoNonSecureCodec, 3}};
286     mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
287     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
288     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
289     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
290 }
291 
TEST_F(ResourceObserverServiceTest,testRemoveResourceBasic)292 TEST_F(ResourceObserverServiceTest, testRemoveResourceBasic) {
293     registerObservers();
294 
295     std::vector<MediaObservableParcel> observables1, observables2, observables3;
296     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
297     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
298     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
299                    {MediaObservableType::kVideoNonSecureCodec, 1}};
300 
301     std::vector<MediaResourceParcel> resources;
302     // Add secure video codec to client1.
303     resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/)};
304     mService->addResource(kTestPid1, kTestUid1, getId(mTestClient1), mTestClient1, resources);
305     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
306     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
307     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
308     // Remove secure video codec. observer 1&3 should receive updates.
309     mService->removeResource(kTestPid1, getId(mTestClient1), resources);
310     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid1, kTestPid1, observables1));
311     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
312     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid1, kTestPid1, observables1));
313     // Remove secure video codec again, should have no event.
314     mService->removeResource(kTestPid1, getId(mTestClient1), resources);
315     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
316     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
317     EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
318     // Remove client1, should have no event.
319     mService->removeClient(kTestPid1, getId(mTestClient1));
320     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
321     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
322     EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
323 
324     // Add non-secure video codec to client2.
325     resources = {MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
326     mService->addResource(kTestPid2, kTestUid2, getId(mTestClient2), mTestClient2, resources);
327     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
328     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
329     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
330     // Remove client2, observer 2&3 should receive updates.
331     mService->removeClient(kTestPid2, getId(mTestClient2));
332     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
333     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
334     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
335     // Remove non-secure codec after client2 removed, should have no event.
336     mService->removeResource(kTestPid2, getId(mTestClient2), resources);
337     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
338     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
339     EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
340     // Remove client2 again, should have no event.
341     mService->removeClient(kTestPid2, getId(mTestClient2));
342     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
343     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
344     EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
345 
346     // Add secure & non-secure video codecs, plus audio codecs (that's ignored).
347     resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
348                  MediaResource::CodecResource(0 /*secure*/, 1 /*video*/),
349                  MediaResource::CodecResource(1 /*secure*/, 0 /*video*/),
350                  MediaResource::CodecResource(0 /*secure*/, 0 /*video*/)};
351     mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
352     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
353     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
354     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
355     // Remove one audio codec, should have no event.
356     resources = {MediaResource::CodecResource(1 /*secure*/, 0 /*video*/)};
357     mService->removeResource(kTestPid2, getId(mTestClient3), resources);
358     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
359     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
360     EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
361     // Remove the other audio codec and the secure video codec, only secure video codec
362     // removal should be reported.
363     resources = {MediaResource::CodecResource(0 /*secure*/, 0 /*video*/),
364                  MediaResource::CodecResource(1 /*secure*/, 1 /*video*/)};
365     mService->removeResource(kTestPid2, getId(mTestClient3), resources);
366     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
367     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
368     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
369     // Remove client3 entirely. Non-secure video codec removal should be reported.
370     mService->removeClient(kTestPid2, getId(mTestClient3));
371     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
372     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
373     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
374 }
375 
TEST_F(ResourceObserverServiceTest,testRemoveResourceMultiple)376 TEST_F(ResourceObserverServiceTest, testRemoveResourceMultiple) {
377     registerObservers();
378 
379     std::vector<MediaObservableParcel> observables1, observables2, observables3;
380     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
381     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
382     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
383                     {MediaObservableType::kVideoNonSecureCodec, 1}};
384 
385     std::vector<MediaResourceParcel> resources;
386 
387     // Add multiple secure & non-secure video codecs, plus audio codecs (that's ignored).
388     // (ResourceManager will merge these internally.)
389     resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
390                  MediaResource::CodecResource(0 /*secure*/, 1 /*video*/, 4 /*count*/),
391                  MediaResource::CodecResource(1 /*secure*/, 0 /*video*/),
392                  MediaResource::CodecResource(0 /*secure*/, 0 /*video*/)};
393     mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
394     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
395     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 4}};
396     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
397                     {MediaObservableType::kVideoNonSecureCodec, 4}};
398     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
399     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
400     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
401     // Remove one audio codec, 2 secure video codecs and 2 non-secure video codecs.
402     // 1 secure video codec removal and 2 non-secure video codec removals should be reported.
403     resources = {MediaResource::CodecResource(0 /*secure*/, 0 /*video*/),
404                  MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
405                  MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
406                  MediaResource::CodecResource(0 /*secure*/, 1 /*video*/, 2 /*count*/)};
407     mService->removeResource(kTestPid2, getId(mTestClient3), resources);
408     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
409     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 2}};
410     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
411                     {MediaObservableType::kVideoNonSecureCodec, 2}};
412     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
413     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
414     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables3));
415     // Remove client3 entirely. 2 non-secure video codecs removal should be reported.
416     mService->removeClient(kTestPid2, getId(mTestClient3));
417     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
418     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
419     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
420 }
421 
TEST_F(ResourceObserverServiceTest,testEventFilters)422 TEST_F(ResourceObserverServiceTest, testEventFilters) {
423     // Register observers with different event filters.
424     std::vector<MediaObservableFilter> filters1, filters2, filters3;
425     filters1 = {{MediaObservableType::kVideoSecureCodec, BUSY}};
426     filters2 = {{MediaObservableType::kVideoNonSecureCodec, IDLE}};
427     filters3 = {{MediaObservableType::kVideoSecureCodec, IDLE},
428                {MediaObservableType::kVideoNonSecureCodec, BUSY}};
429 
430     // mTestObserver1 monitors secure video codecs.
431     EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
432 
433     // mTestObserver2 monitors non-secure video codecs.
434     EXPECT_TRUE(mObserverService->registerObserver(mTestObserver2, filters2).isOk());
435 
436     // mTestObserver3 monitors both secure & non-secure video codecs.
437     EXPECT_TRUE(mObserverService->registerObserver(mTestObserver3, filters3).isOk());
438 
439     std::vector<MediaObservableParcel> observables1, observables2;
440     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
441     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
442 
443     std::vector<MediaResourceParcel> resources;
444 
445     // Add secure & non-secure video codecs.
446     resources = {MediaResource::CodecResource(1 /*secure*/, 1 /*video*/),
447                  MediaResource::CodecResource(0 /*secure*/, 1 /*video*/)};
448     mService->addResource(kTestPid2, kTestUid2, getId(mTestClient3), mTestClient3, resources);
449     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
450     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
451     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
452 
453     // Remove secure & non-secure video codecs.
454     mService->removeResource(kTestPid2, getId(mTestClient3), resources);
455     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
456     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
457     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
458 }
459 
460 } // namespace android
461