blob: 4809d7abe50c935b67d57e6c893b1b6eb61e4f82 [file] [log] [blame]
Chong Zhangbc062482020-10-14 16:43:53 -07001/*
2 * Copyright (C) 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// Unit Test for TranscodingSessionController
18
19// #define LOG_NDEBUG 0
20#define LOG_TAG "TranscodingSessionControllerTest"
21
22#include <aidl/android/media/BnTranscodingClientCallback.h>
23#include <aidl/android/media/IMediaTranscodingService.h>
24#include <aidl/android/media/ITranscodingClient.h>
25#include <aidl/android/media/ITranscodingClientCallback.h>
26#include <android-base/logging.h>
27#include <android/binder_manager.h>
28#include <android/binder_process.h>
29#include <gtest/gtest.h>
30#include <media/TranscodingClientManager.h>
31#include <media/TranscodingSessionController.h>
32#include <utils/Log.h>
33
34#include <unordered_set>
35
36namespace android {
37
38using Status = ::ndk::ScopedAStatus;
39using aidl::android::media::BnTranscodingClientCallback;
40using aidl::android::media::IMediaTranscodingService;
41using aidl::android::media::ITranscodingClient;
42using aidl::android::media::TranscodingRequestParcel;
43
44constexpr ClientIdType kClientId = 1000;
45constexpr SessionIdType kClientSessionId = 0;
46constexpr uid_t kClientUid = 5000;
47constexpr uid_t kInvalidUid = (uid_t)-1;
48
49#define CLIENT(n) (kClientId + (n))
50#define SESSION(n) (kClientSessionId + (n))
51#define UID(n) (kClientUid + (n))
52
53class TestUidPolicy : public UidPolicyInterface {
54public:
55 TestUidPolicy() = default;
56 virtual ~TestUidPolicy() = default;
57
58 // UidPolicyInterface
59 void registerMonitorUid(uid_t /*uid*/) override {}
60 void unregisterMonitorUid(uid_t /*uid*/) override {}
61 bool isUidOnTop(uid_t uid) override { return mTopUids.count(uid) > 0; }
62 std::unordered_set<uid_t> getTopUids() const override { return mTopUids; }
63 void setCallback(const std::shared_ptr<UidPolicyCallbackInterface>& cb) override {
64 mUidPolicyCallback = cb;
65 }
66 void setTop(uid_t uid) {
67 std::unordered_set<uid_t> uids = {uid};
68 setTop(uids);
69 }
70 void setTop(const std::unordered_set<uid_t>& uids) {
71 mTopUids = uids;
72 auto uidPolicyCb = mUidPolicyCallback.lock();
73 if (uidPolicyCb != nullptr) {
74 uidPolicyCb->onTopUidsChanged(mTopUids);
75 }
76 }
77
78 std::unordered_set<uid_t> mTopUids;
79 std::weak_ptr<UidPolicyCallbackInterface> mUidPolicyCallback;
80};
81
82class TestTranscoder : public TranscoderInterface {
83public:
84 TestTranscoder() : mLastError(TranscodingErrorCode::kUnknown) {}
85 virtual ~TestTranscoder() {}
86
87 // TranscoderInterface
88 void setCallback(const std::shared_ptr<TranscoderCallbackInterface>& /*cb*/) override {}
89
90 void start(ClientIdType clientId, SessionIdType sessionId,
91 const TranscodingRequestParcel& /*request*/,
92 const std::shared_ptr<ITranscodingClientCallback>& /*clientCallback*/) override {
93 mEventQueue.push_back(Start(clientId, sessionId));
94 }
95 void pause(ClientIdType clientId, SessionIdType sessionId) override {
96 mEventQueue.push_back(Pause(clientId, sessionId));
97 }
98 void resume(ClientIdType clientId, SessionIdType sessionId,
99 const TranscodingRequestParcel& /*request*/,
100 const std::shared_ptr<ITranscodingClientCallback>& /*clientCallback*/) override {
101 mEventQueue.push_back(Resume(clientId, sessionId));
102 }
103 void stop(ClientIdType clientId, SessionIdType sessionId) override {
104 mEventQueue.push_back(Stop(clientId, sessionId));
105 }
106
107 void onFinished(ClientIdType clientId, SessionIdType sessionId) {
108 mEventQueue.push_back(Finished(clientId, sessionId));
109 }
110
111 void onFailed(ClientIdType clientId, SessionIdType sessionId, TranscodingErrorCode err) {
112 mLastError = err;
113 mEventQueue.push_back(Failed(clientId, sessionId));
114 }
115
116 TranscodingErrorCode getLastError() {
117 TranscodingErrorCode result = mLastError;
118 mLastError = TranscodingErrorCode::kUnknown;
119 return result;
120 }
121
122 struct Event {
123 enum { NoEvent, Start, Pause, Resume, Stop, Finished, Failed } type;
124 ClientIdType clientId;
125 SessionIdType sessionId;
126 };
127
128 static constexpr Event NoEvent = {Event::NoEvent, 0, 0};
129
130#define DECLARE_EVENT(action) \
131 static Event action(ClientIdType clientId, SessionIdType sessionId) { \
132 return {Event::action, clientId, sessionId}; \
133 }
134
135 DECLARE_EVENT(Start);
136 DECLARE_EVENT(Pause);
137 DECLARE_EVENT(Resume);
138 DECLARE_EVENT(Stop);
139 DECLARE_EVENT(Finished);
140 DECLARE_EVENT(Failed);
141
142 const Event& popEvent() {
143 if (mEventQueue.empty()) {
144 mPoppedEvent = NoEvent;
145 } else {
146 mPoppedEvent = *mEventQueue.begin();
147 mEventQueue.pop_front();
148 }
149 return mPoppedEvent;
150 }
151
152private:
153 Event mPoppedEvent;
154 std::list<Event> mEventQueue;
155 TranscodingErrorCode mLastError;
156};
157
158bool operator==(const TestTranscoder::Event& lhs, const TestTranscoder::Event& rhs) {
159 return lhs.type == rhs.type && lhs.clientId == rhs.clientId && lhs.sessionId == rhs.sessionId;
160}
161
162struct TestClientCallback : public BnTranscodingClientCallback {
163 TestClientCallback(TestTranscoder* owner, int64_t clientId)
164 : mOwner(owner), mClientId(clientId) {
165 ALOGD("TestClient Created");
166 }
167
168 Status openFileDescriptor(const std::string& /*in_fileUri*/, const std::string& /*in_mode*/,
169 ::ndk::ScopedFileDescriptor* /*_aidl_return*/) override {
170 return Status::ok();
171 }
172
173 Status onTranscodingStarted(int32_t /*in_sessionId*/) override { return Status::ok(); }
174
175 Status onTranscodingPaused(int32_t /*in_sessionId*/) override { return Status::ok(); }
176
177 Status onTranscodingResumed(int32_t /*in_sessionId*/) override { return Status::ok(); }
178
179 Status onTranscodingFinished(int32_t in_sessionId,
180 const TranscodingResultParcel& in_result) override {
181 EXPECT_EQ(in_sessionId, in_result.sessionId);
182 ALOGD("TestClientCallback: received onTranscodingFinished");
183 mOwner->onFinished(mClientId, in_sessionId);
184 return Status::ok();
185 }
186
187 Status onTranscodingFailed(int32_t in_sessionId, TranscodingErrorCode in_errorCode) override {
188 mOwner->onFailed(mClientId, in_sessionId, in_errorCode);
189 return Status::ok();
190 }
191
192 Status onAwaitNumberOfSessionsChanged(int32_t /* in_sessionId */,
193 int32_t /* in_oldAwaitNumber */,
194 int32_t /* in_newAwaitNumber */) override {
195 return Status::ok();
196 }
197
198 Status onProgressUpdate(int32_t /* in_sessionId */, int32_t /* in_progress */) override {
199 return Status::ok();
200 }
201
202 virtual ~TestClientCallback() { ALOGI("TestClient destroyed"); };
203
204private:
205 TestTranscoder* mOwner;
206 int64_t mClientId;
207 TestClientCallback(const TestClientCallback&) = delete;
208 TestClientCallback& operator=(const TestClientCallback&) = delete;
209};
210
211class TranscodingSessionControllerTest : public ::testing::Test {
212public:
213 TranscodingSessionControllerTest() { ALOGI("TranscodingSessionControllerTest created"); }
214
215 void SetUp() override {
216 ALOGI("TranscodingSessionControllerTest set up");
217 mTranscoder.reset(new TestTranscoder());
218 mUidPolicy.reset(new TestUidPolicy());
219 mController.reset(new TranscodingSessionController(mTranscoder, mUidPolicy,
220 nullptr /*resourcePolicy*/));
221 mUidPolicy->setCallback(mController);
222
223 // Set priority only, ignore other fields for now.
224 mOfflineRequest.priority = TranscodingSessionPriority::kUnspecified;
225 mRealtimeRequest.priority = TranscodingSessionPriority::kHigh;
226 mClientCallback0 =
227 ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(0));
228 mClientCallback1 =
229 ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(1));
230 mClientCallback2 =
231 ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(2));
232 mClientCallback3 =
233 ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(3));
234 }
235
236 void TearDown() override { ALOGI("TranscodingSessionControllerTest tear down"); }
237
238 ~TranscodingSessionControllerTest() { ALOGD("TranscodingSessionControllerTest destroyed"); }
239
240 std::shared_ptr<TestTranscoder> mTranscoder;
241 std::shared_ptr<TestUidPolicy> mUidPolicy;
242 std::shared_ptr<TranscodingSessionController> mController;
243 TranscodingRequestParcel mOfflineRequest;
244 TranscodingRequestParcel mRealtimeRequest;
245 std::shared_ptr<TestClientCallback> mClientCallback0;
246 std::shared_ptr<TestClientCallback> mClientCallback1;
247 std::shared_ptr<TestClientCallback> mClientCallback2;
248 std::shared_ptr<TestClientCallback> mClientCallback3;
249};
250
251TEST_F(TranscodingSessionControllerTest, TestSubmitSession) {
252 ALOGD("TestSubmitSession");
253
254 // Start with UID(1) on top.
255 mUidPolicy->setTop(UID(1));
256
257 // Submit offline session to CLIENT(0) in UID(0).
258 // Should start immediately (because this is the only session).
259 mController->submit(CLIENT(0), SESSION(0), UID(0), mOfflineRequest, mClientCallback0);
260 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), 0));
261
262 // Submit real-time session to CLIENT(0).
263 // Should pause offline session and start new session, even if UID(0) is not on top.
264 mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
265 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
266 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
267
268 // Submit real-time session to CLIENT(0), should be queued after the previous session.
269 mController->submit(CLIENT(0), SESSION(2), UID(0), mRealtimeRequest, mClientCallback0);
270 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
271
272 // Submit real-time session to CLIENT(1) in same uid, should be queued after the previous
273 // session.
274 mController->submit(CLIENT(1), SESSION(0), UID(0), mRealtimeRequest, mClientCallback1);
275 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
276
277 // Submit real-time session to CLIENT(2) in UID(1).
278 // Should pause previous session and start new session, because UID(1) is (has been) top.
279 mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
280 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
281 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
282
283 // Submit offline session, shouldn't generate any event.
284 mController->submit(CLIENT(2), SESSION(1), UID(1), mOfflineRequest, mClientCallback2);
285 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
286
287 // Bring UID(0) to top.
288 mUidPolicy->setTop(UID(0));
289 // Should pause current session, and resume last session in UID(0).
290 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
291 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(1)));
292}
293
294TEST_F(TranscodingSessionControllerTest, TestCancelSession) {
295 ALOGD("TestCancelSession");
296
297 // Submit real-time session SESSION(0), should start immediately.
298 mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
299 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
300
301 // Submit real-time session SESSION(1), should not start.
302 mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
303 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
304
305 // Submit offline session SESSION(2), should not start.
306 mController->submit(CLIENT(0), SESSION(2), UID(0), mOfflineRequest, mClientCallback0);
307 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
308
309 // Cancel queued real-time session.
310 // Cancel real-time session SESSION(1), should be cancelled.
311 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(1)));
312
313 // Cancel queued offline session.
314 // Cancel offline session SESSION(2), should be cancelled.
315 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(2)));
316
317 // Submit offline session SESSION(3), shouldn't cause any event.
318 mController->submit(CLIENT(0), SESSION(3), UID(0), mOfflineRequest, mClientCallback0);
319 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
320
321 // Cancel running real-time session SESSION(0).
322 // - Should be stopped first then cancelled.
323 // - Should also start offline session SESSION(2) because real-time queue is empty.
324 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
325 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
326 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(3)));
327
328 // Submit real-time session SESSION(4), offline SESSION(3) should pause and SESSION(4)
329 // should start.
330 mController->submit(CLIENT(0), SESSION(4), UID(0), mRealtimeRequest, mClientCallback0);
331 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(3)));
332 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(4)));
333
334 // Cancel paused SESSION(3). SESSION(3) should be stopped.
335 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(3)));
336 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(3)));
337}
338
339TEST_F(TranscodingSessionControllerTest, TestFinishSession) {
340 ALOGD("TestFinishSession");
341
342 // Start with unspecified top UID.
343 // Finish without any sessions submitted, should be ignored.
344 mController->onFinish(CLIENT(0), SESSION(0));
345 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
346
347 // Submit offline session SESSION(0), should start immediately.
348 mController->submit(CLIENT(0), SESSION(0), UID(0), mOfflineRequest, mClientCallback0);
349 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
350
351 // Submit real-time session SESSION(1), should pause offline session and start immediately.
352 mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
353 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
354 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
355
356 // Submit real-time session SESSION(2), should not start.
357 mController->submit(CLIENT(0), SESSION(2), UID(0), mRealtimeRequest, mClientCallback0);
358 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
359
360 // Finish when the session never started, should be ignored.
361 mController->onFinish(CLIENT(0), SESSION(2));
362 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
363
364 // UID(1) moves to top.
365 mUidPolicy->setTop(UID(1));
366 // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
367 // new session.
368 mController->submit(CLIENT(1), SESSION(0), UID(1), mRealtimeRequest, mClientCallback1);
369 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
370 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
371
372 // Simulate Finish that arrived late, after pause issued by controller.
373 // Should still be propagated to client, but shouldn't trigger any new start.
374 mController->onFinish(CLIENT(0), SESSION(1));
375 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(1)));
376
377 // Finish running real-time session, should start next real-time session in queue.
378 mController->onFinish(CLIENT(1), SESSION(0));
379 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(1), SESSION(0)));
380 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
381
382 // Finish running real-time session, should resume next session (offline session) in queue.
383 mController->onFinish(CLIENT(0), SESSION(2));
384 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(2)));
385 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
386
387 // Finish running offline session.
388 mController->onFinish(CLIENT(0), SESSION(0));
389 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
390
391 // Duplicate finish for last session, should be ignored.
392 mController->onFinish(CLIENT(0), SESSION(0));
393 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
394}
395
396TEST_F(TranscodingSessionControllerTest, TestFailSession) {
397 ALOGD("TestFailSession");
398
399 // Start with unspecified top UID.
400 // Fail without any sessions submitted, should be ignored.
401 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
402 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
403
404 // Submit offline session SESSION(0), should start immediately.
405 mController->submit(CLIENT(0), SESSION(0), UID(0), mOfflineRequest, mClientCallback0);
406 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
407
408 // Submit real-time session SESSION(1), should pause offline session and start immediately.
409 mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
410 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
411 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
412
413 // Submit real-time session SESSION(2), should not start.
414 mController->submit(CLIENT(0), SESSION(2), UID(0), mRealtimeRequest, mClientCallback0);
415 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
416
417 // Fail when the session never started, should be ignored.
418 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
419 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
420
421 // UID(1) moves to top.
422 mUidPolicy->setTop(UID(1));
423 // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
424 // new session.
425 mController->submit(CLIENT(1), SESSION(0), UID(1), mRealtimeRequest, mClientCallback1);
426 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
427 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
428
429 // Simulate Fail that arrived late, after pause issued by controller.
430 // Should still be propagated to client, but shouldn't trigger any new start.
431 mController->onError(CLIENT(0), SESSION(1), TranscodingErrorCode::kUnknown);
432 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
433
434 // Fail running real-time session, should start next real-time session in queue.
435 mController->onError(CLIENT(1), SESSION(0), TranscodingErrorCode::kUnknown);
436 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(1), SESSION(0)));
437 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
438
439 // Fail running real-time session, should resume next session (offline session) in queue.
440 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
441 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(2)));
442 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
443
444 // Fail running offline session, and test error code propagation.
445 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kInvalidOperation);
446 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(0)));
447 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kInvalidOperation);
448
449 // Duplicate fail for last session, should be ignored.
450 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
451 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
452}
453
454TEST_F(TranscodingSessionControllerTest, TestTopUidChanged) {
455 ALOGD("TestTopUidChanged");
456
457 // Start with unspecified top UID.
458 // Submit real-time session to CLIENT(0), session should start immediately.
459 mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
460 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
461
462 // Submit offline session to CLIENT(0), should not start.
463 mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
464 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
465
466 // Move UID(1) to top.
467 mUidPolicy->setTop(UID(1));
468 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
469
470 // Submit real-time session to CLIENT(2) in different uid UID(1).
471 // Should pause previous session and start new session.
472 mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
473 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
474 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
475
476 // Bring UID(0) back to top.
477 mUidPolicy->setTop(UID(0));
478 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
479 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
480
481 // Bring invalid uid to top.
482 mUidPolicy->setTop(kInvalidUid);
483 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
484
485 // Finish session, next real-time session should resume.
486 mController->onFinish(CLIENT(0), SESSION(0));
487 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
488 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
489
490 // Finish session, offline session should start.
491 mController->onFinish(CLIENT(2), SESSION(0));
492 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
493 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
494}
495
496TEST_F(TranscodingSessionControllerTest, TestTopUidSetChanged) {
497 ALOGD("TestTopUidChanged_MultipleUids");
498
499 // Start with unspecified top UID.
500 // Submit real-time session to CLIENT(0), session should start immediately.
501 mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
502 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
503
504 // Submit offline session to CLIENT(0), should not start.
505 mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
506 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
507
508 // Set UID(0), UID(1) to top set.
509 // UID(0) should continue to run.
510 mUidPolicy->setTop({UID(0), UID(1)});
511 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
512
513 // Submit real-time session to CLIENT(2) in different uid UID(1).
514 // UID(0) should pause and UID(1) should start.
515 mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
516 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
517 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
518
519 // Remove UID(0) from top set, and only leave UID(1) in the set.
520 // UID(1) should continue to run.
521 mUidPolicy->setTop(UID(1));
522 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
523
524 // Set UID(0), UID(2) to top set.
525 // UID(1) should continue to run.
526 mUidPolicy->setTop({UID(1), UID(2)});
527 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
528
529 // Bring UID(0) back to top.
530 mUidPolicy->setTop(UID(0));
531 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
532 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
533
534 // Bring invalid uid to top.
535 mUidPolicy->setTop(kInvalidUid);
536 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
537
538 // Finish session, next real-time session from UID(1) should resume, even if UID(1)
539 // no longer top.
540 mController->onFinish(CLIENT(0), SESSION(0));
541 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
542 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
543
544 // Finish session, offline session should start.
545 mController->onFinish(CLIENT(2), SESSION(0));
546 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
547 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
548}
549
550TEST_F(TranscodingSessionControllerTest, TestResourceLost) {
551 ALOGD("TestResourceLost");
552
553 // Start with unspecified top UID.
554 // Submit real-time session to CLIENT(0), session should start immediately.
555 mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
556 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
557
558 // Submit offline session to CLIENT(0), should not start.
559 mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
560 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
561
562 // Move UID(1) to top.
563 mUidPolicy->setTop(UID(1));
564 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
565
566 // Submit real-time session to CLIENT(2) in different uid UID(1).
567 // Should pause previous session and start new session.
568 mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
569 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
570 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
571
572 // Test 1: No queue change during resource loss.
573 // Signal resource lost.
574 mController->onResourceLost();
575 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
576
577 // Signal resource available, CLIENT(2) should resume.
578 mController->onResourceAvailable();
579 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
580
581 // Test 2: Change of queue order during resource loss.
582 // Signal resource lost.
583 mController->onResourceLost();
584 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
585
586 // Move UID(0) back to top, should have no resume due to no resource.
587 mUidPolicy->setTop(UID(0));
588 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
589
590 // Signal resource available, CLIENT(0) should resume.
591 mController->onResourceAvailable();
592 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
593
594 // Test 3: Adding new queue during resource loss.
595 // Signal resource lost.
596 mController->onResourceLost();
597 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
598
599 // Move UID(2) to top.
600 mUidPolicy->setTop(UID(2));
601
602 // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start due to no resource.
603 mController->submit(CLIENT(3), SESSION(0), UID(2), mRealtimeRequest, mClientCallback3);
604 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
605
606 // Signal resource available, CLIENT(3)'s session should start.
607 mController->onResourceAvailable();
608 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), SESSION(0)));
609}
610
611} // namespace android