blob: a0d728c1f128f22fcc96e1a3915827477f6c7dbc [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
Brian Lindahla88d90c2022-01-17 10:38:35 +0100119static MediaResource createSecureVideoCodecResource(int amount = 1) {
120 return MediaResource(MediaResource::Type::kSecureCodec,
121 MediaResource::SubType::kVideoCodec, amount);
122}
123
124static MediaResource createNonSecureVideoCodecResource(int amount = 1) {
125 return MediaResource(MediaResource::Type::kNonSecureCodec,
126 MediaResource::SubType::kVideoCodec, amount);
127}
128
129static MediaResource createSecureAudioCodecResource(int amount = 1) {
130 return MediaResource(MediaResource::Type::kSecureCodec,
131 MediaResource::SubType::kAudioCodec, amount);
132}
133
134static MediaResource createNonSecureAudioCodecResource(int amount = 1) {
135 return MediaResource(MediaResource::Type::kNonSecureCodec,
136 MediaResource::SubType::kAudioCodec, amount);
137}
138
Chong Zhanga9d45c72020-09-09 12:41:17 -0700139// Operators for GTest macros.
140bool 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
145std::ostream& operator<<(std::ostream& str, const EventTracker::Event& v) {
146 str << EventTracker::toString(v);
147 return str;
148}
149
150struct TestObserver : public BnResourceObserver, public EventTracker {
151 TestObserver(const char *name) : mName(name) {}
152 ~TestObserver() = default;
153 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
167class ResourceObserverServiceTest : public ResourceManagerServiceTestBase {
168public:
169 ResourceObserverServiceTest() : ResourceManagerServiceTestBase(),
170 mObserverService(::ndk::SharedRefBase::make<ResourceObserverService>()),
171 mTestObserver1(::ndk::SharedRefBase::make<TestObserver>("observer1")),
172 mTestObserver2(::ndk::SharedRefBase::make<TestObserver>("observer2")),
173 mTestObserver3(::ndk::SharedRefBase::make<TestObserver>("observer3")) {
174 mService->setObserverService(mObserverService);
175 }
176
177 void registerObservers(MediaObservableEvent filter = ALL) {
178 std::vector<MediaObservableFilter> filters1, filters2, filters3;
179 filters1 = {{MediaObservableType::kVideoSecureCodec, filter}};
180 filters2 = {{MediaObservableType::kVideoNonSecureCodec, filter}};
181 filters3 = {{MediaObservableType::kVideoSecureCodec, filter},
182 {MediaObservableType::kVideoNonSecureCodec, filter}};
183
184 // mTestObserver1 monitors secure video codecs.
185 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
186
187 // mTestObserver2 monitors non-secure video codecs.
188 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver2, filters2).isOk());
189
190 // mTestObserver3 monitors both secure & non-secure video codecs.
191 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver3, filters3).isOk());
192 }
193
194protected:
195 std::shared_ptr<ResourceObserverService> mObserverService;
196 std::shared_ptr<TestObserver> mTestObserver1;
197 std::shared_ptr<TestObserver> mTestObserver2;
198 std::shared_ptr<TestObserver> mTestObserver3;
199};
200
201TEST_F(ResourceObserverServiceTest, testRegisterObserver) {
202 std::vector<MediaObservableFilter> filters1;
203 Status status;
204
Chong Zhanga781cee2021-03-17 11:42:33 -0700205 // Register with null observer should fail.
206 status = mObserverService->registerObserver(nullptr, filters1);
207 EXPECT_FALSE(status.isOk());
208 EXPECT_EQ(status.getServiceSpecificError(), BAD_VALUE);
209
Chong Zhanga9d45c72020-09-09 12:41:17 -0700210 // Register with empty observables should fail.
211 status = mObserverService->registerObserver(mTestObserver1, filters1);
212 EXPECT_FALSE(status.isOk());
213 EXPECT_EQ(status.getServiceSpecificError(), BAD_VALUE);
214
215 // mTestObserver1 monitors secure video codecs.
216 filters1 = {{MediaObservableType::kVideoSecureCodec, ALL}};
217 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
218
219 // Register duplicates should fail.
220 status = mObserverService->registerObserver(mTestObserver1, filters1);
221 EXPECT_FALSE(status.isOk());
222 EXPECT_EQ(status.getServiceSpecificError(), ALREADY_EXISTS);
223}
224
225TEST_F(ResourceObserverServiceTest, testUnregisterObserver) {
226 std::vector<MediaObservableFilter> filters1;
227 Status status;
228
229 // Unregister without registering first should fail.
230 status = mObserverService->unregisterObserver(mTestObserver1);
231 EXPECT_FALSE(status.isOk());
232 EXPECT_EQ(status.getServiceSpecificError(), NAME_NOT_FOUND);
233
234 // mTestObserver1 monitors secure video codecs.
235 filters1 = {{MediaObservableType::kVideoSecureCodec, ALL}};
236 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
237 EXPECT_TRUE(mObserverService->unregisterObserver(mTestObserver1).isOk());
238
239 // Unregister again should fail.
240 status = mObserverService->unregisterObserver(mTestObserver1);
241 EXPECT_FALSE(status.isOk());
242 EXPECT_EQ(status.getServiceSpecificError(), NAME_NOT_FOUND);
243}
244
245TEST_F(ResourceObserverServiceTest, testAddResourceBasic) {
246 registerObservers();
247
248 std::vector<MediaObservableParcel> observables1, observables2, observables3;
249 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
250 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
251 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
252 {MediaObservableType::kVideoNonSecureCodec, 1}};
253
Girish9128e242022-11-23 20:52:29 +0000254 ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
255 .uid = static_cast<int32_t>(kTestUid1),
256 .id = getId(mTestClient1),
257 .name = "none"};
258
259 ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
260 .uid = static_cast<int32_t>(kTestUid2),
261 .id = getId(mTestClient2),
262 .name = "none"};
263
264 ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
265 .uid = static_cast<int32_t>(kTestUid2),
266 .id = getId(mTestClient3),
267 .name = "none"};
Chong Zhanga9d45c72020-09-09 12:41:17 -0700268 std::vector<MediaResourceParcel> resources;
269 // Add secure video codec.
Brian Lindahla88d90c2022-01-17 10:38:35 +0100270 resources = {createSecureVideoCodecResource()};
Girish9128e242022-11-23 20:52:29 +0000271 mService->addResource(client1Info, mTestClient1, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700272 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
273 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
274 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
275
276 // Add non-secure video codec.
Brian Lindahla88d90c2022-01-17 10:38:35 +0100277 resources = {createNonSecureVideoCodecResource()};
Girish9128e242022-11-23 20:52:29 +0000278 mService->addResource(client2Info, mTestClient2, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700279 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
280 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
281 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
282
283 // Add secure & non-secure video codecs.
Brian Lindahla88d90c2022-01-17 10:38:35 +0100284 resources = {createSecureVideoCodecResource(),
285 createNonSecureVideoCodecResource()};
Girish9128e242022-11-23 20:52:29 +0000286 mService->addResource(client3Info, mTestClient3, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700287 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 // Add additional audio codecs, should be ignored.
Brian Lindahla88d90c2022-01-17 10:38:35 +0100292 resources.push_back(createSecureAudioCodecResource());
293 resources.push_back(createNonSecureAudioCodecResource());
Girish9128e242022-11-23 20:52:29 +0000294 mService->addResource(client1Info, mTestClient1, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700295 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
296 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables2));
297 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables3));
298}
299
300TEST_F(ResourceObserverServiceTest, testAddResourceMultiple) {
301 registerObservers();
302
303 std::vector<MediaObservableParcel> observables1, observables2, observables3;
304 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
305 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
306 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
307 {MediaObservableType::kVideoNonSecureCodec, 1}};
308
309 std::vector<MediaResourceParcel> resources;
310
311 // Add multiple secure & non-secure video codecs.
312 // Multiple entries of the same type should be merged, count should be propagated correctly.
Brian Lindahla88d90c2022-01-17 10:38:35 +0100313 resources = {createSecureVideoCodecResource(),
314 createSecureVideoCodecResource(),
315 createNonSecureVideoCodecResource(3)};
Chong Zhanga9d45c72020-09-09 12:41:17 -0700316 observables1 = {{MediaObservableType::kVideoSecureCodec, 2}};
317 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 3}};
318 observables3 = {{MediaObservableType::kVideoSecureCodec, 2},
319 {MediaObservableType::kVideoNonSecureCodec, 3}};
Girish9128e242022-11-23 20:52:29 +0000320 ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
321 .uid = static_cast<int32_t>(kTestUid2),
322 .id = getId(mTestClient3),
323 .name = "none"};
324 mService->addResource(client3Info, mTestClient3, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700325 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
326 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
327 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
328}
329
330TEST_F(ResourceObserverServiceTest, testRemoveResourceBasic) {
331 registerObservers();
332
333 std::vector<MediaObservableParcel> observables1, observables2, observables3;
334 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
335 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
336 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
337 {MediaObservableType::kVideoNonSecureCodec, 1}};
338
Girish9128e242022-11-23 20:52:29 +0000339 ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
340 .uid = static_cast<int32_t>(kTestUid1),
341 .id = getId(mTestClient1),
342 .name = "none"};
343
344 ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
345 .uid = static_cast<int32_t>(kTestUid2),
346 .id = getId(mTestClient2),
347 .name = "none"};
348
349 ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
350 .uid = static_cast<int32_t>(kTestUid2),
351 .id = getId(mTestClient3),
352 .name = "none"};
Chong Zhanga9d45c72020-09-09 12:41:17 -0700353 std::vector<MediaResourceParcel> resources;
354 // Add secure video codec to client1.
Brian Lindahla88d90c2022-01-17 10:38:35 +0100355 resources = {createSecureVideoCodecResource()};
Girish9128e242022-11-23 20:52:29 +0000356 mService->addResource(client1Info, mTestClient1, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700357 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
358 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
359 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid1, kTestPid1, observables1));
360 // Remove secure video codec. observer 1&3 should receive updates.
Girish9128e242022-11-23 20:52:29 +0000361 mService->removeResource(client1Info, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700362 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid1, kTestPid1, observables1));
363 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
364 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid1, kTestPid1, observables1));
365 // Remove secure video codec again, should have no event.
Girish9128e242022-11-23 20:52:29 +0000366 mService->removeResource(client1Info, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700367 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
368 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
369 EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
370 // Remove client1, should have no event.
Girish9128e242022-11-23 20:52:29 +0000371 mService->removeClient(client1Info);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700372 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
373 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
374 EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
375
376 // Add non-secure video codec to client2.
Brian Lindahla88d90c2022-01-17 10:38:35 +0100377 resources = {createNonSecureVideoCodecResource()};
Girish9128e242022-11-23 20:52:29 +0000378 mService->addResource(client2Info, mTestClient2, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700379 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
380 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
381 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
382 // Remove client2, observer 2&3 should receive updates.
Girish9128e242022-11-23 20:52:29 +0000383 mService->removeClient(client2Info);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700384 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
385 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
386 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
387 // Remove non-secure codec after client2 removed, should have no event.
Girish9128e242022-11-23 20:52:29 +0000388 mService->removeResource(client2Info, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700389 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
390 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
391 EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
392 // Remove client2 again, should have no event.
Girish9128e242022-11-23 20:52:29 +0000393 mService->removeClient(client2Info);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700394 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
395 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
396 EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
397
398 // Add secure & non-secure video codecs, plus audio codecs (that's ignored).
Brian Lindahla88d90c2022-01-17 10:38:35 +0100399 resources = {createSecureVideoCodecResource(),
400 createNonSecureVideoCodecResource(),
401 createSecureAudioCodecResource(),
402 createNonSecureAudioCodecResource()};
Girish9128e242022-11-23 20:52:29 +0000403 mService->addResource(client3Info, mTestClient3, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700404 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
405 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
406 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
407 // Remove one audio codec, should have no event.
Brian Lindahla88d90c2022-01-17 10:38:35 +0100408 resources = {createSecureAudioCodecResource()};
Girish9128e242022-11-23 20:52:29 +0000409 mService->removeResource(client3Info, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700410 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
411 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
412 EXPECT_EQ(mTestObserver3->pop(), EventTracker::NoEvent);
413 // Remove the other audio codec and the secure video codec, only secure video codec
414 // removal should be reported.
Brian Lindahla88d90c2022-01-17 10:38:35 +0100415 resources = {createNonSecureAudioCodecResource(),
416 createSecureVideoCodecResource()};
Girish9128e242022-11-23 20:52:29 +0000417 mService->removeResource(client3Info, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700418 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
419 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
420 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
421 // Remove client3 entirely. Non-secure video codec removal should be reported.
Girish9128e242022-11-23 20:52:29 +0000422 mService->removeClient(client3Info);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700423 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
424 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
425 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
426}
427
428TEST_F(ResourceObserverServiceTest, testRemoveResourceMultiple) {
429 registerObservers();
430
431 std::vector<MediaObservableParcel> observables1, observables2, observables3;
432 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
433 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
434 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
435 {MediaObservableType::kVideoNonSecureCodec, 1}};
436
437 std::vector<MediaResourceParcel> resources;
438
439 // Add multiple secure & non-secure video codecs, plus audio codecs (that's ignored).
440 // (ResourceManager will merge these internally.)
Brian Lindahla88d90c2022-01-17 10:38:35 +0100441 resources = {createSecureVideoCodecResource(),
442 createNonSecureVideoCodecResource(4),
443 createSecureAudioCodecResource(),
444 createNonSecureAudioCodecResource()};
Girish9128e242022-11-23 20:52:29 +0000445
446 ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
447 .uid = static_cast<int32_t>(kTestUid2),
448 .id = getId(mTestClient3),
449 .name = "none"};
450 mService->addResource(client3Info, mTestClient3, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700451 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
452 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 4}};
453 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
454 {MediaObservableType::kVideoNonSecureCodec, 4}};
455 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
456 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
457 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables3));
458 // Remove one audio codec, 2 secure video codecs and 2 non-secure video codecs.
459 // 1 secure video codec removal and 2 non-secure video codec removals should be reported.
Brian Lindahla88d90c2022-01-17 10:38:35 +0100460 resources = {createNonSecureAudioCodecResource(),
461 createSecureVideoCodecResource(),
462 createSecureVideoCodecResource(),
463 createNonSecureVideoCodecResource(2)};
Girish9128e242022-11-23 20:52:29 +0000464 mService->removeResource(client3Info, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700465 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
466 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 2}};
467 observables3 = {{MediaObservableType::kVideoSecureCodec, 1},
468 {MediaObservableType::kVideoNonSecureCodec, 2}};
469 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
470 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
471 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables3));
472 // Remove client3 entirely. 2 non-secure video codecs removal should be reported.
Girish9128e242022-11-23 20:52:29 +0000473 mService->removeClient(client3Info);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700474 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
475 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
476 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
477}
478
479TEST_F(ResourceObserverServiceTest, testEventFilters) {
480 // Register observers with different event filters.
481 std::vector<MediaObservableFilter> filters1, filters2, filters3;
482 filters1 = {{MediaObservableType::kVideoSecureCodec, BUSY}};
483 filters2 = {{MediaObservableType::kVideoNonSecureCodec, IDLE}};
484 filters3 = {{MediaObservableType::kVideoSecureCodec, IDLE},
485 {MediaObservableType::kVideoNonSecureCodec, BUSY}};
486
487 // mTestObserver1 monitors secure video codecs.
488 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver1, filters1).isOk());
489
490 // mTestObserver2 monitors non-secure video codecs.
491 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver2, filters2).isOk());
492
493 // mTestObserver3 monitors both secure & non-secure video codecs.
494 EXPECT_TRUE(mObserverService->registerObserver(mTestObserver3, filters3).isOk());
495
496 std::vector<MediaObservableParcel> observables1, observables2;
497 observables1 = {{MediaObservableType::kVideoSecureCodec, 1}};
498 observables2 = {{MediaObservableType::kVideoNonSecureCodec, 1}};
499
500 std::vector<MediaResourceParcel> resources;
501
502 // Add secure & non-secure video codecs.
Brian Lindahla88d90c2022-01-17 10:38:35 +0100503 resources = {createSecureVideoCodecResource(),
504 createNonSecureVideoCodecResource()};
Girish9128e242022-11-23 20:52:29 +0000505 ClientInfoParcel client1Info{.pid = static_cast<int32_t>(kTestPid1),
506 .uid = static_cast<int32_t>(kTestUid1),
507 .id = getId(mTestClient1),
508 .name = "none"};
509
510 ClientInfoParcel client2Info{.pid = static_cast<int32_t>(kTestPid2),
511 .uid = static_cast<int32_t>(kTestUid2),
512 .id = getId(mTestClient2),
513 .name = "none"};
514
515 ClientInfoParcel client3Info{.pid = static_cast<int32_t>(kTestPid2),
516 .uid = static_cast<int32_t>(kTestUid2),
517 .id = getId(mTestClient3),
518 .name = "none"};
519 mService->addResource(client3Info, mTestClient3, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700520 EXPECT_EQ(mTestObserver1->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables1));
521 EXPECT_EQ(mTestObserver2->pop(), EventTracker::NoEvent);
522 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Busy(kTestUid2, kTestPid2, observables2));
523
524 // Remove secure & non-secure video codecs.
Girish9128e242022-11-23 20:52:29 +0000525 mService->removeResource(client3Info, resources);
Chong Zhanga9d45c72020-09-09 12:41:17 -0700526 EXPECT_EQ(mTestObserver1->pop(), EventTracker::NoEvent);
527 EXPECT_EQ(mTestObserver2->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables2));
528 EXPECT_EQ(mTestObserver3->pop(), EventTracker::Idle(kTestUid2, kTestPid2, observables1));
529}
530
531} // namespace android