1 /*
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
36 namespace android {
37
38 using Status = ::ndk::ScopedAStatus;
39 using aidl::android::media::BnTranscodingClientCallback;
40 using aidl::android::media::IMediaTranscodingService;
41 using aidl::android::media::ITranscodingClient;
42 using aidl::android::media::TranscodingRequestParcel;
43
44 constexpr ClientIdType kClientId = 1000;
45 constexpr SessionIdType kClientSessionId = 0;
46 constexpr uid_t kClientUid = 5000;
47 constexpr pid_t kClientPid = 10000;
48 constexpr uid_t kInvalidUid = (uid_t)-1;
49 constexpr pid_t kInvalidPid = (pid_t)-1;
50
51 #define CLIENT(n) (kClientId + (n))
52 #define SESSION(n) (kClientSessionId + (n))
53 #define UID(n) (kClientUid + (n))
54 #define PID(n) (kClientPid + (n))
55
56 class TestUidPolicy : public UidPolicyInterface {
57 public:
58 TestUidPolicy() = default;
59 virtual ~TestUidPolicy() = default;
60
61 // UidPolicyInterface
registerMonitorUid(uid_t)62 void registerMonitorUid(uid_t /*uid*/) override {}
unregisterMonitorUid(uid_t)63 void unregisterMonitorUid(uid_t /*uid*/) override {}
isUidOnTop(uid_t uid)64 bool isUidOnTop(uid_t uid) override { return mTopUids.count(uid) > 0; }
getTopUids() const65 std::unordered_set<uid_t> getTopUids() const override { return mTopUids; }
setCallback(const std::shared_ptr<UidPolicyCallbackInterface> & cb)66 void setCallback(const std::shared_ptr<UidPolicyCallbackInterface>& cb) override {
67 mUidPolicyCallback = cb;
68 }
setTop(uid_t uid)69 void setTop(uid_t uid) {
70 std::unordered_set<uid_t> uids = {uid};
71 setTop(uids);
72 }
setTop(const std::unordered_set<uid_t> & uids)73 void setTop(const std::unordered_set<uid_t>& uids) {
74 mTopUids = uids;
75 auto uidPolicyCb = mUidPolicyCallback.lock();
76 if (uidPolicyCb != nullptr) {
77 uidPolicyCb->onTopUidsChanged(mTopUids);
78 }
79 }
80
81 std::unordered_set<uid_t> mTopUids;
82 std::weak_ptr<UidPolicyCallbackInterface> mUidPolicyCallback;
83 };
84
85 class TestResourcePolicy : public ResourcePolicyInterface {
86 public:
TestResourcePolicy()87 TestResourcePolicy() { reset(); }
88 virtual ~TestResourcePolicy() = default;
89
90 // ResourcePolicyInterface
setCallback(const std::shared_ptr<ResourcePolicyCallbackInterface> &)91 void setCallback(const std::shared_ptr<ResourcePolicyCallbackInterface>& /*cb*/) override {}
setPidResourceLost(pid_t pid)92 void setPidResourceLost(pid_t pid) override { mResourceLostPid = pid; }
93 // ~ResourcePolicyInterface
94
getPid()95 pid_t getPid() {
96 pid_t result = mResourceLostPid;
97 reset();
98 return result;
99 }
100
101 private:
reset()102 void reset() { mResourceLostPid = kInvalidPid; }
103 pid_t mResourceLostPid;
104 };
105
106 class TestThermalPolicy : public ThermalPolicyInterface {
107 public:
108 TestThermalPolicy() = default;
109 virtual ~TestThermalPolicy() = default;
110
111 // ThermalPolicyInterface
setCallback(const std::shared_ptr<ThermalPolicyCallbackInterface> &)112 void setCallback(const std::shared_ptr<ThermalPolicyCallbackInterface>& /*cb*/) override {}
getThrottlingStatus()113 bool getThrottlingStatus() { return false; }
114 // ~ThermalPolicyInterface
115
116 private:
117 };
118
119 class TestTranscoder : public TranscoderInterface {
120 public:
TestTranscoder()121 TestTranscoder() : mGeneration(0) {}
~TestTranscoder()122 virtual ~TestTranscoder() {}
123
124 // TranscoderInterface
start(ClientIdType clientId,SessionIdType sessionId,const TranscodingRequestParcel &,uid_t,const std::shared_ptr<ITranscodingClientCallback> &)125 void start(ClientIdType clientId, SessionIdType sessionId,
126 const TranscodingRequestParcel& /*request*/, uid_t /*callingUid*/,
127 const std::shared_ptr<ITranscodingClientCallback>& /*clientCallback*/) override {
128 append(Start(clientId, sessionId));
129 }
pause(ClientIdType clientId,SessionIdType sessionId)130 void pause(ClientIdType clientId, SessionIdType sessionId) override {
131 append(Pause(clientId, sessionId));
132 }
resume(ClientIdType clientId,SessionIdType sessionId,const TranscodingRequestParcel &,uid_t,const std::shared_ptr<ITranscodingClientCallback> &)133 void resume(ClientIdType clientId, SessionIdType sessionId,
134 const TranscodingRequestParcel& /*request*/, uid_t /*callingUid*/,
135 const std::shared_ptr<ITranscodingClientCallback>& /*clientCallback*/) override {
136 append(Resume(clientId, sessionId));
137 }
stop(ClientIdType clientId,SessionIdType sessionId,bool abandon)138 void stop(ClientIdType clientId, SessionIdType sessionId, bool abandon) override {
139 append(abandon ? Abandon(clientId, sessionId) : Stop(clientId, sessionId));
140 }
141
onFinished(ClientIdType clientId,SessionIdType sessionId)142 void onFinished(ClientIdType clientId, SessionIdType sessionId) {
143 append(Finished(clientId, sessionId));
144 }
145
onFailed(ClientIdType clientId,SessionIdType sessionId,TranscodingErrorCode err)146 void onFailed(ClientIdType clientId, SessionIdType sessionId, TranscodingErrorCode err) {
147 append(Failed(clientId, sessionId), err);
148 }
149
onCreated()150 void onCreated() {
151 std::scoped_lock lock{mLock};
152 mGeneration++;
153 }
154
155 struct Event {
156 enum { NoEvent, Start, Pause, Resume, Stop, Finished, Failed, Abandon } type;
157 ClientIdType clientId;
158 SessionIdType sessionId;
159 };
160
161 static constexpr Event NoEvent = {Event::NoEvent, 0, 0};
162
163 #define DECLARE_EVENT(action) \
164 static Event action(ClientIdType clientId, SessionIdType sessionId) { \
165 return {Event::action, clientId, sessionId}; \
166 }
167
168 DECLARE_EVENT(Start);
169 DECLARE_EVENT(Pause);
170 DECLARE_EVENT(Resume);
171 DECLARE_EVENT(Stop);
172 DECLARE_EVENT(Finished);
173 DECLARE_EVENT(Failed);
174 DECLARE_EVENT(Abandon);
175
176 // Push 1 event to back.
append(const Event & event,const TranscodingErrorCode err=TranscodingErrorCode::kNoError)177 void append(const Event& event,
178 const TranscodingErrorCode err = TranscodingErrorCode::kNoError) {
179 std::unique_lock lock(mLock);
180
181 mEventQueue.push_back(event);
182 // Error is sticky, non-error event will not erase it, only getLastError()
183 // clears last error.
184 if (err != TranscodingErrorCode::kNoError) {
185 mLastErrorQueue.push_back(err);
186 }
187 mCondition.notify_one();
188 }
189
190 // Pop 1 event from front, wait for up to timeoutUs if empty.
popEvent(int64_t timeoutUs=0)191 const Event& popEvent(int64_t timeoutUs = 0) {
192 std::unique_lock lock(mLock);
193
194 if (mEventQueue.empty() && timeoutUs > 0) {
195 mCondition.wait_for(lock, std::chrono::microseconds(timeoutUs));
196 }
197
198 if (mEventQueue.empty()) {
199 mPoppedEvent = NoEvent;
200 } else {
201 mPoppedEvent = *mEventQueue.begin();
202 mEventQueue.pop_front();
203 }
204
205 return mPoppedEvent;
206 }
207
getLastError()208 TranscodingErrorCode getLastError() {
209 std::scoped_lock lock{mLock};
210 if (mLastErrorQueue.empty()) {
211 return TranscodingErrorCode::kNoError;
212 }
213 TranscodingErrorCode err = mLastErrorQueue.front();
214 mLastErrorQueue.pop_front();
215 return err;
216 }
217
getGeneration()218 int32_t getGeneration() {
219 std::scoped_lock lock{mLock};
220 return mGeneration;
221 }
222
223 private:
224 std::mutex mLock;
225 std::condition_variable mCondition;
226 Event mPoppedEvent;
227 std::list<Event> mEventQueue;
228 std::list<TranscodingErrorCode> mLastErrorQueue;
229 int32_t mGeneration;
230 };
231
operator ==(const TestTranscoder::Event & lhs,const TestTranscoder::Event & rhs)232 bool operator==(const TestTranscoder::Event& lhs, const TestTranscoder::Event& rhs) {
233 return lhs.type == rhs.type && lhs.clientId == rhs.clientId && lhs.sessionId == rhs.sessionId;
234 }
235
236 struct TestClientCallback : public BnTranscodingClientCallback {
TestClientCallbackandroid::TestClientCallback237 TestClientCallback(TestTranscoder* owner, ClientIdType clientId, uid_t clientUid)
238 : mOwner(owner), mClientId(clientId), mClientUid(clientUid) {
239 ALOGD("TestClient Created");
240 }
241
clientIdandroid::TestClientCallback242 ClientIdType clientId() const { return mClientId; }
clientUidandroid::TestClientCallback243 uid_t clientUid() const { return mClientUid; }
244
openFileDescriptorandroid::TestClientCallback245 Status openFileDescriptor(const std::string& /*in_fileUri*/, const std::string& /*in_mode*/,
246 ::ndk::ScopedFileDescriptor* /*_aidl_return*/) override {
247 return Status::ok();
248 }
249
onTranscodingStartedandroid::TestClientCallback250 Status onTranscodingStarted(int32_t /*in_sessionId*/) override { return Status::ok(); }
251
onTranscodingPausedandroid::TestClientCallback252 Status onTranscodingPaused(int32_t /*in_sessionId*/) override { return Status::ok(); }
253
onTranscodingResumedandroid::TestClientCallback254 Status onTranscodingResumed(int32_t /*in_sessionId*/) override { return Status::ok(); }
255
onTranscodingFinishedandroid::TestClientCallback256 Status onTranscodingFinished(int32_t in_sessionId,
257 const TranscodingResultParcel& in_result) override {
258 EXPECT_EQ(in_sessionId, in_result.sessionId);
259 ALOGD("TestClientCallback: received onTranscodingFinished");
260 mOwner->onFinished(mClientId, in_sessionId);
261 return Status::ok();
262 }
263
onTranscodingFailedandroid::TestClientCallback264 Status onTranscodingFailed(int32_t in_sessionId, TranscodingErrorCode in_errorCode) override {
265 mOwner->onFailed(mClientId, in_sessionId, in_errorCode);
266 return Status::ok();
267 }
268
onAwaitNumberOfSessionsChangedandroid::TestClientCallback269 Status onAwaitNumberOfSessionsChanged(int32_t /* in_sessionId */,
270 int32_t /* in_oldAwaitNumber */,
271 int32_t /* in_newAwaitNumber */) override {
272 return Status::ok();
273 }
274
onProgressUpdateandroid::TestClientCallback275 Status onProgressUpdate(int32_t /* in_sessionId */, int32_t /* in_progress */) override {
276 return Status::ok();
277 }
278
~TestClientCallbackandroid::TestClientCallback279 virtual ~TestClientCallback() { ALOGI("TestClient destroyed"); };
280
281 private:
282 TestTranscoder* mOwner;
283 ClientIdType mClientId;
284 uid_t mClientUid;
285 TestClientCallback(const TestClientCallback&) = delete;
286 TestClientCallback& operator=(const TestClientCallback&) = delete;
287 };
288
289 class TranscodingSessionControllerTest : public ::testing::Test {
290 public:
TranscodingSessionControllerTest()291 TranscodingSessionControllerTest() { ALOGI("TranscodingSessionControllerTest created"); }
~TranscodingSessionControllerTest()292 ~TranscodingSessionControllerTest() { ALOGD("TranscodingSessionControllerTest destroyed"); }
293
SetUp()294 void SetUp() override {
295 ALOGI("TranscodingSessionControllerTest set up");
296 mTranscoder.reset(new TestTranscoder());
297 mUidPolicy.reset(new TestUidPolicy());
298 mResourcePolicy.reset(new TestResourcePolicy());
299 mThermalPolicy.reset(new TestThermalPolicy());
300 // Overrid default burst params with shorter values for testing.
301 TranscodingSessionController::ControllerConfig config = {
302 .pacerBurstThresholdMs = 500,
303 .pacerBurstCountQuota = 10,
304 .pacerBurstTimeQuotaSeconds = 3,
305 };
306 mController.reset(new TranscodingSessionController(
307 [this](const std::shared_ptr<TranscoderCallbackInterface>& /*cb*/) {
308 // Here we require that the SessionController clears out all its refcounts of
309 // the transcoder object when it calls create.
310 EXPECT_EQ(mTranscoder.use_count(), 1);
311 mTranscoder->onCreated();
312 return mTranscoder;
313 },
314 mUidPolicy, mResourcePolicy, mThermalPolicy, &config));
315 mUidPolicy->setCallback(mController);
316
317 // Set priority only, ignore other fields for now.
318 mOfflineRequest.priority = TranscodingSessionPriority::kUnspecified;
319 mRealtimeRequest.priority = TranscodingSessionPriority::kHigh;
320 mClientCallback0 = ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(),
321 CLIENT(0), UID(0));
322 mClientCallback1 = ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(),
323 CLIENT(1), UID(1));
324 mClientCallback2 = ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(),
325 CLIENT(2), UID(2));
326 mClientCallback3 = ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(),
327 CLIENT(3), UID(3));
328 }
329
TearDown()330 void TearDown() override { ALOGI("TranscodingSessionControllerTest tear down"); }
331
expectTimeout(int64_t clientId,int32_t sessionId,int32_t generation)332 void expectTimeout(int64_t clientId, int32_t sessionId, int32_t generation) {
333 EXPECT_EQ(mTranscoder->popEvent(2900000), TestTranscoder::NoEvent);
334 EXPECT_EQ(mTranscoder->popEvent(200000), TestTranscoder::Abandon(clientId, sessionId));
335 EXPECT_EQ(mTranscoder->popEvent(100000), TestTranscoder::Failed(clientId, sessionId));
336 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kWatchdogTimeout);
337 // Should have created new transcoder.
338 EXPECT_EQ(mTranscoder->getGeneration(), generation);
339 EXPECT_EQ(mTranscoder.use_count(), 2);
340 }
341
testPacerHelper(int numSubmits,int sessionDurationMs,int expectedSuccess)342 void testPacerHelper(int numSubmits, int sessionDurationMs, int expectedSuccess) {
343 testPacerHelper(numSubmits, sessionDurationMs, expectedSuccess, mClientCallback0, {},
344 false /*pauseLastSuccessSession*/, true /*useRealCallingUid*/);
345 }
346
testPacerHelperWithPause(int numSubmits,int sessionDurationMs,int expectedSuccess)347 void testPacerHelperWithPause(int numSubmits, int sessionDurationMs, int expectedSuccess) {
348 testPacerHelper(numSubmits, sessionDurationMs, expectedSuccess, mClientCallback0, {},
349 true /*pauseLastSuccessSession*/, true /*useRealCallingUid*/);
350 }
351
testPacerHelperWithMultipleUids(int numSubmits,int sessionDurationMs,int expectedSuccess,const std::shared_ptr<TestClientCallback> & client,const std::vector<int> & additionalClientUids)352 void testPacerHelperWithMultipleUids(int numSubmits, int sessionDurationMs, int expectedSuccess,
353 const std::shared_ptr<TestClientCallback>& client,
354 const std::vector<int>& additionalClientUids) {
355 testPacerHelper(numSubmits, sessionDurationMs, expectedSuccess, client,
356 additionalClientUids, false /*pauseLastSuccessSession*/,
357 true /*useRealCallingUid*/);
358 }
359
testPacerHelperWithSelfUid(int numSubmits,int sessionDurationMs,int expectedSuccess)360 void testPacerHelperWithSelfUid(int numSubmits, int sessionDurationMs, int expectedSuccess) {
361 testPacerHelper(numSubmits, sessionDurationMs, expectedSuccess, mClientCallback0, {},
362 false /*pauseLastSuccessSession*/, false /*useRealCallingUid*/);
363 }
364
testPacerHelper(int numSubmits,int sessionDurationMs,int expectedSuccess,const std::shared_ptr<TestClientCallback> & client,const std::vector<int> & additionalClientUids,bool pauseLastSuccessSession,bool useRealCallingUid)365 void testPacerHelper(int numSubmits, int sessionDurationMs, int expectedSuccess,
366 const std::shared_ptr<TestClientCallback>& client,
367 const std::vector<int>& additionalClientUids, bool pauseLastSuccessSession,
368 bool useRealCallingUid) {
369 uid_t callingUid = useRealCallingUid ? ::getuid() : client->clientUid();
370 for (int i = 0; i < numSubmits; i++) {
371 mController->submit(client->clientId(), SESSION(i), callingUid, client->clientUid(),
372 mRealtimeRequest, client);
373 for (int additionalUid : additionalClientUids) {
374 mController->addClientUid(client->clientId(), SESSION(i), additionalUid);
375 }
376 }
377 for (int i = 0; i < expectedSuccess; i++) {
378 EXPECT_EQ(mTranscoder->popEvent(),
379 TestTranscoder::Start(client->clientId(), SESSION(i)));
380 if ((i == expectedSuccess - 1) && pauseLastSuccessSession) {
381 // Insert a pause of 3 sec to the last success running session
382 mController->onThrottlingStarted();
383 EXPECT_EQ(mTranscoder->popEvent(),
384 TestTranscoder::Pause(client->clientId(), SESSION(i)));
385 sleep(3);
386 mController->onThrottlingStopped();
387 EXPECT_EQ(mTranscoder->popEvent(),
388 TestTranscoder::Resume(client->clientId(), SESSION(i)));
389 }
390 usleep(sessionDurationMs * 1000);
391 // Test half of Finish and half of Error, both should be counted as burst runs.
392 if (i & 1) {
393 mController->onFinish(client->clientId(), SESSION(i));
394 EXPECT_EQ(mTranscoder->popEvent(),
395 TestTranscoder::Finished(client->clientId(), SESSION(i)));
396 } else {
397 mController->onError(client->clientId(), SESSION(i),
398 TranscodingErrorCode::kUnknown);
399 EXPECT_EQ(mTranscoder->popEvent(100000),
400 TestTranscoder::Failed(client->clientId(), SESSION(i)));
401 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
402 }
403 }
404 for (int i = expectedSuccess; i < numSubmits; i++) {
405 EXPECT_EQ(mTranscoder->popEvent(),
406 TestTranscoder::Failed(client->clientId(), SESSION(i)));
407 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kDroppedByService);
408 }
409 }
410
411 std::shared_ptr<TestTranscoder> mTranscoder;
412 std::shared_ptr<TestUidPolicy> mUidPolicy;
413 std::shared_ptr<TestResourcePolicy> mResourcePolicy;
414 std::shared_ptr<TestThermalPolicy> mThermalPolicy;
415 std::shared_ptr<TranscodingSessionController> mController;
416 TranscodingRequestParcel mOfflineRequest;
417 TranscodingRequestParcel mRealtimeRequest;
418 std::shared_ptr<TestClientCallback> mClientCallback0;
419 std::shared_ptr<TestClientCallback> mClientCallback1;
420 std::shared_ptr<TestClientCallback> mClientCallback2;
421 std::shared_ptr<TestClientCallback> mClientCallback3;
422 };
423
TEST_F(TranscodingSessionControllerTest,TestSubmitSession)424 TEST_F(TranscodingSessionControllerTest, TestSubmitSession) {
425 ALOGD("TestSubmitSession");
426
427 // Start with UID(1) on top.
428 mUidPolicy->setTop(UID(1));
429
430 // Submit offline session to CLIENT(0) in UID(0).
431 // Should start immediately (because this is the only session).
432 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mOfflineRequest, mClientCallback0);
433 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), 0));
434
435 // Submit real-time session to CLIENT(0).
436 // Should pause offline session and start new session, even if UID(0) is not on top.
437 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
438 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
439 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
440
441 // Submit real-time session to CLIENT(0), should be queued after the previous session.
442 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
443 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
444
445 // Submit real-time session to CLIENT(1) in same uid, should be queued after the previous
446 // session.
447 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mRealtimeRequest, mClientCallback1);
448 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
449
450 // Submit real-time session to CLIENT(2) in UID(1).
451 // Should pause previous session and start new session, because UID(1) is (has been) top.
452 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
453 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
454 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
455
456 // Submit offline session, shouldn't generate any event.
457 mController->submit(CLIENT(2), SESSION(1), UID(2), UID(1), mOfflineRequest, mClientCallback2);
458 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
459
460 // Bring UID(0) to top.
461 mUidPolicy->setTop(UID(0));
462 // Should pause current session, and resume last session in UID(0).
463 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
464 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(1)));
465 }
466
TEST_F(TranscodingSessionControllerTest,TestCancelSession)467 TEST_F(TranscodingSessionControllerTest, TestCancelSession) {
468 ALOGD("TestCancelSession");
469
470 // Submit real-time session SESSION(0), should start immediately.
471 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
472 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
473
474 // Submit real-time session SESSION(1), should not start.
475 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
476 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
477
478 // Submit offline session SESSION(2), should not start.
479 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
480 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
481
482 // Cancel queued real-time session.
483 // Cancel real-time session SESSION(1), should be cancelled.
484 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(1)));
485
486 // Cancel queued offline session.
487 // Cancel offline session SESSION(2), should be cancelled.
488 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(2)));
489
490 // Submit offline session SESSION(3), shouldn't cause any event.
491 mController->submit(CLIENT(0), SESSION(3), UID(0), UID(0), mOfflineRequest, mClientCallback0);
492 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
493
494 // Cancel running real-time session SESSION(0).
495 // - Should be stopped first then cancelled.
496 // - Should also start offline session SESSION(2) because real-time queue is empty.
497 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
498 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
499 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(3)));
500
501 // Submit real-time session SESSION(4), offline SESSION(3) should pause and SESSION(4)
502 // should start.
503 mController->submit(CLIENT(0), SESSION(4), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
504 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(3)));
505 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(4)));
506
507 // Cancel paused SESSION(3). SESSION(3) should be stopped.
508 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(3)));
509 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(3)));
510 }
511
TEST_F(TranscodingSessionControllerTest,TestCancelSessionWithMultipleUids)512 TEST_F(TranscodingSessionControllerTest, TestCancelSessionWithMultipleUids) {
513 ALOGD("TestCancelSessionWithMultipleUids");
514 std::vector<int32_t> clientUids;
515
516 // Submit real-time session SESSION(0), should start immediately.
517 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
518 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
519
520 // Submit real-time session SESSION(1), should not start.
521 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
522 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
523
524 // Submit offline session SESSION(2), should not start.
525 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
526 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
527
528 // UID(1) moves to top.
529 mUidPolicy->setTop(UID(1));
530
531 // Add UID(1) to the offline SESSION(2), SESSION(2) should start and SESSION(0) should pause.
532 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
533 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
534 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
535
536 // Add UID(1) to SESSION(1) as well.
537 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
538
539 // Cancel SESSION(2), should be cancelled and SESSION(1) should start.
540 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(2)));
541 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
542 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(2)));
543 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
544
545 // Cancel SESSION(1), should be cancelled and SESSION(0) should resume.
546 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(1)));
547 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
548 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(1)));
549 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
550 }
551
TEST_F(TranscodingSessionControllerTest,TestCancelAllSessionsForClient)552 TEST_F(TranscodingSessionControllerTest, TestCancelAllSessionsForClient) {
553 // Submit real-time session SESSION(0), should start immediately.
554 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
555 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
556
557 // Submit real-time session SESSION(1), should not start.
558 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
559 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
560
561 // Submit offline session SESSION(2), should not start.
562 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
563 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
564
565 std::vector<int32_t> clientUids;
566 // Make some more uids blocked on the sessions.
567 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(1)));
568 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
569 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
570 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
571 EXPECT_EQ(clientUids.size(), 2);
572 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
573 EXPECT_EQ(clientUids.size(), 2);
574 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
575 EXPECT_EQ(clientUids.size(), 1);
576
577 // Cancel all sessions for CLIENT(0) with -1.
578 // Expect SESSION(0) and SESSION(1) to be gone.
579 // Expect SESSION(2) still there with empty client uid list (only kept for offline) and start.
580 EXPECT_TRUE(mController->cancel(CLIENT(0), -1));
581 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
582 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
583 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
584 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
585 EXPECT_EQ(clientUids.size(), 0);
586 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
587 }
588
TEST_F(TranscodingSessionControllerTest,TestFinishSession)589 TEST_F(TranscodingSessionControllerTest, TestFinishSession) {
590 ALOGD("TestFinishSession");
591
592 // Start with unspecified top UID.
593 // Finish without any sessions submitted, should be ignored.
594 mController->onFinish(CLIENT(0), SESSION(0));
595 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
596
597 // Submit offline session SESSION(0), should start immediately.
598 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mOfflineRequest, mClientCallback0);
599 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
600
601 // Submit real-time session SESSION(1), should pause offline session and start immediately.
602 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
603 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
604 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
605
606 // Submit real-time session SESSION(2), should not start.
607 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
608 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
609
610 // Finish when the session never started, should be ignored.
611 mController->onFinish(CLIENT(0), SESSION(2));
612 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
613
614 // UID(1) moves to top.
615 mUidPolicy->setTop(UID(1));
616 // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
617 // new session.
618 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(1), mRealtimeRequest, mClientCallback1);
619 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
620 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
621
622 // Simulate Finish that arrived late, after pause issued by controller.
623 // Should still be propagated to client, but shouldn't trigger any new start.
624 mController->onFinish(CLIENT(0), SESSION(1));
625 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(1)));
626
627 // Finish running real-time session, should start next real-time session in queue.
628 mController->onFinish(CLIENT(1), SESSION(0));
629 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(1), SESSION(0)));
630 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
631
632 // Finish running real-time session, should resume next session (offline session) in queue.
633 mController->onFinish(CLIENT(0), SESSION(2));
634 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(2)));
635 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
636
637 // Finish running offline session.
638 mController->onFinish(CLIENT(0), SESSION(0));
639 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
640
641 // Duplicate finish for last session, should be ignored.
642 mController->onFinish(CLIENT(0), SESSION(0));
643 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
644 }
645
TEST_F(TranscodingSessionControllerTest,TestFinishSessionWithMultipleUids)646 TEST_F(TranscodingSessionControllerTest, TestFinishSessionWithMultipleUids) {
647 ALOGD("TestFinishSessionWithMultipleUids");
648 std::vector<int32_t> clientUids;
649
650 // Start with unspecified top uid.
651 // Submit real-time session SESSION(0), should start immediately.
652 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
653 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
654
655 // Submit real-time session SESSION(1), should not start.
656 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
657 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
658 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
659
660 // Submit real-time session SESSION(2), should not start.
661 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
662 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
663 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
664 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(2)));
665
666 // UID(1) moves to top.
667 mUidPolicy->setTop(UID(1));
668 // SESSION(0) should pause, SESSION(1) should start.
669 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
670 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
671
672 // Finish SESSION(1), SESSION(2) (next in line for UID(1)) should start.
673 mController->onFinish(CLIENT(0), SESSION(1));
674 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(1)));
675 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
676 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
677
678 // Finish SESSION(2), SESSION(0) should resume.
679 mController->onFinish(CLIENT(0), SESSION(2));
680 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(2)));
681 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
682 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
683 }
684
TEST_F(TranscodingSessionControllerTest,TestFailSession)685 TEST_F(TranscodingSessionControllerTest, TestFailSession) {
686 ALOGD("TestFailSession");
687
688 // Start with unspecified top UID.
689 // Fail without any sessions submitted, should be ignored.
690 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
691 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
692
693 // Submit offline session SESSION(0), should start immediately.
694 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mOfflineRequest, mClientCallback0);
695 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
696
697 // Submit real-time session SESSION(1), should pause offline session and start immediately.
698 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
699 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
700 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
701
702 // Submit real-time session SESSION(2), should not start.
703 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
704 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
705
706 // Fail when the session never started, should be ignored.
707 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
708 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
709
710 // UID(1) moves to top.
711 mUidPolicy->setTop(UID(1));
712 // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
713 // new session.
714 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(1), mRealtimeRequest, mClientCallback1);
715 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
716 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
717
718 // Simulate Fail that arrived late, after pause issued by controller.
719 // Should still be propagated to client, but shouldn't trigger any new start.
720 mController->onError(CLIENT(0), SESSION(1), TranscodingErrorCode::kUnknown);
721 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
722 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
723
724 // Fail running real-time session, should start next real-time session in queue.
725 mController->onError(CLIENT(1), SESSION(0), TranscodingErrorCode::kUnknown);
726 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(1), SESSION(0)));
727 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
728 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
729
730 // Fail running real-time session, should resume next session (offline session) in queue.
731 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
732 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(2)));
733 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
734 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
735
736 // Fail running offline session, and test error code propagation.
737 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kInvalidOperation);
738 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(0)));
739 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kInvalidOperation);
740
741 // Duplicate fail for last session, should be ignored.
742 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
743 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
744 }
745
TEST_F(TranscodingSessionControllerTest,TestFailSessionWithMultipleUids)746 TEST_F(TranscodingSessionControllerTest, TestFailSessionWithMultipleUids) {
747 ALOGD("TestFailSessionWithMultipleUids");
748 std::vector<int32_t> clientUids;
749
750 // Start with unspecified top uid.
751 // Submit real-time session SESSION(0), should start immediately.
752 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
753 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
754
755 // Submit real-time session SESSION(1), should not start.
756 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
757 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
758 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
759
760 // Submit real-time session SESSION(2), should not start.
761 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
762 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
763
764 // UID(1) moves to top.
765 mUidPolicy->setTop(UID(1));
766 // SESSION(0) should pause, SESSION(1) should start.
767 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
768 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
769
770 // Add UID(1) and UID(2) to SESSION(2).
771 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
772 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(2)));
773
774 // Fail SESSION(1), SESSION(2) (next in line for UID(1)) should start.
775 mController->onError(CLIENT(0), SESSION(1), TranscodingErrorCode::kUnknown);
776 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
777 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
778 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
779 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
780
781 // Fail SESSION(2), SESSION(0) should resume.
782 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kInvalidOperation);
783 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(2)));
784 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kInvalidOperation);
785 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
786 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
787 }
788
TEST_F(TranscodingSessionControllerTest,TestTopUidChanged)789 TEST_F(TranscodingSessionControllerTest, TestTopUidChanged) {
790 ALOGD("TestTopUidChanged");
791
792 // Start with unspecified top UID.
793 // Submit real-time session to CLIENT(0), session should start immediately.
794 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
795 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
796
797 // Submit offline session to CLIENT(0), should not start.
798 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
799 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
800
801 // Move UID(1) to top.
802 mUidPolicy->setTop(UID(1));
803 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
804
805 // Submit real-time session to CLIENT(2) in different uid UID(1).
806 // Should pause previous session and start new session.
807 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
808 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
809 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
810
811 // Bring UID(0) back to top.
812 mUidPolicy->setTop(UID(0));
813 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
814 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
815
816 // Bring invalid uid to top.
817 mUidPolicy->setTop(kInvalidUid);
818 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
819
820 // Finish session, next real-time session should resume.
821 mController->onFinish(CLIENT(0), SESSION(0));
822 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
823 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
824
825 // Finish session, offline session should start.
826 mController->onFinish(CLIENT(2), SESSION(0));
827 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
828 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
829 }
830
TEST_F(TranscodingSessionControllerTest,TestTopUidChangedMultipleUids)831 TEST_F(TranscodingSessionControllerTest, TestTopUidChangedMultipleUids) {
832 ALOGD("TestTopUidChangedMultipleUids");
833
834 // Start with unspecified top UID.
835 // Submit real-time session to CLIENT(0), session should start immediately.
836 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
837 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
838
839 // Submit offline session to CLIENT(0), should not start.
840 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
841 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
842
843 // Bring UID(1) to top.
844 mUidPolicy->setTop(UID(1));
845 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
846
847 // Add UID(1) to SESSION(0), SESSION(0) should continue to run
848 // (no pause&resume of the same session).
849 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(1)));
850 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
851
852 // Bring UID(0) back to top, SESSION(0) should continue to run
853 // (no pause&resume of the same session).
854 mUidPolicy->setTop(UID(0));
855 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
856
857 // Bring UID(2) to top.
858 mUidPolicy->setTop(UID(2));
859 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
860 // Add UID(2) to the offline session, it should be started.
861 EXPECT_TRUE(mController->addClientUid(CLIENT(1), SESSION(0), UID(2)));
862 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
863 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
864
865 // ADD UID(3) to SESSION(0).
866 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(3)));
867 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
868 // Bring UID(3) to top, SESSION(0) should resume.
869 mUidPolicy->setTop(UID(3));
870 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(1), SESSION(0)));
871 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
872
873 // Now make UID(2) also blocked on CLIENT(0), SESSION(0).
874 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(2)));
875
876 // Bring UID(2) back to top, CLIENT(0), SESSION(0) should continue to run (even if it's
877 // added to UID(2)'s queue later than CLIENT(1)'s SESSION(0)).
878 mUidPolicy->setTop(UID(2));
879 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
880 }
881
TEST_F(TranscodingSessionControllerTest,TestTopUidSetChanged)882 TEST_F(TranscodingSessionControllerTest, TestTopUidSetChanged) {
883 ALOGD("TestTopUidSetChanged");
884
885 // Start with unspecified top UID.
886 // Submit real-time session to CLIENT(0), session should start immediately.
887 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
888 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
889
890 // Submit offline session to CLIENT(0), should not start.
891 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
892 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
893
894 // Set UID(0), UID(1) to top set.
895 // UID(0) should continue to run.
896 mUidPolicy->setTop({UID(0), UID(1)});
897 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
898
899 // Submit real-time session to CLIENT(2) in different uid UID(1).
900 // UID(0) should pause and UID(1) should start.
901 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
902 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
903 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
904
905 // Remove UID(0) from top set, and only leave UID(1) in the set.
906 // UID(1) should continue to run.
907 mUidPolicy->setTop(UID(1));
908 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
909
910 // Set UID(0), UID(2) to top set.
911 // UID(1) should continue to run.
912 mUidPolicy->setTop({UID(1), UID(2)});
913 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
914
915 // Bring UID(0) back to top.
916 mUidPolicy->setTop(UID(0));
917 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
918 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
919
920 // Bring invalid uid to top.
921 mUidPolicy->setTop(kInvalidUid);
922 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
923
924 // Finish session, next real-time session from UID(1) should resume, even if UID(1)
925 // no longer top.
926 mController->onFinish(CLIENT(0), SESSION(0));
927 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
928 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
929
930 // Finish session, offline session should start.
931 mController->onFinish(CLIENT(2), SESSION(0));
932 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
933 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
934 }
935
TEST_F(TranscodingSessionControllerTest,TestUidGone)936 TEST_F(TranscodingSessionControllerTest, TestUidGone) {
937 ALOGD("TestUidGone");
938
939 mUidPolicy->setTop(UID(0));
940 // Start with unspecified top UID.
941 // Submit real-time sessions to CLIENT(0), session should start immediately.
942 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
943 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
944
945 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
946 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
947 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
948
949 // Submit real-time session to CLIENT(1), should not start.
950 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(1), mOfflineRequest, mClientCallback1);
951 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
952 EXPECT_TRUE(mController->addClientUid(CLIENT(1), SESSION(0), UID(1)));
953
954 // Tell the controller that UID(0) is gone.
955 mUidPolicy->setTop(UID(1));
956 // CLIENT(0)'s SESSION(1) should start, SESSION(0) should be cancelled.
957 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
958 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
959 mController->onUidGone(UID(0));
960 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
961 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(0)));
962 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
963
964 std::vector<int32_t> clientUids;
965 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
966 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
967 EXPECT_EQ(clientUids.size(), 1);
968 EXPECT_EQ(clientUids[0], UID(1));
969
970 // Tell the controller that UID(1) is gone too.
971 mController->onUidGone(UID(1));
972 // CLIENT(1)'s SESSION(0) should start, CLIENT(0)'s SESSION(1) should be cancelled.
973 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(1)));
974 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
975 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
976 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
977 // CLIENT(1) SESSION(0) should not have any client uids as it's only kept for offline.
978 EXPECT_TRUE(mController->getClientUids(CLIENT(1), SESSION(0), &clientUids));
979 EXPECT_EQ(clientUids.size(), 0);
980 }
981
TEST_F(TranscodingSessionControllerTest,TestAddGetClientUids)982 TEST_F(TranscodingSessionControllerTest, TestAddGetClientUids) {
983 ALOGD("TestAddGetClientUids");
984
985 // Add/get client uids with non-existent session, should fail.
986 std::vector<int32_t> clientUids;
987 uid_t ownUid = ::getuid();
988 EXPECT_FALSE(mController->addClientUid(CLIENT(0), SESSION(0), ownUid));
989 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
990
991 // Submit a real-time request.
992 EXPECT_TRUE(mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest,
993 mClientCallback0));
994 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
995
996 // Should have own uid in client uids.
997 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
998 EXPECT_EQ(clientUids.size(), 1);
999 EXPECT_EQ(clientUids[0], UID(0));
1000
1001 // Add UID(0) again should fail.
1002 EXPECT_FALSE(mController->addClientUid(CLIENT(0), SESSION(0), UID(0)));
1003
1004 // Add own uid should succeed.
1005 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), ownUid));
1006 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
1007 std::unordered_set<uid_t> uidSet;
1008 uidSet.insert(clientUids.begin(), clientUids.end());
1009 EXPECT_EQ(uidSet.size(), 2);
1010 EXPECT_EQ(uidSet.count(UID(0)), 1);
1011 EXPECT_EQ(uidSet.count(ownUid), 1);
1012
1013 // Submit an offline request.
1014 EXPECT_TRUE(mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mOfflineRequest,
1015 mClientCallback0));
1016 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1017
1018 // Should not have own uid in client uids.
1019 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
1020 EXPECT_EQ(clientUids.size(), 0);
1021
1022 // Move UID(1) to top.
1023 mUidPolicy->setTop(UID(1));
1024 // Add UID(1) to offline session, offline session should start and SESSION(0) should pause.
1025 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
1026 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1027 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
1028 }
1029
1030 /* Test resource lost without thermal throttling */
TEST_F(TranscodingSessionControllerTest,TestResourceLost)1031 TEST_F(TranscodingSessionControllerTest, TestResourceLost) {
1032 ALOGD("TestResourceLost");
1033
1034 // Start with unspecified top UID.
1035 // Submit real-time session to CLIENT(0), session should start immediately.
1036 mRealtimeRequest.clientPid = PID(0);
1037 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
1038 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1039
1040 // Submit offline session to CLIENT(0), should not start.
1041 mOfflineRequest.clientPid = PID(0);
1042 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
1043 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1044
1045 // Move UID(1) to top.
1046 mUidPolicy->setTop(UID(1));
1047 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1048
1049 // Submit real-time session to CLIENT(2) in different uid UID(1).
1050 // Should pause previous session and start new session.
1051 mRealtimeRequest.clientPid = PID(1);
1052 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
1053 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1054 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
1055
1056 // Test 0: No call into ResourcePolicy if resource lost is from a non-running
1057 // or non-existent session.
1058 mController->onResourceLost(CLIENT(0), SESSION(0));
1059 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
1060 mController->onResourceLost(CLIENT(3), SESSION(0));
1061 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
1062
1063 // Test 1: No queue change during resource loss.
1064 // Signal resource lost.
1065 mController->onResourceLost(CLIENT(2), SESSION(0));
1066 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
1067 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1068
1069 // Signal resource available, CLIENT(2) should resume.
1070 mController->onResourceAvailable();
1071 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1072
1073 // Test 2: Change of queue order during resource loss.
1074 // Signal resource lost.
1075 mController->onResourceLost(CLIENT(2), SESSION(0));
1076 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
1077 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1078
1079 // Move UID(0) back to top, should have no resume due to no resource.
1080 mUidPolicy->setTop(UID(0));
1081 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1082
1083 // Signal resource available, CLIENT(0) should resume.
1084 mController->onResourceAvailable();
1085 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
1086
1087 // Test 3:
1088 mController->onResourceLost(CLIENT(0), SESSION(0));
1089 EXPECT_EQ(mResourcePolicy->getPid(), PID(0));
1090 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1091 // Cancel the paused top session during resource lost.
1092 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
1093 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
1094 // Signal resource available, CLIENT(2)'s session should start.
1095 mController->onResourceAvailable();
1096 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1097
1098 // Test 4: Adding new queue during resource loss.
1099 // Signal resource lost.
1100 mController->onResourceLost(CLIENT(2), SESSION(0));
1101 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
1102 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1103
1104 // Move UID(2) to top.
1105 mUidPolicy->setTop(UID(2));
1106
1107 // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start due to no resource.
1108 mRealtimeRequest.clientPid = PID(2);
1109 mController->submit(CLIENT(3), SESSION(0), UID(3), UID(2), mRealtimeRequest, mClientCallback3);
1110 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1111
1112 // Signal resource available, CLIENT(3)'s session should start.
1113 mController->onResourceAvailable();
1114 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), SESSION(0)));
1115 }
1116
1117 /* Test thermal throttling without resource lost */
TEST_F(TranscodingSessionControllerTest,TestThermalCallback)1118 TEST_F(TranscodingSessionControllerTest, TestThermalCallback) {
1119 ALOGD("TestThermalCallback");
1120
1121 // Start with unspecified top UID.
1122 // Submit real-time session to CLIENT(0), session should start immediately.
1123 mRealtimeRequest.clientPid = PID(0);
1124 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
1125 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1126
1127 // Submit offline session to CLIENT(0), should not start.
1128 mOfflineRequest.clientPid = PID(0);
1129 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
1130 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1131
1132 // Move UID(1) to top.
1133 mUidPolicy->setTop(UID(1));
1134 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1135
1136 // Submit real-time session to CLIENT(2) in different uid UID(1).
1137 // Should pause previous session and start new session.
1138 mRealtimeRequest.clientPid = PID(1);
1139 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
1140 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1141 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
1142
1143 // Test 0: Basic case, no queue change during throttling, top session should pause/resume
1144 // with throttling.
1145 mController->onThrottlingStarted();
1146 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1147 mController->onThrottlingStopped();
1148 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1149
1150 // Test 1: Change of queue order during thermal throttling, when throttling stops,
1151 // new top session should resume.
1152 mController->onThrottlingStarted();
1153 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1154 mUidPolicy->setTop(UID(0));
1155 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1156 mController->onThrottlingStopped();
1157 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
1158
1159 // Test 2: Cancel session during throttling, when throttling stops, new top
1160 // session should resume.
1161 mController->onThrottlingStarted();
1162 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1163 // Cancel the paused top session during throttling.
1164 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
1165 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
1166 // Throttling stops, CLIENT(2)'s session should start.
1167 mController->onThrottlingStopped();
1168 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1169
1170 // Test 3: Add new queue during throttling, when throttling stops, new top
1171 // session should resume.
1172 mController->onThrottlingStarted();
1173 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1174 // Move UID(2) to top.
1175 mUidPolicy->setTop(UID(2));
1176 // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start during throttling.
1177 mRealtimeRequest.clientPid = PID(2);
1178 mController->submit(CLIENT(3), SESSION(0), UID(3), UID(2), mRealtimeRequest, mClientCallback3);
1179 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1180 // Throttling stops, CLIENT(3)'s session should start.
1181 mController->onThrottlingStopped();
1182 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), SESSION(0)));
1183 }
1184
1185 /* Test resource lost and thermal throttling happening simultaneously */
TEST_F(TranscodingSessionControllerTest,TestResourceLostAndThermalCallback)1186 TEST_F(TranscodingSessionControllerTest, TestResourceLostAndThermalCallback) {
1187 ALOGD("TestResourceLostAndThermalCallback");
1188
1189 // Start with unspecified top UID.
1190 // Submit real-time session to CLIENT(0), session should start immediately.
1191 mRealtimeRequest.clientPid = PID(0);
1192 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
1193 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1194
1195 // Submit offline session to CLIENT(0), should not start.
1196 mOfflineRequest.clientPid = PID(0);
1197 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
1198 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1199
1200 // Move UID(1) to top.
1201 mUidPolicy->setTop(UID(1));
1202 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1203
1204 // Submit real-time session to CLIENT(2) in different uid UID(1).
1205 // Should pause previous session and start new session.
1206 mRealtimeRequest.clientPid = PID(1);
1207 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
1208 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1209 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
1210
1211 // Test 0: Resource lost during throttling.
1212 // Throttling starts, top session should pause.
1213 mController->onThrottlingStarted();
1214 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1215 // Signal resource lost, this should get ignored because the session is now paused.
1216 mController->onResourceLost(CLIENT(2), SESSION(0));
1217 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
1218 // Signal resource available, CLIENT(2) shouldn't resume.
1219 mController->onResourceAvailable();
1220 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1221 // Throttling ends, top session should resume.
1222 mController->onThrottlingStopped();
1223 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1224
1225 // Test 1: Throttling during resource lost.
1226 mController->onResourceLost(CLIENT(2), SESSION(0));
1227 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
1228 mController->onThrottlingStarted();
1229 mController->onThrottlingStopped();
1230 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1231 mController->onResourceAvailable();
1232 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1233
1234 // Test 2: Interleaving resource lost and throttling.
1235 mController->onResourceLost(CLIENT(2), SESSION(0));
1236 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
1237 mController->onThrottlingStarted();
1238 mController->onResourceAvailable();
1239 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1240 mController->onThrottlingStopped();
1241 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1242 }
1243
TEST_F(TranscodingSessionControllerTest,TestTranscoderWatchdogNoHeartbeat)1244 TEST_F(TranscodingSessionControllerTest, TestTranscoderWatchdogNoHeartbeat) {
1245 ALOGD("TestTranscoderWatchdogTimeout");
1246
1247 // Submit session to CLIENT(0) in UID(0).
1248 // Should start immediately (because this is the only session).
1249 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
1250 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1251
1252 // Test 1: If not sending keep-alive at all, timeout after 3 seconds.
1253 expectTimeout(CLIENT(0), SESSION(0), 2);
1254 }
1255
TEST_F(TranscodingSessionControllerTest,TestTranscoderWatchdogHeartbeat)1256 TEST_F(TranscodingSessionControllerTest, TestTranscoderWatchdogHeartbeat) {
1257 // Test 2: No timeout as long as keep-alive coming; timeout after keep-alive stops.
1258 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
1259 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
1260
1261 for (int i = 0; i < 5; i++) {
1262 EXPECT_EQ(mTranscoder->popEvent(1000000), TestTranscoder::NoEvent);
1263 mController->onHeartBeat(CLIENT(0), SESSION(1));
1264 }
1265 expectTimeout(CLIENT(0), SESSION(1), 2);
1266 }
1267
TEST_F(TranscodingSessionControllerTest,TestTranscoderWatchdogDuringPause)1268 TEST_F(TranscodingSessionControllerTest, TestTranscoderWatchdogDuringPause) {
1269 int expectedGen = 2;
1270
1271 // Test 3a: No timeout for paused session even if no keep-alive is sent.
1272 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
1273 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
1274 // Trigger a pause by sending a resource lost.
1275 mController->onResourceLost(CLIENT(0), SESSION(2));
1276 EXPECT_EQ(mTranscoder->popEvent(3100000), TestTranscoder::NoEvent);
1277 mController->onResourceAvailable();
1278 EXPECT_EQ(mTranscoder->popEvent(100000), TestTranscoder::Resume(CLIENT(0), SESSION(2)));
1279 expectTimeout(CLIENT(0), SESSION(2), expectedGen++);
1280
1281 // Test 3b: No timeout for paused session even if no keep-alive is sent.
1282 mController->submit(CLIENT(0), SESSION(3), UID(0), UID(0), mOfflineRequest, mClientCallback0);
1283 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(3)));
1284 // Let the session run almost to timeout, to test timeout reset after pause.
1285 EXPECT_EQ(mTranscoder->popEvent(2900000), TestTranscoder::NoEvent);
1286 // Trigger a pause by submitting a higher-priority request.
1287 mController->submit(CLIENT(0), SESSION(4), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
1288 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(3)));
1289 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(4)));
1290 // Finish the higher-priority session, lower-priority session should resume,
1291 // and the timeout should reset to full value.
1292 mController->onFinish(CLIENT(0), SESSION(4));
1293 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(4)));
1294 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(3)));
1295 expectTimeout(CLIENT(0), SESSION(3), expectedGen++);
1296 }
1297
TEST_F(TranscodingSessionControllerTest,TestTranscoderPacerOverCountOnly)1298 TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerOverCountOnly) {
1299 ALOGD("TestTranscoderPacerOverCountOnly");
1300 testPacerHelper(12 /*numSubmits*/, 100 /*sessionDurationMs*/, 12 /*expectedSuccess*/);
1301 }
1302
TEST_F(TranscodingSessionControllerTest,TestTranscoderPacerOverTimeOnly)1303 TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerOverTimeOnly) {
1304 ALOGD("TestTranscoderPacerOverTimeOnly");
1305 testPacerHelper(5 /*numSubmits*/, 1000 /*sessionDurationMs*/, 5 /*expectedSuccess*/);
1306 }
1307
TEST_F(TranscodingSessionControllerTest,TestTranscoderPacerOverQuota)1308 TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerOverQuota) {
1309 ALOGD("TestTranscoderPacerOverQuota");
1310 testPacerHelper(12 /*numSubmits*/, 400 /*sessionDurationMs*/, 10 /*expectedSuccess*/);
1311 }
1312
TEST_F(TranscodingSessionControllerTest,TestTranscoderPacerWithPause)1313 TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerWithPause) {
1314 ALOGD("TestTranscoderPacerDuringPause");
1315 testPacerHelperWithPause(12 /*numSubmits*/, 400 /*sessionDurationMs*/, 10 /*expectedSuccess*/);
1316 }
1317
1318 /*
1319 * Test the case where multiple client uids request the same session. Session should only
1320 * be dropped when all clients are over quota.
1321 */
TEST_F(TranscodingSessionControllerTest,TestTranscoderPacerMultipleUids)1322 TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerMultipleUids) {
1323 ALOGD("TestTranscoderPacerMultipleUids");
1324 // First, run mClientCallback0 to the point of no quota.
1325 testPacerHelperWithMultipleUids(12 /*numSubmits*/, 400 /*sessionDurationMs*/,
1326 10 /*expectedSuccess*/, mClientCallback0, {});
1327 // Make UID(0) block on Client1's sessions too, Client1's quota should not be affected.
1328 testPacerHelperWithMultipleUids(12 /*numSubmits*/, 400 /*sessionDurationMs*/,
1329 10 /*expectedSuccess*/, mClientCallback1, {UID(0)});
1330 // Make UID(10) block on Client2's sessions. We expect to see 11 succeeds (instead of 10),
1331 // because the addClientUid() is called after the submit, and first session is already
1332 // started by the time UID(10) is added. UID(10) allowed us to run the 11th session,
1333 // after that both UID(10) and UID(2) are out of quota.
1334 testPacerHelperWithMultipleUids(12 /*numSubmits*/, 400 /*sessionDurationMs*/,
1335 11 /*expectedSuccess*/, mClientCallback2, {UID(10)});
1336 }
1337
1338 /*
1339 * Use same uid for clientUid and callingUid, should not be limited by quota.
1340 */
TEST_F(TranscodingSessionControllerTest,TestTranscoderPacerSelfUid)1341 TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerSelfUid) {
1342 ALOGD("TestTranscoderPacerSelfUid");
1343 testPacerHelperWithSelfUid(12 /*numSubmits*/, 400 /*sessionDurationMs*/,
1344 12 /*expectedSuccess*/);
1345 }
1346
1347 } // namespace android
1348