transcoding: separate client interface from service

Refactor AIDL to separate client interface from service.

Use client listener binder as unique id for client, as multiple
clients could exist for the same pid.

Misc unit testing changes.

bug: 145233472
test: mediatranscodingservice_test, TranscodingClientManager_tests
Change-Id: I8d9522da23163375df8df7822d0f6ae270cff1b4
diff --git a/media/libmediatranscoding/Android.bp b/media/libmediatranscoding/Android.bp
index 7468426..0f413ef 100644
--- a/media/libmediatranscoding/Android.bp
+++ b/media/libmediatranscoding/Android.bp
@@ -20,7 +20,8 @@
     local_include_dir: "aidl",
     srcs: [
         "aidl/android/media/IMediaTranscodingService.aidl",
-        "aidl/android/media/ITranscodingServiceClient.aidl",
+        "aidl/android/media/ITranscodingClient.aidl",
+        "aidl/android/media/ITranscodingClientListener.aidl",
         "aidl/android/media/TranscodingErrorCode.aidl",
         "aidl/android/media/TranscodingJobPriority.aidl",
         "aidl/android/media/TranscodingType.aidl",
diff --git a/media/libmediatranscoding/TranscodingClientManager.cpp b/media/libmediatranscoding/TranscodingClientManager.cpp
index 7252437..0f99983 100644
--- a/media/libmediatranscoding/TranscodingClientManager.cpp
+++ b/media/libmediatranscoding/TranscodingClientManager.cpp
@@ -17,13 +17,96 @@
 // #define LOG_NDEBUG 0
 #define LOG_TAG "TranscodingClientManager"
 
+#include <aidl/android/media/BnTranscodingClient.h>
+#include <android/binder_ibinder.h>
 #include <inttypes.h>
 #include <media/TranscodingClientManager.h>
 #include <utils/Log.h>
 
 namespace android {
 
+using ::aidl::android::media::BnTranscodingClient;
+using ::aidl::android::media::TranscodingJobParcel;
+using ::aidl::android::media::TranscodingRequestParcel;
 using Status = ::ndk::ScopedAStatus;
+using ::ndk::SpAIBinder;
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * ClientImpl implements a single client and contains all its information.
+ */
+struct TranscodingClientManager::ClientImpl : public BnTranscodingClient {
+    /* The remote client listener that this ClientInfo is associated with.
+     * Once the ClientInfo is created, we hold an SpAIBinder so that the binder
+     * object doesn't get created again, otherwise the binder object pointer
+     * may not be unique.
+     */
+    SpAIBinder mClientListener;
+    /* A unique id assigned to the client by the service. This number is used
+     * by the service for indexing. Here we use the binder object's pointer
+     * (casted to int64t_t) as the client id.
+     */
+    ClientIdType mClientId;
+    int32_t mClientPid;
+    int32_t mClientUid;
+    std::string mClientName;
+    std::string mClientOpPackageName;
+    TranscodingClientManager* mOwner;
+
+    ClientImpl(const std::shared_ptr<ITranscodingClientListener>& listener,
+               int32_t pid, int32_t uid,
+               const std::string& clientName,
+               const std::string& opPackageName,
+               TranscodingClientManager* owner);
+
+    Status submitRequest(const TranscodingRequestParcel& /*in_request*/,
+            TranscodingJobParcel* /*out_job*/, int32_t* /*_aidl_return*/) override;
+
+    Status cancelJob(int32_t /*in_jobId*/, bool* /*_aidl_return*/) override;
+
+    Status getJobWithId(int32_t /*in_jobId*/,
+            TranscodingJobParcel* /*out_job*/, bool* /*_aidl_return*/) override;
+
+    Status unregister() override;
+};
+
+TranscodingClientManager::ClientImpl::ClientImpl(
+        const std::shared_ptr<ITranscodingClientListener>& listener,
+        int32_t pid, int32_t uid,
+        const std::string& clientName,
+        const std::string& opPackageName,
+        TranscodingClientManager* owner)
+: mClientListener((listener != nullptr) ? listener->asBinder() : nullptr),
+  mClientId((int64_t)mClientListener.get()),
+  mClientPid(pid),
+  mClientUid(uid),
+  mClientName(clientName),
+  mClientOpPackageName(opPackageName),
+  mOwner(owner) {}
+
+Status TranscodingClientManager::ClientImpl::submitRequest(
+        const TranscodingRequestParcel& /*in_request*/,
+        TranscodingJobParcel* /*out_job*/, int32_t* /*_aidl_return*/) {
+    return Status::ok();
+}
+
+Status TranscodingClientManager::ClientImpl::cancelJob(
+        int32_t /*in_jobId*/, bool* /*_aidl_return*/) {
+    return Status::ok();
+}
+
+Status TranscodingClientManager::ClientImpl::getJobWithId(int32_t /*in_jobId*/,
+        TranscodingJobParcel* /*out_job*/, bool* /*_aidl_return*/) {
+    return Status::ok();
+}
+
+Status TranscodingClientManager::ClientImpl::unregister() {
+    mOwner->removeClient(mClientId);
+    return Status::ok();
+}
+
+///////////////////////////////////////////////////////////////////////////////
 
 // static
 TranscodingClientManager& TranscodingClientManager::getInstance() {
@@ -33,8 +116,8 @@
 
 // static
 void TranscodingClientManager::BinderDiedCallback(void* cookie) {
-    int32_t clientId = static_cast<int32_t>(reinterpret_cast<intptr_t>(cookie));
-    ALOGD("Client %" PRId32 " is dead", clientId);
+    ClientIdType clientId = static_cast<ClientIdType>(reinterpret_cast<intptr_t>(cookie));
+    ALOGD("Client %lld is dead", (long long) clientId);
     // Don't check for pid validity since we know it's already dead.
     TranscodingClientManager& manager = TranscodingClientManager::getInstance();
     manager.removeClient(clientId);
@@ -49,9 +132,8 @@
     ALOGD("TranscodingClientManager exited");
 }
 
-bool TranscodingClientManager::isClientIdRegistered(int32_t clientId) const {
-    std::scoped_lock lock{mLock};
-    return mClientIdToClientInfoMap.find(clientId) != mClientIdToClientInfoMap.end();
+bool TranscodingClientManager::isClientIdRegistered(ClientIdType clientId) const {
+    return mClientIdToClientMap.find(clientId) != mClientIdToClientMap.end();
 }
 
 void TranscodingClientManager::dumpAllClients(int fd, const Vector<String16>& args __unused) {
@@ -60,86 +142,95 @@
     const size_t SIZE = 256;
     char buffer[SIZE];
 
-    snprintf(buffer, SIZE, "    Total num of Clients: %zu\n", mClientIdToClientInfoMap.size());
+    snprintf(buffer, SIZE, "    Total num of Clients: %zu\n", mClientIdToClientMap.size());
     result.append(buffer);
 
-    if (mClientIdToClientInfoMap.size() > 0) {
+    if (mClientIdToClientMap.size() > 0) {
         snprintf(buffer, SIZE, "========== Dumping all clients =========\n");
         result.append(buffer);
     }
 
-    for (const auto& iter : mClientIdToClientInfoMap) {
-        const std::shared_ptr<ITranscodingServiceClient> client = iter.second->mClient;
-        std::string clientName;
-        Status status = client->getName(&clientName);
-        if (!status.isOk()) {
-            ALOGE("Failed to get client: %d information", iter.first);
-            continue;
-        }
-        snprintf(buffer, SIZE, "    -- Clients: %d  name: %s\n", iter.first, clientName.c_str());
+    for (const auto& iter : mClientIdToClientMap) {
+        snprintf(buffer, SIZE, "    -- Client id: %lld  name: %s\n",
+                (long long)iter.first, iter.second->mClientName.c_str());
         result.append(buffer);
     }
 
     write(fd, result.string(), result.size());
 }
 
-status_t TranscodingClientManager::addClient(std::unique_ptr<ClientInfo> client) {
+status_t TranscodingClientManager::addClient(
+        const std::shared_ptr<ITranscodingClientListener>& listener,
+        int32_t pid, int32_t uid,
+        const std::string& clientName,
+        const std::string& opPackageName,
+        std::shared_ptr<ITranscodingClient>* outClient) {
     // Validate the client.
-    if (client == nullptr || client->mClientId < 0 || client->mClientPid < 0 ||
-        client->mClientUid < 0 || client->mClientOpPackageName.empty() ||
-        client->mClientOpPackageName == "") {
+    if (listener == nullptr || pid < 0 || uid < 0 ||
+            clientName.empty() || opPackageName.empty()) {
         ALOGE("Invalid client");
         return BAD_VALUE;
     }
 
+    // Creates the client and uses its process id as client id.
+    std::shared_ptr<ClientImpl> client =
+            ::ndk::SharedRefBase::make<ClientImpl>(
+                    listener, pid, uid, clientName, opPackageName, this);
+
     std::scoped_lock lock{mLock};
 
-    // Check if the client already exists.
-    if (mClientIdToClientInfoMap.count(client->mClientId) != 0) {
-        ALOGW("Client already exists.");
+    // Checks if the client already registers.
+    if (isClientIdRegistered(client->mClientId)) {
         return ALREADY_EXISTS;
     }
 
-    ALOGD("Adding client id %d pid: %d uid: %d %s", client->mClientId, client->mClientPid,
-          client->mClientUid, client->mClientOpPackageName.c_str());
+    ALOGD("Adding client id %lld, pid %d, uid %d, name %s, package %s",
+            (long long)client->mClientId,
+            client->mClientPid,
+            client->mClientUid,
+            client->mClientName.c_str(),
+            client->mClientOpPackageName.c_str());
 
-    AIBinder_linkToDeath(client->mClient->asBinder().get(), mDeathRecipient.get(),
+    AIBinder_linkToDeath(client->mClientListener.get(), mDeathRecipient.get(),
                          reinterpret_cast<void*>(client->mClientId));
 
     // Adds the new client to the map.
-    mClientIdToClientInfoMap[client->mClientId] = std::move(client);
+    mClientIdToClientMap[client->mClientId] = client;
+
+    *outClient = client;
 
     return OK;
 }
 
-status_t TranscodingClientManager::removeClient(int32_t clientId) {
-    ALOGD("Removing client id %d", clientId);
+
+status_t TranscodingClientManager::removeClient(ClientIdType clientId) {
+    ALOGD("Removing client id %lld", (long long)clientId);
     std::scoped_lock lock{mLock};
 
     // Checks if the client is valid.
-    auto it = mClientIdToClientInfoMap.find(clientId);
-    if (it == mClientIdToClientInfoMap.end()) {
-        ALOGE("Client id %d does not exist", clientId);
+    auto it = mClientIdToClientMap.find(clientId);
+    if (it == mClientIdToClientMap.end()) {
+        ALOGE("Client id %lld does not exist", (long long)clientId);
         return INVALID_OPERATION;
     }
 
-    std::shared_ptr<ITranscodingServiceClient> client = it->second->mClient;
+    SpAIBinder listener = it->second->mClientListener;
 
     // Check if the client still live. If alive, unlink the death.
-    if (client) {
-        AIBinder_unlinkToDeath(client->asBinder().get(), mDeathRecipient.get(),
+    if (listener.get() != nullptr) {
+        AIBinder_unlinkToDeath(listener.get(), mDeathRecipient.get(),
                                reinterpret_cast<void*>(clientId));
     }
 
     // Erase the entry.
-    mClientIdToClientInfoMap.erase(it);
+    mClientIdToClientMap.erase(it);
 
     return OK;
 }
 
 size_t TranscodingClientManager::getNumOfClients() const {
     std::scoped_lock lock{mLock};
-    return mClientIdToClientInfoMap.size();
+    return mClientIdToClientMap.size();
 }
 
 }  // namespace android
diff --git a/media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl b/media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
index 07b6c1a..9888456 100644
--- a/media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
+++ b/media/libmediatranscoding/aidl/android/media/IMediaTranscodingService.aidl
@@ -16,9 +16,10 @@
 
 package android.media;
 
+import android.media.ITranscodingClient;
+import android.media.ITranscodingClientListener;
 import android.media.TranscodingJobParcel;
 import android.media.TranscodingRequestParcel;
-import android.media.ITranscodingServiceClient;
 
 /**
  * Binder interface for MediaTranscodingService.
@@ -48,64 +49,29 @@
     /**
      * Register the client with the MediaTranscodingService.
      *
-     * Client must call this function to register itself with the service in order to perform
-     * transcoding. This function will return a unique positive Id assigned by the service.
-     * Client should save this Id and use it for all the transaction with the service.
+     * Client must call this function to register itself with the service in
+     * order to perform transcoding tasks. This function will return an
+     * ITranscodingClient interface object. The client should save and use it
+     * for all future transactions with the service.
      *
-     * @param client interface for the MediaTranscodingService to call the client.
+     * @param listener client interface for the MediaTranscodingService to call
+     *        the client.
+     * @param clientName name of the client.
      * @param opPackageName op package name of the client.
      * @param clientUid user id of the client.
      * @param clientPid process id of the client.
-     * @return a unique positive Id assigned to the client by the service, -1  means failed to
-     * register.
+     * @return an ITranscodingClient interface object, with nullptr indicating
+     *         failure to register.
      */
-    int registerClient(in ITranscodingServiceClient client,
-                       in String opPackageName,
-                       in int clientUid,
-                       in int clientPid);
-
-    /**
-    * Unregister the client with the MediaTranscodingService.
-    *
-    * Client will not be able to perform any more transcoding after unregister.
-    *
-    * @param clientId assigned Id of the client.
-    * @return true if succeeds, false otherwise.
-    */
-    boolean unregisterClient(in int clientId);
+    ITranscodingClient registerClient(
+            in ITranscodingClientListener listener,
+            in String clientName,
+            in String opPackageName,
+            in int clientUid,
+            in int clientPid);
 
     /**
     * Returns the number of clients. This is used for debugging.
     */
     int getNumOfClients();
-
-    /**
-     * Submits a transcoding request to MediaTranscodingService.
-     *
-     * @param clientId assigned Id of the client.
-     * @param request a TranscodingRequest contains transcoding configuration.
-     * @param job(output variable) a TranscodingJob generated by the MediaTranscodingService.
-     * @return a unique positive jobId generated by the MediaTranscodingService, -1 means failure.
-     */
-    int submitRequest(in int clientId,
-                      in TranscodingRequestParcel request,
-                      out TranscodingJobParcel job);
-
-    /**
-     * Cancels a transcoding job.
-     *
-     * @param clientId assigned id of the client.
-     * @param jobId a TranscodingJob generated by the MediaTranscodingService.
-     * @return true if succeeds, false otherwise.
-     */
-    boolean cancelJob(in int clientId, in int jobId);
-
-    /**
-     * Queries the job detail associated with a jobId.
-     *
-     * @param jobId a TranscodingJob generated by the MediaTranscodingService.
-     * @param job(output variable) the TranscodingJob associated with the jobId.
-     * @return true if succeeds, false otherwise.
-     */
-    boolean getJobWithId(in int jobId, out TranscodingJobParcel job);
 }
diff --git a/media/libmediatranscoding/aidl/android/media/ITranscodingClient.aidl b/media/libmediatranscoding/aidl/android/media/ITranscodingClient.aidl
new file mode 100644
index 0000000..a3852c2
--- /dev/null
+++ b/media/libmediatranscoding/aidl/android/media/ITranscodingClient.aidl
@@ -0,0 +1,64 @@
+/**
+ * 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.
+ */
+
+package android.media;
+
+import android.media.TranscodingJobParcel;
+import android.media.TranscodingRequestParcel;
+
+/**
+ * ITranscodingClient
+ *
+ * Interface for a client to communicate with MediaTranscodingService.
+ *
+ * {@hide}
+ */
+interface ITranscodingClient {
+    /**
+     * Submits a transcoding request to MediaTranscodingService.
+     *
+     * @param request a TranscodingRequest contains transcoding configuration.
+     * @param job(output variable) a TranscodingJob generated by the MediaTranscodingService.
+     * @return a unique positive jobId for the client generated by the
+     *         MediaTranscodingService, -1 means failure.
+     */
+    int submitRequest(in TranscodingRequestParcel request,
+                      out TranscodingJobParcel job);
+
+    /**
+     * Cancels a transcoding job.
+     *
+     * @param jobId a TranscodingJob generated by the MediaTranscodingService.
+     * @return true if succeeds, false otherwise.
+     */
+    boolean cancelJob(in int jobId);
+
+    /**
+     * Queries the job detail associated with a jobId.
+     *
+     * @param jobId a TranscodingJob generated by the MediaTranscodingService.
+     * @param job(output variable) the TranscodingJob associated with the jobId.
+     * @return true if succeeds, false otherwise.
+     */
+    boolean getJobWithId(in int jobId, out TranscodingJobParcel job);
+
+    /**
+    * Unregister the client with the MediaTranscodingService.
+    *
+    * Client will not be able to perform any more transcoding after unregister.
+    */
+    void unregister();
+}
diff --git a/media/libmediatranscoding/aidl/android/media/ITranscodingServiceClient.aidl b/media/libmediatranscoding/aidl/android/media/ITranscodingClientListener.aidl
similarity index 90%
rename from media/libmediatranscoding/aidl/android/media/ITranscodingServiceClient.aidl
rename to media/libmediatranscoding/aidl/android/media/ITranscodingClientListener.aidl
index e23c833..a57bb54 100644
--- a/media/libmediatranscoding/aidl/android/media/ITranscodingServiceClient.aidl
+++ b/media/libmediatranscoding/aidl/android/media/ITranscodingClientListener.aidl
@@ -21,17 +21,13 @@
 import android.media.TranscodingResultParcel;
 
 /**
- * ITranscodingServiceClient interface for the MediaTranscodingervice to communicate with the
- * client.
+ * ITranscodingClientListener
+ *
+ * Interface for the MediaTranscodingService to communicate with the client.
  *
  * {@hide}
  */
-//TODO(hkuang): Implement the interface.
-interface ITranscodingServiceClient {
-    /**
-     * Retrieves the name of the client.
-     */
-    @utf8InCpp String getName();
+interface ITranscodingClientListener {
 
     /**
     * Called when the transcoding associated with the jobId finished.
diff --git a/media/libmediatranscoding/include/media/TranscodingClientManager.h b/media/libmediatranscoding/include/media/TranscodingClientManager.h
index eec120a..645e0a7 100644
--- a/media/libmediatranscoding/include/media/TranscodingClientManager.h
+++ b/media/libmediatranscoding/include/media/TranscodingClientManager.h
@@ -17,11 +17,10 @@
 #ifndef ANDROID_MEDIA_TRANSCODING_CLIENT_MANAGER_H
 #define ANDROID_MEDIA_TRANSCODING_CLIENT_MANAGER_H
 
-#include <aidl/android/media/BnTranscodingServiceClient.h>
-#include <android/binder_ibinder.h>
+#include <aidl/android/media/ITranscodingClient.h>
+#include <aidl/android/media/ITranscodingClientListener.h>
 #include <sys/types.h>
 #include <utils/Condition.h>
-#include <utils/RefBase.h>
 #include <utils/String8.h>
 #include <utils/Vector.h>
 
@@ -30,8 +29,8 @@
 
 namespace android {
 
-using ::aidl::android::media::ITranscodingServiceClient;
-
+using ::aidl::android::media::ITranscodingClient;
+using ::aidl::android::media::ITranscodingClientListener;
 class MediaTranscodingService;
 
 /*
@@ -46,44 +45,55 @@
  * TODO(hkuang): Hook up with MediaMetrics to log all the transactions.
  */
 class TranscodingClientManager {
-   public:
-    virtual ~TranscodingClientManager();
-
-    /**
-     * ClientInfo contains a single client's information.
-     */
-    struct ClientInfo {
-        /* The remote client that this ClientInfo is associated with. */
-        std::shared_ptr<ITranscodingServiceClient> mClient;
-        /* A unique positive Id assigned to the client by the service. */
-        int32_t mClientId;
-        /* Process id of the client */
-        int32_t mClientPid;
-        /* User id of the client. */
-        int32_t mClientUid;
-        /* Package name of the client. */
-        std::string mClientOpPackageName;
-
-        ClientInfo(const std::shared_ptr<ITranscodingServiceClient>& client, int64_t clientId,
-                   int32_t pid, int32_t uid, const std::string& opPackageName)
-            : mClient(client),
-              mClientId(clientId),
-              mClientPid(pid),
-              mClientUid(uid),
-              mClientOpPackageName(opPackageName) {}
-    };
+public:
 
     /**
      * Adds a new client to the manager.
      *
-     * The client must have valid clientId, pid, uid and opPackageName, otherwise, this will return
-     * a non-zero errorcode. If the client has already been added, it will also return non-zero
-     * errorcode.
+     * The client must have valid listener, pid, uid, clientName and opPackageName.
+     * Otherwise, this will return a non-zero errorcode. If the client listener has
+     * already been added, it will also return non-zero errorcode.
      *
-     * @param client to be added to the manager.
+     * @param listener client listener for the service to call this client.
+     * @param pid client's process id.
+     * @param uid client's user id.
+     * @param clientName client's name.
+     * @param opPackageName client's package name.
+     * @param client output holding the ITranscodingClient interface for the client
+     *        to use for subsequent communications with the service.
      * @return 0 if client is added successfully, non-zero errorcode otherwise.
      */
-    status_t addClient(std::unique_ptr<ClientInfo> client);
+    status_t addClient(
+            const std::shared_ptr<ITranscodingClientListener>& listener,
+            int32_t pid, int32_t uid,
+            const std::string& clientName,
+            const std::string& opPackageName,
+            std::shared_ptr<ITranscodingClient>* client);
+
+    /**
+     * Gets the number of clients.
+     */
+    size_t getNumOfClients() const;
+
+    /**
+     * Dump all the client information to the fd.
+     */
+    void dumpAllClients(int fd, const Vector<String16>& args);
+
+private:
+    friend class MediaTranscodingService;
+    friend class TranscodingClientManagerTest;
+
+    typedef int64_t ClientIdType;
+    struct ClientImpl;
+
+    TranscodingClientManager();
+    virtual ~TranscodingClientManager();
+
+    /**
+     * Checks if a client with clientId is already registered.
+     */
+    bool isClientIdRegistered(ClientIdType clientId) const;
 
     /**
      * Removes an existing client from the manager.
@@ -93,36 +103,15 @@
      * @param clientId id of the client to be removed..
      * @return 0 if client is removed successfully, non-zero errorcode otherwise.
      */
-    status_t removeClient(int32_t clientId);
-
-    /**
-     * Gets the number of clients.
-     */
-    size_t getNumOfClients() const;
-
-    /**
-     * Checks if a client with clientId is already registered.
-     */
-    bool isClientIdRegistered(int32_t clientId) const;
-
-    /**
-     * Dump all the client information to the fd.
-     */
-    void dumpAllClients(int fd, const Vector<String16>& args);
-
-   private:
-    friend class MediaTranscodingService;
-    friend class TranscodingClientManagerTest;
+    status_t removeClient(ClientIdType clientId);
 
     /** Get the singleton instance of the TranscodingClientManager. */
     static TranscodingClientManager& getInstance();
 
-    TranscodingClientManager();
-
     static void BinderDiedCallback(void* cookie);
 
     mutable std::mutex mLock;
-    std::unordered_map<int32_t, std::unique_ptr<ClientInfo>> mClientIdToClientInfoMap
+    std::unordered_map<ClientIdType, std::shared_ptr<ClientImpl>> mClientIdToClientMap
             GUARDED_BY(mLock);
 
     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
diff --git a/media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp b/media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
index 5d2419d..d23ea87 100644
--- a/media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
+++ b/media/libmediatranscoding/tests/TranscodingClientManager_tests.cpp
@@ -19,9 +19,8 @@
 // #define LOG_NDEBUG 0
 #define LOG_TAG "TranscodingClientManagerTest"
 
-#include <aidl/android/media/BnTranscodingServiceClient.h>
+#include <aidl/android/media/BnTranscodingClientListener.h>
 #include <aidl/android/media/IMediaTranscodingService.h>
-#include <aidl/android/media/ITranscodingServiceClient.h>
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
@@ -32,30 +31,24 @@
 namespace android {
 
 using Status = ::ndk::ScopedAStatus;
-using aidl::android::media::BnTranscodingServiceClient;
+using aidl::android::media::BnTranscodingClientListener;
 using aidl::android::media::IMediaTranscodingService;
-using aidl::android::media::ITranscodingServiceClient;
 
-constexpr int32_t kInvalidClientId = -1;
 constexpr int32_t kInvalidClientPid = -1;
 constexpr int32_t kInvalidClientUid = -1;
-constexpr const char* kInvalidClientOpPackageName = "";
+constexpr const char* kInvalidClientName = "";
+constexpr const char* kInvalidClientPackage = "";
 
-constexpr int32_t kClientId = 1;
 constexpr int32_t kClientPid = 2;
 constexpr int32_t kClientUid = 3;
-constexpr const char* kClientOpPackageName = "TestClient";
+constexpr const char* kClientName = "TestClientName";
+constexpr const char* kClientPackage = "TestClientPackage";
 
-struct TestClient : public BnTranscodingServiceClient {
-    TestClient(const std::shared_ptr<IMediaTranscodingService>& service) : mService(service) {
+struct TestClient : public BnTranscodingClientListener {
+    TestClient() {
         ALOGD("TestClient Created");
     }
 
-    Status getName(std::string* _aidl_return) override {
-        *_aidl_return = "test_client";
-        return Status::ok();
-    }
-
     Status onTranscodingFinished(
             int32_t /* in_jobId */,
             const ::aidl::android::media::TranscodingResultParcel& /* in_result */) override {
@@ -79,8 +72,7 @@
 
     virtual ~TestClient() { ALOGI("TestClient destroyed"); };
 
-   private:
-    std::shared_ptr<IMediaTranscodingService> mService;
+private:
     TestClient(const TestClient&) = delete;
     TestClient& operator=(const TestClient&) = delete;
 };
@@ -92,189 +84,128 @@
     }
 
     void SetUp() override {
-        ::ndk::SpAIBinder binder(AServiceManager_getService("media.transcoding"));
-        mService = IMediaTranscodingService::fromBinder(binder);
-        if (mService == nullptr) {
-            ALOGE("Failed to connect to the media.trascoding service.");
-            return;
-        }
-
-        mTestClient = ::ndk::SharedRefBase::make<TestClient>(mService);
+        mClientListener = ::ndk::SharedRefBase::make<TestClient>();
+        mClientListener2 = ::ndk::SharedRefBase::make<TestClient>();
+        mClientListener3 = ::ndk::SharedRefBase::make<TestClient>();
     }
 
     void TearDown() override {
         ALOGI("TranscodingClientManagerTest tear down");
-        mService = nullptr;
     }
 
     ~TranscodingClientManagerTest() { ALOGD("TranscodingClientManagerTest destroyed"); }
 
     TranscodingClientManager& mClientManager;
-    std::shared_ptr<ITranscodingServiceClient> mTestClient = nullptr;
-    std::shared_ptr<IMediaTranscodingService> mService = nullptr;
+    std::shared_ptr<ITranscodingClientListener> mClientListener;
+    std::shared_ptr<ITranscodingClientListener> mClientListener2;
+    std::shared_ptr<ITranscodingClientListener> mClientListener3;
 };
 
-TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientId) {
-    std::shared_ptr<ITranscodingServiceClient> client =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
-
-    // Create a client with invalid client id.
-    std::unique_ptr<TranscodingClientManager::ClientInfo> clientInfo =
-            std::make_unique<TranscodingClientManager::ClientInfo>(
-                    client, kInvalidClientId, kClientPid, kClientUid, kClientOpPackageName);
-
-    // Add the client to the manager and expect failure.
-    status_t err = mClientManager.addClient(std::move(clientInfo));
-    EXPECT_TRUE(err != OK);
+TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientListener) {
+    // Add a client with null listener and expect failure.
+    std::shared_ptr<ITranscodingClient> client;
+    status_t err = mClientManager.addClient(nullptr,
+            kClientPid, kClientUid, kClientName, kClientPackage, &client);
+    EXPECT_EQ(err, BAD_VALUE);
 }
 
 TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientPid) {
-    std::shared_ptr<ITranscodingServiceClient> client =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
-
-    // Create a client with invalid Pid.
-    std::unique_ptr<TranscodingClientManager::ClientInfo> clientInfo =
-            std::make_unique<TranscodingClientManager::ClientInfo>(
-                    client, kClientId, kInvalidClientPid, kClientUid, kClientOpPackageName);
-
-    // Add the client to the manager and expect failure.
-    status_t err = mClientManager.addClient(std::move(clientInfo));
-    EXPECT_TRUE(err != OK);
+    // Add a client with invalid Pid and expect failure.
+    std::shared_ptr<ITranscodingClient> client;
+    status_t err = mClientManager.addClient(mClientListener,
+            kInvalidClientPid, kClientUid, kClientName, kClientPackage, &client);
+    EXPECT_EQ(err, BAD_VALUE);
 }
 
 TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientUid) {
-    std::shared_ptr<ITranscodingServiceClient> client =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
+    // Add a client with invalid Uid and expect failure.
+    std::shared_ptr<ITranscodingClient> client;
+    status_t err = mClientManager.addClient(mClientListener,
+            kClientPid, kInvalidClientUid, kClientName, kClientPackage, &client);
+    EXPECT_EQ(err, BAD_VALUE);
+}
 
-    // Create a client with invalid Uid.
-    std::unique_ptr<TranscodingClientManager::ClientInfo> clientInfo =
-            std::make_unique<TranscodingClientManager::ClientInfo>(
-                    client, kClientId, kClientPid, kInvalidClientUid, kClientOpPackageName);
-
-    // Add the client to the manager and expect failure.
-    status_t err = mClientManager.addClient(std::move(clientInfo));
-    EXPECT_TRUE(err != OK);
+TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientName) {
+    // Add a client with invalid name and expect failure.
+    std::shared_ptr<ITranscodingClient> client;
+    status_t err = mClientManager.addClient(mClientListener,
+            kClientPid, kClientUid, kInvalidClientName, kClientPackage, &client);
+    EXPECT_EQ(err, BAD_VALUE);
 }
 
 TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientPackageName) {
-    std::shared_ptr<ITranscodingServiceClient> client =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
-
-    // Create a client with invalid packagename.
-    std::unique_ptr<TranscodingClientManager::ClientInfo> clientInfo =
-            std::make_unique<TranscodingClientManager::ClientInfo>(
-                    client, kClientId, kClientPid, kClientUid, kInvalidClientOpPackageName);
-
-    // Add the client to the manager and expect failure.
-    status_t err = mClientManager.addClient(std::move(clientInfo));
-    EXPECT_TRUE(err != OK);
+    // Add a client with invalid packagename and expect failure.
+    std::shared_ptr<ITranscodingClient> client;
+    status_t err = mClientManager.addClient(mClientListener,
+            kClientPid, kClientUid, kClientName, kInvalidClientPackage, &client);
+    EXPECT_EQ(err, BAD_VALUE);
 }
 
 TEST_F(TranscodingClientManagerTest, TestAddingValidClient) {
-    std::shared_ptr<ITranscodingServiceClient> client1 =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
+    // Add a valid client, should succeed
+    std::shared_ptr<ITranscodingClient> client;
+    status_t err = mClientManager.addClient(mClientListener,
+            kClientPid, kClientUid, kClientName, kClientPackage, &client);
+    EXPECT_EQ(err, OK);
+    EXPECT_NE(client.get(), nullptr);
+    EXPECT_EQ(mClientManager.getNumOfClients(), 1);
 
-    std::unique_ptr<TranscodingClientManager::ClientInfo> clientInfo =
-            std::make_unique<TranscodingClientManager::ClientInfo>(
-                    client1, kClientId, kClientPid, kClientUid, kClientOpPackageName);
-
-    status_t err = mClientManager.addClient(std::move(clientInfo));
-    EXPECT_TRUE(err == OK);
-
-    size_t numOfClients = mClientManager.getNumOfClients();
-    EXPECT_EQ(numOfClients, 1);
-
-    err = mClientManager.removeClient(kClientId);
-    EXPECT_TRUE(err == OK);
+    // unregister client, should succeed
+    Status status = client->unregister();
+    EXPECT_TRUE(status.isOk());
+    EXPECT_EQ(mClientManager.getNumOfClients(), 0);
 }
 
 TEST_F(TranscodingClientManagerTest, TestAddingDupliacteClient) {
-    std::shared_ptr<ITranscodingServiceClient> client1 =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
+    std::shared_ptr<ITranscodingClient> client;
+    status_t err = mClientManager.addClient(mClientListener,
+            kClientPid, kClientUid, kClientName, kClientPackage, &client);
+    EXPECT_EQ(err, OK);
+    EXPECT_NE(client.get(), nullptr);
+    EXPECT_EQ(mClientManager.getNumOfClients(), 1);
 
-    std::unique_ptr<TranscodingClientManager::ClientInfo> clientInfo =
-            std::make_unique<TranscodingClientManager::ClientInfo>(
-                    client1, kClientId, kClientPid, kClientUid, kClientOpPackageName);
+    std::shared_ptr<ITranscodingClient> dupClient;
+    err = mClientManager.addClient(mClientListener,
+            kClientPid, kClientUid, "dupClient", "dupPackage", &dupClient);
+    EXPECT_EQ(err, ALREADY_EXISTS);
+    EXPECT_EQ(dupClient.get(), nullptr);
+    EXPECT_EQ(mClientManager.getNumOfClients(), 1);
 
-    status_t err = mClientManager.addClient(std::move(clientInfo));
-    EXPECT_TRUE(err == OK);
+    Status status = client->unregister();
+    EXPECT_TRUE(status.isOk());
+    EXPECT_EQ(mClientManager.getNumOfClients(), 0);
 
-    err = mClientManager.addClient(std::move(clientInfo));
-    EXPECT_TRUE(err != OK);
+    err = mClientManager.addClient(mClientListener,
+            kClientPid, kClientUid, "dupClient", "dupPackage", &dupClient);
+    EXPECT_EQ(err, OK);
+    EXPECT_NE(dupClient.get(), nullptr);
+    EXPECT_EQ(mClientManager.getNumOfClients(), 1);
 
-    err = mClientManager.removeClient(kClientId);
-    EXPECT_TRUE(err == OK);
+    status = dupClient->unregister();
+    EXPECT_TRUE(status.isOk());
+    EXPECT_EQ(mClientManager.getNumOfClients(), 0);
 }
 
 TEST_F(TranscodingClientManagerTest, TestAddingMultipleClient) {
-    std::shared_ptr<ITranscodingServiceClient> client1 =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
+    std::shared_ptr<ITranscodingClient> client1, client2, client3;
 
-    std::unique_ptr<TranscodingClientManager::ClientInfo> clientInfo1 =
-            std::make_unique<TranscodingClientManager::ClientInfo>(
-                    client1, kClientId, kClientPid, kClientUid, kClientOpPackageName);
+    EXPECT_EQ(mClientManager.addClient(mClientListener,
+            kClientPid, kClientUid, kClientName, kClientPackage, &client1), OK);
+    EXPECT_NE(client1, nullptr);
 
-    status_t err = mClientManager.addClient(std::move(clientInfo1));
-    EXPECT_TRUE(err == OK);
+    EXPECT_EQ(mClientManager.addClient(mClientListener2,
+            kClientPid, kClientUid, kClientName, kClientPackage, &client2), OK);
+    EXPECT_NE(client2, nullptr);
 
-    std::shared_ptr<ITranscodingServiceClient> client2 =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
+    EXPECT_EQ(mClientManager.addClient(mClientListener3,
+            kClientPid, kClientUid, kClientName, kClientPackage, &client3), OK);
+    EXPECT_NE(client3, nullptr);
 
-    std::unique_ptr<TranscodingClientManager::ClientInfo> clientInfo2 =
-            std::make_unique<TranscodingClientManager::ClientInfo>(
-                    client2, kClientId + 1, kClientPid, kClientUid, kClientOpPackageName);
-
-    err = mClientManager.addClient(std::move(clientInfo2));
-    EXPECT_TRUE(err == OK);
-
-    std::shared_ptr<ITranscodingServiceClient> client3 =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
-
-    // Create a client with invalid packagename.
-    std::unique_ptr<TranscodingClientManager::ClientInfo> clientInfo3 =
-            std::make_unique<TranscodingClientManager::ClientInfo>(
-                    client3, kClientId + 2, kClientPid, kClientUid, kClientOpPackageName);
-
-    err = mClientManager.addClient(std::move(clientInfo3));
-    EXPECT_TRUE(err == OK);
-
-    size_t numOfClients = mClientManager.getNumOfClients();
-    EXPECT_EQ(numOfClients, 3);
-
-    err = mClientManager.removeClient(kClientId);
-    EXPECT_TRUE(err == OK);
-
-    err = mClientManager.removeClient(kClientId + 1);
-    EXPECT_TRUE(err == OK);
-
-    err = mClientManager.removeClient(kClientId + 2);
-    EXPECT_TRUE(err == OK);
+    EXPECT_EQ(mClientManager.getNumOfClients(), 3);
+    EXPECT_TRUE(client1->unregister().isOk());
+    EXPECT_TRUE(client2->unregister().isOk());
+    EXPECT_TRUE(client3->unregister().isOk());
+    EXPECT_EQ(mClientManager.getNumOfClients(), 0);
 }
 
-TEST_F(TranscodingClientManagerTest, TestRemovingNonExistClient) {
-    status_t err = mClientManager.removeClient(kInvalidClientId);
-    EXPECT_TRUE(err != OK);
-
-    err = mClientManager.removeClient(1000 /* clientId */);
-    EXPECT_TRUE(err != OK);
-}
-
-TEST_F(TranscodingClientManagerTest, TestCheckClientWithClientId) {
-    std::shared_ptr<ITranscodingServiceClient> client =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
-
-    std::unique_ptr<TranscodingClientManager::ClientInfo> clientInfo =
-            std::make_unique<TranscodingClientManager::ClientInfo>(
-                    client, kClientId, kClientPid, kClientUid, kClientOpPackageName);
-
-    status_t err = mClientManager.addClient(std::move(clientInfo));
-    EXPECT_TRUE(err == OK);
-
-    bool res = mClientManager.isClientIdRegistered(kClientId);
-    EXPECT_TRUE(res);
-
-    res = mClientManager.isClientIdRegistered(kInvalidClientId);
-    EXPECT_FALSE(res);
-}
-
-}  // namespace android
\ No newline at end of file
+}  // 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 d8e4830..ec15a21 100644
--- a/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
+++ b/media/libmediatranscoding/tests/build_and_run_all_unit_tests.sh
@@ -20,7 +20,10 @@
 echo "========================================"
 
 echo "testing TranscodingClientManager"
-adb shell /data/nativetest64/TranscodingClientManager_tests/TranscodingClientManager_tests
+#adb shell /data/nativetest64/TranscodingClientManager_tests/TranscodingClientManager_tests
+adb shell /data/nativetest/TranscodingClientManager_tests/TranscodingClientManager_tests
 
 echo "testing AdjustableMaxPriorityQueue"
-adb shell /data/nativetest64/AdjustableMaxPriorityQueue_tests/AdjustableMaxPriorityQueue_tests
+#adb shell /data/nativetest64/AdjustableMaxPriorityQueue_tests/AdjustableMaxPriorityQueue_tests
+adb shell /data/nativetest/AdjustableMaxPriorityQueue_tests/AdjustableMaxPriorityQueue_tests
+
diff --git a/services/mediatranscoding/MediaTranscodingService.cpp b/services/mediatranscoding/MediaTranscodingService.cpp
index 82d4161..b441449 100644
--- a/services/mediatranscoding/MediaTranscodingService.cpp
+++ b/services/mediatranscoding/MediaTranscodingService.cpp
@@ -80,19 +80,22 @@
 }
 
 Status MediaTranscodingService::registerClient(
-        const std::shared_ptr<ITranscodingServiceClient>& in_client,
-        const std::string& in_opPackageName, int32_t in_clientUid, int32_t in_clientPid,
-        int32_t* _aidl_return) {
-    if (in_client == nullptr) {
-        ALOGE("Client can not be null");
-        *_aidl_return = kInvalidJobId;
+        const std::shared_ptr<ITranscodingClientListener>& in_listener,
+        const std::string& in_clientName,
+        const std::string& in_opPackageName,
+        int32_t in_clientUid, int32_t in_clientPid,
+        std::shared_ptr<ITranscodingClient>* _aidl_return) {
+    if (in_listener == nullptr) {
+        ALOGE("Client listener can not be null");
+        *_aidl_return = nullptr;
         return Status::fromServiceSpecificError(ERROR_ILLEGAL_ARGUMENT);
     }
 
     int32_t callingPid = AIBinder_getCallingPid();
     int32_t callingUid = AIBinder_getCallingUid();
 
-    // Check if we can trust clientUid. Only privilege caller could forward the uid on app client's behalf.
+    // Check if we can trust clientUid. Only privilege caller could forward the
+    // uid on app client's behalf.
     if (in_clientUid == USE_CALLING_UID) {
         in_clientUid = callingUid;
     } else if (!isTrustedCallingUid(callingUid)) {
@@ -106,7 +109,8 @@
                                 in_clientPid, in_clientUid);
     }
 
-    // Check if we can trust clientPid. Only privilege caller could forward the pid on app client's behalf.
+    // Check if we can trust clientPid. Only privilege caller could forward the
+    // pid on app client's behalf.
     if (in_clientPid == USE_CALLING_PID) {
         in_clientPid = callingPid;
     } else if (!isTrustedCallingUid(callingUid)) {
@@ -120,51 +124,17 @@
                                 in_clientPid, in_clientUid);
     }
 
-    // We know the clientId must be equal to its pid as we assigned client's pid as its clientId.
-    int32_t clientId = in_clientPid;
-
-    // Checks if the client already registers.
-    if (mTranscodingClientManager.isClientIdRegistered(clientId)) {
-        return Status::fromServiceSpecificError(ERROR_ALREADY_EXISTS);
-    }
-
     // Creates the client and uses its process id as client id.
-    std::unique_ptr<TranscodingClientManager::ClientInfo> newClient =
-            std::make_unique<TranscodingClientManager::ClientInfo>(
-                    in_client, clientId, in_clientPid, in_clientUid, in_opPackageName);
-    status_t err = mTranscodingClientManager.addClient(std::move(newClient));
+    std::shared_ptr<ITranscodingClient> newClient;
+
+    status_t err = mTranscodingClientManager.addClient(in_listener,
+            in_clientPid, in_clientUid, in_clientName, in_opPackageName, &newClient);
     if (err != OK) {
-        *_aidl_return = kInvalidClientId;
+        *_aidl_return = nullptr;
         return STATUS_ERROR_FMT(err, "Failed to add client to TranscodingClientManager");
     }
 
-    ALOGD("Assign client: %s pid: %d, uid: %d with id: %d", in_opPackageName.c_str(), in_clientPid,
-          in_clientUid, clientId);
-
-    *_aidl_return = clientId;
-    return Status::ok();
-}
-
-Status MediaTranscodingService::unregisterClient(int32_t clientId, bool* _aidl_return) {
-    ALOGD("unregisterClient id: %d", clientId);
-    int32_t callingUid = AIBinder_getCallingUid();
-    int32_t callingPid = AIBinder_getCallingPid();
-
-    // Only the client with clientId or the trusted caller could unregister the client.
-    if (callingPid != clientId) {
-        if (!isTrustedCallingUid(callingUid)) {
-            ALOGE("Untrusted caller (calling PID %d, UID %d) trying to "
-                  "unregister client with id: %d",
-                  callingUid, callingPid, clientId);
-            *_aidl_return = true;
-            return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
-                                    "Untrusted caller (calling PID %d, UID %d) trying to "
-                                    "unregister client with id: %d",
-                                    callingUid, callingPid, clientId);
-        }
-    }
-
-    *_aidl_return = (mTranscodingClientManager.removeClient(clientId) == OK);
+    *_aidl_return = newClient;
     return Status::ok();
 }
 
@@ -174,25 +144,4 @@
     return Status::ok();
 }
 
-Status MediaTranscodingService::submitRequest(int32_t /*clientId*/,
-                                              const TranscodingRequestParcel& /*request*/,
-                                              TranscodingJobParcel* /*job*/,
-                                              int32_t* /*_aidl_return*/) {
-    // TODO(hkuang): Add implementation.
-    return Status::ok();
-}
-
-Status MediaTranscodingService::cancelJob(int32_t /*in_clientId*/, int32_t /*in_jobId*/,
-                                          bool* /*_aidl_return*/) {
-    // TODO(hkuang): Add implementation.
-    return Status::ok();
-}
-
-Status MediaTranscodingService::getJobWithId(int32_t /*in_jobId*/,
-                                             TranscodingJobParcel* /*out_job*/,
-                                             bool* /*_aidl_return*/) {
-    // TODO(hkuang): Add implementation.
-    return Status::ok();
-}
-
 }  // namespace android
diff --git a/services/mediatranscoding/MediaTranscodingService.h b/services/mediatranscoding/MediaTranscodingService.h
index cc69727..785bc4d 100644
--- a/services/mediatranscoding/MediaTranscodingService.h
+++ b/services/mediatranscoding/MediaTranscodingService.h
@@ -25,7 +25,8 @@
 
 using Status = ::ndk::ScopedAStatus;
 using ::aidl::android::media::BnMediaTranscodingService;
-using ::aidl::android::media::ITranscodingServiceClient;
+using ::aidl::android::media::ITranscodingClient;
+using ::aidl::android::media::ITranscodingClientListener;
 using ::aidl::android::media::TranscodingJobParcel;
 using ::aidl::android::media::TranscodingRequestParcel;
 
@@ -41,23 +42,17 @@
 
     static const char* getServiceName() { return "media.transcoding"; }
 
-    Status registerClient(const std::shared_ptr<ITranscodingServiceClient>& in_client,
-                          const std::string& in_opPackageName, int32_t in_clientUid,
-                          int32_t in_clientPid, int32_t* _aidl_return) override;
-
-    Status unregisterClient(int32_t clientId, bool* _aidl_return) override;
+    Status registerClient(
+            const std::shared_ptr<ITranscodingClientListener>& in_listener,
+            const std::string& in_clientName,
+            const std::string& in_opPackageName,
+            int32_t in_clientUid, int32_t in_clientPid,
+            std::shared_ptr<ITranscodingClient>* _aidl_return) override;
 
     Status getNumOfClients(int32_t* _aidl_return) override;
 
-    Status submitRequest(int32_t in_clientId, const TranscodingRequestParcel& in_request,
-                         TranscodingJobParcel* out_job, int32_t* _aidl_return) override;
-
-    Status cancelJob(int32_t in_clientId, int32_t in_jobId, bool* _aidl_return) override;
-
-    Status getJobWithId(int32_t in_jobId, TranscodingJobParcel* out_job,
-                        bool* _aidl_return) override;
-
-    virtual inline binder_status_t dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);
+    virtual inline binder_status_t dump(
+            int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);
 
 private:
     friend class MediaTranscodingServiceTest;
diff --git a/services/mediatranscoding/tests/mediatranscodingservice_tests.cpp b/services/mediatranscoding/tests/mediatranscodingservice_tests.cpp
index 5a791fe..accfd03 100644
--- a/services/mediatranscoding/tests/mediatranscodingservice_tests.cpp
+++ b/services/mediatranscoding/tests/mediatranscodingservice_tests.cpp
@@ -19,9 +19,10 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaTranscodingServiceTest"
 
-#include <aidl/android/media/BnTranscodingServiceClient.h>
+#include <aidl/android/media/BnTranscodingClientListener.h>
 #include <aidl/android/media/IMediaTranscodingService.h>
-#include <aidl/android/media/ITranscodingServiceClient.h>
+#include <aidl/android/media/ITranscodingClient.h>
+#include <aidl/android/media/ITranscodingClientListener.h>
 #include <android-base/logging.h>
 #include <android-base/unique_fd.h>
 #include <android/binder_ibinder_jni.h>
@@ -38,48 +39,30 @@
 namespace media {
 
 using Status = ::ndk::ScopedAStatus;
-using aidl::android::media::BnTranscodingServiceClient;
+using aidl::android::media::BnTranscodingClientListener;
+using aidl::android::media::ITranscodingClient;
+using aidl::android::media::ITranscodingClientListener;
 using aidl::android::media::IMediaTranscodingService;
-using aidl::android::media::ITranscodingServiceClient;
-
-constexpr int32_t kInvalidClientId = -5;
 
 // Note that -1 is valid and means using calling pid/uid for the service. But only privilege caller could
 // use them. This test is not a privilege caller.
 constexpr int32_t kInvalidClientPid = -5;
 constexpr int32_t kInvalidClientUid = -5;
+constexpr const char* kInvalidClientName = "";
 constexpr const char* kInvalidClientOpPackageName = "";
 
 constexpr int32_t kClientUseCallingPid = -1;
 constexpr int32_t kClientUseCallingUid = -1;
-constexpr const char* kClientOpPackageName = "TestClient";
+constexpr const char* kClientName = "TestClient";
+constexpr const char* kClientOpPackageName = "TestClientPackage";
 
-class MediaTranscodingServiceTest : public ::testing::Test {
-public:
-    MediaTranscodingServiceTest() { ALOGD("MediaTranscodingServiceTest created"); }
-
-    void SetUp() override {
-        ::ndk::SpAIBinder binder(AServiceManager_getService("media.transcoding"));
-        mService = IMediaTranscodingService::fromBinder(binder);
-        if (mService == nullptr) {
-            ALOGE("Failed to connect to the media.trascoding service.");
-            return;
-        }
-    }
-
-    ~MediaTranscodingServiceTest() { ALOGD("MediaTranscodingingServiceTest destroyed"); }
-
-    std::shared_ptr<IMediaTranscodingService> mService = nullptr;
-};
-
-struct TestClient : public BnTranscodingServiceClient {
-    TestClient(const std::shared_ptr<IMediaTranscodingService>& service) : mService(service) {
+struct TestClient : public BnTranscodingClientListener {
+    TestClient() {
         ALOGD("TestClient Created");
     }
 
-    Status getName(std::string* _aidl_return) override {
-        *_aidl_return = "test_client";
-        return Status::ok();
+    virtual ~TestClient() {
+        ALOGI("TestClient destroyed");
     }
 
     Status onTranscodingFinished(
@@ -102,71 +85,97 @@
     Status onProgressUpdate(int32_t /* in_jobId */, int32_t /* in_progress */) override {
         return Status::ok();
     }
-
-    virtual ~TestClient() { ALOGI("TestClient destroyed"); };
-
-private:
-    std::shared_ptr<IMediaTranscodingService> mService;
 };
 
+class MediaTranscodingServiceTest : public ::testing::Test {
+public:
+    MediaTranscodingServiceTest() {
+        ALOGD("MediaTranscodingServiceTest created");
+    }
+
+    ~MediaTranscodingServiceTest() {
+        ALOGD("MediaTranscodingingServiceTest destroyed");
+    }
+
+    void SetUp() override {
+        ::ndk::SpAIBinder binder(AServiceManager_getService("media.transcoding"));
+        mService = IMediaTranscodingService::fromBinder(binder);
+        if (mService == nullptr) {
+            ALOGE("Failed to connect to the media.trascoding service.");
+            return;
+        }
+        mClientListener = ::ndk::SharedRefBase::make<TestClient>();
+        mClientListener2 = ::ndk::SharedRefBase::make<TestClient>();
+        mClientListener3 = ::ndk::SharedRefBase::make<TestClient>();
+    }
+
+    std::shared_ptr<IMediaTranscodingService> mService;
+    std::shared_ptr<ITranscodingClientListener> mClientListener;
+    std::shared_ptr<ITranscodingClientListener> mClientListener2;
+    std::shared_ptr<ITranscodingClientListener> mClientListener3;
+};
+
+
 TEST_F(MediaTranscodingServiceTest, TestRegisterNullClient) {
-    std::shared_ptr<ITranscodingServiceClient> client = nullptr;
-    int32_t clientId = 0;
-    Status status = mService->registerClient(client, kClientOpPackageName, kClientUseCallingUid,
-                                             kClientUseCallingPid, &clientId);
+    std::shared_ptr<ITranscodingClient> client;
+
+    // Register the client with null listener
+    Status status = mService->registerClient(
+            nullptr, kClientName, kClientOpPackageName,
+            kClientUseCallingUid, kClientUseCallingPid, &client);
     EXPECT_FALSE(status.isOk());
 }
 
 TEST_F(MediaTranscodingServiceTest, TestRegisterClientWithInvalidClientPid) {
-    std::shared_ptr<ITranscodingServiceClient> client =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
-    EXPECT_TRUE(client != nullptr);
+    std::shared_ptr<ITranscodingClient> client;
 
     // Register the client with the service.
-    int32_t clientId = 0;
-    Status status = mService->registerClient(client, kClientOpPackageName, kClientUseCallingUid,
-                                             kInvalidClientPid, &clientId);
+    Status status = mService->registerClient(
+            mClientListener, kClientName, kClientOpPackageName,
+            kClientUseCallingUid, kInvalidClientPid, &client);
     EXPECT_FALSE(status.isOk());
 }
 
 TEST_F(MediaTranscodingServiceTest, TestRegisterClientWithInvalidClientUid) {
-    std::shared_ptr<ITranscodingServiceClient> client =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
-    EXPECT_TRUE(client != nullptr);
+    std::shared_ptr<ITranscodingClient> client;
 
     // Register the client with the service.
-    int32_t clientId = 0;
-    Status status = mService->registerClient(client, kClientOpPackageName, kInvalidClientUid,
-                                             kClientUseCallingPid, &clientId);
+    Status status = mService->registerClient(
+            mClientListener, kClientName, kClientOpPackageName,
+            kInvalidClientUid, kClientUseCallingPid, &client);
+    EXPECT_FALSE(status.isOk());
+}
+
+TEST_F(MediaTranscodingServiceTest, TestRegisterClientWithInvalidClientName) {
+    std::shared_ptr<ITranscodingClient> client;
+
+    // Register the client with the service.
+    Status status = mService->registerClient(
+            mClientListener, kInvalidClientName, kInvalidClientOpPackageName,
+            kClientUseCallingUid, kClientUseCallingPid, &client);
     EXPECT_FALSE(status.isOk());
 }
 
 TEST_F(MediaTranscodingServiceTest, TestRegisterClientWithInvalidClientPackageName) {
-    std::shared_ptr<ITranscodingServiceClient> client =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
-    EXPECT_TRUE(client != nullptr);
+    std::shared_ptr<ITranscodingClient> client;
 
     // Register the client with the service.
-    int32_t clientId = 0;
-    Status status = mService->registerClient(client, kInvalidClientOpPackageName,
-                                             kClientUseCallingUid, kClientUseCallingPid, &clientId);
+    Status status = mService->registerClient(
+            mClientListener, kClientName, kInvalidClientOpPackageName,
+            kClientUseCallingUid, kClientUseCallingPid, &client);
     EXPECT_FALSE(status.isOk());
 }
 
 TEST_F(MediaTranscodingServiceTest, TestRegisterOneClient) {
-    std::shared_ptr<ITranscodingServiceClient> client =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
-    EXPECT_TRUE(client != nullptr);
+    std::shared_ptr<ITranscodingClient> client;
 
-    // Register the client with the service.
-    int32_t clientId = 0;
-    Status status = mService->registerClient(client, kClientOpPackageName, kClientUseCallingPid,
-                                             kClientUseCallingUid, &clientId);
-    ALOGD("client id is %d", clientId);
+    Status status = mService->registerClient(
+            mClientListener, kClientName, kClientOpPackageName,
+            kClientUseCallingUid, kClientUseCallingPid, &client);
     EXPECT_TRUE(status.isOk());
 
-    // Validate the clientId.
-    EXPECT_TRUE(clientId > 0);
+    // Validate the client.
+    EXPECT_TRUE(client != nullptr);
 
     // Check the number of Clients.
     int32_t numOfClients;
@@ -175,65 +184,82 @@
     EXPECT_EQ(1, numOfClients);
 
     // Unregister the client.
-    bool res;
-    status = mService->unregisterClient(clientId, &res);
+    status = client->unregister();
     EXPECT_TRUE(status.isOk());
-    EXPECT_TRUE(res);
-}
-
-TEST_F(MediaTranscodingServiceTest, TestUnRegisterClientWithInvalidClientId) {
-    std::shared_ptr<ITranscodingServiceClient> client =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
-    EXPECT_TRUE(client != nullptr);
-
-    // Register the client with the service.
-    int32_t clientId = 0;
-    Status status = mService->registerClient(client, kClientOpPackageName, kClientUseCallingUid,
-                                             kClientUseCallingPid, &clientId);
-    ALOGD("client id is %d", clientId);
-    EXPECT_TRUE(status.isOk());
-
-    // Validate the clientId.
-    EXPECT_TRUE(clientId > 0);
 
     // Check the number of Clients.
-    int32_t numOfClients;
     status = mService->getNumOfClients(&numOfClients);
     EXPECT_TRUE(status.isOk());
-    EXPECT_EQ(1, numOfClients);
-
-    // Unregister the client with invalid ID
-    bool res;
-    mService->unregisterClient(kInvalidClientId, &res);
-    EXPECT_FALSE(res);
-
-    // Unregister the valid client.
-    mService->unregisterClient(clientId, &res);
+    EXPECT_EQ(0, numOfClients);
 }
 
 TEST_F(MediaTranscodingServiceTest, TestRegisterClientTwice) {
-    std::shared_ptr<ITranscodingServiceClient> client =
-            ::ndk::SharedRefBase::make<TestClient>(mService);
-    EXPECT_TRUE(client != nullptr);
+    std::shared_ptr<ITranscodingClient> client;
 
-    // Register the client with the service.
-    int32_t clientId = 0;
-    Status status = mService->registerClient(client, kClientOpPackageName, kClientUseCallingUid,
-                                             kClientUseCallingPid, &clientId);
+    Status status = mService->registerClient(
+            mClientListener, kClientName, kClientOpPackageName,
+            kClientUseCallingUid, kClientUseCallingPid, &client);
     EXPECT_TRUE(status.isOk());
 
-    // Validate the clientId.
-    EXPECT_TRUE(clientId > 0);
+    // Validate the client.
+    EXPECT_TRUE(client != nullptr);
 
     // Register the client again and expects failure.
-    status = mService->registerClient(client, kClientOpPackageName, kClientUseCallingUid,
-                                      kClientUseCallingPid, &clientId);
+    std::shared_ptr<ITranscodingClient> client1;
+    status = mService->registerClient(
+            mClientListener, kClientName, kClientOpPackageName,
+            kClientUseCallingUid, kClientUseCallingPid, &client1);
     EXPECT_FALSE(status.isOk());
 
-    // Unregister the valid client.
-    bool res;
-    mService->unregisterClient(clientId, &res);
+    // Unregister the client.
+    status = client->unregister();
+    EXPECT_TRUE(status.isOk());
 }
 
+TEST_F(MediaTranscodingServiceTest, TestRegisterMultipleClients) {
+    std::shared_ptr<ITranscodingClient> client1;
+    std::shared_ptr<ITranscodingClient> client2;
+    std::shared_ptr<ITranscodingClient> client3;
+
+    // Register 3 clients.
+    Status status = mService->registerClient(
+            mClientListener, kClientName, kClientOpPackageName,
+            kClientUseCallingUid, kClientUseCallingPid, &client1);
+    EXPECT_TRUE(status.isOk());
+    EXPECT_TRUE(client1 != nullptr);
+
+    status = mService->registerClient(
+            mClientListener2, kClientName, kClientOpPackageName,
+            kClientUseCallingUid, kClientUseCallingPid, &client2);
+    EXPECT_TRUE(status.isOk());
+    EXPECT_TRUE(client2 != nullptr);
+
+    status = mService->registerClient(
+            mClientListener3, kClientName, kClientOpPackageName,
+            kClientUseCallingUid, kClientUseCallingPid, &client3);
+    EXPECT_TRUE(status.isOk());
+    EXPECT_TRUE(client3 != nullptr);
+
+    // Check the number of clients.
+    int32_t numOfClients;
+    status = mService->getNumOfClients(&numOfClients);
+    EXPECT_TRUE(status.isOk());
+    EXPECT_EQ(3, numOfClients);
+
+    // Unregister the clients.
+    status = client1->unregister();
+    EXPECT_TRUE(status.isOk());
+
+    status = client2->unregister();
+    EXPECT_TRUE(status.isOk());
+
+    status = client3->unregister();
+    EXPECT_TRUE(status.isOk());
+
+    // Check the number of clients.
+    status = mService->getNumOfClients(&numOfClients);
+    EXPECT_TRUE(status.isOk());
+    EXPECT_EQ(0, numOfClients);
+}
 }  // namespace media
 }  // namespace android