transcoding: add uid state based scheduling policy
bug: 145233472
bug: 154734285
test: unit tests
Change-Id: I9e8038252c2be834eb4e2fb2945396572d37b036
diff --git a/media/libmediatranscoding/tests/Android.bp b/media/libmediatranscoding/tests/Android.bp
index 1017d29..b54022a 100644
--- a/media/libmediatranscoding/tests/Android.bp
+++ b/media/libmediatranscoding/tests/Android.bp
@@ -37,6 +37,9 @@
srcs: ["TranscodingClientManager_tests.cpp"],
}
+//
+// TranscodingJobScheduler unit test
+//
cc_test {
name: "TranscodingJobScheduler_tests",
defaults: ["libmediatranscoding_test_defaults"],
diff --git a/media/libmediatranscoding/tests/TranscodingJobScheduler_tests.cpp b/media/libmediatranscoding/tests/TranscodingJobScheduler_tests.cpp
index 6bc9e20..95edf1d 100644
--- a/media/libmediatranscoding/tests/TranscodingJobScheduler_tests.cpp
+++ b/media/libmediatranscoding/tests/TranscodingJobScheduler_tests.cpp
@@ -31,6 +31,8 @@
#include <media/TranscodingJobScheduler.h>
#include <utils/Log.h>
+#include <unordered_set>
+
namespace android {
using Status = ::ndk::ScopedAStatus;
@@ -47,10 +49,39 @@
#define JOB(n) (kClientJobId + (n))
#define UID(n) (kClientUid + (n))
-class TestCallback : public TranscoderInterface, public UidPolicyInterface {
+class TestUidPolicy : public UidPolicyInterface {
public:
- TestCallback() : mTopUid(kInvalidUid), mLastError(TranscodingErrorCode::kUnknown) {}
- virtual ~TestCallback() {}
+ TestUidPolicy() = default;
+ virtual ~TestUidPolicy() = default;
+
+ // UidPolicyInterface
+ void registerMonitorUid(uid_t /*uid*/) override {}
+ void unregisterMonitorUid(uid_t /*uid*/) override {}
+ bool isUidOnTop(uid_t uid) override { return mTopUids.count(uid) > 0; }
+ std::unordered_set<uid_t> getTopUids() const override { return mTopUids; }
+ void setCallback(const std::shared_ptr<UidPolicyCallbackInterface>& cb) override {
+ mUidPolicyCallback = cb;
+ }
+ void setTop(uid_t uid) {
+ std::unordered_set<uid_t> uids = {uid};
+ setTop(uids);
+ }
+ void setTop(const std::unordered_set<uid_t>& uids) {
+ mTopUids = uids;
+ auto uidPolicyCb = mUidPolicyCallback.lock();
+ if (uidPolicyCb != nullptr) {
+ uidPolicyCb->onTopUidsChanged(mTopUids);
+ }
+ }
+
+ std::unordered_set<uid_t> mTopUids;
+ std::weak_ptr<UidPolicyCallbackInterface> mUidPolicyCallback;
+};
+
+class TestTranscoder : public TranscoderInterface {
+public:
+ TestTranscoder() : mLastError(TranscodingErrorCode::kUnknown) {}
+ virtual ~TestTranscoder() {}
// TranscoderInterface
void start(int64_t clientId, int32_t jobId) override {
@@ -63,9 +94,6 @@
mEventQueue.push_back(Resume(clientId, jobId));
}
- // UidPolicyInterface
- bool isUidOnTop(uid_t uid) override { return uid == mTopUid; }
-
void onFinished(int64_t clientId, int32_t jobId) {
mEventQueue.push_back(Finished(clientId, jobId));
}
@@ -75,8 +103,6 @@
mEventQueue.push_back(Failed(clientId, jobId));
}
- void setTop(uid_t uid) { mTopUid = uid; }
-
TranscodingErrorCode getLastError() {
TranscodingErrorCode result = mLastError;
mLastError = TranscodingErrorCode::kUnknown;
@@ -115,16 +141,16 @@
private:
Event mPoppedEvent;
std::list<Event> mEventQueue;
- uid_t mTopUid;
TranscodingErrorCode mLastError;
};
-bool operator==(const TestCallback::Event& lhs, const TestCallback::Event& rhs) {
+bool operator==(const TestTranscoder::Event& lhs, const TestTranscoder::Event& rhs) {
return lhs.type == rhs.type && lhs.clientId == rhs.clientId && lhs.jobId == rhs.jobId;
}
struct TestClientCallback : public BnTranscodingClientCallback {
- TestClientCallback(TestCallback* owner, int64_t clientId) : mOwner(owner), mClientId(clientId) {
+ TestClientCallback(TestTranscoder* owner, int64_t clientId)
+ : mOwner(owner), mClientId(clientId) {
ALOGD("TestClient Created");
}
@@ -152,7 +178,7 @@
virtual ~TestClientCallback() { ALOGI("TestClient destroyed"); };
private:
- TestCallback* mOwner;
+ TestTranscoder* mOwner;
int64_t mClientId;
TestClientCallback(const TestClientCallback&) = delete;
TestClientCallback& operator=(const TestClientCallback&) = delete;
@@ -164,27 +190,30 @@
void SetUp() override {
ALOGI("TranscodingJobSchedulerTest set up");
- mCallback.reset(new TestCallback());
- mScheduler.reset(new TranscodingJobScheduler(mCallback, mCallback));
+ mTranscoder.reset(new TestTranscoder());
+ mUidPolicy.reset(new TestUidPolicy());
+ mScheduler.reset(new TranscodingJobScheduler(mTranscoder, mUidPolicy));
+ mUidPolicy->setCallback(mScheduler);
// Set priority only, ignore other fields for now.
mOfflineRequest.priority = TranscodingJobPriority::kUnspecified;
mRealtimeRequest.priority = TranscodingJobPriority::kHigh;
mClientCallback0 =
- ::ndk::SharedRefBase::make<TestClientCallback>(mCallback.get(), CLIENT(0));
+ ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(0));
mClientCallback1 =
- ::ndk::SharedRefBase::make<TestClientCallback>(mCallback.get(), CLIENT(1));
+ ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(1));
mClientCallback2 =
- ::ndk::SharedRefBase::make<TestClientCallback>(mCallback.get(), CLIENT(2));
+ ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(2));
mClientCallback3 =
- ::ndk::SharedRefBase::make<TestClientCallback>(mCallback.get(), CLIENT(3));
+ ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(3));
}
void TearDown() override { ALOGI("TranscodingJobSchedulerTest tear down"); }
~TranscodingJobSchedulerTest() { ALOGD("TranscodingJobSchedulerTest destroyed"); }
- std::shared_ptr<TestCallback> mCallback;
+ std::shared_ptr<TestTranscoder> mTranscoder;
+ std::shared_ptr<TestUidPolicy> mUidPolicy;
std::shared_ptr<TranscodingJobScheduler> mScheduler;
TranscodingRequestParcel mOfflineRequest;
TranscodingRequestParcel mRealtimeRequest;
@@ -198,44 +227,42 @@
ALOGD("TestSubmitJob");
// Start with UID(1) on top.
- mCallback->setTop(UID(1));
+ mUidPolicy->setTop(UID(1));
// Submit offline job to CLIENT(0) in UID(0).
// Should start immediately (because this is the only job).
mScheduler->submit(CLIENT(0), JOB(0), UID(0), mOfflineRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), 0));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), 0));
// Submit real-time job to CLIENT(0).
// Should pause offline job and start new job, even if UID(0) is not on top.
mScheduler->submit(CLIENT(0), JOB(1), UID(0), mRealtimeRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Pause(CLIENT(0), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), JOB(1)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(1)));
// Submit real-time job to CLIENT(0), should be queued after the previous job.
mScheduler->submit(CLIENT(0), JOB(2), UID(0), mRealtimeRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Submit real-time job to CLIENT(1) in same uid, should be queued after the previous job.
mScheduler->submit(CLIENT(1), JOB(0), UID(0), mRealtimeRequest, mClientCallback1);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Submit real-time job to CLIENT(2) in UID(1).
- // Should pause previous job and start new job, because UID(1) is top.
- mCallback->setTop(UID(1));
+ // Should pause previous job and start new job, because UID(1) is (has been) top.
mScheduler->submit(CLIENT(2), JOB(0), UID(1), mRealtimeRequest, mClientCallback2);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Pause(CLIENT(0), JOB(1)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(2), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(1)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), JOB(0)));
// Submit offline job, shouldn't generate any event.
mScheduler->submit(CLIENT(2), JOB(1), UID(1), mOfflineRequest, mClientCallback2);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
- mCallback->setTop(UID(0));
- // Submit real-time job to CLIENT(1) in UID(0).
+ // Bring UID(0) to top.
+ mUidPolicy->setTop(UID(0));
// Should pause current job, and resume last job in UID(0).
- mScheduler->submit(CLIENT(1), JOB(1), UID(0), mRealtimeRequest, mClientCallback1);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Pause(CLIENT(2), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Resume(CLIENT(0), JOB(1)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), JOB(1)));
}
TEST_F(TranscodingJobSchedulerTest, TestCancelJob) {
@@ -243,15 +270,15 @@
// Submit real-time job JOB(0), should start immediately.
mScheduler->submit(CLIENT(0), JOB(0), UID(0), mRealtimeRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(0)));
// Submit real-time job JOB(1), should not start.
mScheduler->submit(CLIENT(0), JOB(1), UID(0), mRealtimeRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Submit offline job JOB(2), should not start.
mScheduler->submit(CLIENT(0), JOB(2), UID(0), mOfflineRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Cancel queued real-time job.
// Cancel real-time job JOB(1), should be cancelled.
@@ -263,224 +290,283 @@
// Submit offline job JOB(3), shouldn't cause any event.
mScheduler->submit(CLIENT(0), JOB(3), UID(0), mOfflineRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Cancel running real-time job JOB(0).
// - Should be paused first then cancelled.
// - Should also start offline job JOB(2) because real-time queue is empty.
EXPECT_TRUE(mScheduler->cancel(CLIENT(0), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Pause(CLIENT(0), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), JOB(3)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(3)));
}
TEST_F(TranscodingJobSchedulerTest, TestFinishJob) {
ALOGD("TestFinishJob");
- // Fail without any jobs submitted, should be ignored.
+ // Start with unspecified top UID.
+ // Finish without any jobs submitted, should be ignored.
mScheduler->onFinish(CLIENT(0), JOB(0));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Submit offline job JOB(0), should start immediately.
mScheduler->submit(CLIENT(0), JOB(0), UID(0), mOfflineRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(0)));
// Submit real-time job JOB(1), should pause offline job and start immediately.
mScheduler->submit(CLIENT(0), JOB(1), UID(0), mRealtimeRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Pause(CLIENT(0), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), JOB(1)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(1)));
// Submit real-time job JOB(2), should not start.
mScheduler->submit(CLIENT(0), JOB(2), UID(0), mRealtimeRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
- // Fail when the job never started, should be ignored.
+ // Finish when the job never started, should be ignored.
mScheduler->onFinish(CLIENT(0), JOB(2));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// UID(1) moves to top.
- mCallback->setTop(UID(1));
+ mUidPolicy->setTop(UID(1));
// Submit real-time job to CLIENT(1) in UID(1), should pause previous job and start new job.
mScheduler->submit(CLIENT(1), JOB(0), UID(1), mRealtimeRequest, mClientCallback1);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Pause(CLIENT(0), JOB(1)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(1), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(1)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), JOB(0)));
- // Simulate Fail that arrived late, after pause issued by scheduler.
+ // Simulate Finish that arrived late, after pause issued by scheduler.
// Should still be propagated to client, but shouldn't trigger any new start.
mScheduler->onFinish(CLIENT(0), JOB(1));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Finished(CLIENT(0), JOB(1)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), JOB(1)));
- // Fail running real-time job, should start next real-time job in queue.
+ // Finish running real-time job, should start next real-time job in queue.
mScheduler->onFinish(CLIENT(1), JOB(0));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Finished(CLIENT(1), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), JOB(2)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(1), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(2)));
- // Fail running real-time job, should resume next job (offline job) in queue.
+ // Finish running real-time job, should resume next job (offline job) in queue.
mScheduler->onFinish(CLIENT(0), JOB(2));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Finished(CLIENT(0), JOB(2)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Resume(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), JOB(2)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), JOB(0)));
- // Fail running offline job.
+ // Finish running offline job.
mScheduler->onFinish(CLIENT(0), JOB(0));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Finished(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), JOB(0)));
- // Duplicate fail for last job, should be ignored.
+ // Duplicate finish for last job, should be ignored.
mScheduler->onFinish(CLIENT(0), JOB(0));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
}
TEST_F(TranscodingJobSchedulerTest, TestFailJob) {
ALOGD("TestFailJob");
+ // Start with unspecified top UID.
// Fail without any jobs submitted, should be ignored.
mScheduler->onError(CLIENT(0), JOB(0), TranscodingErrorCode::kUnknown);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Submit offline job JOB(0), should start immediately.
mScheduler->submit(CLIENT(0), JOB(0), UID(0), mOfflineRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(0)));
// Submit real-time job JOB(1), should pause offline job and start immediately.
mScheduler->submit(CLIENT(0), JOB(1), UID(0), mRealtimeRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Pause(CLIENT(0), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), JOB(1)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(1)));
// Submit real-time job JOB(2), should not start.
mScheduler->submit(CLIENT(0), JOB(2), UID(0), mRealtimeRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Fail when the job never started, should be ignored.
mScheduler->onError(CLIENT(0), JOB(2), TranscodingErrorCode::kUnknown);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// UID(1) moves to top.
- mCallback->setTop(UID(1));
+ mUidPolicy->setTop(UID(1));
// Submit real-time job to CLIENT(1) in UID(1), should pause previous job and start new job.
mScheduler->submit(CLIENT(1), JOB(0), UID(1), mRealtimeRequest, mClientCallback1);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Pause(CLIENT(0), JOB(1)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(1), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(1)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), JOB(0)));
// Simulate Fail that arrived late, after pause issued by scheduler.
// Should still be propagated to client, but shouldn't trigger any new start.
mScheduler->onError(CLIENT(0), JOB(1), TranscodingErrorCode::kUnknown);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Failed(CLIENT(0), JOB(1)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), JOB(1)));
// Fail running real-time job, should start next real-time job in queue.
mScheduler->onError(CLIENT(1), JOB(0), TranscodingErrorCode::kUnknown);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Failed(CLIENT(1), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), JOB(2)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(1), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(2)));
// Fail running real-time job, should resume next job (offline job) in queue.
mScheduler->onError(CLIENT(0), JOB(2), TranscodingErrorCode::kUnknown);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Failed(CLIENT(0), JOB(2)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Resume(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), JOB(2)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), JOB(0)));
// Fail running offline job, and test error code propagation.
mScheduler->onError(CLIENT(0), JOB(0), TranscodingErrorCode::kInvalidBitstream);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Failed(CLIENT(0), JOB(0)));
- EXPECT_EQ(mCallback->getLastError(), TranscodingErrorCode::kInvalidBitstream);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kInvalidBitstream);
// Duplicate fail for last job, should be ignored.
mScheduler->onError(CLIENT(0), JOB(0), TranscodingErrorCode::kUnknown);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
}
TEST_F(TranscodingJobSchedulerTest, TestTopUidChanged) {
ALOGD("TestTopUidChanged");
+ // Start with unspecified top UID.
// Submit real-time job to CLIENT(0), job should start immediately.
mScheduler->submit(CLIENT(0), JOB(0), UID(0), mRealtimeRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(0)));
// Submit offline job to CLIENT(0), should not start.
mScheduler->submit(CLIENT(1), JOB(0), UID(0), mOfflineRequest, mClientCallback1);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Move UID(1) to top.
- mCallback->setTop(UID(1));
+ mUidPolicy->setTop(UID(1));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
// Submit real-time job to CLIENT(2) in different uid UID(1).
// Should pause previous job and start new job.
mScheduler->submit(CLIENT(2), JOB(0), UID(1), mRealtimeRequest, mClientCallback2);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Pause(CLIENT(0), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(2), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), JOB(0)));
// Bring UID(0) back to top.
- mCallback->setTop(UID(0));
- mScheduler->onTopUidChanged(UID(0));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Pause(CLIENT(2), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Resume(CLIENT(0), JOB(0)));
+ mUidPolicy->setTop(UID(0));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), JOB(0)));
// Bring invalid uid to top.
- mScheduler->onTopUidChanged(kInvalidUid);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ mUidPolicy->setTop(kInvalidUid);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Finish job, next real-time job should resume.
mScheduler->onFinish(CLIENT(0), JOB(0));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Finished(CLIENT(0), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Resume(CLIENT(2), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), JOB(0)));
// Finish job, offline job should start.
mScheduler->onFinish(CLIENT(2), JOB(0));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Finished(CLIENT(2), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(1), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), JOB(0)));
+}
+
+TEST_F(TranscodingJobSchedulerTest, TestTopUidSetChanged) {
+ ALOGD("TestTopUidChanged_MultipleUids");
+
+ // Start with unspecified top UID.
+ // Submit real-time job to CLIENT(0), job should start immediately.
+ mScheduler->submit(CLIENT(0), JOB(0), UID(0), mRealtimeRequest, mClientCallback0);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(0)));
+
+ // Submit offline job to CLIENT(0), should not start.
+ mScheduler->submit(CLIENT(1), JOB(0), UID(0), mOfflineRequest, mClientCallback1);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+ // Set UID(0), UID(1) to top set.
+ // UID(0) should continue to run.
+ mUidPolicy->setTop({UID(0), UID(1)});
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+ // Submit real-time job to CLIENT(2) in different uid UID(1).
+ // UID(0) should pause and UID(1) should start.
+ mScheduler->submit(CLIENT(2), JOB(0), UID(1), mRealtimeRequest, mClientCallback2);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), JOB(0)));
+
+ // Remove UID(0) from top set, and only leave UID(1) in the set.
+ // UID(1) should continue to run.
+ mUidPolicy->setTop(UID(1));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+ // Set UID(0), UID(2) to top set.
+ // UID(1) should continue to run.
+ mUidPolicy->setTop({UID(1), UID(2)});
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+ // Bring UID(0) back to top.
+ mUidPolicy->setTop(UID(0));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), JOB(0)));
+
+ // Bring invalid uid to top.
+ mUidPolicy->setTop(kInvalidUid);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+ // Finish job, next real-time job from UID(1) should resume, even if UID(1) no longer top.
+ mScheduler->onFinish(CLIENT(0), JOB(0));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), JOB(0)));
+
+ // Finish job, offline job should start.
+ mScheduler->onFinish(CLIENT(2), JOB(0));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), JOB(0)));
}
TEST_F(TranscodingJobSchedulerTest, TestResourceLost) {
ALOGD("TestResourceLost");
+ // Start with unspecified top UID.
// Submit real-time job to CLIENT(0), job should start immediately.
mScheduler->submit(CLIENT(0), JOB(0), UID(0), mRealtimeRequest, mClientCallback0);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(0)));
// Submit offline job to CLIENT(0), should not start.
mScheduler->submit(CLIENT(1), JOB(0), UID(0), mOfflineRequest, mClientCallback1);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Move UID(1) to top.
- mCallback->setTop(UID(1));
+ mUidPolicy->setTop(UID(1));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Submit real-time job to CLIENT(2) in different uid UID(1).
// Should pause previous job and start new job.
mScheduler->submit(CLIENT(2), JOB(0), UID(1), mRealtimeRequest, mClientCallback2);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Pause(CLIENT(0), JOB(0)));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(2), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), JOB(0)));
// Test 1: No queue change during resource loss.
// Signal resource lost.
mScheduler->onResourceLost();
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Signal resource available, CLIENT(2) should resume.
mScheduler->onResourceAvailable();
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Resume(CLIENT(2), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), JOB(0)));
// Test 2: Change of queue order during resource loss.
// Signal resource lost.
mScheduler->onResourceLost();
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Move UID(0) back to top, should have no resume due to no resource.
- mScheduler->onTopUidChanged(UID(0));
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ mUidPolicy->setTop(UID(0));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Signal resource available, CLIENT(0) should resume.
mScheduler->onResourceAvailable();
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Resume(CLIENT(0), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), JOB(0)));
// Test 3: Adding new queue during resource loss.
// Signal resource lost.
mScheduler->onResourceLost();
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Move UID(2) to top.
- mCallback->setTop(UID(2));
+ mUidPolicy->setTop(UID(2));
// Submit real-time job to CLIENT(3) in UID(2), job shouldn't start due to no resource.
mScheduler->submit(CLIENT(3), JOB(0), UID(2), mRealtimeRequest, mClientCallback3);
- EXPECT_EQ(mCallback->popEvent(), TestCallback::NoEvent);
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
// Signal resource available, CLIENT(3)'s job should start.
mScheduler->onResourceAvailable();
- EXPECT_EQ(mCallback->popEvent(), TestCallback::Start(CLIENT(3), JOB(0)));
+ EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), JOB(0)));
}
} // namespace android