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 
createSecureVideoCodecResource(int amount=1)119 static MediaResource createSecureVideoCodecResource(int amount = 1) {
120     return MediaResource(MediaResource::Type::kSecureCodec,
121         MediaResource::SubType::kHwVideoCodec, amount);
122 }
123 
createNonSecureVideoCodecResource(int amount=1)124 static MediaResource createNonSecureVideoCodecResource(int amount = 1) {
125     return MediaResource(MediaResource::Type::kNonSecureCodec,
126         MediaResource::SubType::kHwVideoCodec, amount);
127 }
128 
createSecureAudioCodecResource(int amount=1)129 static MediaResource createSecureAudioCodecResource(int amount = 1) {
130     return MediaResource(MediaResource::Type::kSecureCodec,
131         MediaResource::SubType::kHwAudioCodec, amount);
132 }
133 
createNonSecureAudioCodecResource(int amount=1)134 static MediaResource createNonSecureAudioCodecResource(int amount = 1) {
135     return MediaResource(MediaResource::Type::kNonSecureCodec,
136         MediaResource::SubType::kHwAudioCodec, amount);
137 }
138 
139 // Operators for GTest macros.
operator ==(const EventTracker::Event & lhs,const EventTracker::Event & rhs)140 bool operator==(const EventTracker::Event& lhs, const EventTracker::Event& rhs) {
141     return lhs.type == rhs.type && lhs.uid == rhs.uid && lhs.pid == rhs.pid &&
142             lhs.observables == rhs.observables;
143 }
144 
operator <<(std::ostream & str,const EventTracker::Event & v)145 std::ostream& operator<<(std::ostream& str, const EventTracker::Event& v) {
146     str << EventTracker::toString(v);
147     return str;
148 }
149 
150 struct TestObserver : public BnResourceObserver, public EventTracker {
TestObserverandroid::TestObserver151     TestObserver(const char *name) : mName(name) {}
152     ~TestObserver() = default;
onStatusChangedandroid::TestObserver153     Status onStatusChanged(MediaObservableEvent event, int32_t uid, int32_t pid,
154             const std::vector<MediaObservableParcel>& observables) override {
155         ALOGD("%s: %s", mName.c_str(), __FUNCTION__);
156         if (event == MediaObservableEvent::kBusy) {
157             append(Busy(uid, pid, observables));
158         } else {
159             append(Idle(uid, pid, observables));
160         }
161 
162         return Status::ok();
163     }
164     std::string mName;
165 };
166 
167 class ResourceObserverServiceTest : public ResourceManagerServiceTestBase {
168 public:
ResourceObserverServiceTest()169     ResourceObserverServiceTest() : ResourceManagerServiceTestBase() {}
170 
SetUp()171     void SetUp() override {
172         ResourceManagerServiceTestBase::SetUp();
173         mObserverService = ::ndk::SharedRefBase::make<ResourceObserverService>();
174         mTestObserver1 = ::ndk::SharedRefBase::make<TestObserver>("observer1");
175         mTestObserver2 = ::ndk::SharedRefBase::make<TestObserver>("observer2");
176         mTestObserver3 = ::ndk::SharedRefBase::make<TestObserver>("observer3");
177         mService->setObserverService(mObserverService);
178     }
179 
registerObservers(MediaObservableEvent filter=ALL)180     void registerObservers(MediaObservableEvent filter = ALL) {
181         std::vector<MediaObservableFilter> filters1, filters2, filters3;
182         filters1 = {{MediaObservableType::kVideoSecureCodec, filter}};
183         filters2 = {{MediaObservableType::kVideoNonSecureCodec, filter}};
184         filters3 = {{MediaObservableType::kVideoSecureCodec, filter},
185                    {MediaObservableType::kVideoNonSecureCodec, filter}};
186 
187         // mTestObserver1 monitors secure video codecs.
188         EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
189 
190         // mTestObserver2 monitors non-secure video codecs.
191         EXPECT_TRUE(mObserverService->registerObserver(mTestObserver2, filters2).isOk());
192 
193         // mTestObserver3 monitors both secure & non-secure video codecs.
194         EXPECT_TRUE(mObserverService->registerObserver(mTestObserver3, filters3).isOk());
195     }
196 
197 protected:
198     std::shared_ptr<ResourceObserverService> mObserverService;
199     std::shared_ptr<TestObserver> mTestObserver1;
200     std::shared_ptr<TestObserver> mTestObserver2;
201     std::shared_ptr<TestObserver> mTestObserver3;
202 };
203 
TEST_F(ResourceObserverServiceTest,testRegisterObserver)204 TEST_F(ResourceObserverServiceTest, testRegisterObserver) {
205     std::vector<MediaObservableFilter> filters1;
206     Status status;
207 
208     // Register with null observer should fail.
209     status = mObserverService->registerObserver(nullptr, filters1);
210     EXPECT_FALSE(status.isOk());
211     EXPECT_EQ(status.getServiceSpecificError(), BAD_VALUE);
212 
213     // Register with empty observables should fail.
214     status = mObserverService->registerObserver(mTestObserver1, filters1);
215     EXPECT_FALSE(status.isOk());
216     EXPECT_EQ(status.getServiceSpecificError(), BAD_VALUE);
217 
218     // mTestObserver1 monitors secure video codecs.
219     filters1 = {{MediaObservableType::kVideoSecureCodec, ALL}};
220     EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
221 
222     // Register duplicates should fail.
223     status = mObserverService->registerObserver(mTestObserver1, filters1);
224     EXPECT_FALSE(status.isOk());
225     EXPECT_EQ(status.getServiceSpecificError(), ALREADY_EXISTS);
226 }
227 
TEST_F(ResourceObserverServiceTest,testUnregisterObserver)228 TEST_F(ResourceObserverServiceTest, testUnregisterObserver) {
229     std::vector<MediaObservableFilter> filters1;
230     Status status;
231 
232     // Unregister without registering first should fail.
233     status = mObserverService->unregisterObserver(mTestObserver1);
234     EXPECT_FALSE(status.isOk());
235     EXPECT_EQ(status.getServiceSpecificError(), NAME_NOT_FOUND);
236 
237     // mTestObserver1 monitors secure video codecs.
238     filters1 = {{MediaObservableType::kVideoSecureCodec, ALL}};
239     EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
240     EXPECT_TRUE(mObserverService->unregisterObserver(mTestObserver1).isOk());
241 
242     // Unregister again should fail.
243     status = mObserverService->unregisterObserver(mTestObserver1);
244     EXPECT_FALSE(status.isOk());
245     EXPECT_EQ(status.getServiceSpecificError(), NAME_NOT_FOUND);
246 }
247 
TEST_F(ResourceObserverServiceTest,testAddResourceBasic)248 TEST_F(ResourceObserverServiceTest, testAddResourceBasic) {
249     registerObservers();
250 
251     std::vector<MediaObservableParcel> observables1, observables2, observables3;
252     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
253     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
254     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
255                    {MediaObservableType::kVideoNonSecureCodec, 1}};
256 
257     ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
258                                  .uid = static_cast<int32_t>(kTestUid1),
259                                  .id = getId(mTestClient1),
260                                  .name = "none"};
261 
262     ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
263                                  .uid = static_cast<int32_t>(kTestUid2),
264                                  .id = getId(mTestClient2),
265                                  .name = "none"};
266 
267     ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
268                                  .uid = static_cast<int32_t>(kTestUid2),
269                                  .id = getId(mTestClient3),
270                                  .name = "none"};
271     std::vector<MediaResourceParcel> resources;
272     // Add secure video codec.
273     resources = {createSecureVideoCodecResource()};
274     mService->addResource(client1Info, mTestClient1, resources);
275     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
276     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
277     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
278 
279     // Add non-secure video codec.
280     resources = {createNonSecureVideoCodecResource()};
281     mService->addResource(client2Info, mTestClient2, resources);
282     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
283     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
284     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
285 
286     // Add secure & non-secure video codecs.
287     resources = {createSecureVideoCodecResource(),
288                  createNonSecureVideoCodecResource()};
289     mService->addResource(client3Info, 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     // Add additional audio codecs, should be ignored.
295     resources.push_back(createSecureAudioCodecResource());
296     resources.push_back(createNonSecureAudioCodecResource());
297     mService->addResource(client1Info, mTestClient1, resources);
298     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
299     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables2));
300     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables3));
301 }
302 
TEST_F(ResourceObserverServiceTest,testAddResourceMultiple)303 TEST_F(ResourceObserverServiceTest, testAddResourceMultiple) {
304     registerObservers();
305 
306     std::vector<MediaObservableParcel> observables1, observables2, observables3;
307     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
308     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
309     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
310                    {MediaObservableType::kVideoNonSecureCodec, 1}};
311 
312     std::vector<MediaResourceParcel> resources;
313 
314     // Add multiple secure & non-secure video codecs.
315     // Multiple entries of the same type should be merged, count should be propagated correctly.
316     resources = {createSecureVideoCodecResource(),
317                  createSecureVideoCodecResource(),
318                  createNonSecureVideoCodecResource(3)};
319     observables1 = {{MediaObservableType::kVideoSecureCodec, 2}};
320     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 3}};
321     observables3 = {{MediaObservableType::kVideoSecureCodec, 2},
322                    {MediaObservableType::kVideoNonSecureCodec, 3}};
323     ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
324                                  .uid = static_cast<int32_t>(kTestUid2),
325                                  .id = getId(mTestClient3),
326                                  .name = "none"};
327     mService->addResource(client3Info, mTestClient3, resources);
328     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
329     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
330     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
331 }
332 
TEST_F(ResourceObserverServiceTest,testRemoveResourceBasic)333 TEST_F(ResourceObserverServiceTest, testRemoveResourceBasic) {
334     registerObservers();
335 
336     std::vector<MediaObservableParcel> observables1, observables2, observables3;
337     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
338     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
339     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
340                    {MediaObservableType::kVideoNonSecureCodec, 1}};
341 
342     ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
343                                  .uid = static_cast<int32_t>(kTestUid1),
344                                  .id = getId(mTestClient1),
345                                  .name = "none"};
346 
347     ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
348                                  .uid = static_cast<int32_t>(kTestUid2),
349                                  .id = getId(mTestClient2),
350                                  .name = "none"};
351 
352     ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
353                                  .uid = static_cast<int32_t>(kTestUid2),
354                                  .id = getId(mTestClient3),
355                                  .name = "none"};
356     std::vector<MediaResourceParcel> resources;
357     // Add secure video codec to client1.
358     resources = {createSecureVideoCodecResource()};
359     mService->addResource(client1Info, mTestClient1, resources);
360     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
361     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
362     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
363     // Remove secure video codec. observer 1&3 should receive updates.
364     mService->removeResource(client1Info, resources);
365     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid1, kTestPid1, observables1));
366     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
367     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid1, kTestPid1, observables1));
368     // Remove secure video codec again, should have no event.
369     mService->removeResource(client1Info, resources);
370     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
371     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
372     EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
373     // Remove client1, should have no event.
374     mService->removeClient(client1Info);
375     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
376     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
377     EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
378 
379     // Add non-secure video codec to client2.
380     resources = {createNonSecureVideoCodecResource()};
381     mService->addResource(client2Info, mTestClient2, resources);
382     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
383     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
384     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
385     // Remove client2, observer 2&3 should receive updates.
386     mService->removeClient(client2Info);
387     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
388     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
389     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
390     // Remove non-secure codec after client2 removed, should have no event.
391     mService->removeResource(client2Info, resources);
392     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
393     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
394     EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
395     // Remove client2 again, should have no event.
396     mService->removeClient(client2Info);
397     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
398     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
399     EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
400 
401     // Add secure & non-secure video codecs, plus audio codecs (that's ignored).
402     resources = {createSecureVideoCodecResource(),
403                  createNonSecureVideoCodecResource(),
404                  createSecureAudioCodecResource(),
405                  createNonSecureAudioCodecResource()};
406     mService->addResource(client3Info, mTestClient3, resources);
407     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
408     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
409     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
410     // Remove one audio codec, should have no event.
411     resources = {createSecureAudioCodecResource()};
412     mService->removeResource(client3Info, resources);
413     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
414     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
415     EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
416     // Remove the other audio codec and the secure video codec, only secure video codec
417     // removal should be reported.
418     resources = {createNonSecureAudioCodecResource(),
419                  createSecureVideoCodecResource()};
420     mService->removeResource(client3Info, resources);
421     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
422     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
423     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
424     // Remove client3 entirely. Non-secure video codec removal should be reported.
425     mService->removeClient(client3Info);
426     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
427     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
428     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
429 }
430 
TEST_F(ResourceObserverServiceTest,testRemoveResourceMultiple)431 TEST_F(ResourceObserverServiceTest, testRemoveResourceMultiple) {
432     registerObservers();
433 
434     std::vector<MediaObservableParcel> observables1, observables2, observables3;
435     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
436     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
437     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
438                     {MediaObservableType::kVideoNonSecureCodec, 1}};
439 
440     std::vector<MediaResourceParcel> resources;
441 
442     // Add multiple secure & non-secure video codecs, plus audio codecs (that's ignored).
443     // (ResourceManager will merge these internally.)
444     resources = {createSecureVideoCodecResource(),
445                  createNonSecureVideoCodecResource(4),
446                  createSecureAudioCodecResource(),
447                  createNonSecureAudioCodecResource()};
448 
449     ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
450                                  .uid = static_cast<int32_t>(kTestUid2),
451                                  .id = getId(mTestClient3),
452                                  .name = "none"};
453     mService->addResource(client3Info, mTestClient3, resources);
454     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
455     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 4}};
456     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
457                     {MediaObservableType::kVideoNonSecureCodec, 4}};
458     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
459     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
460     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
461     // Remove one audio codec, 2 secure video codecs and 2 non-secure video codecs.
462     // 1 secure video codec removal and 2 non-secure video codec removals should be reported.
463     resources = {createNonSecureAudioCodecResource(),
464                  createSecureVideoCodecResource(),
465                  createSecureVideoCodecResource(),
466                  createNonSecureVideoCodecResource(2)};
467     mService->removeResource(client3Info, resources);
468     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
469     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 2}};
470     observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
471                     {MediaObservableType::kVideoNonSecureCodec, 2}};
472     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
473     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
474     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables3));
475     // Remove client3 entirely. 2 non-secure video codecs removal should be reported.
476     mService->removeClient(client3Info);
477     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
478     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
479     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
480 }
481 
TEST_F(ResourceObserverServiceTest,testEventFilters)482 TEST_F(ResourceObserverServiceTest, testEventFilters) {
483     // Register observers with different event filters.
484     std::vector<MediaObservableFilter> filters1, filters2, filters3;
485     filters1 = {{MediaObservableType::kVideoSecureCodec, BUSY}};
486     filters2 = {{MediaObservableType::kVideoNonSecureCodec, IDLE}};
487     filters3 = {{MediaObservableType::kVideoSecureCodec, IDLE},
488                {MediaObservableType::kVideoNonSecureCodec, BUSY}};
489 
490     // mTestObserver1 monitors secure video codecs.
491     EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
492 
493     // mTestObserver2 monitors non-secure video codecs.
494     EXPECT_TRUE(mObserverService->registerObserver(mTestObserver2, filters2).isOk());
495 
496     // mTestObserver3 monitors both secure & non-secure video codecs.
497     EXPECT_TRUE(mObserverService->registerObserver(mTestObserver3, filters3).isOk());
498 
499     std::vector<MediaObservableParcel> observables1, observables2;
500     observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
501     observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
502 
503     std::vector<MediaResourceParcel> resources;
504 
505     // Add secure & non-secure video codecs.
506     resources = {createSecureVideoCodecResource(),
507                  createNonSecureVideoCodecResource()};
508     ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
509                                  .uid = static_cast<int32_t>(kTestUid1),
510                                  .id = getId(mTestClient1),
511                                  .name = "none"};
512 
513     ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
514                                  .uid = static_cast<int32_t>(kTestUid2),
515                                  .id = getId(mTestClient2),
516                                  .name = "none"};
517 
518     ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
519                                  .uid = static_cast<int32_t>(kTestUid2),
520                                  .id = getId(mTestClient3),
521                                  .name = "none"};
522     mService->addResource(client3Info, mTestClient3, resources);
523     EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
524     EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
525     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
526 
527     // Remove secure & non-secure video codecs.
528     mService->removeResource(client3Info, resources);
529     EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
530     EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
531     EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
532 }
533 
534 } // namespace android
535