transcoding: instantiate job scheduler with dummy hooks
Instantiate job scheduler with dummy hooks for transcoder
and procInfo to allow more unit testing.
bug: 145233472
test: mediatranscodingservice_tests
Change-Id: I99754d724164c453623fb00affddefca5c84c26c
diff --git a/services/mediatranscoding/MediaTranscodingService.cpp b/services/mediatranscoding/MediaTranscodingService.cpp
index b441449..0289613 100644
--- a/services/mediatranscoding/MediaTranscodingService.cpp
+++ b/services/mediatranscoding/MediaTranscodingService.cpp
@@ -16,9 +16,12 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaTranscodingService"
-#include <MediaTranscodingService.h>
+#include "MediaTranscodingService.h"
+
#include <android/binder_manager.h>
#include <android/binder_process.h>
+#include <media/TranscodingClientManager.h>
+#include <media/TranscodingJobScheduler.h>
#include <private/android_filesystem_config.h>
#include <utils/Log.h>
#include <utils/Vector.h>
@@ -45,8 +48,41 @@
}
}
+// DummyTranscoder and DummyProcessInfo are currently used to instantiate
+// MediaTranscodingService on service side for testing, so that we could
+// actually test the IPC calls of MediaTranscodingService to expose some
+// issues that's observable only over IPC.
+class DummyTranscoder : public TranscoderInterface {
+ void start(int64_t clientId, int32_t jobId) override {
+ (void)clientId;
+ (void)jobId;
+ }
+ void pause(int64_t clientId, int32_t jobId) override {
+ (void)clientId;
+ (void)jobId;
+ }
+ void resume(int64_t clientId, int32_t jobId) override {
+ (void)clientId;
+ (void)jobId;
+ }
+};
+
+class DummyProcessInfo : public ProcessInfoInterface {
+ bool isProcessOnTop(int32_t pid) override {
+ (void)pid;
+ return true;
+ }
+};
+
MediaTranscodingService::MediaTranscodingService()
- : mTranscodingClientManager(TranscodingClientManager::getInstance()) {
+ : MediaTranscodingService(std::make_shared<DummyTranscoder>(),
+ std::make_shared<DummyProcessInfo>()) {}
+
+MediaTranscodingService::MediaTranscodingService(
+ const std::shared_ptr<TranscoderInterface>& transcoder,
+ const std::shared_ptr<ProcessInfoInterface>& procInfo)
+ : mJobScheduler(new TranscodingJobScheduler(transcoder, procInfo)),
+ mClientManager(new TranscodingClientManager(mJobScheduler)) {
ALOGV("MediaTranscodingService is created");
}
@@ -64,7 +100,7 @@
write(fd, result.string(), result.size());
Vector<String16> args;
- mTranscodingClientManager.dumpAllClients(fd, args);
+ mClientManager->dumpAllClients(fd, args);
return OK;
}
@@ -80,13 +116,11 @@
}
Status MediaTranscodingService::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) {
- if (in_listener == nullptr) {
- ALOGE("Client listener can not be null");
+ const std::shared_ptr<ITranscodingClientCallback>& in_callback,
+ 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_callback == nullptr) {
+ ALOGE("Client callback can not be null");
*_aidl_return = nullptr;
return Status::fromServiceSpecificError(ERROR_ILLEGAL_ARGUMENT);
}
@@ -127,8 +161,8 @@
// Creates the client and uses its process id as client id.
std::shared_ptr<ITranscodingClient> newClient;
- status_t err = mTranscodingClientManager.addClient(in_listener,
- in_clientPid, in_clientUid, in_clientName, in_opPackageName, &newClient);
+ status_t err = mClientManager->addClient(in_callback, in_clientPid, in_clientUid, in_clientName,
+ in_opPackageName, &newClient);
if (err != OK) {
*_aidl_return = nullptr;
return STATUS_ERROR_FMT(err, "Failed to add client to TranscodingClientManager");
@@ -140,7 +174,7 @@
Status MediaTranscodingService::getNumOfClients(int32_t* _aidl_return) {
ALOGD("MediaTranscodingService::getNumOfClients");
- *_aidl_return = mTranscodingClientManager.getNumOfClients();
+ *_aidl_return = mClientManager->getNumOfClients();
return Status::ok();
}
diff --git a/services/mediatranscoding/MediaTranscodingService.h b/services/mediatranscoding/MediaTranscodingService.h
index 785bc4d..36db9b3 100644
--- a/services/mediatranscoding/MediaTranscodingService.h
+++ b/services/mediatranscoding/MediaTranscodingService.h
@@ -19,16 +19,19 @@
#include <aidl/android/media/BnMediaTranscodingService.h>
#include <binder/IServiceManager.h>
-#include <media/TranscodingClientManager.h>
namespace android {
using Status = ::ndk::ScopedAStatus;
using ::aidl::android::media::BnMediaTranscodingService;
using ::aidl::android::media::ITranscodingClient;
-using ::aidl::android::media::ITranscodingClientListener;
+using ::aidl::android::media::ITranscodingClientCallback;
using ::aidl::android::media::TranscodingJobParcel;
using ::aidl::android::media::TranscodingRequestParcel;
+class TranscodingClientManager;
+class TranscodingJobScheduler;
+class TranscoderInterface;
+class ProcessInfoInterface;
class MediaTranscodingService : public BnMediaTranscodingService {
public:
@@ -36,30 +39,30 @@
static constexpr int32_t kInvalidClientId = -1;
MediaTranscodingService();
+ MediaTranscodingService(const std::shared_ptr<TranscoderInterface>& transcoder,
+ const std::shared_ptr<ProcessInfoInterface>& procInfo);
virtual ~MediaTranscodingService();
static void instantiate();
static const char* getServiceName() { return "media.transcoding"; }
- 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 registerClient(const std::shared_ptr<ITranscodingClientCallback>& in_callback,
+ 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;
- 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;
mutable std::mutex mServiceLock;
- TranscodingClientManager& mTranscodingClientManager;
+ std::shared_ptr<TranscodingJobScheduler> mJobScheduler;
+ std::shared_ptr<TranscodingClientManager> mClientManager;
};
} // namespace android
diff --git a/services/mediatranscoding/tests/build_and_run_all_unit_tests.sh b/services/mediatranscoding/tests/build_and_run_all_unit_tests.sh
index bcdc7f7..ce017d7 100644
--- a/services/mediatranscoding/tests/build_and_run_all_unit_tests.sh
+++ b/services/mediatranscoding/tests/build_and_run_all_unit_tests.sh
@@ -20,4 +20,5 @@
echo "========================================"
echo "testing mediatranscodingservice"
-adb shell /data/nativetest64/mediatranscodingservice_tests/mediatranscodingservice_tests
+#adb shell /data/nativetest64/mediatranscodingservice_tests/mediatranscodingservice_tests
+adb shell /data/nativetest/mediatranscodingservice_tests/mediatranscodingservice_tests
diff --git a/services/mediatranscoding/tests/mediatranscodingservice_tests.cpp b/services/mediatranscoding/tests/mediatranscodingservice_tests.cpp
index accfd03..351f830 100644
--- a/services/mediatranscoding/tests/mediatranscodingservice_tests.cpp
+++ b/services/mediatranscoding/tests/mediatranscodingservice_tests.cpp
@@ -14,15 +14,17 @@
* limitations under the License.
*/
-// Unit Test for MediaTranscoding Service.
+// Unit Test for MediaTranscodingService.
//#define LOG_NDEBUG 0
#define LOG_TAG "MediaTranscodingServiceTest"
-#include <aidl/android/media/BnTranscodingClientListener.h>
+#include <aidl/android/media/BnTranscodingClientCallback.h>
#include <aidl/android/media/IMediaTranscodingService.h>
#include <aidl/android/media/ITranscodingClient.h>
-#include <aidl/android/media/ITranscodingClientListener.h>
+#include <aidl/android/media/ITranscodingClientCallback.h>
+#include <aidl/android/media/TranscodingJobParcel.h>
+#include <aidl/android/media/TranscodingRequestParcel.h>
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <android/binder_ibinder_jni.h>
@@ -39,31 +41,28 @@
namespace media {
using Status = ::ndk::ScopedAStatus;
-using aidl::android::media::BnTranscodingClientListener;
-using aidl::android::media::ITranscodingClient;
-using aidl::android::media::ITranscodingClientListener;
+using aidl::android::media::BnTranscodingClientCallback;
using aidl::android::media::IMediaTranscodingService;
+using aidl::android::media::ITranscodingClient;
+using aidl::android::media::ITranscodingClientCallback;
+using aidl::android::media::TranscodingJobParcel;
+using aidl::android::media::TranscodingRequestParcel;
// 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 int32_t kClientUseCallingPid = IMediaTranscodingService::USE_CALLING_PID;
+constexpr int32_t kClientUseCallingUid = IMediaTranscodingService::USE_CALLING_UID;
constexpr const char* kClientName = "TestClient";
constexpr const char* kClientOpPackageName = "TestClientPackage";
-struct TestClient : public BnTranscodingClientListener {
- TestClient() {
- ALOGD("TestClient Created");
- }
+struct TestClient : public BnTranscodingClientCallback {
+ TestClient() { ALOGD("TestClient Created"); }
- virtual ~TestClient() {
- ALOGI("TestClient destroyed");
- }
+ virtual ~TestClient() { ALOGI("TestClient destroyed"); }
Status onTranscodingFinished(
int32_t /* in_jobId */,
@@ -89,13 +88,9 @@
class MediaTranscodingServiceTest : public ::testing::Test {
public:
- MediaTranscodingServiceTest() {
- ALOGD("MediaTranscodingServiceTest created");
- }
+ MediaTranscodingServiceTest() { ALOGD("MediaTranscodingServiceTest created"); }
- ~MediaTranscodingServiceTest() {
- ALOGD("MediaTranscodingingServiceTest destroyed");
- }
+ ~MediaTranscodingServiceTest() { ALOGD("MediaTranscodingingServiceTest destroyed"); }
void SetUp() override {
::ndk::SpAIBinder binder(AServiceManager_getService("media.transcoding"));
@@ -104,25 +99,69 @@
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>();
+ mClientCallback = ::ndk::SharedRefBase::make<TestClient>();
+ mClientCallback2 = ::ndk::SharedRefBase::make<TestClient>();
+ mClientCallback3 = ::ndk::SharedRefBase::make<TestClient>();
+ }
+
+ void registerMultipleClients() {
+ // Register 3 clients.
+ Status status =
+ mService->registerClient(mClientCallback, kClientName, kClientOpPackageName,
+ kClientUseCallingUid, kClientUseCallingPid, &mClient1);
+ EXPECT_TRUE(status.isOk());
+ EXPECT_TRUE(mClient1 != nullptr);
+
+ status = mService->registerClient(mClientCallback2, kClientName, kClientOpPackageName,
+ kClientUseCallingUid, kClientUseCallingPid, &mClient2);
+ EXPECT_TRUE(status.isOk());
+ EXPECT_TRUE(mClient2 != nullptr);
+
+ status = mService->registerClient(mClientCallback3, kClientName, kClientOpPackageName,
+ kClientUseCallingUid, kClientUseCallingPid, &mClient3);
+ EXPECT_TRUE(status.isOk());
+ EXPECT_TRUE(mClient3 != nullptr);
+
+ // Check the number of clients.
+ int32_t numOfClients;
+ status = mService->getNumOfClients(&numOfClients);
+ EXPECT_TRUE(status.isOk());
+ EXPECT_EQ(3, numOfClients);
+ }
+
+ void unregisterMultipleClients() {
+ // Unregister the clients.
+ Status status = mClient1->unregister();
+ EXPECT_TRUE(status.isOk());
+
+ status = mClient2->unregister();
+ EXPECT_TRUE(status.isOk());
+
+ status = mClient3->unregister();
+ EXPECT_TRUE(status.isOk());
+
+ // Check the number of clients.
+ int32_t numOfClients;
+ status = mService->getNumOfClients(&numOfClients);
+ EXPECT_TRUE(status.isOk());
+ EXPECT_EQ(0, numOfClients);
}
std::shared_ptr<IMediaTranscodingService> mService;
- std::shared_ptr<ITranscodingClientListener> mClientListener;
- std::shared_ptr<ITranscodingClientListener> mClientListener2;
- std::shared_ptr<ITranscodingClientListener> mClientListener3;
+ std::shared_ptr<ITranscodingClientCallback> mClientCallback;
+ std::shared_ptr<ITranscodingClientCallback> mClientCallback2;
+ std::shared_ptr<ITranscodingClientCallback> mClientCallback3;
+ std::shared_ptr<ITranscodingClient> mClient1;
+ std::shared_ptr<ITranscodingClient> mClient2;
+ std::shared_ptr<ITranscodingClient> mClient3;
};
-
TEST_F(MediaTranscodingServiceTest, TestRegisterNullClient) {
std::shared_ptr<ITranscodingClient> client;
- // Register the client with null listener
- Status status = mService->registerClient(
- nullptr, kClientName, kClientOpPackageName,
- kClientUseCallingUid, kClientUseCallingPid, &client);
+ // Register the client with null callback.
+ Status status = mService->registerClient(nullptr, kClientName, kClientOpPackageName,
+ kClientUseCallingUid, kClientUseCallingPid, &client);
EXPECT_FALSE(status.isOk());
}
@@ -130,19 +169,8 @@
std::shared_ptr<ITranscodingClient> client;
// Register the client with the service.
- Status status = mService->registerClient(
- mClientListener, kClientName, kClientOpPackageName,
- kClientUseCallingUid, kInvalidClientPid, &client);
- EXPECT_FALSE(status.isOk());
-}
-
-TEST_F(MediaTranscodingServiceTest, TestRegisterClientWithInvalidClientUid) {
- std::shared_ptr<ITranscodingClient> client;
-
- // Register the client with the service.
- Status status = mService->registerClient(
- mClientListener, kClientName, kClientOpPackageName,
- kInvalidClientUid, kClientUseCallingPid, &client);
+ Status status = mService->registerClient(mClientCallback, kClientName, kClientOpPackageName,
+ kClientUseCallingUid, kInvalidClientPid, &client);
EXPECT_FALSE(status.isOk());
}
@@ -150,9 +178,9 @@
std::shared_ptr<ITranscodingClient> client;
// Register the client with the service.
- Status status = mService->registerClient(
- mClientListener, kInvalidClientName, kInvalidClientOpPackageName,
- kClientUseCallingUid, kClientUseCallingPid, &client);
+ Status status = mService->registerClient(mClientCallback, kInvalidClientName,
+ kInvalidClientOpPackageName, kClientUseCallingUid,
+ kClientUseCallingPid, &client);
EXPECT_FALSE(status.isOk());
}
@@ -160,18 +188,17 @@
std::shared_ptr<ITranscodingClient> client;
// Register the client with the service.
- Status status = mService->registerClient(
- mClientListener, kClientName, kInvalidClientOpPackageName,
- kClientUseCallingUid, kClientUseCallingPid, &client);
+ Status status =
+ mService->registerClient(mClientCallback, kClientName, kInvalidClientOpPackageName,
+ kClientUseCallingUid, kClientUseCallingPid, &client);
EXPECT_FALSE(status.isOk());
}
TEST_F(MediaTranscodingServiceTest, TestRegisterOneClient) {
std::shared_ptr<ITranscodingClient> client;
- Status status = mService->registerClient(
- mClientListener, kClientName, kClientOpPackageName,
- kClientUseCallingUid, kClientUseCallingPid, &client);
+ Status status = mService->registerClient(mClientCallback, kClientName, kClientOpPackageName,
+ kClientUseCallingUid, kClientUseCallingPid, &client);
EXPECT_TRUE(status.isOk());
// Validate the client.
@@ -196,9 +223,8 @@
TEST_F(MediaTranscodingServiceTest, TestRegisterClientTwice) {
std::shared_ptr<ITranscodingClient> client;
- Status status = mService->registerClient(
- mClientListener, kClientName, kClientOpPackageName,
- kClientUseCallingUid, kClientUseCallingPid, &client);
+ Status status = mService->registerClient(mClientCallback, kClientName, kClientOpPackageName,
+ kClientUseCallingUid, kClientUseCallingPid, &client);
EXPECT_TRUE(status.isOk());
// Validate the client.
@@ -206,9 +232,8 @@
// Register the client again and expects failure.
std::shared_ptr<ITranscodingClient> client1;
- status = mService->registerClient(
- mClientListener, kClientName, kClientOpPackageName,
- kClientUseCallingUid, kClientUseCallingPid, &client1);
+ status = mService->registerClient(mClientCallback, kClientName, kClientOpPackageName,
+ kClientUseCallingUid, kClientUseCallingPid, &client1);
EXPECT_FALSE(status.isOk());
// Unregister the client.
@@ -217,49 +242,80 @@
}
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);
+ registerMultipleClients();
+ unregisterMultipleClients();
}
+
+TEST_F(MediaTranscodingServiceTest, TestSubmitCancelGetJobs) {
+ registerMultipleClients();
+
+ // Test jobId assignment.
+ TranscodingRequestParcel request;
+ request.fileName = "test_file_0";
+ TranscodingJobParcel job;
+ bool result;
+ EXPECT_TRUE(mClient1->submitRequest(request, &job, &result).isOk());
+ EXPECT_TRUE(result);
+ EXPECT_EQ(job.jobId, 0);
+
+ request.fileName = "test_file_1";
+ EXPECT_TRUE(mClient1->submitRequest(request, &job, &result).isOk());
+ EXPECT_TRUE(result);
+ EXPECT_EQ(job.jobId, 1);
+
+ request.fileName = "test_file_2";
+ EXPECT_TRUE(mClient1->submitRequest(request, &job, &result).isOk());
+ EXPECT_TRUE(result);
+ EXPECT_EQ(job.jobId, 2);
+
+ // Test submit bad request (no valid fileName) fails.
+ TranscodingRequestParcel badRequest;
+ EXPECT_TRUE(mClient1->submitRequest(badRequest, &job, &result).isOk());
+ EXPECT_FALSE(result);
+
+ // Test get jobs by id.
+ EXPECT_TRUE(mClient1->getJobWithId(2, &job, &result).isOk());
+ EXPECT_EQ(job.jobId, 2);
+ EXPECT_EQ(job.request.fileName, "test_file_2");
+ EXPECT_TRUE(result);
+
+ // Test get jobs by invalid id fails.
+ EXPECT_TRUE(mClient1->getJobWithId(100, &job, &result).isOk());
+ EXPECT_FALSE(result);
+
+ // Test cancel non-existent job fail.
+ EXPECT_TRUE(mClient2->cancelJob(100, &result).isOk());
+ EXPECT_FALSE(result);
+
+ // Test cancel valid jobId in arbitrary order.
+ EXPECT_TRUE(mClient1->cancelJob(2, &result).isOk());
+ EXPECT_TRUE(result);
+
+ EXPECT_TRUE(mClient1->cancelJob(0, &result).isOk());
+ EXPECT_TRUE(result);
+
+ EXPECT_TRUE(mClient1->cancelJob(1, &result).isOk());
+ EXPECT_TRUE(result);
+
+ // Test cancel job again fails.
+ EXPECT_TRUE(mClient1->cancelJob(1, &result).isOk());
+ EXPECT_FALSE(result);
+
+ // Test get job after cancel fails.
+ EXPECT_TRUE(mClient1->getJobWithId(2, &job, &result).isOk());
+ EXPECT_FALSE(result);
+
+ // Test jobId independence for each client.
+ EXPECT_TRUE(mClient2->submitRequest(request, &job, &result).isOk());
+ EXPECT_TRUE(result);
+ EXPECT_EQ(job.jobId, 0);
+
+ EXPECT_TRUE(mClient2->submitRequest(request, &job, &result).isOk());
+ EXPECT_TRUE(result);
+ EXPECT_EQ(job.jobId, 1);
+
+ unregisterMultipleClients();
+}
+
} // namespace media
} // namespace android