transcoding: renaming to session controller to avoid confusion

No functional change.

bug:154733526

Change-Id: I8731a721ab3a6ae2937e1ac24e4f1a2f1e27da85
diff --git a/media/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp b/media/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp
index 2e49f32..a35ca53 100644
--- a/media/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp
+++ b/media/libmediatranscoding/tests/AdjustableMaxPriorityQueue_tests.cpp
@@ -223,19 +223,19 @@
 }
 
 // Test the heap property and make sure it is the same as std::priority_queue.
-TEST(AdjustableMaxPriorityQueueTest, TranscodingJobTest) {
-    // Test data structure that mimics the Transcoding job.
-    struct TranscodingJob {
+TEST(AdjustableMaxPriorityQueueTest, TranscodingSessionTest) {
+    // Test data structure that mimics the Transcoding session.
+    struct TranscodingSession {
         int32_t priority;
         int64_t createTimeUs;
     };
 
-    // The job is arranging according to priority with highest priority comes first.
-    // For the job with the same priority, the job with early createTime will come first.
-    class TranscodingJobComp {
+    // The session is arranging according to priority with highest priority comes first.
+    // For the session with the same priority, the session with early createTime will come first.
+    class TranscodingSessionComp {
     public:
-        bool operator()(const std::unique_ptr<TranscodingJob>& lhs,
-                        const std::unique_ptr<TranscodingJob>& rhs) const {
+        bool operator()(const std::unique_ptr<TranscodingSession>& lhs,
+                        const std::unique_ptr<TranscodingSession>& rhs) const {
             if (lhs->priority != rhs->priority) {
                 return lhs->priority < rhs->priority;
             }
@@ -244,46 +244,47 @@
     };
 
     // Map to save each value's position in the heap.
-    std::unordered_map<int, TranscodingJob*> jobIdToJobMap;
+    std::unordered_map<int, TranscodingSession*> sessionIdToSessionMap;
 
-    TranscodingJob testJobs[] = {
-            {1 /*priority*/, 66 /*createTimeUs*/},  // First job,
-            {2 /*priority*/, 67 /*createTimeUs*/},  // Second job,
-            {2 /*priority*/, 66 /*createTimeUs*/},  // Third job,
-            {3 /*priority*/, 68 /*createTimeUs*/},  // Fourth job.
+    TranscodingSession testSessions[] = {
+            {1 /*priority*/, 66 /*createTimeUs*/},  // First session,
+            {2 /*priority*/, 67 /*createTimeUs*/},  // Second session,
+            {2 /*priority*/, 66 /*createTimeUs*/},  // Third session,
+            {3 /*priority*/, 68 /*createTimeUs*/},  // Fourth session.
     };
 
-    AdjustableMaxPriorityQueue<std::unique_ptr<TranscodingJob>, TranscodingJobComp> jobQueue;
+    AdjustableMaxPriorityQueue<std::unique_ptr<TranscodingSession>, TranscodingSessionComp>
+            sessionQueue;
 
-    // Pushes all the jobs into the heap.
-    for (int jobId = 0; jobId < 4; ++jobId) {
-        auto newJob = std::make_unique<TranscodingJob>(testJobs[jobId]);
-        jobIdToJobMap[jobId] = newJob.get();
-        EXPECT_TRUE(jobQueue.push(std::move(newJob)));
+    // Pushes all the sessions into the heap.
+    for (int sessionId = 0; sessionId < 4; ++sessionId) {
+        auto newSession = std::make_unique<TranscodingSession>(testSessions[sessionId]);
+        sessionIdToSessionMap[sessionId] = newSession.get();
+        EXPECT_TRUE(sessionQueue.push(std::move(newSession)));
     }
 
-    // Check the job queue size.
-    EXPECT_EQ(4, jobQueue.size());
+    // Check the session queue size.
+    EXPECT_EQ(4, sessionQueue.size());
 
-    // Check the top and it should be Forth job: (3, 68)
-    const std::unique_ptr<TranscodingJob>& topJob = jobQueue.top();
-    EXPECT_EQ(3, topJob->priority);
-    EXPECT_EQ(68, topJob->createTimeUs);
+    // Check the top and it should be Forth session: (3, 68)
+    const std::unique_ptr<TranscodingSession>& topSession = sessionQueue.top();
+    EXPECT_EQ(3, topSession->priority);
+    EXPECT_EQ(68, topSession->createTimeUs);
 
     // Consume the top.
-    std::unique_ptr<TranscodingJob> consumeJob = jobQueue.consume_top();
+    std::unique_ptr<TranscodingSession> consumeSession = sessionQueue.consume_top();
 
-    // Check the top and it should be Third Job (2, 66)
-    const std::unique_ptr<TranscodingJob>& topJob2 = jobQueue.top();
-    EXPECT_EQ(2, topJob2->priority);
-    EXPECT_EQ(66, topJob2->createTimeUs);
+    // Check the top and it should be Third Session (2, 66)
+    const std::unique_ptr<TranscodingSession>& topSession2 = sessionQueue.top();
+    EXPECT_EQ(2, topSession2->priority);
+    EXPECT_EQ(66, topSession2->createTimeUs);
 
-    // Change the Second job's priority to 4 from (2, 67) -> (4, 67). It should becomes top of the
-    // queue.
-    jobIdToJobMap[1]->priority = 4;
-    jobQueue.rebuild();
-    const std::unique_ptr<TranscodingJob>& topJob3 = jobQueue.top();
-    EXPECT_EQ(4, topJob3->priority);
-    EXPECT_EQ(67, topJob3->createTimeUs);
+    // Change the Second session's priority to 4 from (2, 67) -> (4, 67). It should becomes
+    // top of the queue.
+    sessionIdToSessionMap[1]->priority = 4;
+    sessionQueue.rebuild();
+    const std::unique_ptr<TranscodingSession>& topSession3 = sessionQueue.top();
+    EXPECT_EQ(4, topSession3->priority);
+    EXPECT_EQ(67, topSession3->createTimeUs);
 }
 }  // namespace android
\ No newline at end of file
diff --git a/media/libmediatranscoding/tests/Android.bp b/media/libmediatranscoding/tests/Android.bp
index b54022a..7b15b1b 100644
--- a/media/libmediatranscoding/tests/Android.bp
+++ b/media/libmediatranscoding/tests/Android.bp
@@ -38,13 +38,13 @@
 }
 
 //
-// TranscodingJobScheduler unit test
+// TranscodingSessionController unit test
 //
 cc_test {
-    name: "TranscodingJobScheduler_tests",
+    name: "TranscodingSessionController_tests",
     defaults: ["libmediatranscoding_test_defaults"],
 
-    srcs: ["TranscodingJobScheduler_tests.cpp"],
+    srcs: ["TranscodingSessionController_tests.cpp"],
 }
 
 //
diff --git a/media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp b/media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
index c2ca9b4..1a50923 100644
--- a/media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
+++ b/media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
@@ -25,7 +25,7 @@
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <gtest/gtest.h>
-#include <media/SchedulerClientInterface.h>
+#include <media/ControllerClientInterface.h>
 #include <media/TranscodingClientManager.h>
 #include <media/TranscodingRequest.h>
 #include <utils/Log.h>
@@ -38,10 +38,10 @@
 using ::aidl::android::media::BnTranscodingClientCallback;
 using ::aidl::android::media::IMediaTranscodingService;
 using ::aidl::android::media::TranscodingErrorCode;
-using ::aidl::android::media::TranscodingJobParcel;
-using ::aidl::android::media::TranscodingJobPriority;
 using ::aidl::android::media::TranscodingRequestParcel;
 using ::aidl::android::media::TranscodingResultParcel;
+using ::aidl::android::media::TranscodingSessionParcel;
+using ::aidl::android::media::TranscodingSessionPriority;
 
 constexpr pid_t kInvalidClientPid = -5;
 constexpr pid_t kInvalidClientUid = -10;
@@ -51,7 +51,7 @@
 constexpr const char* kClientName = "TestClientName";
 constexpr const char* kClientPackage = "TestClientPackage";
 
-#define JOB(n) (n)
+#define SESSION(n) (n)
 
 struct TestClientCallback : public BnTranscodingClientCallback {
     TestClientCallback() { ALOGI("TestClientCallback Created"); }
@@ -63,30 +63,32 @@
         return Status::ok();
     }
 
-    Status onTranscodingStarted(int32_t /*in_jobId*/) override { return Status::ok(); }
+    Status onTranscodingStarted(int32_t /*in_sessionId*/) override { return Status::ok(); }
 
-    Status onTranscodingPaused(int32_t /*in_jobId*/) override { return Status::ok(); }
+    Status onTranscodingPaused(int32_t /*in_sessionId*/) override { return Status::ok(); }
 
-    Status onTranscodingResumed(int32_t /*in_jobId*/) override { return Status::ok(); }
+    Status onTranscodingResumed(int32_t /*in_sessionId*/) override { return Status::ok(); }
 
-    Status onTranscodingFinished(int32_t in_jobId,
+    Status onTranscodingFinished(int32_t in_sessionId,
                                  const TranscodingResultParcel& in_result) override {
-        EXPECT_EQ(in_jobId, in_result.jobId);
-        mEventQueue.push_back(Finished(in_jobId));
+        EXPECT_EQ(in_sessionId, in_result.sessionId);
+        mEventQueue.push_back(Finished(in_sessionId));
         return Status::ok();
     }
 
-    Status onTranscodingFailed(int32_t in_jobId, TranscodingErrorCode /*in_errorCode */) override {
-        mEventQueue.push_back(Failed(in_jobId));
+    Status onTranscodingFailed(int32_t in_sessionId,
+                               TranscodingErrorCode /*in_errorCode */) override {
+        mEventQueue.push_back(Failed(in_sessionId));
         return Status::ok();
     }
 
-    Status onAwaitNumberOfJobsChanged(int32_t /* in_jobId */, int32_t /* in_oldAwaitNumber */,
-                                      int32_t /* in_newAwaitNumber */) override {
+    Status onAwaitNumberOfSessionsChanged(int32_t /* in_sessionId */,
+                                          int32_t /* in_oldAwaitNumber */,
+                                          int32_t /* in_newAwaitNumber */) override {
         return Status::ok();
     }
 
-    Status onProgressUpdate(int32_t /* in_jobId */, int32_t /* in_progress */) override {
+    Status onProgressUpdate(int32_t /* in_sessionId */, int32_t /* in_progress */) override {
         return Status::ok();
     }
 
@@ -96,12 +98,12 @@
             Finished,
             Failed,
         } type;
-        JobIdType jobId;
+        SessionIdType sessionId;
     };
 
     static constexpr Event NoEvent = {Event::NoEvent, 0};
 #define DECLARE_EVENT(action) \
-    static Event action(JobIdType jobId) { return {Event::action, jobId}; }
+    static Event action(SessionIdType sessionId) { return {Event::action, sessionId}; }
 
     DECLARE_EVENT(Finished);
     DECLARE_EVENT(Failed);
@@ -125,102 +127,102 @@
 };
 
 bool operator==(const TestClientCallback::Event& lhs, const TestClientCallback::Event& rhs) {
-    return lhs.type == rhs.type && lhs.jobId == rhs.jobId;
+    return lhs.type == rhs.type && lhs.sessionId == rhs.sessionId;
 }
 
-struct TestScheduler : public SchedulerClientInterface {
-    TestScheduler() { ALOGI("TestScheduler Created"); }
+struct TestController : public ControllerClientInterface {
+    TestController() { ALOGI("TestController Created"); }
 
-    virtual ~TestScheduler() { ALOGI("TestScheduler Destroyed"); }
+    virtual ~TestController() { ALOGI("TestController Destroyed"); }
 
-    bool submit(ClientIdType clientId, JobIdType jobId, uid_t /*uid*/,
+    bool submit(ClientIdType clientId, SessionIdType sessionId, uid_t /*uid*/,
                 const TranscodingRequestParcel& request,
                 const std::weak_ptr<ITranscodingClientCallback>& clientCallback) override {
-        JobKeyType jobKey = std::make_pair(clientId, jobId);
-        if (mJobs.count(jobKey) > 0) {
+        SessionKeyType sessionKey = std::make_pair(clientId, sessionId);
+        if (mSessions.count(sessionKey) > 0) {
             return false;
         }
 
         // This is the secret name we'll check, to test error propagation from
-        // the scheduler back to client.
+        // the controller back to client.
         if (request.sourceFilePath == "bad_source_file") {
             return false;
         }
 
-        mJobs[jobKey].request = request;
-        mJobs[jobKey].callback = clientCallback;
+        mSessions[sessionKey].request = request;
+        mSessions[sessionKey].callback = clientCallback;
 
-        mLastJob = jobKey;
+        mLastSession = sessionKey;
         return true;
     }
 
-    bool cancel(ClientIdType clientId, JobIdType jobId) override {
-        JobKeyType jobKey = std::make_pair(clientId, jobId);
+    bool cancel(ClientIdType clientId, SessionIdType sessionId) override {
+        SessionKeyType sessionKey = std::make_pair(clientId, sessionId);
 
-        if (mJobs.count(jobKey) == 0) {
+        if (mSessions.count(sessionKey) == 0) {
             return false;
         }
-        mJobs.erase(jobKey);
+        mSessions.erase(sessionKey);
         return true;
     }
 
-    bool getJob(ClientIdType clientId, JobIdType jobId,
-                TranscodingRequestParcel* request) override {
-        JobKeyType jobKey = std::make_pair(clientId, jobId);
-        if (mJobs.count(jobKey) == 0) {
+    bool getSession(ClientIdType clientId, SessionIdType sessionId,
+                    TranscodingRequestParcel* request) override {
+        SessionKeyType sessionKey = std::make_pair(clientId, sessionId);
+        if (mSessions.count(sessionKey) == 0) {
             return false;
         }
 
-        *(TranscodingRequest*)request = mJobs[jobKey].request;
+        *(TranscodingRequest*)request = mSessions[sessionKey].request;
         return true;
     }
 
-    void finishLastJob() {
-        auto it = mJobs.find(mLastJob);
-        if (it == mJobs.end()) {
+    void finishLastSession() {
+        auto it = mSessions.find(mLastSession);
+        if (it == mSessions.end()) {
             return;
         }
         {
             auto clientCallback = it->second.callback.lock();
             if (clientCallback != nullptr) {
                 clientCallback->onTranscodingFinished(
-                        mLastJob.second,
-                        TranscodingResultParcel({mLastJob.second, 0, std::nullopt}));
+                        mLastSession.second,
+                        TranscodingResultParcel({mLastSession.second, 0, std::nullopt}));
             }
         }
-        mJobs.erase(it);
+        mSessions.erase(it);
     }
 
-    void abortLastJob() {
-        auto it = mJobs.find(mLastJob);
-        if (it == mJobs.end()) {
+    void abortLastSession() {
+        auto it = mSessions.find(mLastSession);
+        if (it == mSessions.end()) {
             return;
         }
         {
             auto clientCallback = it->second.callback.lock();
             if (clientCallback != nullptr) {
-                clientCallback->onTranscodingFailed(mLastJob.second,
+                clientCallback->onTranscodingFailed(mLastSession.second,
                                                     TranscodingErrorCode::kUnknown);
             }
         }
-        mJobs.erase(it);
+        mSessions.erase(it);
     }
 
-    struct Job {
+    struct Session {
         TranscodingRequest request;
         std::weak_ptr<ITranscodingClientCallback> callback;
     };
 
-    typedef std::pair<ClientIdType, JobIdType> JobKeyType;
-    std::map<JobKeyType, Job> mJobs;
-    JobKeyType mLastJob;
+    typedef std::pair<ClientIdType, SessionIdType> SessionKeyType;
+    std::map<SessionKeyType, Session> mSessions;
+    SessionKeyType mLastSession;
 };
 
 class TranscodingClientManagerTest : public ::testing::Test {
 public:
     TranscodingClientManagerTest()
-          : mScheduler(new TestScheduler()),
-            mClientManager(new TranscodingClientManager(mScheduler)) {
+          : mController(new TestController()),
+            mClientManager(new TranscodingClientManager(mController)) {
         ALOGD("TranscodingClientManagerTest created");
     }
 
@@ -260,7 +262,7 @@
         EXPECT_EQ(mClientManager->getNumOfClients(), 0);
     }
 
-    std::shared_ptr<TestScheduler> mScheduler;
+    std::shared_ptr<TestController> mController;
     std::shared_ptr<TranscodingClientManager> mClientManager;
     std::shared_ptr<ITranscodingClient> mClient1;
     std::shared_ptr<ITranscodingClient> mClient2;
@@ -349,36 +351,36 @@
     unregisterMultipleClients();
 }
 
-TEST_F(TranscodingClientManagerTest, TestSubmitCancelGetJobs) {
+TEST_F(TranscodingClientManagerTest, TestSubmitCancelGetSessions) {
     addMultipleClients();
 
-    // Test jobId assignment.
+    // Test sessionId assignment.
     TranscodingRequestParcel request;
     request.sourceFilePath = "test_source_file_0";
     request.destinationFilePath = "test_desintaion_file_0";
-    TranscodingJobParcel job;
+    TranscodingSessionParcel session;
     bool result;
-    EXPECT_TRUE(mClient1->submitRequest(request, &job, &result).isOk());
+    EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
     EXPECT_TRUE(result);
-    EXPECT_EQ(job.jobId, JOB(0));
+    EXPECT_EQ(session.sessionId, SESSION(0));
 
     request.sourceFilePath = "test_source_file_1";
     request.destinationFilePath = "test_desintaion_file_1";
-    EXPECT_TRUE(mClient1->submitRequest(request, &job, &result).isOk());
+    EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
     EXPECT_TRUE(result);
-    EXPECT_EQ(job.jobId, JOB(1));
+    EXPECT_EQ(session.sessionId, SESSION(1));
 
     request.sourceFilePath = "test_source_file_2";
     request.destinationFilePath = "test_desintaion_file_2";
-    EXPECT_TRUE(mClient1->submitRequest(request, &job, &result).isOk());
+    EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
     EXPECT_TRUE(result);
-    EXPECT_EQ(job.jobId, JOB(2));
+    EXPECT_EQ(session.sessionId, SESSION(2));
 
     // Test submit bad request (no valid sourceFilePath) fails.
     TranscodingRequestParcel badRequest;
     badRequest.sourceFilePath = "bad_source_file";
     badRequest.destinationFilePath = "bad_destination_file";
-    EXPECT_TRUE(mClient1->submitRequest(badRequest, &job, &result).isOk());
+    EXPECT_TRUE(mClient1->submitRequest(badRequest, &session, &result).isOk());
     EXPECT_FALSE(result);
 
     // Test submit with bad pid/uid.
@@ -386,49 +388,49 @@
     badRequest.destinationFilePath = "test_desintaion_file_3";
     badRequest.clientPid = kInvalidClientPid;
     badRequest.clientUid = kInvalidClientUid;
-    EXPECT_TRUE(mClient1->submitRequest(badRequest, &job, &result).isOk());
+    EXPECT_TRUE(mClient1->submitRequest(badRequest, &session, &result).isOk());
     EXPECT_FALSE(result);
 
-    // Test get jobs by id.
-    EXPECT_TRUE(mClient1->getJobWithId(JOB(2), &job, &result).isOk());
-    EXPECT_EQ(job.jobId, JOB(2));
-    EXPECT_EQ(job.request.sourceFilePath, "test_source_file_2");
+    // Test get sessions by id.
+    EXPECT_TRUE(mClient1->getSessionWithId(SESSION(2), &session, &result).isOk());
+    EXPECT_EQ(session.sessionId, SESSION(2));
+    EXPECT_EQ(session.request.sourceFilePath, "test_source_file_2");
     EXPECT_TRUE(result);
 
-    // Test get jobs by invalid id fails.
-    EXPECT_TRUE(mClient1->getJobWithId(JOB(100), &job, &result).isOk());
+    // Test get sessions by invalid id fails.
+    EXPECT_TRUE(mClient1->getSessionWithId(SESSION(100), &session, &result).isOk());
     EXPECT_FALSE(result);
 
-    // Test cancel non-existent job fail.
-    EXPECT_TRUE(mClient2->cancelJob(JOB(100), &result).isOk());
+    // Test cancel non-existent session fail.
+    EXPECT_TRUE(mClient2->cancelSession(SESSION(100), &result).isOk());
     EXPECT_FALSE(result);
 
-    // Test cancel valid jobId in arbitrary order.
-    EXPECT_TRUE(mClient1->cancelJob(JOB(2), &result).isOk());
+    // Test cancel valid sessionId in arbitrary order.
+    EXPECT_TRUE(mClient1->cancelSession(SESSION(2), &result).isOk());
     EXPECT_TRUE(result);
 
-    EXPECT_TRUE(mClient1->cancelJob(JOB(0), &result).isOk());
+    EXPECT_TRUE(mClient1->cancelSession(SESSION(0), &result).isOk());
     EXPECT_TRUE(result);
 
-    EXPECT_TRUE(mClient1->cancelJob(JOB(1), &result).isOk());
+    EXPECT_TRUE(mClient1->cancelSession(SESSION(1), &result).isOk());
     EXPECT_TRUE(result);
 
-    // Test cancel job again fails.
-    EXPECT_TRUE(mClient1->cancelJob(JOB(1), &result).isOk());
+    // Test cancel session again fails.
+    EXPECT_TRUE(mClient1->cancelSession(SESSION(1), &result).isOk());
     EXPECT_FALSE(result);
 
-    // Test get job after cancel fails.
-    EXPECT_TRUE(mClient1->getJobWithId(JOB(2), &job, &result).isOk());
+    // Test get session after cancel fails.
+    EXPECT_TRUE(mClient1->getSessionWithId(SESSION(2), &session, &result).isOk());
     EXPECT_FALSE(result);
 
-    // Test jobId independence for each client.
-    EXPECT_TRUE(mClient2->submitRequest(request, &job, &result).isOk());
+    // Test sessionId independence for each client.
+    EXPECT_TRUE(mClient2->submitRequest(request, &session, &result).isOk());
     EXPECT_TRUE(result);
-    EXPECT_EQ(job.jobId, JOB(0));
+    EXPECT_EQ(session.sessionId, SESSION(0));
 
-    EXPECT_TRUE(mClient2->submitRequest(request, &job, &result).isOk());
+    EXPECT_TRUE(mClient2->submitRequest(request, &session, &result).isOk());
     EXPECT_TRUE(result);
-    EXPECT_EQ(job.jobId, JOB(1));
+    EXPECT_EQ(session.sessionId, SESSION(1));
 
     unregisterMultipleClients();
 }
@@ -439,32 +441,32 @@
     TranscodingRequestParcel request;
     request.sourceFilePath = "test_source_file_name";
     request.destinationFilePath = "test_destination_file_name";
-    TranscodingJobParcel job;
+    TranscodingSessionParcel session;
     bool result;
-    EXPECT_TRUE(mClient1->submitRequest(request, &job, &result).isOk());
+    EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
     EXPECT_TRUE(result);
-    EXPECT_EQ(job.jobId, JOB(0));
+    EXPECT_EQ(session.sessionId, SESSION(0));
 
-    mScheduler->finishLastJob();
-    EXPECT_EQ(mClientCallback1->popEvent(), TestClientCallback::Finished(job.jobId));
+    mController->finishLastSession();
+    EXPECT_EQ(mClientCallback1->popEvent(), TestClientCallback::Finished(session.sessionId));
 
-    EXPECT_TRUE(mClient1->submitRequest(request, &job, &result).isOk());
+    EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
     EXPECT_TRUE(result);
-    EXPECT_EQ(job.jobId, JOB(1));
+    EXPECT_EQ(session.sessionId, SESSION(1));
 
-    mScheduler->abortLastJob();
-    EXPECT_EQ(mClientCallback1->popEvent(), TestClientCallback::Failed(job.jobId));
+    mController->abortLastSession();
+    EXPECT_EQ(mClientCallback1->popEvent(), TestClientCallback::Failed(session.sessionId));
 
-    EXPECT_TRUE(mClient1->submitRequest(request, &job, &result).isOk());
+    EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
     EXPECT_TRUE(result);
-    EXPECT_EQ(job.jobId, JOB(2));
+    EXPECT_EQ(session.sessionId, SESSION(2));
 
-    EXPECT_TRUE(mClient2->submitRequest(request, &job, &result).isOk());
+    EXPECT_TRUE(mClient2->submitRequest(request, &session, &result).isOk());
     EXPECT_TRUE(result);
-    EXPECT_EQ(job.jobId, JOB(0));
+    EXPECT_EQ(session.sessionId, SESSION(0));
 
-    mScheduler->finishLastJob();
-    EXPECT_EQ(mClientCallback2->popEvent(), TestClientCallback::Finished(job.jobId));
+    mController->finishLastSession();
+    EXPECT_EQ(mClientCallback2->popEvent(), TestClientCallback::Finished(session.sessionId));
 
     unregisterMultipleClients();
 }
@@ -479,20 +481,20 @@
 
     // Submit 2 requests, 1 offline and 1 realtime.
     TranscodingRequestParcel request;
-    TranscodingJobParcel job;
+    TranscodingSessionParcel session;
     bool result;
 
     request.sourceFilePath = "test_source_file_0";
     request.destinationFilePath = "test_destination_file_0";
-    request.priority = TranscodingJobPriority::kUnspecified;
-    EXPECT_TRUE(client->submitRequest(request, &job, &result).isOk() && result);
-    EXPECT_EQ(job.jobId, JOB(0));
+    request.priority = TranscodingSessionPriority::kUnspecified;
+    EXPECT_TRUE(client->submitRequest(request, &session, &result).isOk() && result);
+    EXPECT_EQ(session.sessionId, SESSION(0));
 
     request.sourceFilePath = "test_source_file_1";
     request.destinationFilePath = "test_destination_file_1";
-    request.priority = TranscodingJobPriority::kNormal;
-    EXPECT_TRUE(client->submitRequest(request, &job, &result).isOk() && result);
-    EXPECT_EQ(job.jobId, JOB(1));
+    request.priority = TranscodingSessionPriority::kNormal;
+    EXPECT_TRUE(client->submitRequest(request, &session, &result).isOk() && result);
+    EXPECT_EQ(session.sessionId, SESSION(1));
 
     // Unregister client, should succeed.
     Status status = client->unregister();
@@ -501,36 +503,36 @@
     // Test submit new request after unregister, should fail with ERROR_DISCONNECTED.
     request.sourceFilePath = "test_source_file_2";
     request.destinationFilePath = "test_destination_file_2";
-    request.priority = TranscodingJobPriority::kNormal;
-    status = client->submitRequest(request, &job, &result);
+    request.priority = TranscodingSessionPriority::kNormal;
+    status = client->submitRequest(request, &session, &result);
     EXPECT_FALSE(status.isOk());
     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
 
-    // Test cancel jobs after unregister, should fail with ERROR_DISCONNECTED
-    // regardless of realtime or offline job, or whether the jobId is valid.
-    status = client->cancelJob(JOB(0), &result);
+    // Test cancel sessions after unregister, should fail with ERROR_DISCONNECTED
+    // regardless of realtime or offline session, or whether the sessionId is valid.
+    status = client->cancelSession(SESSION(0), &result);
     EXPECT_FALSE(status.isOk());
     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
 
-    status = client->cancelJob(JOB(1), &result);
+    status = client->cancelSession(SESSION(1), &result);
     EXPECT_FALSE(status.isOk());
     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
 
-    status = client->cancelJob(JOB(2), &result);
+    status = client->cancelSession(SESSION(2), &result);
     EXPECT_FALSE(status.isOk());
     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
 
-    // Test get jobs, should fail with ERROR_DISCONNECTED regardless of realtime
-    // or offline job, or whether the jobId is valid.
-    status = client->getJobWithId(JOB(0), &job, &result);
+    // Test get sessions, should fail with ERROR_DISCONNECTED regardless of realtime
+    // or offline session, or whether the sessionId is valid.
+    status = client->getSessionWithId(SESSION(0), &session, &result);
     EXPECT_FALSE(status.isOk());
     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
 
-    status = client->getJobWithId(JOB(1), &job, &result);
+    status = client->getSessionWithId(SESSION(1), &session, &result);
     EXPECT_FALSE(status.isOk());
     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
 
-    status = client->getJobWithId(JOB(2), &job, &result);
+    status = client->getSessionWithId(SESSION(2), &session, &result);
     EXPECT_FALSE(status.isOk());
     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
 }
diff --git a/media/libmediatranscoding/tests/TranscodingJobScheduler_tests.cpp b/media/libmediatranscoding/tests/TranscodingJobScheduler_tests.cpp
deleted file mode 100644
index 9b9df87..0000000
--- a/media/libmediatranscoding/tests/TranscodingJobScheduler_tests.cpp
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Unit Test for TranscodingJobScheduler
-
-// #define LOG_NDEBUG 0
-#define LOG_TAG "TranscodingJobSchedulerTest"
-
-#include <aidl/android/media/BnTranscodingClientCallback.h>
-#include <aidl/android/media/IMediaTranscodingService.h>
-#include <aidl/android/media/ITranscodingClient.h>
-#include <aidl/android/media/ITranscodingClientCallback.h>
-#include <android-base/logging.h>
-#include <android/binder_manager.h>
-#include <android/binder_process.h>
-#include <gtest/gtest.h>
-#include <media/TranscodingClientManager.h>
-#include <media/TranscodingJobScheduler.h>
-#include <utils/Log.h>
-
-#include <unordered_set>
-
-namespace android {
-
-using Status = ::ndk::ScopedAStatus;
-using aidl::android::media::BnTranscodingClientCallback;
-using aidl::android::media::IMediaTranscodingService;
-using aidl::android::media::ITranscodingClient;
-using aidl::android::media::TranscodingRequestParcel;
-
-constexpr ClientIdType kClientId = 1000;
-constexpr JobIdType kClientJobId = 0;
-constexpr uid_t kClientUid = 5000;
-constexpr uid_t kInvalidUid = (uid_t)-1;
-
-#define CLIENT(n) (kClientId + (n))
-#define JOB(n) (kClientJobId + (n))
-#define UID(n) (kClientUid + (n))
-
-class TestUidPolicy : public UidPolicyInterface {
-public:
-    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 setCallback(const std::shared_ptr<TranscoderCallbackInterface>& /*cb*/) override {}
-
-    void start(ClientIdType clientId, JobIdType jobId, const TranscodingRequestParcel& /*request*/,
-               const std::shared_ptr<ITranscodingClientCallback>& /*clientCallback*/) override {
-        mEventQueue.push_back(Start(clientId, jobId));
-    }
-    void pause(ClientIdType clientId, JobIdType jobId) override {
-        mEventQueue.push_back(Pause(clientId, jobId));
-    }
-    void resume(ClientIdType clientId, JobIdType jobId, const TranscodingRequestParcel& /*request*/,
-                const std::shared_ptr<ITranscodingClientCallback>& /*clientCallback*/) override {
-        mEventQueue.push_back(Resume(clientId, jobId));
-    }
-    void stop(ClientIdType clientId, JobIdType jobId) override {
-        mEventQueue.push_back(Stop(clientId, jobId));
-    }
-
-    void onFinished(ClientIdType clientId, JobIdType jobId) {
-        mEventQueue.push_back(Finished(clientId, jobId));
-    }
-
-    void onFailed(ClientIdType clientId, JobIdType jobId, TranscodingErrorCode err) {
-        mLastError = err;
-        mEventQueue.push_back(Failed(clientId, jobId));
-    }
-
-    TranscodingErrorCode getLastError() {
-        TranscodingErrorCode result = mLastError;
-        mLastError = TranscodingErrorCode::kUnknown;
-        return result;
-    }
-
-    struct Event {
-        enum { NoEvent, Start, Pause, Resume, Stop, Finished, Failed } type;
-        ClientIdType clientId;
-        JobIdType jobId;
-    };
-
-    static constexpr Event NoEvent = {Event::NoEvent, 0, 0};
-
-#define DECLARE_EVENT(action)                                     \
-    static Event action(ClientIdType clientId, JobIdType jobId) { \
-        return {Event::action, clientId, jobId};                  \
-    }
-
-    DECLARE_EVENT(Start);
-    DECLARE_EVENT(Pause);
-    DECLARE_EVENT(Resume);
-    DECLARE_EVENT(Stop);
-    DECLARE_EVENT(Finished);
-    DECLARE_EVENT(Failed);
-
-    const Event& popEvent() {
-        if (mEventQueue.empty()) {
-            mPoppedEvent = NoEvent;
-        } else {
-            mPoppedEvent = *mEventQueue.begin();
-            mEventQueue.pop_front();
-        }
-        return mPoppedEvent;
-    }
-
-private:
-    Event mPoppedEvent;
-    std::list<Event> mEventQueue;
-    TranscodingErrorCode mLastError;
-};
-
-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(TestTranscoder* owner, int64_t clientId)
-          : mOwner(owner), mClientId(clientId) {
-        ALOGD("TestClient Created");
-    }
-
-    Status openFileDescriptor(const std::string& /*in_fileUri*/, const std::string& /*in_mode*/,
-                              ::ndk::ScopedFileDescriptor* /*_aidl_return*/) override {
-        return Status::ok();
-    }
-
-    Status onTranscodingStarted(int32_t /*in_jobId*/) override { return Status::ok(); }
-
-    Status onTranscodingPaused(int32_t /*in_jobId*/) override { return Status::ok(); }
-
-    Status onTranscodingResumed(int32_t /*in_jobId*/) override { return Status::ok(); }
-
-    Status onTranscodingFinished(int32_t in_jobId,
-                                 const TranscodingResultParcel& in_result) override {
-        EXPECT_EQ(in_jobId, in_result.jobId);
-        ALOGD("TestClientCallback: received onTranscodingFinished");
-        mOwner->onFinished(mClientId, in_jobId);
-        return Status::ok();
-    }
-
-    Status onTranscodingFailed(int32_t in_jobId, TranscodingErrorCode in_errorCode) override {
-        mOwner->onFailed(mClientId, in_jobId, in_errorCode);
-        return Status::ok();
-    }
-
-    Status onAwaitNumberOfJobsChanged(int32_t /* in_jobId */, int32_t /* in_oldAwaitNumber */,
-                                      int32_t /* in_newAwaitNumber */) override {
-        return Status::ok();
-    }
-
-    Status onProgressUpdate(int32_t /* in_jobId */, int32_t /* in_progress */) override {
-        return Status::ok();
-    }
-
-    virtual ~TestClientCallback() { ALOGI("TestClient destroyed"); };
-
-private:
-    TestTranscoder* mOwner;
-    int64_t mClientId;
-    TestClientCallback(const TestClientCallback&) = delete;
-    TestClientCallback& operator=(const TestClientCallback&) = delete;
-};
-
-class TranscodingJobSchedulerTest : public ::testing::Test {
-public:
-    TranscodingJobSchedulerTest() { ALOGI("TranscodingJobSchedulerTest created"); }
-
-    void SetUp() override {
-        ALOGI("TranscodingJobSchedulerTest set up");
-        mTranscoder.reset(new TestTranscoder());
-        mUidPolicy.reset(new TestUidPolicy());
-        mScheduler.reset(
-                new TranscodingJobScheduler(mTranscoder, mUidPolicy, nullptr /*resourcePolicy*/));
-        mUidPolicy->setCallback(mScheduler);
-
-        // Set priority only, ignore other fields for now.
-        mOfflineRequest.priority = TranscodingJobPriority::kUnspecified;
-        mRealtimeRequest.priority = TranscodingJobPriority::kHigh;
-        mClientCallback0 =
-                ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(0));
-        mClientCallback1 =
-                ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(1));
-        mClientCallback2 =
-                ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(2));
-        mClientCallback3 =
-                ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(3));
-    }
-
-    void TearDown() override { ALOGI("TranscodingJobSchedulerTest tear down"); }
-
-    ~TranscodingJobSchedulerTest() { ALOGD("TranscodingJobSchedulerTest destroyed"); }
-
-    std::shared_ptr<TestTranscoder> mTranscoder;
-    std::shared_ptr<TestUidPolicy> mUidPolicy;
-    std::shared_ptr<TranscodingJobScheduler> mScheduler;
-    TranscodingRequestParcel mOfflineRequest;
-    TranscodingRequestParcel mRealtimeRequest;
-    std::shared_ptr<TestClientCallback> mClientCallback0;
-    std::shared_ptr<TestClientCallback> mClientCallback1;
-    std::shared_ptr<TestClientCallback> mClientCallback2;
-    std::shared_ptr<TestClientCallback> mClientCallback3;
-};
-
-TEST_F(TranscodingJobSchedulerTest, TestSubmitJob) {
-    ALOGD("TestSubmitJob");
-
-    // Start with UID(1) on top.
-    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(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(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(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(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 (has been) top.
-    mScheduler->submit(CLIENT(2), JOB(0), UID(1), mRealtimeRequest, mClientCallback2);
-    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(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Bring UID(0) to top.
-    mUidPolicy->setTop(UID(0));
-    // Should pause current job, and resume last job in UID(0).
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), JOB(0)));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), JOB(1)));
-}
-
-TEST_F(TranscodingJobSchedulerTest, TestCancelJob) {
-    ALOGD("TestCancelJob");
-
-    // Submit real-time job JOB(0), should start immediately.
-    mScheduler->submit(CLIENT(0), JOB(0), UID(0), mRealtimeRequest, mClientCallback0);
-    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(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Submit offline job JOB(2), should not start.
-    mScheduler->submit(CLIENT(0), JOB(2), UID(0), mOfflineRequest, mClientCallback0);
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Cancel queued real-time job.
-    // Cancel real-time job JOB(1), should be cancelled.
-    EXPECT_TRUE(mScheduler->cancel(CLIENT(0), JOB(1)));
-
-    // Cancel queued offline job.
-    // Cancel offline job JOB(2), should be cancelled.
-    EXPECT_TRUE(mScheduler->cancel(CLIENT(0), JOB(2)));
-
-    // Submit offline job JOB(3), shouldn't cause any event.
-    mScheduler->submit(CLIENT(0), JOB(3), UID(0), mOfflineRequest, mClientCallback0);
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Cancel running real-time job JOB(0).
-    // - Should be stopped 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(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), JOB(0)));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(3)));
-
-    // Submit real-time job JOB(4), offline JOB(3) should pause and JOB(4) should start.
-    mScheduler->submit(CLIENT(0), JOB(4), UID(0), mRealtimeRequest, mClientCallback0);
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(3)));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(4)));
-
-    // Cancel paused JOB(3). JOB(3) should be stopped.
-    EXPECT_TRUE(mScheduler->cancel(CLIENT(0), JOB(3)));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), JOB(3)));
-}
-
-TEST_F(TranscodingJobSchedulerTest, TestFinishJob) {
-    ALOGD("TestFinishJob");
-
-    // Start with unspecified top UID.
-    // Finish without any jobs submitted, should be ignored.
-    mScheduler->onFinish(CLIENT(0), JOB(0));
-    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(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(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(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Finish when the job never started, should be ignored.
-    mScheduler->onFinish(CLIENT(0), JOB(2));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // UID(1) moves to top.
-    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(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(1)));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), JOB(0)));
-
-    // 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(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), JOB(1)));
-
-    // Finish running real-time job, should start next real-time job in queue.
-    mScheduler->onFinish(CLIENT(1), JOB(0));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(1), JOB(0)));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), JOB(2)));
-
-    // Finish running real-time job, should resume next job (offline job) in queue.
-    mScheduler->onFinish(CLIENT(0), JOB(2));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), JOB(2)));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), JOB(0)));
-
-    // Finish running offline job.
-    mScheduler->onFinish(CLIENT(0), JOB(0));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), JOB(0)));
-
-    // Duplicate finish for last job, should be ignored.
-    mScheduler->onFinish(CLIENT(0), JOB(0));
-    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(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Submit offline job JOB(0), should start immediately.
-    mScheduler->submit(CLIENT(0), JOB(0), UID(0), mOfflineRequest, mClientCallback0);
-    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(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(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Fail when the job never started, should be ignored.
-    mScheduler->onError(CLIENT(0), JOB(2), TranscodingErrorCode::kUnknown);
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // UID(1) moves to top.
-    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(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(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(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(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::kInvalidOperation);
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), JOB(0)));
-    EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kInvalidOperation);
-
-    // Duplicate fail for last job, should be ignored.
-    mScheduler->onError(CLIENT(0), JOB(0), TranscodingErrorCode::kUnknown);
-    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(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);
-
-    // Move UID(1) to top.
-    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(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), JOB(0)));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), JOB(0)));
-
-    // 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 should resume.
-    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, 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(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);
-
-    // Move UID(1) to top.
-    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(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(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Signal resource available, CLIENT(2) should resume.
-    mScheduler->onResourceAvailable();
-    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(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Move UID(0) back to top, should have no resume due to no resource.
-    mUidPolicy->setTop(UID(0));
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Signal resource available, CLIENT(0) should resume.
-    mScheduler->onResourceAvailable();
-    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(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Move UID(2) to top.
-    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(mTranscoder->popEvent(), TestTranscoder::NoEvent);
-
-    // Signal resource available, CLIENT(3)'s job should start.
-    mScheduler->onResourceAvailable();
-    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), JOB(0)));
-}
-
-}  // namespace android
diff --git a/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp b/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
new file mode 100644
index 0000000..4809d7a
--- /dev/null
+++ b/media/libmediatranscoding/tests/TranscodingSessionController_tests.cpp
@@ -0,0 +1,611 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Unit Test for TranscodingSessionController
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "TranscodingSessionControllerTest"
+
+#include <aidl/android/media/BnTranscodingClientCallback.h>
+#include <aidl/android/media/IMediaTranscodingService.h>
+#include <aidl/android/media/ITranscodingClient.h>
+#include <aidl/android/media/ITranscodingClientCallback.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+#include <media/TranscodingClientManager.h>
+#include <media/TranscodingSessionController.h>
+#include <utils/Log.h>
+
+#include <unordered_set>
+
+namespace android {
+
+using Status = ::ndk::ScopedAStatus;
+using aidl::android::media::BnTranscodingClientCallback;
+using aidl::android::media::IMediaTranscodingService;
+using aidl::android::media::ITranscodingClient;
+using aidl::android::media::TranscodingRequestParcel;
+
+constexpr ClientIdType kClientId = 1000;
+constexpr SessionIdType kClientSessionId = 0;
+constexpr uid_t kClientUid = 5000;
+constexpr uid_t kInvalidUid = (uid_t)-1;
+
+#define CLIENT(n) (kClientId + (n))
+#define SESSION(n) (kClientSessionId + (n))
+#define UID(n) (kClientUid + (n))
+
+class TestUidPolicy : public UidPolicyInterface {
+public:
+    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 setCallback(const std::shared_ptr<TranscoderCallbackInterface>& /*cb*/) override {}
+
+    void start(ClientIdType clientId, SessionIdType sessionId,
+               const TranscodingRequestParcel& /*request*/,
+               const std::shared_ptr<ITranscodingClientCallback>& /*clientCallback*/) override {
+        mEventQueue.push_back(Start(clientId, sessionId));
+    }
+    void pause(ClientIdType clientId, SessionIdType sessionId) override {
+        mEventQueue.push_back(Pause(clientId, sessionId));
+    }
+    void resume(ClientIdType clientId, SessionIdType sessionId,
+                const TranscodingRequestParcel& /*request*/,
+                const std::shared_ptr<ITranscodingClientCallback>& /*clientCallback*/) override {
+        mEventQueue.push_back(Resume(clientId, sessionId));
+    }
+    void stop(ClientIdType clientId, SessionIdType sessionId) override {
+        mEventQueue.push_back(Stop(clientId, sessionId));
+    }
+
+    void onFinished(ClientIdType clientId, SessionIdType sessionId) {
+        mEventQueue.push_back(Finished(clientId, sessionId));
+    }
+
+    void onFailed(ClientIdType clientId, SessionIdType sessionId, TranscodingErrorCode err) {
+        mLastError = err;
+        mEventQueue.push_back(Failed(clientId, sessionId));
+    }
+
+    TranscodingErrorCode getLastError() {
+        TranscodingErrorCode result = mLastError;
+        mLastError = TranscodingErrorCode::kUnknown;
+        return result;
+    }
+
+    struct Event {
+        enum { NoEvent, Start, Pause, Resume, Stop, Finished, Failed } type;
+        ClientIdType clientId;
+        SessionIdType sessionId;
+    };
+
+    static constexpr Event NoEvent = {Event::NoEvent, 0, 0};
+
+#define DECLARE_EVENT(action)                                             \
+    static Event action(ClientIdType clientId, SessionIdType sessionId) { \
+        return {Event::action, clientId, sessionId};                      \
+    }
+
+    DECLARE_EVENT(Start);
+    DECLARE_EVENT(Pause);
+    DECLARE_EVENT(Resume);
+    DECLARE_EVENT(Stop);
+    DECLARE_EVENT(Finished);
+    DECLARE_EVENT(Failed);
+
+    const Event& popEvent() {
+        if (mEventQueue.empty()) {
+            mPoppedEvent = NoEvent;
+        } else {
+            mPoppedEvent = *mEventQueue.begin();
+            mEventQueue.pop_front();
+        }
+        return mPoppedEvent;
+    }
+
+private:
+    Event mPoppedEvent;
+    std::list<Event> mEventQueue;
+    TranscodingErrorCode mLastError;
+};
+
+bool operator==(const TestTranscoder::Event& lhs, const TestTranscoder::Event& rhs) {
+    return lhs.type == rhs.type && lhs.clientId == rhs.clientId && lhs.sessionId == rhs.sessionId;
+}
+
+struct TestClientCallback : public BnTranscodingClientCallback {
+    TestClientCallback(TestTranscoder* owner, int64_t clientId)
+          : mOwner(owner), mClientId(clientId) {
+        ALOGD("TestClient Created");
+    }
+
+    Status openFileDescriptor(const std::string& /*in_fileUri*/, const std::string& /*in_mode*/,
+                              ::ndk::ScopedFileDescriptor* /*_aidl_return*/) override {
+        return Status::ok();
+    }
+
+    Status onTranscodingStarted(int32_t /*in_sessionId*/) override { return Status::ok(); }
+
+    Status onTranscodingPaused(int32_t /*in_sessionId*/) override { return Status::ok(); }
+
+    Status onTranscodingResumed(int32_t /*in_sessionId*/) override { return Status::ok(); }
+
+    Status onTranscodingFinished(int32_t in_sessionId,
+                                 const TranscodingResultParcel& in_result) override {
+        EXPECT_EQ(in_sessionId, in_result.sessionId);
+        ALOGD("TestClientCallback: received onTranscodingFinished");
+        mOwner->onFinished(mClientId, in_sessionId);
+        return Status::ok();
+    }
+
+    Status onTranscodingFailed(int32_t in_sessionId, TranscodingErrorCode in_errorCode) override {
+        mOwner->onFailed(mClientId, in_sessionId, in_errorCode);
+        return Status::ok();
+    }
+
+    Status onAwaitNumberOfSessionsChanged(int32_t /* in_sessionId */,
+                                          int32_t /* in_oldAwaitNumber */,
+                                          int32_t /* in_newAwaitNumber */) override {
+        return Status::ok();
+    }
+
+    Status onProgressUpdate(int32_t /* in_sessionId */, int32_t /* in_progress */) override {
+        return Status::ok();
+    }
+
+    virtual ~TestClientCallback() { ALOGI("TestClient destroyed"); };
+
+private:
+    TestTranscoder* mOwner;
+    int64_t mClientId;
+    TestClientCallback(const TestClientCallback&) = delete;
+    TestClientCallback& operator=(const TestClientCallback&) = delete;
+};
+
+class TranscodingSessionControllerTest : public ::testing::Test {
+public:
+    TranscodingSessionControllerTest() { ALOGI("TranscodingSessionControllerTest created"); }
+
+    void SetUp() override {
+        ALOGI("TranscodingSessionControllerTest set up");
+        mTranscoder.reset(new TestTranscoder());
+        mUidPolicy.reset(new TestUidPolicy());
+        mController.reset(new TranscodingSessionController(mTranscoder, mUidPolicy,
+                                                           nullptr /*resourcePolicy*/));
+        mUidPolicy->setCallback(mController);
+
+        // Set priority only, ignore other fields for now.
+        mOfflineRequest.priority = TranscodingSessionPriority::kUnspecified;
+        mRealtimeRequest.priority = TranscodingSessionPriority::kHigh;
+        mClientCallback0 =
+                ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(0));
+        mClientCallback1 =
+                ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(1));
+        mClientCallback2 =
+                ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(2));
+        mClientCallback3 =
+                ::ndk::SharedRefBase::make<TestClientCallback>(mTranscoder.get(), CLIENT(3));
+    }
+
+    void TearDown() override { ALOGI("TranscodingSessionControllerTest tear down"); }
+
+    ~TranscodingSessionControllerTest() { ALOGD("TranscodingSessionControllerTest destroyed"); }
+
+    std::shared_ptr<TestTranscoder> mTranscoder;
+    std::shared_ptr<TestUidPolicy> mUidPolicy;
+    std::shared_ptr<TranscodingSessionController> mController;
+    TranscodingRequestParcel mOfflineRequest;
+    TranscodingRequestParcel mRealtimeRequest;
+    std::shared_ptr<TestClientCallback> mClientCallback0;
+    std::shared_ptr<TestClientCallback> mClientCallback1;
+    std::shared_ptr<TestClientCallback> mClientCallback2;
+    std::shared_ptr<TestClientCallback> mClientCallback3;
+};
+
+TEST_F(TranscodingSessionControllerTest, TestSubmitSession) {
+    ALOGD("TestSubmitSession");
+
+    // Start with UID(1) on top.
+    mUidPolicy->setTop(UID(1));
+
+    // Submit offline session to CLIENT(0) in UID(0).
+    // Should start immediately (because this is the only session).
+    mController->submit(CLIENT(0), SESSION(0), UID(0), mOfflineRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), 0));
+
+    // Submit real-time session to CLIENT(0).
+    // Should pause offline session and start new session,  even if UID(0) is not on top.
+    mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
+
+    // Submit real-time session to CLIENT(0), should be queued after the previous session.
+    mController->submit(CLIENT(0), SESSION(2), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Submit real-time session to CLIENT(1) in same uid, should be queued after the previous
+    // session.
+    mController->submit(CLIENT(1), SESSION(0), UID(0), mRealtimeRequest, mClientCallback1);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Submit real-time session to CLIENT(2) in UID(1).
+    // Should pause previous session and start new session, because UID(1) is (has been) top.
+    mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
+
+    // Submit offline session, shouldn't generate any event.
+    mController->submit(CLIENT(2), SESSION(1), UID(1), mOfflineRequest, mClientCallback2);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Bring UID(0) to top.
+    mUidPolicy->setTop(UID(0));
+    // Should pause current session, and resume last session in UID(0).
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(1)));
+}
+
+TEST_F(TranscodingSessionControllerTest, TestCancelSession) {
+    ALOGD("TestCancelSession");
+
+    // Submit real-time session SESSION(0), should start immediately.
+    mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
+
+    // Submit real-time session SESSION(1), should not start.
+    mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Submit offline session SESSION(2), should not start.
+    mController->submit(CLIENT(0), SESSION(2), UID(0), mOfflineRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Cancel queued real-time session.
+    // Cancel real-time session SESSION(1), should be cancelled.
+    EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(1)));
+
+    // Cancel queued offline session.
+    // Cancel offline session SESSION(2), should be cancelled.
+    EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(2)));
+
+    // Submit offline session SESSION(3), shouldn't cause any event.
+    mController->submit(CLIENT(0), SESSION(3), UID(0), mOfflineRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Cancel running real-time session SESSION(0).
+    // - Should be stopped first then cancelled.
+    // - Should also start offline session SESSION(2) because real-time queue is empty.
+    EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(3)));
+
+    // Submit real-time session SESSION(4), offline SESSION(3) should pause and SESSION(4)
+    // should start.
+    mController->submit(CLIENT(0), SESSION(4), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(3)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(4)));
+
+    // Cancel paused SESSION(3). SESSION(3) should be stopped.
+    EXPECT_TRUE(mController->cancel(CLIENT(0), SESSION(3)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Stop(CLIENT(0), SESSION(3)));
+}
+
+TEST_F(TranscodingSessionControllerTest, TestFinishSession) {
+    ALOGD("TestFinishSession");
+
+    // Start with unspecified top UID.
+    // Finish without any sessions submitted, should be ignored.
+    mController->onFinish(CLIENT(0), SESSION(0));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Submit offline session SESSION(0), should start immediately.
+    mController->submit(CLIENT(0), SESSION(0), UID(0), mOfflineRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
+
+    // Submit real-time session SESSION(1), should pause offline session and start immediately.
+    mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
+
+    // Submit real-time session SESSION(2), should not start.
+    mController->submit(CLIENT(0), SESSION(2), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Finish when the session never started, should be ignored.
+    mController->onFinish(CLIENT(0), SESSION(2));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // UID(1) moves to top.
+    mUidPolicy->setTop(UID(1));
+    // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
+    // new session.
+    mController->submit(CLIENT(1), SESSION(0), UID(1), mRealtimeRequest, mClientCallback1);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
+
+    // Simulate Finish that arrived late, after pause issued by controller.
+    // Should still be propagated to client, but shouldn't trigger any new start.
+    mController->onFinish(CLIENT(0), SESSION(1));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(1)));
+
+    // Finish running real-time session, should start next real-time session in queue.
+    mController->onFinish(CLIENT(1), SESSION(0));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(1), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
+
+    // Finish running real-time session, should resume next session (offline session) in queue.
+    mController->onFinish(CLIENT(0), SESSION(2));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(2)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
+
+    // Finish running offline session.
+    mController->onFinish(CLIENT(0), SESSION(0));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
+
+    // Duplicate finish for last session, should be ignored.
+    mController->onFinish(CLIENT(0), SESSION(0));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+}
+
+TEST_F(TranscodingSessionControllerTest, TestFailSession) {
+    ALOGD("TestFailSession");
+
+    // Start with unspecified top UID.
+    // Fail without any sessions submitted, should be ignored.
+    mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Submit offline session SESSION(0), should start immediately.
+    mController->submit(CLIENT(0), SESSION(0), UID(0), mOfflineRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
+
+    // Submit real-time session SESSION(1), should pause offline session and start immediately.
+    mController->submit(CLIENT(0), SESSION(1), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(1)));
+
+    // Submit real-time session SESSION(2), should not start.
+    mController->submit(CLIENT(0), SESSION(2), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Fail when the session never started, should be ignored.
+    mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // UID(1) moves to top.
+    mUidPolicy->setTop(UID(1));
+    // Submit real-time session to CLIENT(1) in UID(1), should pause previous session and start
+    // new session.
+    mController->submit(CLIENT(1), SESSION(0), UID(1), mRealtimeRequest, mClientCallback1);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(1)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
+
+    // Simulate Fail that arrived late, after pause issued by controller.
+    // Should still be propagated to client, but shouldn't trigger any new start.
+    mController->onError(CLIENT(0), SESSION(1), TranscodingErrorCode::kUnknown);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(1)));
+
+    // Fail running real-time session, should start next real-time session in queue.
+    mController->onError(CLIENT(1), SESSION(0), TranscodingErrorCode::kUnknown);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(1), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(2)));
+
+    // Fail running real-time session, should resume next session (offline session) in queue.
+    mController->onError(CLIENT(0), SESSION(2), TranscodingErrorCode::kUnknown);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(2)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
+
+    // Fail running offline session, and test error code propagation.
+    mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kInvalidOperation);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Failed(CLIENT(0), SESSION(0)));
+    EXPECT_EQ(mTranscoder->getLastError(), TranscodingErrorCode::kInvalidOperation);
+
+    // Duplicate fail for last session, should be ignored.
+    mController->onError(CLIENT(0), SESSION(0), TranscodingErrorCode::kUnknown);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+}
+
+TEST_F(TranscodingSessionControllerTest, TestTopUidChanged) {
+    ALOGD("TestTopUidChanged");
+
+    // Start with unspecified top UID.
+    // Submit real-time session to CLIENT(0), session should start immediately.
+    mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
+
+    // Submit offline session to CLIENT(0), should not start.
+    mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Move UID(1) to top.
+    mUidPolicy->setTop(UID(1));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Submit real-time session to CLIENT(2) in different uid UID(1).
+    // Should pause previous session and start new session.
+    mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
+
+    // Bring UID(0) back to top.
+    mUidPolicy->setTop(UID(0));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(2), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
+
+    // Bring invalid uid to top.
+    mUidPolicy->setTop(kInvalidUid);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Finish session, next real-time session should resume.
+    mController->onFinish(CLIENT(0), SESSION(0));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
+
+    // Finish session, offline session should start.
+    mController->onFinish(CLIENT(2), SESSION(0));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
+}
+
+TEST_F(TranscodingSessionControllerTest, TestTopUidSetChanged) {
+    ALOGD("TestTopUidChanged_MultipleUids");
+
+    // Start with unspecified top UID.
+    // Submit real-time session to CLIENT(0), session should start immediately.
+    mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
+
+    // Submit offline session to CLIENT(0), should not start.
+    mController->submit(CLIENT(1), SESSION(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 session to CLIENT(2) in different uid UID(1).
+    // UID(0) should pause and UID(1) should start.
+    mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(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), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
+
+    // Bring invalid uid to top.
+    mUidPolicy->setTop(kInvalidUid);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Finish session, next real-time session from UID(1) should resume, even if UID(1)
+    // no longer top.
+    mController->onFinish(CLIENT(0), SESSION(0));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(0), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
+
+    // Finish session, offline session should start.
+    mController->onFinish(CLIENT(2), SESSION(0));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Finished(CLIENT(2), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(1), SESSION(0)));
+}
+
+TEST_F(TranscodingSessionControllerTest, TestResourceLost) {
+    ALOGD("TestResourceLost");
+
+    // Start with unspecified top UID.
+    // Submit real-time session to CLIENT(0), session should start immediately.
+    mController->submit(CLIENT(0), SESSION(0), UID(0), mRealtimeRequest, mClientCallback0);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(0), SESSION(0)));
+
+    // Submit offline session to CLIENT(0), should not start.
+    mController->submit(CLIENT(1), SESSION(0), UID(0), mOfflineRequest, mClientCallback1);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Move UID(1) to top.
+    mUidPolicy->setTop(UID(1));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Submit real-time session to CLIENT(2) in different uid UID(1).
+    // Should pause previous session and start new session.
+    mController->submit(CLIENT(2), SESSION(0), UID(1), mRealtimeRequest, mClientCallback2);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Pause(CLIENT(0), SESSION(0)));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(2), SESSION(0)));
+
+    // Test 1: No queue change during resource loss.
+    // Signal resource lost.
+    mController->onResourceLost();
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Signal resource available, CLIENT(2) should resume.
+    mController->onResourceAvailable();
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(2), SESSION(0)));
+
+    // Test 2: Change of queue order during resource loss.
+    // Signal resource lost.
+    mController->onResourceLost();
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Move UID(0) back to top, should have no resume due to no resource.
+    mUidPolicy->setTop(UID(0));
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Signal resource available, CLIENT(0) should resume.
+    mController->onResourceAvailable();
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Resume(CLIENT(0), SESSION(0)));
+
+    // Test 3: Adding new queue during resource loss.
+    // Signal resource lost.
+    mController->onResourceLost();
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Move UID(2) to top.
+    mUidPolicy->setTop(UID(2));
+
+    // Submit real-time session to CLIENT(3) in UID(2), session shouldn't start due to no resource.
+    mController->submit(CLIENT(3), SESSION(0), UID(2), mRealtimeRequest, mClientCallback3);
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::NoEvent);
+
+    // Signal resource available, CLIENT(3)'s session should start.
+    mController->onResourceAvailable();
+    EXPECT_EQ(mTranscoder->popEvent(), TestTranscoder::Start(CLIENT(3), SESSION(0)));
+}
+
+}  // namespace android
diff --git a/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh b/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
index ff6df2c..5db9258 100644
--- a/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
+++ b/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
@@ -29,6 +29,6 @@
 #adb shell /data/nativetest64/AdjustableMaxPriorityQueue_tests/AdjustableMaxPriorityQueue_tests
 adb shell /data/nativetest/AdjustableMaxPriorityQueue_tests/AdjustableMaxPriorityQueue_tests
 
-echo "testing TranscodingJobScheduler"
-#adb shell /data/nativetest64/TranscodingJobScheduler_tests/TranscodingJobScheduler_tests
-adb shell /data/nativetest/TranscodingJobScheduler_tests/TranscodingJobScheduler_tests
+echo "testing TranscodingSessionController"
+#adb shell /data/nativetest64/TranscodingSessionController_tests/TranscodingSessionController_tests
+adb shell /data/nativetest/TranscodingSessionController_tests/TranscodingSessionController_tests