blob: 9e7fa9574e248efbc03ff8a02910a0c0f2d57944 [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 Zhang87d199c2021-03-01 19:02:18 -0800121 TestTranscoder() : 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,
Linus Nilssona99f4042021-02-25 15:49:43 -0800126 const TranscodingRequestParcel& /*request*/, uid_t /*callingUid*/,
Chong Zhangbc062482020-10-14 16:43:53 -0700127 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,
Linus Nilssona99f4042021-02-25 15:49:43 -0800134 const TranscodingRequestParcel& /*request*/, uid_t /*callingUid*/,
Chong Zhangbc062482020-10-14 16:43:53 -0700135 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
Chong Zhangbc062482020-10-14 16:43:53 -0700155 struct Event {
Chong Zhang457c6892021-02-01 15:34:20 -0800156 enum { NoEvent, Start, Pause, Resume, Stop, Finished, Failed, Abandon } type;
Chong Zhangbc062482020-10-14 16:43:53 -0700157 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);
Chong Zhang457c6892021-02-01 15:34:20 -0800174 DECLARE_EVENT(Abandon);
Chong Zhangbc062482020-10-14 16:43:53 -0700175
Chong Zhang457c6892021-02-01 15:34:20 -0800176 // Push 1 event to back.
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) {
Chong Zhang87d199c2021-03-01 19:02:18 -0800185 mLastErrorQueue.push_back(err);
Chong Zhang457c6892021-02-01 15:34:20 -0800186 }
187 mCondition.notify_one();
188 }
189
190 // Pop 1 event from front, wait for up to timeoutUs if empty.
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
Chong Zhangbc062482020-10-14 16:43:53 -0700198 if (mEventQueue.empty()) {
199 mPoppedEvent = NoEvent;
200 } else {
201 mPoppedEvent = *mEventQueue.begin();
202 mEventQueue.pop_front();
203 }
Chong Zhang457c6892021-02-01 15:34:20 -0800204
Chong Zhangbc062482020-10-14 16:43:53 -0700205 return mPoppedEvent;
206 }
207
Chong Zhang87d199c2021-03-01 19:02:18 -0800208 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
218 int32_t getGeneration() {
219 std::scoped_lock lock{mLock};
220 return mGeneration;
221 }
222
Chong Zhangbc062482020-10-14 16:43:53 -0700223private:
Chong Zhang457c6892021-02-01 15:34:20 -0800224 std::mutex mLock;
225 std::condition_variable mCondition;
Chong Zhangbc062482020-10-14 16:43:53 -0700226 Event mPoppedEvent;
227 std::list<Event> mEventQueue;
Chong Zhang87d199c2021-03-01 19:02:18 -0800228 std::list<TranscodingErrorCode> mLastErrorQueue;
Chong Zhang457c6892021-02-01 15:34:20 -0800229 int32_t mGeneration;
Chong Zhangbc062482020-10-14 16:43:53 -0700230};
231
232bool 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
236struct TestClientCallback : public BnTranscodingClientCallback {
Chong Zhangebd86d32021-03-29 11:30:56 -0700237 TestClientCallback(TestTranscoder* owner, ClientIdType clientId, uid_t clientUid)
238 : mOwner(owner), mClientId(clientId), mClientUid(clientUid) {
Chong Zhangbc062482020-10-14 16:43:53 -0700239 ALOGD("TestClient Created");
240 }
241
Chong Zhangebd86d32021-03-29 11:30:56 -0700242 ClientIdType clientId() const { return mClientId; }
243 uid_t clientUid() const { return mClientUid; }
244
Chong Zhangbc062482020-10-14 16:43:53 -0700245 Status openFileDescriptor(const std::string& /*in_fileUri*/, const std::string& /*in_mode*/,
246 ::ndk::ScopedFileDescriptor* /*_aidl_return*/) override {
247 return Status::ok();
248 }
249
250 Status onTranscodingStarted(int32_t /*in_sessionId*/) override { return Status::ok(); }
251
252 Status onTranscodingPaused(int32_t /*in_sessionId*/) override { return Status::ok(); }
253
254 Status onTranscodingResumed(int32_t /*in_sessionId*/) override { return Status::ok(); }
255
256 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
264 Status onTranscodingFailed(int32_t in_sessionId, TranscodingErrorCode in_errorCode) override {
265 mOwner->onFailed(mClientId, in_sessionId, in_errorCode);
266 return Status::ok();
267 }
268
269 Status onAwaitNumberOfSessionsChanged(int32_t /* in_sessionId */,
270 int32_t /* in_oldAwaitNumber */,
271 int32_t /* in_newAwaitNumber */) override {
272 return Status::ok();
273 }
274
275 Status onProgressUpdate(int32_t /* in_sessionId */, int32_t /* in_progress */) override {
276 return Status::ok();
277 }
278
279 virtual ~TestClientCallback() { ALOGI("TestClient destroyed"); };
280
281private:
282 TestTranscoder* mOwner;
Chong Zhangebd86d32021-03-29 11:30:56 -0700283 ClientIdType mClientId;
284 uid_t mClientUid;
Chong Zhangbc062482020-10-14 16:43:53 -0700285 TestClientCallback(const TestClientCallback&) = delete;
286 TestClientCallback& operator=(const TestClientCallback&) = delete;
287};
288
289class TranscodingSessionControllerTest : public ::testing::Test {
290public:
291 TranscodingSessionControllerTest() { ALOGI("TranscodingSessionControllerTest created"); }
Chong Zhang457c6892021-02-01 15:34:20 -0800292 ~TranscodingSessionControllerTest() { ALOGD("TranscodingSessionControllerTest destroyed"); }
Chong Zhangbc062482020-10-14 16:43:53 -0700293
294 void SetUp() override {
295 ALOGI("TranscodingSessionControllerTest set up");
296 mTranscoder.reset(new TestTranscoder());
297 mUidPolicy.reset(new TestUidPolicy());
Chong Zhangf47a3572020-12-02 11:35:35 -0800298 mResourcePolicy.reset(new TestResourcePolicy());
Chong Zhang8677f1f2021-01-21 20:37:35 +0000299 mThermalPolicy.reset(new TestThermalPolicy());
Chong Zhang87d199c2021-03-01 19:02:18 -0800300 // Overrid default burst params with shorter values for testing.
301 TranscodingSessionController::ControllerConfig config = {
302 .pacerBurstThresholdMs = 500,
303 .pacerBurstCountQuota = 10,
304 .pacerBurstTimeQuotaSeconds = 3,
305 };
Chong Zhang457c6892021-02-01 15:34:20 -0800306 mController.reset(new TranscodingSessionController(
Chong Zhang87d199c2021-03-01 19:02:18 -0800307 [this](const std::shared_ptr<TranscoderCallbackInterface>& /*cb*/) {
Chong Zhang457c6892021-02-01 15:34:20 -0800308 // 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 },
Chong Zhang87d199c2021-03-01 19:02:18 -0800314 mUidPolicy, mResourcePolicy, mThermalPolicy, &config));
Chong Zhangbc062482020-10-14 16:43:53 -0700315 mUidPolicy->setCallback(mController);
316
317 // Set priority only, ignore other fields for now.
318 mOfflineRequest.priority = TranscodingSessionPriority::kUnspecified;
319 mRealtimeRequest.priority = TranscodingSessionPriority::kHigh;
Chong Zhangebd86d32021-03-29 11:30:56 -0700320 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));
Chong Zhangbc062482020-10-14 16:43:53 -0700328 }
329
330 void TearDown() override { ALOGI("TranscodingSessionControllerTest tear down"); }
331
Chong Zhang457c6892021-02-01 15:34:20 -0800332 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 }
Chong Zhangbc062482020-10-14 16:43:53 -0700341
Chong Zhang87d199c2021-03-01 19:02:18 -0800342 void testPacerHelper(int numSubmits, int sessionDurationMs, int expectedSuccess,
343 bool pauseLastSuccessSession = false) {
Chong Zhangebd86d32021-03-29 11:30:56 -0700344 testPacerHelper(numSubmits, sessionDurationMs, expectedSuccess, mClientCallback0, {},
345 pauseLastSuccessSession);
346 }
347
348 void testPacerHelper(int numSubmits, int sessionDurationMs, int expectedSuccess,
349 const std::shared_ptr<TestClientCallback>& client,
350 const std::vector<int>& additionalClientUids,
351 bool pauseLastSuccessSession) {
Chong Zhang87d199c2021-03-01 19:02:18 -0800352 for (int i = 0; i < numSubmits; i++) {
Chong Zhangebd86d32021-03-29 11:30:56 -0700353 mController->submit(client->clientId(), SESSION(i), client->clientUid(),
354 client->clientUid(), mRealtimeRequest, client);
355 for (int additionalUid : additionalClientUids) {
356 mController->addClientUid(client->clientId(), SESSION(i), additionalUid);
357 }
Chong Zhang87d199c2021-03-01 19:02:18 -0800358 }
359 for (int i = 0; i < expectedSuccess; i++) {
Chong Zhangebd86d32021-03-29 11:30:56 -0700360 EXPECT_EQ(mTranscoder->popEvent(),
361 TestTranscoder::Start(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800362 if ((i == expectedSuccess - 1) && pauseLastSuccessSession) {
363 // Insert a pause of 3 sec to the last success running session
364 mController->onThrottlingStarted();
Chong Zhangebd86d32021-03-29 11:30:56 -0700365 EXPECT_EQ(mTranscoder->popEvent(),
366 TestTranscoder::Pause(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800367 sleep(3);
368 mController->onThrottlingStopped();
Chong Zhangebd86d32021-03-29 11:30:56 -0700369 EXPECT_EQ(mTranscoder->popEvent(),
370 TestTranscoder::Resume(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800371 }
372 usleep(sessionDurationMs * 1000);
373 // Test half of Finish and half of Error, both should be counted as burst runs.
374 if (i & 1) {
Chong Zhangebd86d32021-03-29 11:30:56 -0700375 mController->onFinish(client->clientId(), SESSION(i));
376 EXPECT_EQ(mTranscoder->popEvent(),
377 TestTranscoder::Finished(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800378 } else {
Chong Zhangebd86d32021-03-29 11:30:56 -0700379 mController->onError(client->clientId(), SESSION(i),
380 TranscodingErrorCode::kUnknown);
Chong Zhang87d199c2021-03-01 19:02:18 -0800381 EXPECT_EQ(mTranscoder->popEvent(100000),
Chong Zhangebd86d32021-03-29 11:30:56 -0700382 TestTranscoder::Failed(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800383 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
384 }
385 }
386 for (int i = expectedSuccess; i < numSubmits; i++) {
Chong Zhangebd86d32021-03-29 11:30:56 -0700387 EXPECT_EQ(mTranscoder->popEvent(),
388 TestTranscoder::Failed(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800389 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kDroppedByService);
390 }
391 }
392
Chong Zhangbc062482020-10-14 16:43:53 -0700393 std::shared_ptr<TestTranscoder> mTranscoder;
394 std::shared_ptr<TestUidPolicy> mUidPolicy;
Chong Zhangf47a3572020-12-02 11:35:35 -0800395 std::shared_ptr<TestResourcePolicy> mResourcePolicy;
Chong Zhang8677f1f2021-01-21 20:37:35 +0000396 std::shared_ptr<TestThermalPolicy> mThermalPolicy;
Chong Zhangbc062482020-10-14 16:43:53 -0700397 std::shared_ptr<TranscodingSessionController> mController;
398 TranscodingRequestParcel mOfflineRequest;
399 TranscodingRequestParcel mRealtimeRequest;
400 std::shared_ptr<TestClientCallback> mClientCallback0;
401 std::shared_ptr<TestClientCallback> mClientCallback1;
402 std::shared_ptr<TestClientCallback> mClientCallback2;
403 std::shared_ptr<TestClientCallback> mClientCallback3;
404};
405
406TEST_F(TranscodingSessionControllerTest, TestSubmitSession) {
407 ALOGD("TestSubmitSession");
408
409 // Start with UID(1) on top.
410 mUidPolicy->setTop(UID(1));
411
412 // Submit offline session to CLIENT(0) in UID(0).
413 // Should start immediately (because this is the only session).
Linus Nilssona99f4042021-02-25 15:49:43 -0800414 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700415 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), 0));
416
417 // Submit real-time session to CLIENT(0).
418 // Should pause offline session and start new session, even if UID(0) is not on top.
Linus Nilssona99f4042021-02-25 15:49:43 -0800419 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700420 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
421 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
422
423 // Submit real-time session to CLIENT(0), should be queued after the previous session.
Linus Nilssona99f4042021-02-25 15:49:43 -0800424 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700425 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
426
427 // Submit real-time session to CLIENT(1) in same uid, should be queued after the previous
428 // session.
Linus Nilssona99f4042021-02-25 15:49:43 -0800429 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mRealtimeRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -0700430 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
431
432 // Submit real-time session to CLIENT(2) in UID(1).
433 // Should pause previous session and start new session, because UID(1) is (has been) top.
Linus Nilssona99f4042021-02-25 15:49:43 -0800434 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhangbc062482020-10-14 16:43:53 -0700435 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
436 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
437
438 // Submit offline session, shouldn't generate any event.
Linus Nilssona99f4042021-02-25 15:49:43 -0800439 mController->submit(CLIENT(2), SESSION(1), UID(2), UID(1), mOfflineRequest, mClientCallback2);
Chong Zhangbc062482020-10-14 16:43:53 -0700440 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
441
442 // Bring UID(0) to top.
443 mUidPolicy->setTop(UID(0));
444 // Should pause current session, and resume last session in UID(0).
445 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
446 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(1)));
447}
448
449TEST_F(TranscodingSessionControllerTest, TestCancelSession) {
450 ALOGD("TestCancelSession");
451
452 // Submit real-time session SESSION(0), should start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800453 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700454 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
455
456 // Submit real-time session SESSION(1), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800457 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700458 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
459
460 // Submit offline session SESSION(2), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800461 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700462 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
463
464 // Cancel queued real-time session.
465 // Cancel real-time session SESSION(1), should be cancelled.
466 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(1)));
467
468 // Cancel queued offline session.
469 // Cancel offline session SESSION(2), should be cancelled.
470 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(2)));
471
472 // Submit offline session SESSION(3), shouldn't cause any event.
Linus Nilssona99f4042021-02-25 15:49:43 -0800473 mController->submit(CLIENT(0), SESSION(3), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700474 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
475
476 // Cancel running real-time session SESSION(0).
477 // - Should be stopped first then cancelled.
478 // - Should also start offline session SESSION(2) because real-time queue is empty.
479 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
480 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
481 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(3)));
482
483 // Submit real-time session SESSION(4), offline SESSION(3) should pause and SESSION(4)
484 // should start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800485 mController->submit(CLIENT(0), SESSION(4), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700486 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(3)));
487 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(4)));
488
489 // Cancel paused SESSION(3). SESSION(3) should be stopped.
490 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(3)));
491 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(3)));
492}
493
Chong Zhangebd86d32021-03-29 11:30:56 -0700494TEST_F(TranscodingSessionControllerTest, TestCancelSessionWithMultipleUids) {
495 ALOGD("TestCancelSessionWithMultipleUids");
496 std::vector<int32_t> clientUids;
497
498 // Submit real-time session SESSION(0), should start immediately.
499 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
500 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
501
502 // Submit real-time session SESSION(1), should not start.
503 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
504 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
505
506 // Submit offline session SESSION(2), should not start.
507 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
508 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
509
510 // UID(1) moves to top.
511 mUidPolicy->setTop(UID(1));
512
513 // Add UID(1) to the offline SESSION(2), SESSION(2) should start and SESSION(0) should pause.
514 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
515 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
516 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
517
518 // Add UID(1) to SESSION(1) as well.
519 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
520
521 // Cancel SESSION(2), should be cancelled and SESSION(1) should start.
522 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(2)));
523 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
524 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(2)));
525 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
526
527 // Cancel SESSION(1), should be cancelled and SESSION(0) should resume.
528 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(1)));
529 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
530 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(1)));
531 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
532}
533
534TEST_F(TranscodingSessionControllerTest, TestCancelAllSessionsForClient) {
535 // Submit real-time session SESSION(0), should start immediately.
536 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
537 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
538
539 // Submit real-time session SESSION(1), should not start.
540 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
541 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
542
543 // Submit offline session SESSION(2), should not start.
544 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
545 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
546
547 std::vector<int32_t> clientUids;
548 // Make some more uids blocked on the sessions.
549 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(1)));
550 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
551 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
552 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
553 EXPECT_EQ(clientUids.size(), 2);
554 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
555 EXPECT_EQ(clientUids.size(), 2);
556 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
557 EXPECT_EQ(clientUids.size(), 1);
558
559 // Cancel all sessions for CLIENT(0) with -1.
560 // Expect SESSION(0) and SESSION(1) to be gone.
561 // Expect SESSION(2) still there with empty client uid list (only kept for offline) and start.
562 EXPECT_TRUE(mController->cancel(CLIENT(0), -1));
563 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
564 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
565 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
566 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
567 EXPECT_EQ(clientUids.size(), 0);
568 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
569}
570
Chong Zhangbc062482020-10-14 16:43:53 -0700571TEST_F(TranscodingSessionControllerTest, TestFinishSession) {
572 ALOGD("TestFinishSession");
573
574 // Start with unspecified top UID.
575 // Finish without any sessions submitted, should be ignored.
576 mController->onFinish(CLIENT(0), SESSION(0));
577 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
578
579 // Submit offline session SESSION(0), should start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800580 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700581 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
582
583 // Submit real-time session SESSION(1), should pause offline session and start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800584 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700585 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
586 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
587
588 // Submit real-time session SESSION(2), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800589 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700590 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
591
592 // Finish when the session never started, should be ignored.
593 mController->onFinish(CLIENT(0), SESSION(2));
594 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
595
596 // UID(1) moves to top.
597 mUidPolicy->setTop(UID(1));
598 // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
599 // new session.
Linus Nilssona99f4042021-02-25 15:49:43 -0800600 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(1), mRealtimeRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -0700601 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
602 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
603
604 // Simulate Finish that arrived late, after pause issued by controller.
605 // Should still be propagated to client, but shouldn't trigger any new start.
606 mController->onFinish(CLIENT(0), SESSION(1));
607 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(1)));
608
609 // Finish running real-time session, should start next real-time session in queue.
610 mController->onFinish(CLIENT(1), SESSION(0));
611 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(1), SESSION(0)));
612 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
613
614 // Finish running real-time session, should resume next session (offline session) in queue.
615 mController->onFinish(CLIENT(0), SESSION(2));
616 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(2)));
617 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
618
619 // Finish running offline session.
620 mController->onFinish(CLIENT(0), SESSION(0));
621 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
622
623 // Duplicate finish for last session, should be ignored.
624 mController->onFinish(CLIENT(0), SESSION(0));
625 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
626}
627
Chong Zhangebd86d32021-03-29 11:30:56 -0700628TEST_F(TranscodingSessionControllerTest, TestFinishSessionWithMultipleUids) {
629 ALOGD("TestFinishSessionWithMultipleUids");
630 std::vector<int32_t> clientUids;
631
632 // Start with unspecified top uid.
633 // Submit real-time session SESSION(0), should start immediately.
634 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
635 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
636
637 // Submit real-time session SESSION(1), should not start.
638 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
639 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
640 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
641
642 // Submit real-time session SESSION(2), should not start.
643 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
644 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
645 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
646 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(2)));
647
648 // UID(1) moves to top.
649 mUidPolicy->setTop(UID(1));
650 // SESSION(0) should pause, SESSION(1) should start.
651 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
652 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
653
654 // Finish SESSION(1), SESSION(2) (next in line for UID(1)) should start.
655 mController->onFinish(CLIENT(0), SESSION(1));
656 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(1)));
657 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
658 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
659
660 // Finish SESSION(2), SESSION(0) should resume.
661 mController->onFinish(CLIENT(0), SESSION(2));
662 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(2)));
663 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
664 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
665}
666
Chong Zhangbc062482020-10-14 16:43:53 -0700667TEST_F(TranscodingSessionControllerTest, TestFailSession) {
668 ALOGD("TestFailSession");
669
670 // Start with unspecified top UID.
671 // Fail without any sessions submitted, should be ignored.
672 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
673 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
674
675 // Submit offline session SESSION(0), should start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800676 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700677 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
678
679 // Submit real-time session SESSION(1), should pause offline session and start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800680 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700681 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
682 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
683
684 // Submit real-time session SESSION(2), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800685 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700686 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
687
688 // Fail when the session never started, should be ignored.
689 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
690 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
691
692 // UID(1) moves to top.
693 mUidPolicy->setTop(UID(1));
694 // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
695 // new session.
Linus Nilssona99f4042021-02-25 15:49:43 -0800696 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(1), mRealtimeRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -0700697 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
698 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
699
700 // Simulate Fail that arrived late, after pause issued by controller.
701 // Should still be propagated to client, but shouldn't trigger any new start.
702 mController->onError(CLIENT(0), SESSION(1), TranscodingErrorCode::kUnknown);
703 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800704 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
Chong Zhangbc062482020-10-14 16:43:53 -0700705
706 // Fail running real-time session, should start next real-time session in queue.
707 mController->onError(CLIENT(1), SESSION(0), TranscodingErrorCode::kUnknown);
708 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(1), SESSION(0)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800709 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
Chong Zhangbc062482020-10-14 16:43:53 -0700710 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
711
712 // Fail running real-time session, should resume next session (offline session) in queue.
713 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
714 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(2)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800715 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
Chong Zhangbc062482020-10-14 16:43:53 -0700716 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
717
718 // Fail running offline session, and test error code propagation.
719 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kInvalidOperation);
720 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(0)));
721 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kInvalidOperation);
722
723 // Duplicate fail for last session, should be ignored.
724 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
725 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
726}
727
Chong Zhangebd86d32021-03-29 11:30:56 -0700728TEST_F(TranscodingSessionControllerTest, TestFailSessionWithMultipleUids) {
729 ALOGD("TestFailSessionWithMultipleUids");
730 std::vector<int32_t> clientUids;
731
732 // Start with unspecified top uid.
733 // Submit real-time session SESSION(0), should start immediately.
734 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
735 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
736
737 // Submit real-time session SESSION(1), should not start.
738 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
739 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
740 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
741
742 // Submit real-time session SESSION(2), should not start.
743 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
744 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
745
746 // UID(1) moves to top.
747 mUidPolicy->setTop(UID(1));
748 // SESSION(0) should pause, SESSION(1) should start.
749 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
750 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
751
752 // Add UID(1) and UID(2) to SESSION(2).
753 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
754 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(2)));
755
756 // Fail SESSION(1), SESSION(2) (next in line for UID(1)) should start.
757 mController->onError(CLIENT(0), SESSION(1), TranscodingErrorCode::kUnknown);
758 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
759 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
760 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
761 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
762
763 // Fail SESSION(2), SESSION(0) should resume.
764 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kInvalidOperation);
765 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(2)));
766 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kInvalidOperation);
767 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
768 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
769}
770
Chong Zhangbc062482020-10-14 16:43:53 -0700771TEST_F(TranscodingSessionControllerTest, TestTopUidChanged) {
772 ALOGD("TestTopUidChanged");
773
774 // Start with unspecified top UID.
775 // Submit real-time session to CLIENT(0), session should start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800776 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700777 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
778
779 // Submit offline session to CLIENT(0), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800780 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -0700781 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
782
783 // Move UID(1) to top.
784 mUidPolicy->setTop(UID(1));
785 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
786
787 // Submit real-time session to CLIENT(2) in different uid UID(1).
788 // Should pause previous session and start new session.
Linus Nilssona99f4042021-02-25 15:49:43 -0800789 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhangbc062482020-10-14 16:43:53 -0700790 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
791 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
792
793 // Bring UID(0) back to top.
794 mUidPolicy->setTop(UID(0));
795 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
796 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
797
798 // Bring invalid uid to top.
799 mUidPolicy->setTop(kInvalidUid);
800 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
801
802 // Finish session, next real-time session should resume.
803 mController->onFinish(CLIENT(0), SESSION(0));
804 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
805 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
806
807 // Finish session, offline session should start.
808 mController->onFinish(CLIENT(2), SESSION(0));
809 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
810 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
811}
812
Chong Zhangebd86d32021-03-29 11:30:56 -0700813TEST_F(TranscodingSessionControllerTest, TestTopUidChangedMultipleUids) {
814 ALOGD("TestTopUidChangedMultipleUids");
815
816 // Start with unspecified top UID.
817 // Submit real-time session to CLIENT(0), session should start immediately.
818 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
819 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
820
821 // Submit offline session to CLIENT(0), should not start.
822 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
823 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
824
825 // Bring UID(1) to top.
826 mUidPolicy->setTop(UID(1));
827 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
828
829 // Add UID(1) to SESSION(0), SESSION(0) should continue to run
830 // (no pause&resume of the same session).
831 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(1)));
832 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
833
834 // Bring UID(0) back to top, SESSION(0) should continue to run
835 // (no pause&resume of the same session).
836 mUidPolicy->setTop(UID(0));
837 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
838
839 // Bring UID(2) to top.
840 mUidPolicy->setTop(UID(2));
841 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
842 // Add UID(2) to the offline session, it should be started.
843 EXPECT_TRUE(mController->addClientUid(CLIENT(1), SESSION(0), UID(2)));
844 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
845 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
846
847 // ADD UID(3) to SESSION(0).
848 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(3)));
849 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
850 // Bring UID(3) to top, SESSION(0) should resume.
851 mUidPolicy->setTop(UID(3));
852 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(1), SESSION(0)));
853 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
854
855 // Now make UID(2) also blocked on CLIENT(0), SESSION(0).
856 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(2)));
857
858 // Bring UID(2) back to top, CLIENT(0), SESSION(0) should continue to run (even if it's
859 // added to UID(2)'s queue later than CLIENT(1)'s SESSION(0)).
860 mUidPolicy->setTop(UID(2));
861 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
862}
863
Chong Zhangbc062482020-10-14 16:43:53 -0700864TEST_F(TranscodingSessionControllerTest, TestTopUidSetChanged) {
Chong Zhangebd86d32021-03-29 11:30:56 -0700865 ALOGD("TestTopUidSetChanged");
Chong Zhangbc062482020-10-14 16:43:53 -0700866
867 // Start with unspecified top UID.
868 // Submit real-time session to CLIENT(0), session should start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800869 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700870 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
871
872 // Submit offline session to CLIENT(0), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800873 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -0700874 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
875
876 // Set UID(0), UID(1) to top set.
877 // UID(0) should continue to run.
878 mUidPolicy->setTop({UID(0), UID(1)});
879 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
880
881 // Submit real-time session to CLIENT(2) in different uid UID(1).
882 // UID(0) should pause and UID(1) should start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800883 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhangbc062482020-10-14 16:43:53 -0700884 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
885 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
886
887 // Remove UID(0) from top set, and only leave UID(1) in the set.
888 // UID(1) should continue to run.
889 mUidPolicy->setTop(UID(1));
890 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
891
892 // Set UID(0), UID(2) to top set.
893 // UID(1) should continue to run.
894 mUidPolicy->setTop({UID(1), UID(2)});
895 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
896
897 // Bring UID(0) back to top.
898 mUidPolicy->setTop(UID(0));
899 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
900 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
901
902 // Bring invalid uid to top.
903 mUidPolicy->setTop(kInvalidUid);
904 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
905
906 // Finish session, next real-time session from UID(1) should resume, even if UID(1)
907 // no longer top.
908 mController->onFinish(CLIENT(0), SESSION(0));
909 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
910 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
911
912 // Finish session, offline session should start.
913 mController->onFinish(CLIENT(2), SESSION(0));
914 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
915 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
916}
917
Chong Zhang2a3c9672021-03-31 15:36:32 -0700918TEST_F(TranscodingSessionControllerTest, TestUidGone) {
919 ALOGD("TestUidGone");
920
921 mUidPolicy->setTop(UID(0));
922 // Start with unspecified top UID.
923 // Submit real-time sessions to CLIENT(0), session should start immediately.
924 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
925 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
926
927 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
928 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
929 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
930
931 // Submit real-time session to CLIENT(1), should not start.
932 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(1), mOfflineRequest, mClientCallback1);
933 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
934 EXPECT_TRUE(mController->addClientUid(CLIENT(1), SESSION(0), UID(1)));
935
936 // Tell the controller that UID(0) is gone.
937 mUidPolicy->setTop(UID(1));
938 // CLIENT(0)'s SESSION(1) should start, SESSION(0) should be cancelled.
939 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
940 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
941 mController->onUidGone(UID(0));
942 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
943 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(0)));
944 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
945
946 std::vector<int32_t> clientUids;
947 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
948 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
949 EXPECT_EQ(clientUids.size(), 1);
950 EXPECT_EQ(clientUids[0], UID(1));
951
952 // Tell the controller that UID(1) is gone too.
953 mController->onUidGone(UID(1));
954 // CLIENT(1)'s SESSION(0) should start, CLIENT(0)'s SESSION(1) should be cancelled.
955 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(1)));
956 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
957 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
958 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
959 // CLIENT(1) SESSION(0) should not have any client uids as it's only kept for offline.
960 EXPECT_TRUE(mController->getClientUids(CLIENT(1), SESSION(0), &clientUids));
961 EXPECT_EQ(clientUids.size(), 0);
962}
963
Chong Zhangebd86d32021-03-29 11:30:56 -0700964TEST_F(TranscodingSessionControllerTest, TestAddGetClientUids) {
965 ALOGD("TestAddGetClientUids");
966
967 // Add/get client uids with non-existent session, should fail.
968 std::vector<int32_t> clientUids;
969 uid_t ownUid = ::getuid();
970 EXPECT_FALSE(mController->addClientUid(CLIENT(0), SESSION(0), ownUid));
971 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
972
973 // Submit a real-time request.
974 EXPECT_TRUE(mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest,
975 mClientCallback0));
976 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
977
978 // Should have own uid in client uids.
979 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
980 EXPECT_EQ(clientUids.size(), 1);
981 EXPECT_EQ(clientUids[0], UID(0));
982
983 // Add UID(0) again should fail.
984 EXPECT_FALSE(mController->addClientUid(CLIENT(0), SESSION(0), UID(0)));
985
986 // Add own uid should succeed.
987 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), ownUid));
988 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
989 std::unordered_set<uid_t> uidSet;
990 uidSet.insert(clientUids.begin(), clientUids.end());
991 EXPECT_EQ(uidSet.size(), 2);
992 EXPECT_EQ(uidSet.count(UID(0)), 1);
993 EXPECT_EQ(uidSet.count(ownUid), 1);
994
995 // Submit an offline request.
996 EXPECT_TRUE(mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mOfflineRequest,
997 mClientCallback0));
998 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
999
1000 // Should not have own uid in client uids.
1001 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
1002 EXPECT_EQ(clientUids.size(), 0);
1003
1004 // Move UID(1) to top.
1005 mUidPolicy->setTop(UID(1));
1006 // Add UID(1) to offline session, offline session should start and SESSION(0) should pause.
1007 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
1008 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1009 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
1010}
1011
Chong Zhang8677f1f2021-01-21 20:37:35 +00001012/* Test resource lost without thermal throttling */
Chong Zhangbc062482020-10-14 16:43:53 -07001013TEST_F(TranscodingSessionControllerTest, TestResourceLost) {
1014 ALOGD("TestResourceLost");
1015
1016 // Start with unspecified top UID.
1017 // Submit real-time session to CLIENT(0), session should start immediately.
Chong Zhangeffd8962020-12-02 14:29:09 -08001018 mRealtimeRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001019 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -07001020 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1021
1022 // Submit offline session to CLIENT(0), should not start.
Chong Zhangeffd8962020-12-02 14:29:09 -08001023 mOfflineRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001024 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -07001025 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1026
1027 // Move UID(1) to top.
1028 mUidPolicy->setTop(UID(1));
1029 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1030
1031 // Submit real-time session to CLIENT(2) in different uid UID(1).
1032 // Should pause previous session and start new session.
Chong Zhangeffd8962020-12-02 14:29:09 -08001033 mRealtimeRequest.clientPid = PID(1);
Linus Nilssona99f4042021-02-25 15:49:43 -08001034 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhangbc062482020-10-14 16:43:53 -07001035 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1036 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
1037
Chong Zhangeffd8962020-12-02 14:29:09 -08001038 // Test 0: No call into ResourcePolicy if resource lost is from a non-running
1039 // or non-existent session.
1040 mController->onResourceLost(CLIENT(0), SESSION(0));
1041 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
1042 mController->onResourceLost(CLIENT(3), SESSION(0));
1043 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
1044
Chong Zhangbc062482020-10-14 16:43:53 -07001045 // Test 1: No queue change during resource loss.
1046 // Signal resource lost.
Chong Zhangeffd8962020-12-02 14:29:09 -08001047 mController->onResourceLost(CLIENT(2), SESSION(0));
1048 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
Chong Zhangbc062482020-10-14 16:43:53 -07001049 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1050
1051 // Signal resource available, CLIENT(2) should resume.
1052 mController->onResourceAvailable();
1053 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1054
1055 // Test 2: Change of queue order during resource loss.
1056 // Signal resource lost.
Chong Zhangeffd8962020-12-02 14:29:09 -08001057 mController->onResourceLost(CLIENT(2), SESSION(0));
1058 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
Chong Zhangbc062482020-10-14 16:43:53 -07001059 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1060
1061 // Move UID(0) back to top, should have no resume due to no resource.
1062 mUidPolicy->setTop(UID(0));
1063 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1064
1065 // Signal resource available, CLIENT(0) should resume.
1066 mController->onResourceAvailable();
1067 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
1068
Chong Zhang8677f1f2021-01-21 20:37:35 +00001069 // Test 3:
Chong Zhangeffd8962020-12-02 14:29:09 -08001070 mController->onResourceLost(CLIENT(0), SESSION(0));
1071 EXPECT_EQ(mResourcePolicy->getPid(), PID(0));
Chong Zhangbc062482020-10-14 16:43:53 -07001072 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001073 // Cancel the paused top session during resource lost.
1074 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
1075 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
1076 // Signal resource available, CLIENT(2)'s session should start.
1077 mController->onResourceAvailable();
1078 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1079
1080 // Test 4: Adding new queue during resource loss.
1081 // Signal resource lost.
1082 mController->onResourceLost(CLIENT(2), SESSION(0));
1083 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
1084 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
Chong Zhangbc062482020-10-14 16:43:53 -07001085
1086 // Move UID(2) to top.
1087 mUidPolicy->setTop(UID(2));
1088
1089 // 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 -08001090 mRealtimeRequest.clientPid = PID(2);
Linus Nilssona99f4042021-02-25 15:49:43 -08001091 mController->submit(CLIENT(3), SESSION(0), UID(3), UID(2), mRealtimeRequest, mClientCallback3);
Chong Zhangbc062482020-10-14 16:43:53 -07001092 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1093
1094 // Signal resource available, CLIENT(3)'s session should start.
1095 mController->onResourceAvailable();
1096 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), SESSION(0)));
1097}
1098
Chong Zhang8677f1f2021-01-21 20:37:35 +00001099/* Test thermal throttling without resource lost */
1100TEST_F(TranscodingSessionControllerTest, TestThermalCallback) {
1101 ALOGD("TestThermalCallback");
1102
1103 // Start with unspecified top UID.
1104 // Submit real-time session to CLIENT(0), session should start immediately.
1105 mRealtimeRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001106 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001107 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1108
1109 // Submit offline session to CLIENT(0), should not start.
1110 mOfflineRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001111 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001112 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1113
1114 // Move UID(1) to top.
1115 mUidPolicy->setTop(UID(1));
1116 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1117
1118 // Submit real-time session to CLIENT(2) in different uid UID(1).
1119 // Should pause previous session and start new session.
1120 mRealtimeRequest.clientPid = PID(1);
Linus Nilssona99f4042021-02-25 15:49:43 -08001121 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001122 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1123 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
1124
1125 // Test 0: Basic case, no queue change during throttling, top session should pause/resume
1126 // with throttling.
1127 mController->onThrottlingStarted();
1128 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1129 mController->onThrottlingStopped();
1130 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1131
1132 // Test 1: Change of queue order during thermal throttling, when throttling stops,
1133 // new top session should resume.
1134 mController->onThrottlingStarted();
1135 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1136 mUidPolicy->setTop(UID(0));
1137 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1138 mController->onThrottlingStopped();
1139 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
1140
1141 // Test 2: Cancel session during throttling, when throttling stops, new top
1142 // session should resume.
1143 mController->onThrottlingStarted();
1144 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1145 // Cancel the paused top session during throttling.
1146 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
1147 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
1148 // Throttling stops, CLIENT(2)'s session should start.
1149 mController->onThrottlingStopped();
1150 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1151
1152 // Test 3: Add new queue during throttling, when throttling stops, new top
1153 // session should resume.
1154 mController->onThrottlingStarted();
1155 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1156 // Move UID(2) to top.
1157 mUidPolicy->setTop(UID(2));
1158 // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start during throttling.
1159 mRealtimeRequest.clientPid = PID(2);
Linus Nilssona99f4042021-02-25 15:49:43 -08001160 mController->submit(CLIENT(3), SESSION(0), UID(3), UID(2), mRealtimeRequest, mClientCallback3);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001161 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1162 // Throttling stops, CLIENT(3)'s session should start.
1163 mController->onThrottlingStopped();
1164 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), SESSION(0)));
1165}
1166
1167/* Test resource lost and thermal throttling happening simultaneously */
1168TEST_F(TranscodingSessionControllerTest, TestResourceLostAndThermalCallback) {
1169 ALOGD("TestResourceLostAndThermalCallback");
1170
1171 // Start with unspecified top UID.
1172 // Submit real-time session to CLIENT(0), session should start immediately.
1173 mRealtimeRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001174 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001175 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1176
1177 // Submit offline session to CLIENT(0), should not start.
1178 mOfflineRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001179 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001180 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1181
1182 // Move UID(1) to top.
1183 mUidPolicy->setTop(UID(1));
1184 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1185
1186 // Submit real-time session to CLIENT(2) in different uid UID(1).
1187 // Should pause previous session and start new session.
1188 mRealtimeRequest.clientPid = PID(1);
Linus Nilssona99f4042021-02-25 15:49:43 -08001189 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001190 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1191 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
1192
1193 // Test 0: Resource lost during throttling.
1194 // Throttling starts, top session should pause.
1195 mController->onThrottlingStarted();
1196 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1197 // Signal resource lost, this should get ignored because the session is now paused.
1198 mController->onResourceLost(CLIENT(2), SESSION(0));
1199 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
1200 // Signal resource available, CLIENT(2) shouldn't resume.
1201 mController->onResourceAvailable();
1202 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1203 // Throttling ends, top session should resume.
1204 mController->onThrottlingStopped();
1205 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1206
1207 // Test 1: Throttling during resource lost.
1208 mController->onResourceLost(CLIENT(2), SESSION(0));
1209 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
1210 mController->onThrottlingStarted();
1211 mController->onThrottlingStopped();
1212 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1213 mController->onResourceAvailable();
1214 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1215
1216 // Test 2: Interleaving resource lost and throttling.
1217 mController->onResourceLost(CLIENT(2), SESSION(0));
1218 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
1219 mController->onThrottlingStarted();
1220 mController->onResourceAvailable();
1221 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1222 mController->onThrottlingStopped();
1223 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1224}
1225
Chong Zhang87d199c2021-03-01 19:02:18 -08001226TEST_F(TranscodingSessionControllerTest, TestTranscoderWatchdogNoHeartbeat) {
Chong Zhang457c6892021-02-01 15:34:20 -08001227 ALOGD("TestTranscoderWatchdogTimeout");
1228
1229 // Submit session to CLIENT(0) in UID(0).
1230 // Should start immediately (because this is the only session).
Linus Nilssona99f4042021-02-25 15:49:43 -08001231 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhang457c6892021-02-01 15:34:20 -08001232 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1233
Chong Zhang457c6892021-02-01 15:34:20 -08001234 // Test 1: If not sending keep-alive at all, timeout after 3 seconds.
Chong Zhang87d199c2021-03-01 19:02:18 -08001235 expectTimeout(CLIENT(0), SESSION(0), 2);
1236}
Chong Zhang457c6892021-02-01 15:34:20 -08001237
Chong Zhang87d199c2021-03-01 19:02:18 -08001238TEST_F(TranscodingSessionControllerTest, TestTranscoderWatchdogHeartbeat) {
Chong Zhang457c6892021-02-01 15:34:20 -08001239 // Test 2: No timeout as long as keep-alive coming; timeout after keep-alive stops.
Linus Nilssona99f4042021-02-25 15:49:43 -08001240 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhang457c6892021-02-01 15:34:20 -08001241 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
Chong Zhang87d199c2021-03-01 19:02:18 -08001242
Chong Zhang457c6892021-02-01 15:34:20 -08001243 for (int i = 0; i < 5; i++) {
1244 EXPECT_EQ(mTranscoder->popEvent(1000000), TestTranscoder::NoEvent);
1245 mController->onHeartBeat(CLIENT(0), SESSION(1));
1246 }
Chong Zhang87d199c2021-03-01 19:02:18 -08001247 expectTimeout(CLIENT(0), SESSION(1), 2);
1248}
1249
1250TEST_F(TranscodingSessionControllerTest, TestTranscoderWatchdogDuringPause) {
1251 int expectedGen = 2;
Chong Zhang457c6892021-02-01 15:34:20 -08001252
1253 // Test 3a: No timeout for paused session even if no keep-alive is sent.
Linus Nilssona99f4042021-02-25 15:49:43 -08001254 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhang457c6892021-02-01 15:34:20 -08001255 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
1256 // Trigger a pause by sending a resource lost.
1257 mController->onResourceLost(CLIENT(0), SESSION(2));
1258 EXPECT_EQ(mTranscoder->popEvent(3100000), TestTranscoder::NoEvent);
1259 mController->onResourceAvailable();
1260 EXPECT_EQ(mTranscoder->popEvent(100000), TestTranscoder::Resume(CLIENT(0), SESSION(2)));
1261 expectTimeout(CLIENT(0), SESSION(2), expectedGen++);
1262
1263 // Test 3b: No timeout for paused session even if no keep-alive is sent.
Linus Nilssona99f4042021-02-25 15:49:43 -08001264 mController->submit(CLIENT(0), SESSION(3), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhang457c6892021-02-01 15:34:20 -08001265 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(3)));
1266 // Let the session run almost to timeout, to test timeout reset after pause.
1267 EXPECT_EQ(mTranscoder->popEvent(2900000), TestTranscoder::NoEvent);
1268 // Trigger a pause by submitting a higher-priority request.
Linus Nilssona99f4042021-02-25 15:49:43 -08001269 mController->submit(CLIENT(0), SESSION(4), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhang457c6892021-02-01 15:34:20 -08001270 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(3)));
1271 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(4)));
1272 // Finish the higher-priority session, lower-priority session should resume,
1273 // and the timeout should reset to full value.
1274 mController->onFinish(CLIENT(0), SESSION(4));
1275 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(4)));
1276 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(3)));
1277 expectTimeout(CLIENT(0), SESSION(3), expectedGen++);
1278}
1279
Chong Zhang87d199c2021-03-01 19:02:18 -08001280TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerOverCountOnly) {
1281 ALOGD("TestTranscoderPacerOverCountOnly");
1282 testPacerHelper(12 /*numSubmits*/, 100 /*sessionDurationMs*/, 12 /*expectedSuccess*/);
1283}
1284
1285TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerOverTimeOnly) {
1286 ALOGD("TestTranscoderPacerOverTimeOnly");
1287 testPacerHelper(5 /*numSubmits*/, 1000 /*sessionDurationMs*/, 5 /*expectedSuccess*/);
1288}
1289
1290TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerOverQuota) {
1291 ALOGD("TestTranscoderPacerOverQuota");
1292 testPacerHelper(12 /*numSubmits*/, 400 /*sessionDurationMs*/, 10 /*expectedSuccess*/);
1293}
1294
1295TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerWithPause) {
1296 ALOGD("TestTranscoderPacerDuringPause");
1297 testPacerHelper(12 /*numSubmits*/, 400 /*sessionDurationMs*/, 10 /*expectedSuccess*/,
1298 true /*pauseLastSuccessSession*/);
1299}
1300
Chong Zhangebd86d32021-03-29 11:30:56 -07001301/*
1302 * Test the case where multiple client uids request the same session. Session should only
1303 * be dropped when all clients are over quota.
1304 */
1305TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerMultipleUids) {
1306 ALOGD("TestTranscoderPacerMultipleUids");
1307 // First, run mClientCallback0 to the point of no quota.
1308 testPacerHelper(12 /*numSubmits*/, 400 /*sessionDurationMs*/, 10 /*expectedSuccess*/,
1309 mClientCallback0, {}, false /*pauseLastSuccessSession*/);
1310 // Make UID(0) block on Client1's sessions too, Client1's quota should not be affected.
1311 testPacerHelper(12 /*numSubmits*/, 400 /*sessionDurationMs*/, 10 /*expectedSuccess*/,
1312 mClientCallback1, {UID(0)}, false /*pauseLastSuccessSession*/);
1313 // Make UID(10) block on Client2's sessions. We expect to see 11 succeeds (instead of 10),
1314 // because the addClientUid() is called after the submit, and first session is already
1315 // started by the time UID(10) is added. UID(10) allowed us to run the 11th session,
1316 // after that both UID(10) and UID(2) are out of quota.
1317 testPacerHelper(12 /*numSubmits*/, 400 /*sessionDurationMs*/, 11 /*expectedSuccess*/,
1318 mClientCallback2, {UID(10)}, false /*pauseLastSuccessSession*/);
1319}
1320
Chong Zhangbc062482020-10-14 16:43:53 -07001321} // namespace android