blob: ef9c4f85eef5ec349adcf70ff93747b3bbfb1082 [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 Zhangb28d6ca2021-04-15 18:02:21 -0700342 void testPacerHelper(int numSubmits, int sessionDurationMs, int expectedSuccess) {
Chong Zhangebd86d32021-03-29 11:30:56 -0700343 testPacerHelper(numSubmits, sessionDurationMs, expectedSuccess, mClientCallback0, {},
Chong Zhangb28d6ca2021-04-15 18:02:21 -0700344 false /*pauseLastSuccessSession*/, true /*useRealCallingUid*/);
345 }
346
347 void testPacerHelperWithPause(int numSubmits, int sessionDurationMs, int expectedSuccess) {
348 testPacerHelper(numSubmits, sessionDurationMs, expectedSuccess, mClientCallback0, {},
349 true /*pauseLastSuccessSession*/, true /*useRealCallingUid*/);
350 }
351
352 void testPacerHelperWithMultipleUids(int numSubmits, int sessionDurationMs, int expectedSuccess,
353 const std::shared_ptr<TestClientCallback>& client,
354 const std::vector<int>& additionalClientUids) {
355 testPacerHelper(numSubmits, sessionDurationMs, expectedSuccess, client,
356 additionalClientUids, false /*pauseLastSuccessSession*/,
357 true /*useRealCallingUid*/);
358 }
359
360 void testPacerHelperWithSelfUid(int numSubmits, int sessionDurationMs, int expectedSuccess) {
361 testPacerHelper(numSubmits, sessionDurationMs, expectedSuccess, mClientCallback0, {},
362 false /*pauseLastSuccessSession*/, false /*useRealCallingUid*/);
Chong Zhangebd86d32021-03-29 11:30:56 -0700363 }
364
365 void testPacerHelper(int numSubmits, int sessionDurationMs, int expectedSuccess,
366 const std::shared_ptr<TestClientCallback>& client,
Chong Zhangb28d6ca2021-04-15 18:02:21 -0700367 const std::vector<int>& additionalClientUids, bool pauseLastSuccessSession,
368 bool useRealCallingUid) {
369 uid_t callingUid = useRealCallingUid ? ::getuid() : client->clientUid();
Chong Zhang87d199c2021-03-01 19:02:18 -0800370 for (int i = 0; i < numSubmits; i++) {
Chong Zhangb28d6ca2021-04-15 18:02:21 -0700371 mController->submit(client->clientId(), SESSION(i), callingUid, client->clientUid(),
372 mRealtimeRequest, client);
Chong Zhangebd86d32021-03-29 11:30:56 -0700373 for (int additionalUid : additionalClientUids) {
374 mController->addClientUid(client->clientId(), SESSION(i), additionalUid);
375 }
Chong Zhang87d199c2021-03-01 19:02:18 -0800376 }
377 for (int i = 0; i < expectedSuccess; i++) {
Chong Zhangebd86d32021-03-29 11:30:56 -0700378 EXPECT_EQ(mTranscoder->popEvent(),
379 TestTranscoder::Start(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800380 if ((i == expectedSuccess - 1) && pauseLastSuccessSession) {
381 // Insert a pause of 3 sec to the last success running session
382 mController->onThrottlingStarted();
Chong Zhangebd86d32021-03-29 11:30:56 -0700383 EXPECT_EQ(mTranscoder->popEvent(),
384 TestTranscoder::Pause(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800385 sleep(3);
386 mController->onThrottlingStopped();
Chong Zhangebd86d32021-03-29 11:30:56 -0700387 EXPECT_EQ(mTranscoder->popEvent(),
388 TestTranscoder::Resume(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800389 }
390 usleep(sessionDurationMs * 1000);
391 // Test half of Finish and half of Error, both should be counted as burst runs.
392 if (i & 1) {
Chong Zhangebd86d32021-03-29 11:30:56 -0700393 mController->onFinish(client->clientId(), SESSION(i));
394 EXPECT_EQ(mTranscoder->popEvent(),
395 TestTranscoder::Finished(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800396 } else {
Chong Zhangebd86d32021-03-29 11:30:56 -0700397 mController->onError(client->clientId(), SESSION(i),
398 TranscodingErrorCode::kUnknown);
Chong Zhang87d199c2021-03-01 19:02:18 -0800399 EXPECT_EQ(mTranscoder->popEvent(100000),
Chong Zhangebd86d32021-03-29 11:30:56 -0700400 TestTranscoder::Failed(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800401 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
402 }
403 }
404 for (int i = expectedSuccess; i < numSubmits; i++) {
Chong Zhangebd86d32021-03-29 11:30:56 -0700405 EXPECT_EQ(mTranscoder->popEvent(),
406 TestTranscoder::Failed(client->clientId(), SESSION(i)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800407 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kDroppedByService);
408 }
409 }
410
Chong Zhangbc062482020-10-14 16:43:53 -0700411 std::shared_ptr<TestTranscoder> mTranscoder;
412 std::shared_ptr<TestUidPolicy> mUidPolicy;
Chong Zhangf47a3572020-12-02 11:35:35 -0800413 std::shared_ptr<TestResourcePolicy> mResourcePolicy;
Chong Zhang8677f1f2021-01-21 20:37:35 +0000414 std::shared_ptr<TestThermalPolicy> mThermalPolicy;
Chong Zhangbc062482020-10-14 16:43:53 -0700415 std::shared_ptr<TranscodingSessionController> mController;
416 TranscodingRequestParcel mOfflineRequest;
417 TranscodingRequestParcel mRealtimeRequest;
418 std::shared_ptr<TestClientCallback> mClientCallback0;
419 std::shared_ptr<TestClientCallback> mClientCallback1;
420 std::shared_ptr<TestClientCallback> mClientCallback2;
421 std::shared_ptr<TestClientCallback> mClientCallback3;
422};
423
424TEST_F(TranscodingSessionControllerTest, TestSubmitSession) {
425 ALOGD("TestSubmitSession");
426
427 // Start with UID(1) on top.
428 mUidPolicy->setTop(UID(1));
429
430 // Submit offline session to CLIENT(0) in UID(0).
431 // Should start immediately (because this is the only session).
Linus Nilssona99f4042021-02-25 15:49:43 -0800432 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700433 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), 0));
434
435 // Submit real-time session to CLIENT(0).
436 // Should pause offline session and start new session, even if UID(0) is not on top.
Linus Nilssona99f4042021-02-25 15:49:43 -0800437 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700438 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
439 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
440
441 // Submit real-time session to CLIENT(0), should be queued after the previous session.
Linus Nilssona99f4042021-02-25 15:49:43 -0800442 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700443 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
444
445 // Submit real-time session to CLIENT(1) in same uid, should be queued after the previous
446 // session.
Linus Nilssona99f4042021-02-25 15:49:43 -0800447 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mRealtimeRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -0700448 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
449
450 // Submit real-time session to CLIENT(2) in UID(1).
451 // Should pause previous session and start new session, because UID(1) is (has been) top.
Linus Nilssona99f4042021-02-25 15:49:43 -0800452 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhangbc062482020-10-14 16:43:53 -0700453 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
454 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
455
456 // Submit offline session, shouldn't generate any event.
Linus Nilssona99f4042021-02-25 15:49:43 -0800457 mController->submit(CLIENT(2), SESSION(1), UID(2), UID(1), mOfflineRequest, mClientCallback2);
Chong Zhangbc062482020-10-14 16:43:53 -0700458 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
459
460 // Bring UID(0) to top.
461 mUidPolicy->setTop(UID(0));
462 // Should pause current session, and resume last session in UID(0).
463 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
464 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(1)));
465}
466
467TEST_F(TranscodingSessionControllerTest, TestCancelSession) {
468 ALOGD("TestCancelSession");
469
470 // Submit real-time session SESSION(0), should start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800471 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700472 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
473
474 // Submit real-time session SESSION(1), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800475 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700476 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
477
478 // Submit offline session SESSION(2), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800479 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700480 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
481
482 // Cancel queued real-time session.
483 // Cancel real-time session SESSION(1), should be cancelled.
484 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(1)));
485
486 // Cancel queued offline session.
487 // Cancel offline session SESSION(2), should be cancelled.
488 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(2)));
489
490 // Submit offline session SESSION(3), shouldn't cause any event.
Linus Nilssona99f4042021-02-25 15:49:43 -0800491 mController->submit(CLIENT(0), SESSION(3), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700492 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
493
494 // Cancel running real-time session SESSION(0).
495 // - Should be stopped first then cancelled.
496 // - Should also start offline session SESSION(2) because real-time queue is empty.
497 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
498 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
499 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(3)));
500
501 // Submit real-time session SESSION(4), offline SESSION(3) should pause and SESSION(4)
502 // should start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800503 mController->submit(CLIENT(0), SESSION(4), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700504 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(3)));
505 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(4)));
506
507 // Cancel paused SESSION(3). SESSION(3) should be stopped.
508 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(3)));
509 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(3)));
510}
511
Chong Zhangebd86d32021-03-29 11:30:56 -0700512TEST_F(TranscodingSessionControllerTest, TestCancelSessionWithMultipleUids) {
513 ALOGD("TestCancelSessionWithMultipleUids");
514 std::vector<int32_t> clientUids;
515
516 // Submit real-time session SESSION(0), should start immediately.
517 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
518 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
519
520 // Submit real-time session SESSION(1), should not start.
521 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
522 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
523
524 // Submit offline session SESSION(2), should not start.
525 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
526 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
527
528 // UID(1) moves to top.
529 mUidPolicy->setTop(UID(1));
530
531 // Add UID(1) to the offline SESSION(2), SESSION(2) should start and SESSION(0) should pause.
532 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
533 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
534 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
535
536 // Add UID(1) to SESSION(1) as well.
537 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
538
539 // Cancel SESSION(2), should be cancelled and SESSION(1) should start.
540 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(2)));
541 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
542 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(2)));
543 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
544
545 // Cancel SESSION(1), should be cancelled and SESSION(0) should resume.
546 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(1)));
547 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
548 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(1)));
549 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
550}
551
552TEST_F(TranscodingSessionControllerTest, TestCancelAllSessionsForClient) {
553 // Submit real-time session SESSION(0), should start immediately.
554 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
555 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
556
557 // Submit real-time session SESSION(1), should not start.
558 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
559 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
560
561 // Submit offline session SESSION(2), should not start.
562 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
563 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
564
565 std::vector<int32_t> clientUids;
566 // Make some more uids blocked on the sessions.
567 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(1)));
568 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
569 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
570 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
571 EXPECT_EQ(clientUids.size(), 2);
572 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
573 EXPECT_EQ(clientUids.size(), 2);
574 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
575 EXPECT_EQ(clientUids.size(), 1);
576
577 // Cancel all sessions for CLIENT(0) with -1.
578 // Expect SESSION(0) and SESSION(1) to be gone.
579 // Expect SESSION(2) still there with empty client uid list (only kept for offline) and start.
580 EXPECT_TRUE(mController->cancel(CLIENT(0), -1));
581 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
582 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
583 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
584 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
585 EXPECT_EQ(clientUids.size(), 0);
586 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
587}
588
Chong Zhangbc062482020-10-14 16:43:53 -0700589TEST_F(TranscodingSessionControllerTest, TestFinishSession) {
590 ALOGD("TestFinishSession");
591
592 // Start with unspecified top UID.
593 // Finish without any sessions submitted, should be ignored.
594 mController->onFinish(CLIENT(0), SESSION(0));
595 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
596
597 // Submit offline session SESSION(0), should start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800598 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700599 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
600
601 // Submit real-time session SESSION(1), should pause offline session and start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800602 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700603 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
604 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
605
606 // Submit real-time session SESSION(2), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800607 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700608 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
609
610 // Finish when the session never started, should be ignored.
611 mController->onFinish(CLIENT(0), SESSION(2));
612 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
613
614 // UID(1) moves to top.
615 mUidPolicy->setTop(UID(1));
616 // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
617 // new session.
Linus Nilssona99f4042021-02-25 15:49:43 -0800618 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(1), mRealtimeRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -0700619 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
620 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
621
622 // Simulate Finish that arrived late, after pause issued by controller.
623 // Should still be propagated to client, but shouldn't trigger any new start.
624 mController->onFinish(CLIENT(0), SESSION(1));
625 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(1)));
626
627 // Finish running real-time session, should start next real-time session in queue.
628 mController->onFinish(CLIENT(1), SESSION(0));
629 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(1), SESSION(0)));
630 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
631
632 // Finish running real-time session, should resume next session (offline session) in queue.
633 mController->onFinish(CLIENT(0), SESSION(2));
634 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(2)));
635 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
636
637 // Finish running offline session.
638 mController->onFinish(CLIENT(0), SESSION(0));
639 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
640
641 // Duplicate finish for last session, should be ignored.
642 mController->onFinish(CLIENT(0), SESSION(0));
643 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
644}
645
Chong Zhangebd86d32021-03-29 11:30:56 -0700646TEST_F(TranscodingSessionControllerTest, TestFinishSessionWithMultipleUids) {
647 ALOGD("TestFinishSessionWithMultipleUids");
648 std::vector<int32_t> clientUids;
649
650 // Start with unspecified top uid.
651 // Submit real-time session SESSION(0), should start immediately.
652 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
653 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
654
655 // Submit real-time session SESSION(1), should not start.
656 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
657 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
658 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
659
660 // Submit real-time session SESSION(2), should not start.
661 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
662 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
663 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
664 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(2)));
665
666 // UID(1) moves to top.
667 mUidPolicy->setTop(UID(1));
668 // SESSION(0) should pause, SESSION(1) should start.
669 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
670 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
671
672 // Finish SESSION(1), SESSION(2) (next in line for UID(1)) should start.
673 mController->onFinish(CLIENT(0), SESSION(1));
674 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(1)));
675 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
676 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
677
678 // Finish SESSION(2), SESSION(0) should resume.
679 mController->onFinish(CLIENT(0), SESSION(2));
680 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(2)));
681 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
682 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
683}
684
Chong Zhangbc062482020-10-14 16:43:53 -0700685TEST_F(TranscodingSessionControllerTest, TestFailSession) {
686 ALOGD("TestFailSession");
687
688 // Start with unspecified top UID.
689 // Fail without any sessions submitted, should be ignored.
690 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
691 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
692
693 // Submit offline session SESSION(0), should start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800694 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700695 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
696
697 // Submit real-time session SESSION(1), should pause offline session and start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800698 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700699 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
700 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
701
702 // Submit real-time session SESSION(2), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800703 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700704 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
705
706 // Fail when the session never started, should be ignored.
707 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
708 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
709
710 // UID(1) moves to top.
711 mUidPolicy->setTop(UID(1));
712 // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
713 // new session.
Linus Nilssona99f4042021-02-25 15:49:43 -0800714 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(1), mRealtimeRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -0700715 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
716 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
717
718 // Simulate Fail that arrived late, after pause issued by controller.
719 // Should still be propagated to client, but shouldn't trigger any new start.
720 mController->onError(CLIENT(0), SESSION(1), TranscodingErrorCode::kUnknown);
721 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800722 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
Chong Zhangbc062482020-10-14 16:43:53 -0700723
724 // Fail running real-time session, should start next real-time session in queue.
725 mController->onError(CLIENT(1), SESSION(0), TranscodingErrorCode::kUnknown);
726 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(1), SESSION(0)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800727 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
Chong Zhangbc062482020-10-14 16:43:53 -0700728 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
729
730 // Fail running real-time session, should resume next session (offline session) in queue.
731 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
732 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(2)));
Chong Zhang87d199c2021-03-01 19:02:18 -0800733 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
Chong Zhangbc062482020-10-14 16:43:53 -0700734 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
735
736 // Fail running offline session, and test error code propagation.
737 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kInvalidOperation);
738 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(0)));
739 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kInvalidOperation);
740
741 // Duplicate fail for last session, should be ignored.
742 mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
743 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
744}
745
Chong Zhangebd86d32021-03-29 11:30:56 -0700746TEST_F(TranscodingSessionControllerTest, TestFailSessionWithMultipleUids) {
747 ALOGD("TestFailSessionWithMultipleUids");
748 std::vector<int32_t> clientUids;
749
750 // Start with unspecified top uid.
751 // Submit real-time session SESSION(0), should start immediately.
752 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
753 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
754
755 // Submit real-time session SESSION(1), should not start.
756 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
757 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
758 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
759
760 // Submit real-time session SESSION(2), should not start.
761 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
762 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
763
764 // UID(1) moves to top.
765 mUidPolicy->setTop(UID(1));
766 // SESSION(0) should pause, SESSION(1) should start.
767 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
768 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
769
770 // Add UID(1) and UID(2) to SESSION(2).
771 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(1)));
772 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(2), UID(2)));
773
774 // Fail SESSION(1), SESSION(2) (next in line for UID(1)) should start.
775 mController->onError(CLIENT(0), SESSION(1), TranscodingErrorCode::kUnknown);
776 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
777 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUnknown);
778 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
779 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
780
781 // Fail SESSION(2), SESSION(0) should resume.
782 mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kInvalidOperation);
783 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(2)));
784 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kInvalidOperation);
785 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
786 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(2), &clientUids));
787}
788
Chong Zhangbc062482020-10-14 16:43:53 -0700789TEST_F(TranscodingSessionControllerTest, TestTopUidChanged) {
790 ALOGD("TestTopUidChanged");
791
792 // Start with unspecified top UID.
793 // Submit real-time session to CLIENT(0), session should start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800794 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700795 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
796
797 // Submit offline session to CLIENT(0), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800798 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -0700799 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
800
801 // Move UID(1) to top.
802 mUidPolicy->setTop(UID(1));
803 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
804
805 // Submit real-time session to CLIENT(2) in different uid UID(1).
806 // Should pause previous session and start new session.
Linus Nilssona99f4042021-02-25 15:49:43 -0800807 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhangbc062482020-10-14 16:43:53 -0700808 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
809 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
810
811 // Bring UID(0) back to top.
812 mUidPolicy->setTop(UID(0));
813 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
814 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
815
816 // Bring invalid uid to top.
817 mUidPolicy->setTop(kInvalidUid);
818 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
819
820 // Finish session, next real-time session should resume.
821 mController->onFinish(CLIENT(0), SESSION(0));
822 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
823 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
824
825 // Finish session, offline session should start.
826 mController->onFinish(CLIENT(2), SESSION(0));
827 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
828 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
829}
830
Chong Zhangebd86d32021-03-29 11:30:56 -0700831TEST_F(TranscodingSessionControllerTest, TestTopUidChangedMultipleUids) {
832 ALOGD("TestTopUidChangedMultipleUids");
833
834 // Start with unspecified top UID.
835 // Submit real-time session to CLIENT(0), session should start immediately.
836 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
837 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
838
839 // Submit offline session to CLIENT(0), should not start.
840 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
841 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
842
843 // Bring UID(1) to top.
844 mUidPolicy->setTop(UID(1));
845 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
846
847 // Add UID(1) to SESSION(0), SESSION(0) should continue to run
848 // (no pause&resume of the same session).
849 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(1)));
850 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
851
852 // Bring UID(0) back to top, SESSION(0) should continue to run
853 // (no pause&resume of the same session).
854 mUidPolicy->setTop(UID(0));
855 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
856
857 // Bring UID(2) to top.
858 mUidPolicy->setTop(UID(2));
859 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
860 // Add UID(2) to the offline session, it should be started.
861 EXPECT_TRUE(mController->addClientUid(CLIENT(1), SESSION(0), UID(2)));
862 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
863 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
864
865 // ADD UID(3) to SESSION(0).
866 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(3)));
867 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
868 // Bring UID(3) to top, SESSION(0) should resume.
869 mUidPolicy->setTop(UID(3));
870 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(1), SESSION(0)));
871 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
872
873 // Now make UID(2) also blocked on CLIENT(0), SESSION(0).
874 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), UID(2)));
875
876 // Bring UID(2) back to top, CLIENT(0), SESSION(0) should continue to run (even if it's
877 // added to UID(2)'s queue later than CLIENT(1)'s SESSION(0)).
878 mUidPolicy->setTop(UID(2));
879 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
880}
881
Chong Zhangbc062482020-10-14 16:43:53 -0700882TEST_F(TranscodingSessionControllerTest, TestTopUidSetChanged) {
Chong Zhangebd86d32021-03-29 11:30:56 -0700883 ALOGD("TestTopUidSetChanged");
Chong Zhangbc062482020-10-14 16:43:53 -0700884
885 // Start with unspecified top UID.
886 // Submit real-time session to CLIENT(0), session should start immediately.
Linus Nilssona99f4042021-02-25 15:49:43 -0800887 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -0700888 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
889
890 // Submit offline session to CLIENT(0), should not start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800891 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -0700892 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
893
894 // Set UID(0), UID(1) to top set.
895 // UID(0) should continue to run.
896 mUidPolicy->setTop({UID(0), UID(1)});
897 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
898
899 // Submit real-time session to CLIENT(2) in different uid UID(1).
900 // UID(0) should pause and UID(1) should start.
Linus Nilssona99f4042021-02-25 15:49:43 -0800901 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhangbc062482020-10-14 16:43:53 -0700902 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
903 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
904
905 // Remove UID(0) from top set, and only leave UID(1) in the set.
906 // UID(1) should continue to run.
907 mUidPolicy->setTop(UID(1));
908 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
909
910 // Set UID(0), UID(2) to top set.
911 // UID(1) should continue to run.
912 mUidPolicy->setTop({UID(1), UID(2)});
913 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
914
915 // Bring UID(0) back to top.
916 mUidPolicy->setTop(UID(0));
917 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
918 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
919
920 // Bring invalid uid to top.
921 mUidPolicy->setTop(kInvalidUid);
922 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
923
924 // Finish session, next real-time session from UID(1) should resume, even if UID(1)
925 // no longer top.
926 mController->onFinish(CLIENT(0), SESSION(0));
927 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
928 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
929
930 // Finish session, offline session should start.
931 mController->onFinish(CLIENT(2), SESSION(0));
932 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
933 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
934}
935
Chong Zhang2a3c9672021-03-31 15:36:32 -0700936TEST_F(TranscodingSessionControllerTest, TestUidGone) {
937 ALOGD("TestUidGone");
938
939 mUidPolicy->setTop(UID(0));
940 // Start with unspecified top UID.
941 // Submit real-time sessions to CLIENT(0), session should start immediately.
942 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
943 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
944
945 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
946 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
947 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
948
949 // Submit real-time session to CLIENT(1), should not start.
950 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(1), mOfflineRequest, mClientCallback1);
951 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
952 EXPECT_TRUE(mController->addClientUid(CLIENT(1), SESSION(0), UID(1)));
953
954 // Tell the controller that UID(0) is gone.
955 mUidPolicy->setTop(UID(1));
956 // CLIENT(0)'s SESSION(1) should start, SESSION(0) should be cancelled.
957 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
958 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
959 mController->onUidGone(UID(0));
960 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
961 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(0)));
962 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
963
964 std::vector<int32_t> clientUids;
965 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
966 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
967 EXPECT_EQ(clientUids.size(), 1);
968 EXPECT_EQ(clientUids[0], UID(1));
969
970 // Tell the controller that UID(1) is gone too.
971 mController->onUidGone(UID(1));
972 // CLIENT(1)'s SESSION(0) should start, CLIENT(0)'s SESSION(1) should be cancelled.
973 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(1)));
974 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
975 EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kUidGoneCancelled);
976 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
977 // CLIENT(1) SESSION(0) should not have any client uids as it's only kept for offline.
978 EXPECT_TRUE(mController->getClientUids(CLIENT(1), SESSION(0), &clientUids));
979 EXPECT_EQ(clientUids.size(), 0);
980}
981
Chong Zhangebd86d32021-03-29 11:30:56 -0700982TEST_F(TranscodingSessionControllerTest, TestAddGetClientUids) {
983 ALOGD("TestAddGetClientUids");
984
985 // Add/get client uids with non-existent session, should fail.
986 std::vector<int32_t> clientUids;
987 uid_t ownUid = ::getuid();
988 EXPECT_FALSE(mController->addClientUid(CLIENT(0), SESSION(0), ownUid));
989 EXPECT_FALSE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
990
991 // Submit a real-time request.
992 EXPECT_TRUE(mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest,
993 mClientCallback0));
994 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
995
996 // Should have own uid in client uids.
997 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
998 EXPECT_EQ(clientUids.size(), 1);
999 EXPECT_EQ(clientUids[0], UID(0));
1000
1001 // Add UID(0) again should fail.
1002 EXPECT_FALSE(mController->addClientUid(CLIENT(0), SESSION(0), UID(0)));
1003
1004 // Add own uid should succeed.
1005 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(0), ownUid));
1006 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(0), &clientUids));
1007 std::unordered_set<uid_t> uidSet;
1008 uidSet.insert(clientUids.begin(), clientUids.end());
1009 EXPECT_EQ(uidSet.size(), 2);
1010 EXPECT_EQ(uidSet.count(UID(0)), 1);
1011 EXPECT_EQ(uidSet.count(ownUid), 1);
1012
1013 // Submit an offline request.
1014 EXPECT_TRUE(mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mOfflineRequest,
1015 mClientCallback0));
1016 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1017
1018 // Should not have own uid in client uids.
1019 EXPECT_TRUE(mController->getClientUids(CLIENT(0), SESSION(1), &clientUids));
1020 EXPECT_EQ(clientUids.size(), 0);
1021
1022 // Move UID(1) to top.
1023 mUidPolicy->setTop(UID(1));
1024 // Add UID(1) to offline session, offline session should start and SESSION(0) should pause.
1025 EXPECT_TRUE(mController->addClientUid(CLIENT(0), SESSION(1), UID(1)));
1026 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1027 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
1028}
1029
Chong Zhang8677f1f2021-01-21 20:37:35 +00001030/* Test resource lost without thermal throttling */
Chong Zhangbc062482020-10-14 16:43:53 -07001031TEST_F(TranscodingSessionControllerTest, TestResourceLost) {
1032 ALOGD("TestResourceLost");
1033
1034 // Start with unspecified top UID.
1035 // Submit real-time session to CLIENT(0), session should start immediately.
Chong Zhangeffd8962020-12-02 14:29:09 -08001036 mRealtimeRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001037 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhangbc062482020-10-14 16:43:53 -07001038 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1039
1040 // Submit offline session to CLIENT(0), should not start.
Chong Zhangeffd8962020-12-02 14:29:09 -08001041 mOfflineRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001042 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
Chong Zhangbc062482020-10-14 16:43:53 -07001043 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1044
1045 // Move UID(1) to top.
1046 mUidPolicy->setTop(UID(1));
1047 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1048
1049 // Submit real-time session to CLIENT(2) in different uid UID(1).
1050 // Should pause previous session and start new session.
Chong Zhangeffd8962020-12-02 14:29:09 -08001051 mRealtimeRequest.clientPid = PID(1);
Linus Nilssona99f4042021-02-25 15:49:43 -08001052 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhangbc062482020-10-14 16:43:53 -07001053 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1054 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
1055
Chong Zhangeffd8962020-12-02 14:29:09 -08001056 // Test 0: No call into ResourcePolicy if resource lost is from a non-running
1057 // or non-existent session.
1058 mController->onResourceLost(CLIENT(0), SESSION(0));
1059 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
1060 mController->onResourceLost(CLIENT(3), SESSION(0));
1061 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
1062
Chong Zhangbc062482020-10-14 16:43:53 -07001063 // Test 1: No queue change during resource loss.
1064 // Signal resource lost.
Chong Zhangeffd8962020-12-02 14:29:09 -08001065 mController->onResourceLost(CLIENT(2), SESSION(0));
1066 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
Chong Zhangbc062482020-10-14 16:43:53 -07001067 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1068
1069 // Signal resource available, CLIENT(2) should resume.
1070 mController->onResourceAvailable();
1071 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1072
1073 // Test 2: Change of queue order during resource loss.
1074 // Signal resource lost.
Chong Zhangeffd8962020-12-02 14:29:09 -08001075 mController->onResourceLost(CLIENT(2), SESSION(0));
1076 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
Chong Zhangbc062482020-10-14 16:43:53 -07001077 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1078
1079 // Move UID(0) back to top, should have no resume due to no resource.
1080 mUidPolicy->setTop(UID(0));
1081 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1082
1083 // Signal resource available, CLIENT(0) should resume.
1084 mController->onResourceAvailable();
1085 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
1086
Chong Zhang8677f1f2021-01-21 20:37:35 +00001087 // Test 3:
Chong Zhangeffd8962020-12-02 14:29:09 -08001088 mController->onResourceLost(CLIENT(0), SESSION(0));
1089 EXPECT_EQ(mResourcePolicy->getPid(), PID(0));
Chong Zhangbc062482020-10-14 16:43:53 -07001090 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001091 // Cancel the paused top session during resource lost.
1092 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
1093 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
1094 // Signal resource available, CLIENT(2)'s session should start.
1095 mController->onResourceAvailable();
1096 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1097
1098 // Test 4: Adding new queue during resource loss.
1099 // Signal resource lost.
1100 mController->onResourceLost(CLIENT(2), SESSION(0));
1101 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
1102 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
Chong Zhangbc062482020-10-14 16:43:53 -07001103
1104 // Move UID(2) to top.
1105 mUidPolicy->setTop(UID(2));
1106
1107 // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start due to no resource.
Chong Zhangeffd8962020-12-02 14:29:09 -08001108 mRealtimeRequest.clientPid = PID(2);
Linus Nilssona99f4042021-02-25 15:49:43 -08001109 mController->submit(CLIENT(3), SESSION(0), UID(3), UID(2), mRealtimeRequest, mClientCallback3);
Chong Zhangbc062482020-10-14 16:43:53 -07001110 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1111
1112 // Signal resource available, CLIENT(3)'s session should start.
1113 mController->onResourceAvailable();
1114 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), SESSION(0)));
1115}
1116
Chong Zhang8677f1f2021-01-21 20:37:35 +00001117/* Test thermal throttling without resource lost */
1118TEST_F(TranscodingSessionControllerTest, TestThermalCallback) {
1119 ALOGD("TestThermalCallback");
1120
1121 // Start with unspecified top UID.
1122 // Submit real-time session to CLIENT(0), session should start immediately.
1123 mRealtimeRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001124 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001125 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1126
1127 // Submit offline session to CLIENT(0), should not start.
1128 mOfflineRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001129 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001130 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1131
1132 // Move UID(1) to top.
1133 mUidPolicy->setTop(UID(1));
1134 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1135
1136 // Submit real-time session to CLIENT(2) in different uid UID(1).
1137 // Should pause previous session and start new session.
1138 mRealtimeRequest.clientPid = PID(1);
Linus Nilssona99f4042021-02-25 15:49:43 -08001139 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001140 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1141 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
1142
1143 // Test 0: Basic case, no queue change during throttling, top session should pause/resume
1144 // with throttling.
1145 mController->onThrottlingStarted();
1146 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1147 mController->onThrottlingStopped();
1148 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1149
1150 // Test 1: Change of queue order during thermal throttling, when throttling stops,
1151 // new top session should resume.
1152 mController->onThrottlingStarted();
1153 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1154 mUidPolicy->setTop(UID(0));
1155 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1156 mController->onThrottlingStopped();
1157 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
1158
1159 // Test 2: Cancel session during throttling, when throttling stops, new top
1160 // session should resume.
1161 mController->onThrottlingStarted();
1162 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1163 // Cancel the paused top session during throttling.
1164 EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
1165 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
1166 // Throttling stops, CLIENT(2)'s session should start.
1167 mController->onThrottlingStopped();
1168 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1169
1170 // Test 3: Add new queue during throttling, when throttling stops, new top
1171 // session should resume.
1172 mController->onThrottlingStarted();
1173 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1174 // Move UID(2) to top.
1175 mUidPolicy->setTop(UID(2));
1176 // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start during throttling.
1177 mRealtimeRequest.clientPid = PID(2);
Linus Nilssona99f4042021-02-25 15:49:43 -08001178 mController->submit(CLIENT(3), SESSION(0), UID(3), UID(2), mRealtimeRequest, mClientCallback3);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001179 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1180 // Throttling stops, CLIENT(3)'s session should start.
1181 mController->onThrottlingStopped();
1182 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), SESSION(0)));
1183}
1184
1185/* Test resource lost and thermal throttling happening simultaneously */
1186TEST_F(TranscodingSessionControllerTest, TestResourceLostAndThermalCallback) {
1187 ALOGD("TestResourceLostAndThermalCallback");
1188
1189 // Start with unspecified top UID.
1190 // Submit real-time session to CLIENT(0), session should start immediately.
1191 mRealtimeRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001192 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001193 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1194
1195 // Submit offline session to CLIENT(0), should not start.
1196 mOfflineRequest.clientPid = PID(0);
Linus Nilssona99f4042021-02-25 15:49:43 -08001197 mController->submit(CLIENT(1), SESSION(0), UID(1), UID(0), mOfflineRequest, mClientCallback1);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001198 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1199
1200 // Move UID(1) to top.
1201 mUidPolicy->setTop(UID(1));
1202 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1203
1204 // Submit real-time session to CLIENT(2) in different uid UID(1).
1205 // Should pause previous session and start new session.
1206 mRealtimeRequest.clientPid = PID(1);
Linus Nilssona99f4042021-02-25 15:49:43 -08001207 mController->submit(CLIENT(2), SESSION(0), UID(2), UID(1), mRealtimeRequest, mClientCallback2);
Chong Zhang8677f1f2021-01-21 20:37:35 +00001208 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
1209 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
1210
1211 // Test 0: Resource lost during throttling.
1212 // Throttling starts, top session should pause.
1213 mController->onThrottlingStarted();
1214 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
1215 // Signal resource lost, this should get ignored because the session is now paused.
1216 mController->onResourceLost(CLIENT(2), SESSION(0));
1217 EXPECT_EQ(mResourcePolicy->getPid(), kInvalidPid);
1218 // Signal resource available, CLIENT(2) shouldn't resume.
1219 mController->onResourceAvailable();
1220 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1221 // Throttling ends, top session should resume.
1222 mController->onThrottlingStopped();
1223 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1224
1225 // Test 1: Throttling during resource lost.
1226 mController->onResourceLost(CLIENT(2), SESSION(0));
1227 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
1228 mController->onThrottlingStarted();
1229 mController->onThrottlingStopped();
1230 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1231 mController->onResourceAvailable();
1232 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1233
1234 // Test 2: Interleaving resource lost and throttling.
1235 mController->onResourceLost(CLIENT(2), SESSION(0));
1236 EXPECT_EQ(mResourcePolicy->getPid(), PID(1));
1237 mController->onThrottlingStarted();
1238 mController->onResourceAvailable();
1239 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
1240 mController->onThrottlingStopped();
1241 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
1242}
1243
Chong Zhang87d199c2021-03-01 19:02:18 -08001244TEST_F(TranscodingSessionControllerTest, TestTranscoderWatchdogNoHeartbeat) {
Chong Zhang457c6892021-02-01 15:34:20 -08001245 ALOGD("TestTranscoderWatchdogTimeout");
1246
1247 // Submit session to CLIENT(0) in UID(0).
1248 // Should start immediately (because this is the only session).
Linus Nilssona99f4042021-02-25 15:49:43 -08001249 mController->submit(CLIENT(0), SESSION(0), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhang457c6892021-02-01 15:34:20 -08001250 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
1251
Chong Zhang457c6892021-02-01 15:34:20 -08001252 // Test 1: If not sending keep-alive at all, timeout after 3 seconds.
Chong Zhang87d199c2021-03-01 19:02:18 -08001253 expectTimeout(CLIENT(0), SESSION(0), 2);
1254}
Chong Zhang457c6892021-02-01 15:34:20 -08001255
Chong Zhang87d199c2021-03-01 19:02:18 -08001256TEST_F(TranscodingSessionControllerTest, TestTranscoderWatchdogHeartbeat) {
Chong Zhang457c6892021-02-01 15:34:20 -08001257 // Test 2: No timeout as long as keep-alive coming; timeout after keep-alive stops.
Linus Nilssona99f4042021-02-25 15:49:43 -08001258 mController->submit(CLIENT(0), SESSION(1), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhang457c6892021-02-01 15:34:20 -08001259 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
Chong Zhang87d199c2021-03-01 19:02:18 -08001260
Chong Zhang457c6892021-02-01 15:34:20 -08001261 for (int i = 0; i < 5; i++) {
1262 EXPECT_EQ(mTranscoder->popEvent(1000000), TestTranscoder::NoEvent);
1263 mController->onHeartBeat(CLIENT(0), SESSION(1));
1264 }
Chong Zhang87d199c2021-03-01 19:02:18 -08001265 expectTimeout(CLIENT(0), SESSION(1), 2);
1266}
1267
1268TEST_F(TranscodingSessionControllerTest, TestTranscoderWatchdogDuringPause) {
1269 int expectedGen = 2;
Chong Zhang457c6892021-02-01 15:34:20 -08001270
1271 // Test 3a: No timeout for paused session even if no keep-alive is sent.
Linus Nilssona99f4042021-02-25 15:49:43 -08001272 mController->submit(CLIENT(0), SESSION(2), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhang457c6892021-02-01 15:34:20 -08001273 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
1274 // Trigger a pause by sending a resource lost.
1275 mController->onResourceLost(CLIENT(0), SESSION(2));
1276 EXPECT_EQ(mTranscoder->popEvent(3100000), TestTranscoder::NoEvent);
1277 mController->onResourceAvailable();
1278 EXPECT_EQ(mTranscoder->popEvent(100000), TestTranscoder::Resume(CLIENT(0), SESSION(2)));
1279 expectTimeout(CLIENT(0), SESSION(2), expectedGen++);
1280
1281 // Test 3b: No timeout for paused session even if no keep-alive is sent.
Linus Nilssona99f4042021-02-25 15:49:43 -08001282 mController->submit(CLIENT(0), SESSION(3), UID(0), UID(0), mOfflineRequest, mClientCallback0);
Chong Zhang457c6892021-02-01 15:34:20 -08001283 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(3)));
1284 // Let the session run almost to timeout, to test timeout reset after pause.
1285 EXPECT_EQ(mTranscoder->popEvent(2900000), TestTranscoder::NoEvent);
1286 // Trigger a pause by submitting a higher-priority request.
Linus Nilssona99f4042021-02-25 15:49:43 -08001287 mController->submit(CLIENT(0), SESSION(4), UID(0), UID(0), mRealtimeRequest, mClientCallback0);
Chong Zhang457c6892021-02-01 15:34:20 -08001288 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(3)));
1289 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(4)));
1290 // Finish the higher-priority session, lower-priority session should resume,
1291 // and the timeout should reset to full value.
1292 mController->onFinish(CLIENT(0), SESSION(4));
1293 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(4)));
1294 EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(3)));
1295 expectTimeout(CLIENT(0), SESSION(3), expectedGen++);
1296}
1297
Chong Zhang87d199c2021-03-01 19:02:18 -08001298TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerOverCountOnly) {
1299 ALOGD("TestTranscoderPacerOverCountOnly");
1300 testPacerHelper(12 /*numSubmits*/, 100 /*sessionDurationMs*/, 12 /*expectedSuccess*/);
1301}
1302
1303TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerOverTimeOnly) {
1304 ALOGD("TestTranscoderPacerOverTimeOnly");
1305 testPacerHelper(5 /*numSubmits*/, 1000 /*sessionDurationMs*/, 5 /*expectedSuccess*/);
1306}
1307
1308TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerOverQuota) {
1309 ALOGD("TestTranscoderPacerOverQuota");
1310 testPacerHelper(12 /*numSubmits*/, 400 /*sessionDurationMs*/, 10 /*expectedSuccess*/);
1311}
1312
1313TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerWithPause) {
1314 ALOGD("TestTranscoderPacerDuringPause");
Chong Zhangb28d6ca2021-04-15 18:02:21 -07001315 testPacerHelperWithPause(12 /*numSubmits*/, 400 /*sessionDurationMs*/, 10 /*expectedSuccess*/);
Chong Zhang87d199c2021-03-01 19:02:18 -08001316}
1317
Chong Zhangebd86d32021-03-29 11:30:56 -07001318/*
1319 * Test the case where multiple client uids request the same session. Session should only
1320 * be dropped when all clients are over quota.
1321 */
1322TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerMultipleUids) {
1323 ALOGD("TestTranscoderPacerMultipleUids");
1324 // First, run mClientCallback0 to the point of no quota.
Chong Zhangb28d6ca2021-04-15 18:02:21 -07001325 testPacerHelperWithMultipleUids(12 /*numSubmits*/, 400 /*sessionDurationMs*/,
1326 10 /*expectedSuccess*/, mClientCallback0, {});
Chong Zhangebd86d32021-03-29 11:30:56 -07001327 // Make UID(0) block on Client1's sessions too, Client1's quota should not be affected.
Chong Zhangb28d6ca2021-04-15 18:02:21 -07001328 testPacerHelperWithMultipleUids(12 /*numSubmits*/, 400 /*sessionDurationMs*/,
1329 10 /*expectedSuccess*/, mClientCallback1, {UID(0)});
Chong Zhangebd86d32021-03-29 11:30:56 -07001330 // Make UID(10) block on Client2's sessions. We expect to see 11 succeeds (instead of 10),
1331 // because the addClientUid() is called after the submit, and first session is already
1332 // started by the time UID(10) is added. UID(10) allowed us to run the 11th session,
1333 // after that both UID(10) and UID(2) are out of quota.
Chong Zhangb28d6ca2021-04-15 18:02:21 -07001334 testPacerHelperWithMultipleUids(12 /*numSubmits*/, 400 /*sessionDurationMs*/,
1335 11 /*expectedSuccess*/, mClientCallback2, {UID(10)});
1336}
1337
1338/*
1339 * Use same uid for clientUid and callingUid, should not be limited by quota.
1340 */
1341TEST_F(TranscodingSessionControllerTest, TestTranscoderPacerSelfUid) {
1342 ALOGD("TestTranscoderPacerSelfUid");
1343 testPacerHelperWithSelfUid(12 /*numSubmits*/, 400 /*sessionDurationMs*/,
1344 12 /*expectedSuccess*/);
Chong Zhangebd86d32021-03-29 11:30:56 -07001345}
1346
Chong Zhangbc062482020-10-14 16:43:53 -07001347} // namespace android