blob: 2e9daee2272fd87a6641fa2a1243ce2b083716cf [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;
Chong Zhangeffd8962020-12-02 14:29:09 -080047constexpr pid_t kClientPid = 10000;
Chong Zhangbc062482020-10-14 16:43:53 -070048constexpr uid_t kInvalidUid = (uid_t)-1;
Chong Zhangeffd8962020-12-02 14:29:09 -080049constexpr pid_t kInvalidPid = (pid_t)-1;
Chong Zhangbc062482020-10-14 16:43:53 -070050
51#define CLIENT(n) (kClientId + (n))
52#define SESSION(n) (kClientSessionId + (n))
53#define UID(n) (kClientUid + (n))
Chong Zhangeffd8962020-12-02 14:29:09 -080054#define PID(n) (kClientPid + (n))
Chong Zhangbc062482020-10-14 16:43:53 -070055
56class TestUidPolicy : public UidPolicyInterface {
57public:
58 TestUidPolicy() = default;
59 virtual ~TestUidPolicy() = default;
60
61 // UidPolicyInterface
62 void registerMonitorUid(uid_t /*uid*/) override {}
63 void unregisterMonitorUid(uid_t /*uid*/) override {}
64 bool isUidOnTop(uid_t uid) override { return mTopUids.count(uid) > 0; }
65 std::unordered_set<uid_t> getTopUids() const override { return mTopUids; }
66 void setCallback(const std::shared_ptr<UidPolicyCallbackInterface>& cb) override {
67 mUidPolicyCallback = cb;
68 }
69 void setTop(uid_t uid) {
70 std::unordered_set<uid_t> uids = {uid};
71 setTop(uids);
72 }
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
Chong Zhangf47a3572020-12-02 11:35:35 -080085class TestResourcePolicy : public ResourcePolicyInterface {
86public:
Chong Zhangeffd8962020-12-02 14:29:09 -080087 TestResourcePolicy() { reset(); }
Chong Zhangf47a3572020-12-02 11:35:35 -080088 virtual ~TestResourcePolicy() = default;
89
Chong Zhangeffd8962020-12-02 14:29:09 -080090 // ResourcePolicyInterface
Chong Zhangf47a3572020-12-02 11:35:35 -080091 void setCallback(const std::shared_ptr<ResourcePolicyCallbackInterface>& /*cb*/) override {}
Chong Zhang8677f1f2021-01-21 20:37:35 +000092 void setPidResourceLost(pid_t pid) override { mResourceLostPid = pid; }
Chong Zhangeffd8962020-12-02 14:29:09 -080093 // ~ResourcePolicyInterface
94
95 pid_t getPid() {
96 pid_t result = mResourceLostPid;
97 reset();
98 return result;
99 }
100
101private:
Chong Zhang8677f1f2021-01-21 20:37:35 +0000102 void reset() { mResourceLostPid = kInvalidPid; }
Chong Zhangeffd8962020-12-02 14:29:09 -0800103 pid_t mResourceLostPid;
Chong Zhangf47a3572020-12-02 11:35:35 -0800104};
105
Chong Zhang8677f1f2021-01-21 20:37:35 +0000106class TestThermalPolicy : public ThermalPolicyInterface {
107public:
108 TestThermalPolicy() = default;
109 virtual ~TestThermalPolicy() = default;
110
111 // ThermalPolicyInterface
112 void setCallback(const std::shared_ptr<ThermalPolicyCallbackInterface>& /*cb*/) override {}
113 bool getThrottlingStatus() { return false; }
114 // ~ThermalPolicyInterface
115
116private:
117};
118
Chong Zhangbc062482020-10-14 16:43:53 -0700119class TestTranscoder : public TranscoderInterface {
120public:
Chong Zhang457c6892021-02-01 15:34:20 -0800121 TestTranscoder() : mLastError(TranscodingErrorCode::kUnknown), mGeneration(0) {}
Chong Zhangbc062482020-10-14 16:43:53 -0700122 virtual ~TestTranscoder() {}
123
124 // TranscoderInterface
Chong Zhangbc062482020-10-14 16:43:53 -0700125 void start(ClientIdType clientId, SessionIdType sessionId,
126 const TranscodingRequestParcel& /*request*/,
127 const std::shared_ptr<ITranscodingClientCallback>& /*clientCallback*/) override {
Chong Zhang457c6892021-02-01 15:34:20 -0800128 append(Start(clientId, sessionId));
Chong Zhangbc062482020-10-14 16:43:53 -0700129 }
130 void pause(ClientIdType clientId, SessionIdType sessionId) override {
Chong Zhang457c6892021-02-01 15:34:20 -0800131 append(Pause(clientId, sessionId));
Chong Zhangbc062482020-10-14 16:43:53 -0700132 }
133 void resume(ClientIdType clientId, SessionIdType sessionId,
134 const TranscodingRequestParcel& /*request*/,
135 const std::shared_ptr<ITranscodingClientCallback>& /*clientCallback*/) override {
Chong Zhang457c6892021-02-01 15:34:20 -0800136 append(Resume(clientId, sessionId));
Chong Zhangbc062482020-10-14 16:43:53 -0700137 }
Chong Zhang457c6892021-02-01 15:34:20 -0800138 void stop(ClientIdType clientId, SessionIdType sessionId, bool abandon) override {
139 append(abandon ? Abandon(clientId, sessionId) : Stop(clientId, sessionId));
Chong Zhangbc062482020-10-14 16:43:53 -0700140 }
141
142 void onFinished(ClientIdType clientId, SessionIdType sessionId) {
Chong Zhang457c6892021-02-01 15:34:20 -0800143 append(Finished(clientId, sessionId));
Chong Zhangbc062482020-10-14 16:43:53 -0700144 }
145
146 void onFailed(ClientIdType clientId, SessionIdType sessionId, TranscodingErrorCode err) {
Chong Zhang457c6892021-02-01 15:34:20 -0800147 append(Failed(clientId, sessionId), err);
148 }
149
150 void onCreated() {
151 std::scoped_lock lock{mLock};
152 mGeneration++;
Chong Zhangbc062482020-10-14 16:43:53 -0700153 }
154
155 TranscodingErrorCode getLastError() {
Chong Zhang457c6892021-02-01 15:34:20 -0800156 std::scoped_lock lock{mLock};
157 // Clear last error.
Chong Zhangbc062482020-10-14 16:43:53 -0700158 TranscodingErrorCode result = mLastError;
Chong Zhang457c6892021-02-01 15:34:20 -0800159 mLastError = TranscodingErrorCode::kNoError;
Chong Zhangbc062482020-10-14 16:43:53 -0700160 return result;
161 }
162
Chong Zhang457c6892021-02-01 15:34:20 -0800163 int32_t getGeneration() {
164 std::scoped_lock lock{mLock};
165 return mGeneration;
166 }
167
Chong Zhangbc062482020-10-14 16:43:53 -0700168 struct Event {
Chong Zhang457c6892021-02-01 15:34:20 -0800169 enum { NoEvent, Start, Pause, Resume, Stop, Finished, Failed, Abandon } type;
Chong Zhangbc062482020-10-14 16:43:53 -0700170 ClientIdType clientId;
171 SessionIdType sessionId;
172 };
173
174 static constexpr Event NoEvent = {Event::NoEvent, 0, 0};
175
176#define DECLARE_EVENT(action) \
177 static Event action(ClientIdType clientId, SessionIdType sessionId) { \
178 return {Event::action, clientId, sessionId}; \
179 }
180
181 DECLARE_EVENT(Start);
182 DECLARE_EVENT(Pause);
183 DECLARE_EVENT(Resume);
184 DECLARE_EVENT(Stop);
185 DECLARE_EVENT(Finished);
186 DECLARE_EVENT(Failed);
Chong Zhang457c6892021-02-01 15:34:20 -0800187 DECLARE_EVENT(Abandon);
Chong Zhangbc062482020-10-14 16:43:53 -0700188
Chong Zhang457c6892021-02-01 15:34:20 -0800189 // Push 1 event to back.
190 void append(const Event& event,
191 const TranscodingErrorCode err = TranscodingErrorCode::kNoError) {
192 std::unique_lock lock(mLock);
193
194 mEventQueue.push_back(event);
195 // Error is sticky, non-error event will not erase it, only getLastError()
196 // clears last error.
197 if (err != TranscodingErrorCode::kNoError) {
198 mLastError = err;
199 }
200 mCondition.notify_one();
201 }
202
203 // Pop 1 event from front, wait for up to timeoutUs if empty.
204 const Event& popEvent(int64_t timeoutUs = 0) {
205 std::unique_lock lock(mLock);
206
207 if (mEventQueue.empty() && timeoutUs > 0) {
208 mCondition.wait_for(lock, std::chrono::microseconds(timeoutUs));
209 }
210
Chong Zhangbc062482020-10-14 16:43:53 -0700211 if (mEventQueue.empty()) {
212 mPoppedEvent = NoEvent;
213 } else {
214 mPoppedEvent = *mEventQueue.begin();
215 mEventQueue.pop_front();
216 }
Chong Zhang457c6892021-02-01 15:34:20 -0800217
Chong Zhangbc062482020-10-14 16:43:53 -0700218 return mPoppedEvent;
219 }
220
221private:
Chong Zhang457c6892021-02-01 15:34:20 -0800222 std::mutex mLock;
223 std::condition_variable mCondition;
Chong Zhangbc062482020-10-14 16:43:53 -0700224 Event mPoppedEvent;
225 std::list<Event> mEventQueue;
226 TranscodingErrorCode mLastError;
Chong Zhang457c6892021-02-01 15:34:20 -0800227 int32_t mGeneration;
Chong Zhangbc062482020-10-14 16:43:53 -0700228};
229
230bool operator==(const TestTranscoder::Event& lhs, const TestTranscoder::Event& rhs) {
231 return lhs.type == rhs.type && lhs.clientId == rhs.clientId && lhs.sessionId == rhs.sessionId;
232}
233
234struct TestClientCallback : public BnTranscodingClientCallback {
235 TestClientCallback(TestTranscoder* owner, int64_t clientId)
236 : mOwner(owner), mClientId(clientId) {
237 ALOGD("TestClient Created");
238 }
239
240 Status openFileDescriptor(const std::string& /*in_fileUri*/, const std::string& /*in_mode*/,
241 ::ndk::ScopedFileDescriptor* /*_aidl_return*/) override {
242 return Status::ok();
243 }
244
245 Status onTranscodingStarted(int32_t /*in_sessionId*/) override { return Status::ok(); }
246
247 Status onTranscodingPaused(int32_t /*in_sessionId*/) override { return Status::ok(); }
248
249 Status onTranscodingResumed(int32_t /*in_sessionId*/) override { return Status::ok(); }
250
251 Status onTranscodingFinished(int32_t in_sessionId,
252 const TranscodingResultParcel& in_result) override {
253 EXPECT_EQ(in_sessionId, in_result.sessionId);
254 ALOGD("TestClientCallback: received onTranscodingFinished");
255 mOwner->onFinished(mClientId, in_sessionId);
256 return Status::ok();
257 }
258
259 Status onTranscodingFailed(int32_t in_sessionId, TranscodingErrorCode in_errorCode) override {
260 mOwner->onFailed(mClientId, in_sessionId, in_errorCode);
261 return Status::ok();
262 }
263
264 Status onAwaitNumberOfSessionsChanged(int32_t /* in_sessionId */,
265 int32_t /* in_oldAwaitNumber */,
266 int32_t /* in_newAwaitNumber */) override {
267 return Status::ok();
268 }
269
270 Status onProgressUpdate(int32_t /* in_sessionId */, int32_t /* in_progress */) override {
271 return Status::ok();
272 }
273
274 virtual ~TestClientCallback() { ALOGI("TestClient destroyed"); };
275
276private:
277 TestTranscoder* mOwner;
278 int64_t mClientId;
279 TestClientCallback(const TestClientCallback&) = delete;
280 TestClientCallback& operator=(const TestClientCallback&) = delete;
281};
282
283class TranscodingSessionControllerTest : public ::testing::Test {
284public:
285 TranscodingSessionControllerTest() { ALOGI("TranscodingSessionControllerTest created"); }
Chong Zhang457c6892021-02-01 15:34:20 -0800286 ~TranscodingSessionControllerTest() { ALOGD("TranscodingSessionControllerTest destroyed"); }
Chong Zhangbc062482020-10-14 16:43:53 -0700287
288 void SetUp() override {
289 ALOGI("TranscodingSessionControllerTest set up");
290 mTranscoder.reset(new TestTranscoder());
291 mUidPolicy.reset(new TestUidPolicy());
Chong Zhangf47a3572020-12-02 11:35:35 -0800292 mResourcePolicy.reset(new TestResourcePolicy());
Chong Zhang8677f1f2021-01-21 20:37:35 +0000293 mThermalPolicy.reset(new TestThermalPolicy());
Chong Zhang457c6892021-02-01 15:34:20 -0800294 mController.reset(new TranscodingSessionController(
295 [this](const std::shared_ptr<TranscoderCallbackInterface>& /*cb*/,
296 int64_t /*heartBeatIntervalUs*/) {
297 // Here we require that the SessionController clears out all its refcounts of
298 // the transcoder object when it calls create.
299 EXPECT_EQ(mTranscoder.use_count(), 1);
300 mTranscoder->onCreated();
301 return mTranscoder;
302 },
303 mUidPolicy, mResourcePolicy, mThermalPolicy));
Chong Zhangbc062482020-10-14 16:43:53 -0700304 mUidPolicy->setCallback(mController);
305
306 // Set priority only, ignore other fields for now.
307 mOfflineRequest.priority = TranscodingSessionPriority::kUnspecified;
308 mRealtimeRequest.priority = TranscodingSessionPriority::kHigh;
309 mClientCallback0 =
310 ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(0));
311 mClientCallback1 =
312 ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(1));
313 mClientCallback2 =
314 ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(2));
315 mClientCallback3 =
316 ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(3));
317 }
318
319 void TearDown() override { ALOGI("TranscodingSessionControllerTest tear down"); }
320
Chong Zhang457c6892021-02-01 15:34:20 -0800321 void expectTimeout(int64_t clientId, int32_t sessionId, int32_t generation) {
322 EXPECT_EQ(mTranscoder->popEvent(2900000), TestTranscoder::NoEvent);
323 EXPECT_EQ(mTranscoder->popEvent(200000), TestTranscoder::Abandon(clientId, sessionId));
324 EXPECT_EQ(mTranscoder->popEvent(100000), TestTranscoder::Failed(clientId, sessionId));
325 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kWatchdogTimeout);
326 // Should have created new transcoder.
327 EXPECT_EQ(mTranscoder->getGeneration(), generation);
328 EXPECT_EQ(mTranscoder.use_count(), 2);
329 }
Chong Zhangbc062482020-10-14 16:43:53 -0700330
331 std::shared_ptr<TestTranscoder> mTranscoder;
332 std::shared_ptr<TestUidPolicy> mUidPolicy;
Chong Zhangf47a3572020-12-02 11:35:35 -0800333 std::shared_ptr<TestResourcePolicy> mResourcePolicy;
Chong Zhang8677f1f2021-01-21 20:37:35 +0000334 std::shared_ptr<TestThermalPolicy> mThermalPolicy;
Chong Zhangbc062482020-10-14 16:43:53 -0700335 std::shared_ptr<TranscodingSessionController> mController;
336 TranscodingRequestParcel mOfflineRequest;
337 TranscodingRequestParcel mRealtimeRequest;
338 std::shared_ptr<TestClientCallback> mClientCallback0;
339 std::shared_ptr<TestClientCallback> mClientCallback1;
340 std::shared_ptr<TestClientCallback> mClientCallback2;
341 std::shared_ptr<TestClientCallback> mClientCallback3;
342};
343
344TEST_F(TranscodingSessionControllerTest, TestSubmitSession) {
345 ALOGD("TestSubmitSession");
346
347 // Start with UID(1) on top.
348 mUidPolicy->setTop(UID(1));
349
350 // Submit offline session to CLIENT(0) in UID(0).
351 // Should start immediately (because this is the only session).
352 mController->submit(CLIENT(0), SESSION(0), UID(0), mOfflineRequest, mClientCallback0);
353 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), 0));
354
355 // Submit real-time session to CLIENT(0).
356 // Should pause offline session and start new session, even if UID(0) is not on top.
357 mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
358 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
359 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
360
361 // Submit real-time session to CLIENT(0), should be queued after the previous session.
362 mController->submit(CLIENT(0), SESSION(2), UID(0), mRealtimeRequest, mClientCallback0);
363 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
364
365 // Submit real-time session to CLIENT(1) in same uid, should be queued after the previous
366 // session.
367 mController->submit(CLIENT(1), SESSION(0), UID(0), mRealtimeRequest, mClientCallback1);
368 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
369
370 // Submit real-time session to CLIENT(2) in UID(1).
371 // Should pause previous session and start new session, because UID(1) is (has been) top.
372 mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
373 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
374 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
375
376 // Submit offline session, shouldn't generate any event.
377 mController->submit(CLIENT(2), SESSION(1), UID(1), mOfflineRequest, mClientCallback2);
378 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
379
380 // Bring UID(0) to top.
381 mUidPolicy->setTop(UID(0));
382 // Should pause current session, and resume last session in UID(0).
383 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
384 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(1)));
385}
386
387TEST_F(TranscodingSessionControllerTest, TestCancelSession) {
388 ALOGD("TestCancelSession");
389
390 // Submit real-time session SESSION(0), should start immediately.
391 mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
392 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
393
394 // Submit real-time session SESSION(1), should not start.
395 mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
396 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
397
398 // Submit offline session SESSION(2), should not start.
399 mController->submit(CLIENT(0), SESSION(2), UID(0), mOfflineRequest, mClientCallback0);
400 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
401
402 // Cancel queued real-time session.
403 // Cancel real-time session SESSION(1), should be cancelled.
404 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(1)));
405
406 // Cancel queued offline session.
407 // Cancel offline session SESSION(2), should be cancelled.
408 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(2)));
409
410 // Submit offline session SESSION(3), shouldn't cause any event.
411 mController->submit(CLIENT(0), SESSION(3), UID(0), mOfflineRequest, mClientCallback0);
412 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
413
414 // Cancel running real-time session SESSION(0).
415 // - Should be stopped first then cancelled.
416 // - Should also start offline session SESSION(2) because real-time queue is empty.
417 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
418 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
419 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(3)));
420
421 // Submit real-time session SESSION(4), offline SESSION(3) should pause and SESSION(4)
422 // should start.
423 mController->submit(CLIENT(0), SESSION(4), UID(0), mRealtimeRequest, mClientCallback0);
424 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(3)));
425 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(4)));
426
427 // Cancel paused SESSION(3). SESSION(3) should be stopped.
428 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(3)));
429 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(3)));
430}
431
432TEST_F(TranscodingSessionControllerTest, TestFinishSession) {
433 ALOGD("TestFinishSession");
434
435 // Start with unspecified top UID.
436 // Finish without any sessions submitted, should be ignored.
437 mController->onFinish(CLIENT(0), SESSION(0));
438 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
439
440 // Submit offline session SESSION(0), should start immediately.
441 mController->submit(CLIENT(0), SESSION(0), UID(0), mOfflineRequest, mClientCallback0);
442 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
443
444 // Submit real-time session SESSION(1), should pause offline session and start immediately.
445 mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
446 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
447 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
448
449 // Submit real-time session SESSION(2), should not start.
450 mController->submit(CLIENT(0), SESSION(2), UID(0), mRealtimeRequest, mClientCallback0);
451 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
452
453 // Finish when the session never started, should be ignored.
454 mController->onFinish(CLIENT(0), SESSION(2));
455 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
456
457 // UID(1) moves to top.
458 mUidPolicy->setTop(UID(1));
459 // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
460 // new session.
461 mController->submit(CLIENT(1), SESSION(0), UID(1), mRealtimeRequest, mClientCallback1);
462 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
463 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
464
465 // Simulate Finish that arrived late, after pause issued by controller.
466 // Should still be propagated to client, but shouldn't trigger any new start.
467 mController->onFinish(CLIENT(0), SESSION(1));
468 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(1)));
469
470 // Finish running real-time session, should start next real-time session in queue.
471 mController->onFinish(CLIENT(1), SESSION(0));
472 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(1), SESSION(0)));
473 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
474
475 // Finish running real-time session, should resume next session (offline session) in queue.
476 mController->onFinish(CLIENT(0), SESSION(2));
477 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(2)));
478 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
479
480 // Finish running offline session.
481 mController->onFinish(CLIENT(0), SESSION(0));
482 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
483
484 // Duplicate finish for last session, should be ignored.
485 mController->onFinish(CLIENT(0), SESSION(0));
486 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
487}
488
489TEST_F(TranscodingSessionControllerTest, TestFailSession) {
490 ALOGD("TestFailSession");
491
492 // Start with unspecified top UID.
493 // Fail without any sessions submitted, should be ignored.
494 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
495 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
496
497 // Submit offline session SESSION(0), should start immediately.
498 mController->submit(CLIENT(0), SESSION(0), UID(0), mOfflineRequest, mClientCallback0);
499 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
500
501 // Submit real-time session SESSION(1), should pause offline session and start immediately.
502 mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
503 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
504 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
505
506 // Submit real-time session SESSION(2), should not start.
507 mController->submit(CLIENT(0), SESSION(2), UID(0), mRealtimeRequest, mClientCallback0);
508 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
509
510 // Fail when the session never started, should be ignored.
511 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
512 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
513
514 // UID(1) moves to top.
515 mUidPolicy->setTop(UID(1));
516 // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
517 // new session.
518 mController->submit(CLIENT(1), SESSION(0), UID(1), mRealtimeRequest, mClientCallback1);
519 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
520 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
521
522 // Simulate Fail that arrived late, after pause issued by controller.
523 // Should still be propagated to client, but shouldn't trigger any new start.
524 mController->onError(CLIENT(0), SESSION(1), TranscodingErrorCode::kUnknown);
525 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
526
527 // Fail running real-time session, should start next real-time session in queue.
528 mController->onError(CLIENT(1), SESSION(0), TranscodingErrorCode::kUnknown);
529 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(1), SESSION(0)));
530 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
531
532 // Fail running real-time session, should resume next session (offline session) in queue.
533 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
534 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(2)));
535 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
536
537 // Fail running offline session, and test error code propagation.
538 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kInvalidOperation);
539 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(0)));
540 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kInvalidOperation);
541
542 // Duplicate fail for last session, should be ignored.
543 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
544 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
545}
546
547TEST_F(TranscodingSessionControllerTest, TestTopUidChanged) {
548 ALOGD("TestTopUidChanged");
549
550 // Start with unspecified top UID.
551 // Submit real-time session to CLIENT(0), session should start immediately.
552 mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
553 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
554
555 // Submit offline session to CLIENT(0), should not start.
556 mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
557 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
558
559 // Move UID(1) to top.
560 mUidPolicy->setTop(UID(1));
561 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
562
563 // Submit real-time session to CLIENT(2) in different uid UID(1).
564 // Should pause previous session and start new session.
565 mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
566 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
567 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
568
569 // Bring UID(0) back to top.
570 mUidPolicy->setTop(UID(0));
571 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
572 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
573
574 // Bring invalid uid to top.
575 mUidPolicy->setTop(kInvalidUid);
576 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
577
578 // Finish session, next real-time session should resume.
579 mController->onFinish(CLIENT(0), SESSION(0));
580 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
581 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
582
583 // Finish session, offline session should start.
584 mController->onFinish(CLIENT(2), SESSION(0));
585 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
586 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
587}
588
589TEST_F(TranscodingSessionControllerTest, TestTopUidSetChanged) {
590 ALOGD("TestTopUidChanged_MultipleUids");
591
592 // Start with unspecified top UID.
593 // Submit real-time session to CLIENT(0), session should start immediately.
594 mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
595 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
596
597 // Submit offline session to CLIENT(0), should not start.
598 mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
599 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
600
601 // Set UID(0), UID(1) to top set.
602 // UID(0) should continue to run.
603 mUidPolicy->setTop({UID(0), UID(1)});
604 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
605
606 // Submit real-time session to CLIENT(2) in different uid UID(1).
607 // UID(0) should pause and UID(1) should start.
608 mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
609 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
610 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
611
612 // Remove UID(0) from top set, and only leave UID(1) in the set.
613 // UID(1) should continue to run.
614 mUidPolicy->setTop(UID(1));
615 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
616
617 // Set UID(0), UID(2) to top set.
618 // UID(1) should continue to run.
619 mUidPolicy->setTop({UID(1), UID(2)});
620 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
621
622 // Bring UID(0) back to top.
623 mUidPolicy->setTop(UID(0));
624 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
625 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
626
627 // Bring invalid uid to top.
628 mUidPolicy->setTop(kInvalidUid);
629 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
630
631 // Finish session, next real-time session from UID(1) should resume, even if UID(1)
632 // no longer top.
633 mController->onFinish(CLIENT(0), SESSION(0));
634 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
635 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
636
637 // Finish session, offline session should start.
638 mController->onFinish(CLIENT(2), SESSION(0));
639 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
640 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
641}
642
Chong Zhang8677f1f2021-01-21 20:37:35 +0000643/* Test resource lost without thermal throttling */
Chong Zhangbc062482020-10-14 16:43:53 -0700644TEST_F(TranscodingSessionControllerTest, TestResourceLost) {
645 ALOGD("TestResourceLost");
646
647 // Start with unspecified top UID.
648 // Submit real-time session to CLIENT(0), session should start immediately.
Chong Zhangeffd8962020-12-02 14:29:09 -0800649 mRealtimeRequest.clientPid = PID(0);
Chong Zhangbc062482020-10-14 16:43:53 -0700650 mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
651 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
652
653 // Submit offline session to CLIENT(0), should not start.
Chong Zhangeffd8962020-12-02 14:29:09 -0800654 mOfflineRequest.clientPid = PID(0);
Chong Zhangbc062482020-10-14 16:43:53 -0700655 mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
656 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
657
658 // Move UID(1) to top.
659 mUidPolicy->setTop(UID(1));
660 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
661
662 // Submit real-time session to CLIENT(2) in different uid UID(1).
663 // Should pause previous session and start new session.
Chong Zhangeffd8962020-12-02 14:29:09 -0800664 mRealtimeRequest.clientPid = PID(1);
Chong Zhangbc062482020-10-14 16:43:53 -0700665 mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
666 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
667 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
668
Chong Zhangeffd8962020-12-02 14:29:09 -0800669 // Test 0: No call into ResourcePolicy if resource lost is from a non-running
670 // or non-existent session.
671 mController->onResourceLost(CLIENT(0), SESSION(0));
672 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
673 mController->onResourceLost(CLIENT(3), SESSION(0));
674 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
675
Chong Zhangbc062482020-10-14 16:43:53 -0700676 // Test 1: No queue change during resource loss.
677 // Signal resource lost.
Chong Zhangeffd8962020-12-02 14:29:09 -0800678 mController->onResourceLost(CLIENT(2), SESSION(0));
679 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
Chong Zhangbc062482020-10-14 16:43:53 -0700680 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
681
682 // Signal resource available, CLIENT(2) should resume.
683 mController->onResourceAvailable();
684 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
685
686 // Test 2: Change of queue order during resource loss.
687 // Signal resource lost.
Chong Zhangeffd8962020-12-02 14:29:09 -0800688 mController->onResourceLost(CLIENT(2), SESSION(0));
689 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
Chong Zhangbc062482020-10-14 16:43:53 -0700690 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
691
692 // Move UID(0) back to top, should have no resume due to no resource.
693 mUidPolicy->setTop(UID(0));
694 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
695
696 // Signal resource available, CLIENT(0) should resume.
697 mController->onResourceAvailable();
698 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
699
Chong Zhang8677f1f2021-01-21 20:37:35 +0000700 // Test 3:
Chong Zhangeffd8962020-12-02 14:29:09 -0800701 mController->onResourceLost(CLIENT(0), SESSION(0));
702 EXPECT_EQ(mResourcePolicy->getPid(), PID(0));
Chong Zhangbc062482020-10-14 16:43:53 -0700703 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
Chong Zhang8677f1f2021-01-21 20:37:35 +0000704 // Cancel the paused top session during resource lost.
705 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
706 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
707 // Signal resource available, CLIENT(2)'s session should start.
708 mController->onResourceAvailable();
709 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
710
711 // Test 4: Adding new queue during resource loss.
712 // Signal resource lost.
713 mController->onResourceLost(CLIENT(2), SESSION(0));
714 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
715 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
Chong Zhangbc062482020-10-14 16:43:53 -0700716
717 // Move UID(2) to top.
718 mUidPolicy->setTop(UID(2));
719
720 // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start due to no resource.
Chong Zhangeffd8962020-12-02 14:29:09 -0800721 mRealtimeRequest.clientPid = PID(2);
Chong Zhangbc062482020-10-14 16:43:53 -0700722 mController->submit(CLIENT(3), SESSION(0), UID(2), mRealtimeRequest, mClientCallback3);
723 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
724
725 // Signal resource available, CLIENT(3)'s session should start.
726 mController->onResourceAvailable();
727 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), SESSION(0)));
728}
729
Chong Zhang8677f1f2021-01-21 20:37:35 +0000730/* Test thermal throttling without resource lost */
731TEST_F(TranscodingSessionControllerTest, TestThermalCallback) {
732 ALOGD("TestThermalCallback");
733
734 // Start with unspecified top UID.
735 // Submit real-time session to CLIENT(0), session should start immediately.
736 mRealtimeRequest.clientPid = PID(0);
737 mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
738 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
739
740 // Submit offline session to CLIENT(0), should not start.
741 mOfflineRequest.clientPid = PID(0);
742 mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
743 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
744
745 // Move UID(1) to top.
746 mUidPolicy->setTop(UID(1));
747 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
748
749 // Submit real-time session to CLIENT(2) in different uid UID(1).
750 // Should pause previous session and start new session.
751 mRealtimeRequest.clientPid = PID(1);
752 mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
753 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
754 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
755
756 // Test 0: Basic case, no queue change during throttling, top session should pause/resume
757 // with throttling.
758 mController->onThrottlingStarted();
759 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
760 mController->onThrottlingStopped();
761 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
762
763 // Test 1: Change of queue order during thermal throttling, when throttling stops,
764 // new top session should resume.
765 mController->onThrottlingStarted();
766 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
767 mUidPolicy->setTop(UID(0));
768 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
769 mController->onThrottlingStopped();
770 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
771
772 // Test 2: Cancel session during throttling, when throttling stops, new top
773 // session should resume.
774 mController->onThrottlingStarted();
775 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
776 // Cancel the paused top session during throttling.
777 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
778 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
779 // Throttling stops, CLIENT(2)'s session should start.
780 mController->onThrottlingStopped();
781 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
782
783 // Test 3: Add new queue during throttling, when throttling stops, new top
784 // session should resume.
785 mController->onThrottlingStarted();
786 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
787 // Move UID(2) to top.
788 mUidPolicy->setTop(UID(2));
789 // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start during throttling.
790 mRealtimeRequest.clientPid = PID(2);
791 mController->submit(CLIENT(3), SESSION(0), UID(2), mRealtimeRequest, mClientCallback3);
792 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
793 // Throttling stops, CLIENT(3)'s session should start.
794 mController->onThrottlingStopped();
795 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), SESSION(0)));
796}
797
798/* Test resource lost and thermal throttling happening simultaneously */
799TEST_F(TranscodingSessionControllerTest, TestResourceLostAndThermalCallback) {
800 ALOGD("TestResourceLostAndThermalCallback");
801
802 // Start with unspecified top UID.
803 // Submit real-time session to CLIENT(0), session should start immediately.
804 mRealtimeRequest.clientPid = PID(0);
805 mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
806 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
807
808 // Submit offline session to CLIENT(0), should not start.
809 mOfflineRequest.clientPid = PID(0);
810 mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
811 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
812
813 // Move UID(1) to top.
814 mUidPolicy->setTop(UID(1));
815 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
816
817 // Submit real-time session to CLIENT(2) in different uid UID(1).
818 // Should pause previous session and start new session.
819 mRealtimeRequest.clientPid = PID(1);
820 mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
821 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
822 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
823
824 // Test 0: Resource lost during throttling.
825 // Throttling starts, top session should pause.
826 mController->onThrottlingStarted();
827 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
828 // Signal resource lost, this should get ignored because the session is now paused.
829 mController->onResourceLost(CLIENT(2), SESSION(0));
830 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
831 // Signal resource available, CLIENT(2) shouldn't resume.
832 mController->onResourceAvailable();
833 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
834 // Throttling ends, top session should resume.
835 mController->onThrottlingStopped();
836 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
837
838 // Test 1: Throttling during resource lost.
839 mController->onResourceLost(CLIENT(2), SESSION(0));
840 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
841 mController->onThrottlingStarted();
842 mController->onThrottlingStopped();
843 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
844 mController->onResourceAvailable();
845 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
846
847 // Test 2: Interleaving resource lost and throttling.
848 mController->onResourceLost(CLIENT(2), SESSION(0));
849 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
850 mController->onThrottlingStarted();
851 mController->onResourceAvailable();
852 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
853 mController->onThrottlingStopped();
854 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
855}
856
Chong Zhang457c6892021-02-01 15:34:20 -0800857TEST_F(TranscodingSessionControllerTest, TestTranscoderWatchdogTimeout) {
858 ALOGD("TestTranscoderWatchdogTimeout");
859
860 // Submit session to CLIENT(0) in UID(0).
861 // Should start immediately (because this is the only session).
862 mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
863 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
864
865 int32_t expectedGen = 2;
866 // Test 1: If not sending keep-alive at all, timeout after 3 seconds.
867 expectTimeout(CLIENT(0), SESSION(0), expectedGen++);
868
869 // Test 2: No timeout as long as keep-alive coming; timeout after keep-alive stops.
870 mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
871 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
872 for (int i = 0; i < 5; i++) {
873 EXPECT_EQ(mTranscoder->popEvent(1000000), TestTranscoder::NoEvent);
874 mController->onHeartBeat(CLIENT(0), SESSION(1));
875 }
876 expectTimeout(CLIENT(0), SESSION(1), expectedGen++);
877
878 // Test 3a: No timeout for paused session even if no keep-alive is sent.
879 mController->submit(CLIENT(0), SESSION(2), UID(0), mOfflineRequest, mClientCallback0);
880 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
881 // Trigger a pause by sending a resource lost.
882 mController->onResourceLost(CLIENT(0), SESSION(2));
883 EXPECT_EQ(mTranscoder->popEvent(3100000), TestTranscoder::NoEvent);
884 mController->onResourceAvailable();
885 EXPECT_EQ(mTranscoder->popEvent(100000), TestTranscoder::Resume(CLIENT(0), SESSION(2)));
886 expectTimeout(CLIENT(0), SESSION(2), expectedGen++);
887
888 // Test 3b: No timeout for paused session even if no keep-alive is sent.
889 mController->submit(CLIENT(0), SESSION(3), UID(0), mOfflineRequest, mClientCallback0);
890 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(3)));
891 // Let the session run almost to timeout, to test timeout reset after pause.
892 EXPECT_EQ(mTranscoder->popEvent(2900000), TestTranscoder::NoEvent);
893 // Trigger a pause by submitting a higher-priority request.
894 mController->submit(CLIENT(0), SESSION(4), UID(0), mRealtimeRequest, mClientCallback0);
895 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(3)));
896 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(4)));
897 // Finish the higher-priority session, lower-priority session should resume,
898 // and the timeout should reset to full value.
899 mController->onFinish(CLIENT(0), SESSION(4));
900 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(4)));
901 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(3)));
902 expectTimeout(CLIENT(0), SESSION(3), expectedGen++);
903}
904
Chong Zhangbc062482020-10-14 16:43:53 -0700905} // namespace android