blob: 3bc7b151111d3a6eca0ed0cb23af10d75a601e85 [file] [log] [blame]
hkuang9c04b8d2020-01-22 10:03:21 -08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Chong Zhang182b06a2020-04-09 14:38:05 -070017// Unit Test for MediaTranscodingService.
hkuang9c04b8d2020-01-22 10:03:21 -080018
19//#define LOG_NDEBUG 0
20#define LOG_TAG "MediaTranscodingServiceTest"
21
Chong Zhang182b06a2020-04-09 14:38:05 -070022#include <aidl/android/media/BnTranscodingClientCallback.h>
hkuang9c04b8d2020-01-22 10:03:21 -080023#include <aidl/android/media/IMediaTranscodingService.h>
Chong Zhang8e062632020-03-31 10:56:37 -070024#include <aidl/android/media/ITranscodingClient.h>
Chong Zhang182b06a2020-04-09 14:38:05 -070025#include <aidl/android/media/ITranscodingClientCallback.h>
26#include <aidl/android/media/TranscodingJobParcel.h>
Chong Zhang75222182020-04-29 14:43:42 -070027#include <aidl/android/media/TranscodingJobPriority.h>
Chong Zhang182b06a2020-04-09 14:38:05 -070028#include <aidl/android/media/TranscodingRequestParcel.h>
hkuang9c04b8d2020-01-22 10:03:21 -080029#include <android-base/logging.h>
hkuang9c04b8d2020-01-22 10:03:21 -080030#include <android/binder_manager.h>
31#include <android/binder_process.h>
Chong Zhang75222182020-04-29 14:43:42 -070032#include <binder/PermissionController.h>
33#include <cutils/multiuser.h>
hkuang9c04b8d2020-01-22 10:03:21 -080034#include <gtest/gtest.h>
hkuang9c04b8d2020-01-22 10:03:21 -080035#include <utils/Log.h>
36
Chong Zhang75222182020-04-29 14:43:42 -070037#include <iostream>
38#include <list>
39
40#include "SimulatedTranscoder.h"
41
hkuang9c04b8d2020-01-22 10:03:21 -080042namespace android {
43
44namespace media {
45
46using Status = ::ndk::ScopedAStatus;
Chong Zhang182b06a2020-04-09 14:38:05 -070047using aidl::android::media::BnTranscodingClientCallback;
hkuang9c04b8d2020-01-22 10:03:21 -080048using aidl::android::media::IMediaTranscodingService;
Chong Zhang182b06a2020-04-09 14:38:05 -070049using aidl::android::media::ITranscodingClient;
50using aidl::android::media::ITranscodingClientCallback;
51using aidl::android::media::TranscodingJobParcel;
Chong Zhang75222182020-04-29 14:43:42 -070052using aidl::android::media::TranscodingJobPriority;
Chong Zhang182b06a2020-04-09 14:38:05 -070053using aidl::android::media::TranscodingRequestParcel;
hkuang9c04b8d2020-01-22 10:03:21 -080054
55// Note that -1 is valid and means using calling pid/uid for the service. But only privilege caller could
56// use them. This test is not a privilege caller.
57constexpr int32_t kInvalidClientPid = -5;
Chong Zhang8e062632020-03-31 10:56:37 -070058constexpr const char* kInvalidClientName = "";
hkuang9c04b8d2020-01-22 10:03:21 -080059constexpr const char* kInvalidClientOpPackageName = "";
60
Chong Zhang182b06a2020-04-09 14:38:05 -070061constexpr int32_t kClientUseCallingPid = IMediaTranscodingService::USE_CALLING_PID;
62constexpr int32_t kClientUseCallingUid = IMediaTranscodingService::USE_CALLING_UID;
Chong Zhang75222182020-04-29 14:43:42 -070063
64constexpr uid_t kClientUid = 5000;
65#define UID(n) (kClientUid + (n))
66
67constexpr int32_t kClientId = 0;
68#define CLIENT(n) (kClientId + (n))
69
Chong Zhangdd7aeb42020-06-11 11:11:44 -070070constexpr int64_t kPaddingUs = 1000000;
Chong Zhang75222182020-04-29 14:43:42 -070071constexpr int64_t kJobWithPaddingUs = SimulatedTranscoder::kJobDurationUs + kPaddingUs;
72
Chong Zhang8e062632020-03-31 10:56:37 -070073constexpr const char* kClientName = "TestClient";
74constexpr const char* kClientOpPackageName = "TestClientPackage";
Chong Zhang75222182020-04-29 14:43:42 -070075constexpr const char* kClientPackageA = "com.android.tests.transcoding.testapp.A";
76constexpr const char* kClientPackageB = "com.android.tests.transcoding.testapp.B";
77constexpr const char* kClientPackageC = "com.android.tests.transcoding.testapp.C";
78constexpr const char* kTestActivityName = "/com.android.tests.transcoding.MainActivity";
hkuang9c04b8d2020-01-22 10:03:21 -080079
Chong Zhang75222182020-04-29 14:43:42 -070080static status_t getUidForPackage(String16 packageName, userid_t userId, /*inout*/ uid_t& uid) {
81 PermissionController pc;
82 uid = pc.getPackageUid(packageName, 0);
83 if (uid <= 0) {
84 ALOGE("Unknown package: '%s'", String8(packageName).string());
85 return BAD_VALUE;
86 }
hkuang9c04b8d2020-01-22 10:03:21 -080087
Chong Zhang75222182020-04-29 14:43:42 -070088 if (userId < 0) {
89 ALOGE("Invalid user: %d", userId);
90 return BAD_VALUE;
91 }
92
93 uid = multiuser_get_uid(userId, uid);
94 return NO_ERROR;
95}
96
97struct ShellHelper {
98 static bool RunCmd(const std::string& cmdStr) {
99 int ret = system(cmdStr.c_str());
100 if (ret != 0) {
101 ALOGE("Failed to run cmd: %s, exitcode %d", cmdStr.c_str(), ret);
102 return false;
103 }
104 return true;
105 }
106
107 static bool Start(const char* packageName, const char* activityName) {
108 return RunCmd("am start -W " + std::string(packageName) + std::string(activityName) +
109 " &> /dev/null");
110 }
111
112 static bool Stop(const char* packageName) {
113 return RunCmd("am force-stop " + std::string(packageName));
114 }
115};
116
117struct EventTracker {
118 struct Event {
119 enum { NoEvent, Start, Pause, Resume, Finished, Failed } type;
120 int64_t clientId;
121 int32_t jobId;
122 };
123
124#define DECLARE_EVENT(action) \
125 static Event action(int32_t clientId, int32_t jobId) { \
126 return {Event::action, clientId, jobId}; \
127 }
128
129 DECLARE_EVENT(Start);
130 DECLARE_EVENT(Pause);
131 DECLARE_EVENT(Resume);
132 DECLARE_EVENT(Finished);
133 DECLARE_EVENT(Failed);
134
135 static constexpr Event NoEvent = {Event::NoEvent, 0, 0};
136
137 static std::string toString(const Event& event) {
138 std::string eventStr;
139 switch (event.type) {
140 case Event::Start:
141 eventStr = "Start";
142 break;
143 case Event::Pause:
144 eventStr = "Pause";
145 break;
146 case Event::Resume:
147 eventStr = "Resume";
148 break;
149 case Event::Finished:
150 eventStr = "Finished";
151 break;
152 case Event::Failed:
153 eventStr = "Failed";
154 break;
155 default:
156 return "NoEvent";
157 }
158 return "job {" + std::to_string(event.clientId) + ", " + std::to_string(event.jobId) +
159 "}: " + eventStr;
160 }
161
162 // Pop 1 event from front, wait for up to timeoutUs if empty.
163 const Event& pop(int64_t timeoutUs = 0) {
164 std::unique_lock lock(mLock);
165
166 if (mEventQueue.empty() && timeoutUs > 0) {
167 mCondition.wait_for(lock, std::chrono::microseconds(timeoutUs));
168 }
169
170 if (mEventQueue.empty()) {
171 mPoppedEvent = NoEvent;
172 } else {
173 mPoppedEvent = *mEventQueue.begin();
174 mEventQueue.pop_front();
175 }
176
177 return mPoppedEvent;
178 }
179
180 // Push 1 event to back.
181 void append(const Event& event) {
182 ALOGD("%s", toString(event).c_str());
183
184 std::unique_lock lock(mLock);
185
186 mEventQueue.push_back(event);
187 mCondition.notify_one();
188 }
189
190private:
191 std::mutex mLock;
192 std::condition_variable mCondition;
193 Event mPoppedEvent;
194 std::list<Event> mEventQueue;
195};
196
197// Operators for GTest macros.
198bool operator==(const EventTracker::Event& lhs, const EventTracker::Event& rhs) {
199 return lhs.type == rhs.type && lhs.clientId == rhs.clientId && lhs.jobId == rhs.jobId;
200}
201
202std::ostream& operator<<(std::ostream& str, const EventTracker::Event& v) {
203 str << EventTracker::toString(v);
204 return str;
205}
206
207struct TestClientCallback : public BnTranscodingClientCallback, public EventTracker {
208 TestClientCallback(int32_t id) : mClientId(id) {
209 ALOGI("TestClientCallback %d Created", mClientId);
210 }
211
212 virtual ~TestClientCallback() { ALOGI("TestClientCallback %d destroyed", mClientId); }
hkuang9c04b8d2020-01-22 10:03:21 -0800213
hkuang19253092020-06-01 09:10:49 -0700214 Status openFileDescriptor(const std::string& /*in_fileUri*/, const std::string& /*in_mode*/,
215 ::ndk::ScopedFileDescriptor* /*_aidl_return*/) override {
216 return Status::ok();
217 }
218
Chong Zhangde60f062020-06-11 17:05:10 -0700219 Status onTranscodingStarted(int32_t in_jobId) override {
220 append(Start(mClientId, in_jobId));
221 return Status::ok();
222 }
hkuang96471b82020-06-08 11:12:46 -0700223
Chong Zhangde60f062020-06-11 17:05:10 -0700224 Status onTranscodingPaused(int32_t in_jobId) override {
225 append(Pause(mClientId, in_jobId));
226 return Status::ok();
227 }
hkuang96471b82020-06-08 11:12:46 -0700228
Chong Zhangde60f062020-06-11 17:05:10 -0700229 Status onTranscodingResumed(int32_t in_jobId) override {
230 append(Resume(mClientId, in_jobId));
231 return Status::ok();
232 }
hkuang96471b82020-06-08 11:12:46 -0700233
hkuang9c04b8d2020-01-22 10:03:21 -0800234 Status onTranscodingFinished(
Chong Zhang75222182020-04-29 14:43:42 -0700235 int32_t in_jobId,
hkuang9c04b8d2020-01-22 10:03:21 -0800236 const ::aidl::android::media::TranscodingResultParcel& /* in_result */) override {
Chong Zhang75222182020-04-29 14:43:42 -0700237 append(Finished(mClientId, in_jobId));
hkuang9c04b8d2020-01-22 10:03:21 -0800238 return Status::ok();
239 }
240
241 Status onTranscodingFailed(
Chong Zhang75222182020-04-29 14:43:42 -0700242 int32_t in_jobId,
243 ::aidl::android::media::TranscodingErrorCode /* in_errorCode */) override {
244 append(Failed(mClientId, in_jobId));
hkuang9c04b8d2020-01-22 10:03:21 -0800245 return Status::ok();
246 }
247
248 Status onAwaitNumberOfJobsChanged(int32_t /* in_jobId */, int32_t /* in_oldAwaitNumber */,
249 int32_t /* in_newAwaitNumber */) override {
250 return Status::ok();
251 }
252
Chong Zhangde60f062020-06-11 17:05:10 -0700253 Status onProgressUpdate(int32_t /*in_jobId*/, int32_t /*in_progress*/) override {
hkuang9c04b8d2020-01-22 10:03:21 -0800254 return Status::ok();
255 }
Chong Zhang75222182020-04-29 14:43:42 -0700256
257 int32_t mClientId;
hkuang9c04b8d2020-01-22 10:03:21 -0800258};
259
Chong Zhang8e062632020-03-31 10:56:37 -0700260class MediaTranscodingServiceTest : public ::testing::Test {
261public:
Chong Zhang75222182020-04-29 14:43:42 -0700262 MediaTranscodingServiceTest() { ALOGI("MediaTranscodingServiceTest created"); }
Chong Zhang8e062632020-03-31 10:56:37 -0700263
Chong Zhang75222182020-04-29 14:43:42 -0700264 ~MediaTranscodingServiceTest() { ALOGI("MediaTranscodingingServiceTest destroyed"); }
Chong Zhang8e062632020-03-31 10:56:37 -0700265
266 void SetUp() override {
Chong Zhang75222182020-04-29 14:43:42 -0700267 // Need thread pool to receive callbacks, otherwise oneway callbacks are
268 // silently ignored.
269 ABinderProcess_startThreadPool();
Chong Zhang8e062632020-03-31 10:56:37 -0700270 ::ndk::SpAIBinder binder(AServiceManager_getService("media.transcoding"));
271 mService = IMediaTranscodingService::fromBinder(binder);
272 if (mService == nullptr) {
273 ALOGE("Failed to connect to the media.trascoding service.");
274 return;
275 }
Chong Zhang75222182020-04-29 14:43:42 -0700276 mClientCallback1 = ::ndk::SharedRefBase::make<TestClientCallback>(CLIENT(1));
277 mClientCallback2 = ::ndk::SharedRefBase::make<TestClientCallback>(CLIENT(2));
278 mClientCallback3 = ::ndk::SharedRefBase::make<TestClientCallback>(CLIENT(3));
279 }
280
281 std::shared_ptr<ITranscodingClient> registerOneClient(
282 const char* packageName, const std::shared_ptr<TestClientCallback>& callback,
283 uid_t defaultUid) {
284 uid_t uid;
285 if (getUidForPackage(String16(packageName), 0 /*userId*/, uid) != NO_ERROR) {
286 uid = defaultUid;
287 }
288
289 ALOGD("registering %s with uid %d", packageName, uid);
290
291 std::shared_ptr<ITranscodingClient> client;
292 Status status = mService->registerClient(callback, kClientName, packageName, uid,
293 kClientUseCallingPid, &client);
294 return status.isOk() ? client : nullptr;
Chong Zhang182b06a2020-04-09 14:38:05 -0700295 }
296
297 void registerMultipleClients() {
298 // Register 3 clients.
Chong Zhang75222182020-04-29 14:43:42 -0700299 mClient1 = registerOneClient(kClientPackageA, mClientCallback1, UID(1));
Chong Zhang182b06a2020-04-09 14:38:05 -0700300 EXPECT_TRUE(mClient1 != nullptr);
301
Chong Zhang75222182020-04-29 14:43:42 -0700302 mClient2 = registerOneClient(kClientPackageB, mClientCallback2, UID(2));
Chong Zhang182b06a2020-04-09 14:38:05 -0700303 EXPECT_TRUE(mClient2 != nullptr);
304
Chong Zhang75222182020-04-29 14:43:42 -0700305 mClient3 = registerOneClient(kClientPackageC, mClientCallback3, UID(3));
Chong Zhang182b06a2020-04-09 14:38:05 -0700306 EXPECT_TRUE(mClient3 != nullptr);
307
308 // Check the number of clients.
309 int32_t numOfClients;
Chong Zhang75222182020-04-29 14:43:42 -0700310 Status status = mService->getNumOfClients(&numOfClients);
Chong Zhang182b06a2020-04-09 14:38:05 -0700311 EXPECT_TRUE(status.isOk());
312 EXPECT_EQ(3, numOfClients);
313 }
314
315 void unregisterMultipleClients() {
Chong Zhang75222182020-04-29 14:43:42 -0700316 Status status;
317
Chong Zhang182b06a2020-04-09 14:38:05 -0700318 // Unregister the clients.
Chong Zhang75222182020-04-29 14:43:42 -0700319 status = mClient1->unregister();
Chong Zhang182b06a2020-04-09 14:38:05 -0700320 EXPECT_TRUE(status.isOk());
321
322 status = mClient2->unregister();
323 EXPECT_TRUE(status.isOk());
324
325 status = mClient3->unregister();
326 EXPECT_TRUE(status.isOk());
327
328 // Check the number of clients.
329 int32_t numOfClients;
330 status = mService->getNumOfClients(&numOfClients);
331 EXPECT_TRUE(status.isOk());
332 EXPECT_EQ(0, numOfClients);
Chong Zhang8e062632020-03-31 10:56:37 -0700333 }
334
Chong Zhang75222182020-04-29 14:43:42 -0700335 static constexpr bool success = true;
336 static constexpr bool fail = false;
337
338 template <bool expectation = success>
339 bool submit(const std::shared_ptr<ITranscodingClient>& client, int32_t jobId,
hkuang72d105f2020-05-21 10:48:55 -0700340 const char* sourceFilePath, const char* destinationFilePath,
Chong Zhang75222182020-04-29 14:43:42 -0700341 TranscodingJobPriority priority = TranscodingJobPriority::kNormal) {
342 constexpr bool shouldSucceed = (expectation == success);
343 bool result;
344 TranscodingRequestParcel request;
345 TranscodingJobParcel job;
346
hkuang72d105f2020-05-21 10:48:55 -0700347 request.sourceFilePath = sourceFilePath;
348 request.destinationFilePath = destinationFilePath;
Chong Zhang75222182020-04-29 14:43:42 -0700349 request.priority = priority;
350 Status status = client->submitRequest(request, &job, &result);
351
352 EXPECT_TRUE(status.isOk());
353 EXPECT_EQ(result, shouldSucceed);
354 if (shouldSucceed) {
355 EXPECT_EQ(job.jobId, jobId);
356 }
357
358 return status.isOk() && (result == shouldSucceed) && (!shouldSucceed || job.jobId == jobId);
359 }
360
361 template <bool expectation = success>
362 bool cancel(const std::shared_ptr<ITranscodingClient>& client, int32_t jobId) {
363 constexpr bool shouldSucceed = (expectation == success);
364 bool result;
365 Status status = client->cancelJob(jobId, &result);
366
367 EXPECT_TRUE(status.isOk());
368 EXPECT_EQ(result, shouldSucceed);
369
370 return status.isOk() && (result == shouldSucceed);
371 }
372
373 template <bool expectation = success>
374 bool getJob(const std::shared_ptr<ITranscodingClient>& client, int32_t jobId,
hkuang72d105f2020-05-21 10:48:55 -0700375 const char* sourceFilePath, const char* destinationFilePath) {
Chong Zhang75222182020-04-29 14:43:42 -0700376 constexpr bool shouldSucceed = (expectation == success);
377 bool result;
378 TranscodingJobParcel job;
379 Status status = client->getJobWithId(jobId, &job, &result);
380
381 EXPECT_TRUE(status.isOk());
382 EXPECT_EQ(result, shouldSucceed);
383 if (shouldSucceed) {
384 EXPECT_EQ(job.jobId, jobId);
hkuang72d105f2020-05-21 10:48:55 -0700385 EXPECT_EQ(job.request.sourceFilePath, sourceFilePath);
Chong Zhang75222182020-04-29 14:43:42 -0700386 }
387
388 return status.isOk() && (result == shouldSucceed) &&
Chong Zhangde60f062020-06-11 17:05:10 -0700389 (!shouldSucceed ||
390 (job.jobId == jobId && job.request.sourceFilePath == sourceFilePath &&
391 job.request.destinationFilePath == destinationFilePath));
Chong Zhang75222182020-04-29 14:43:42 -0700392 }
393
Chong Zhang8e062632020-03-31 10:56:37 -0700394 std::shared_ptr<IMediaTranscodingService> mService;
Chong Zhang75222182020-04-29 14:43:42 -0700395 std::shared_ptr<TestClientCallback> mClientCallback1;
396 std::shared_ptr<TestClientCallback> mClientCallback2;
397 std::shared_ptr<TestClientCallback> mClientCallback3;
Chong Zhang182b06a2020-04-09 14:38:05 -0700398 std::shared_ptr<ITranscodingClient> mClient1;
399 std::shared_ptr<ITranscodingClient> mClient2;
400 std::shared_ptr<ITranscodingClient> mClient3;
Chong Zhang8e062632020-03-31 10:56:37 -0700401};
402
hkuang9c04b8d2020-01-22 10:03:21 -0800403TEST_F(MediaTranscodingServiceTest, TestRegisterNullClient) {
Chong Zhang8e062632020-03-31 10:56:37 -0700404 std::shared_ptr<ITranscodingClient> client;
405
Chong Zhang182b06a2020-04-09 14:38:05 -0700406 // Register the client with null callback.
407 Status status = mService->registerClient(nullptr, kClientName, kClientOpPackageName,
408 kClientUseCallingUid, kClientUseCallingPid, &client);
hkuang9c04b8d2020-01-22 10:03:21 -0800409 EXPECT_FALSE(status.isOk());
410}
411
412TEST_F(MediaTranscodingServiceTest, TestRegisterClientWithInvalidClientPid) {
Chong Zhang8e062632020-03-31 10:56:37 -0700413 std::shared_ptr<ITranscodingClient> client;
hkuang9c04b8d2020-01-22 10:03:21 -0800414
415 // Register the client with the service.
Chong Zhang75222182020-04-29 14:43:42 -0700416 Status status = mService->registerClient(mClientCallback1, kClientName, kClientOpPackageName,
Chong Zhang182b06a2020-04-09 14:38:05 -0700417 kClientUseCallingUid, kInvalidClientPid, &client);
Chong Zhang8e062632020-03-31 10:56:37 -0700418 EXPECT_FALSE(status.isOk());
419}
420
421TEST_F(MediaTranscodingServiceTest, TestRegisterClientWithInvalidClientName) {
422 std::shared_ptr<ITranscodingClient> client;
423
424 // Register the client with the service.
Chong Zhang75222182020-04-29 14:43:42 -0700425 Status status = mService->registerClient(mClientCallback1, kInvalidClientName,
Chong Zhang182b06a2020-04-09 14:38:05 -0700426 kInvalidClientOpPackageName, kClientUseCallingUid,
427 kClientUseCallingPid, &client);
hkuang9c04b8d2020-01-22 10:03:21 -0800428 EXPECT_FALSE(status.isOk());
429}
430
431TEST_F(MediaTranscodingServiceTest, TestRegisterClientWithInvalidClientPackageName) {
Chong Zhang8e062632020-03-31 10:56:37 -0700432 std::shared_ptr<ITranscodingClient> client;
hkuang9c04b8d2020-01-22 10:03:21 -0800433
434 // Register the client with the service.
Chong Zhang182b06a2020-04-09 14:38:05 -0700435 Status status =
Chong Zhang75222182020-04-29 14:43:42 -0700436 mService->registerClient(mClientCallback1, kClientName, kInvalidClientOpPackageName,
Chong Zhang182b06a2020-04-09 14:38:05 -0700437 kClientUseCallingUid, kClientUseCallingPid, &client);
hkuang9c04b8d2020-01-22 10:03:21 -0800438 EXPECT_FALSE(status.isOk());
439}
440
441TEST_F(MediaTranscodingServiceTest, TestRegisterOneClient) {
Chong Zhang8e062632020-03-31 10:56:37 -0700442 std::shared_ptr<ITranscodingClient> client;
hkuang9c04b8d2020-01-22 10:03:21 -0800443
Chong Zhang75222182020-04-29 14:43:42 -0700444 Status status = mService->registerClient(mClientCallback1, kClientName, kClientOpPackageName,
Chong Zhang182b06a2020-04-09 14:38:05 -0700445 kClientUseCallingUid, kClientUseCallingPid, &client);
hkuang9c04b8d2020-01-22 10:03:21 -0800446 EXPECT_TRUE(status.isOk());
447
Chong Zhang8e062632020-03-31 10:56:37 -0700448 // Validate the client.
449 EXPECT_TRUE(client != nullptr);
hkuang9c04b8d2020-01-22 10:03:21 -0800450
451 // Check the number of Clients.
452 int32_t numOfClients;
453 status = mService->getNumOfClients(&numOfClients);
454 EXPECT_TRUE(status.isOk());
455 EXPECT_EQ(1, numOfClients);
456
457 // Unregister the client.
Chong Zhang8e062632020-03-31 10:56:37 -0700458 status = client->unregister();
hkuang9c04b8d2020-01-22 10:03:21 -0800459 EXPECT_TRUE(status.isOk());
hkuang9c04b8d2020-01-22 10:03:21 -0800460
461 // Check the number of Clients.
hkuang9c04b8d2020-01-22 10:03:21 -0800462 status = mService->getNumOfClients(&numOfClients);
463 EXPECT_TRUE(status.isOk());
Chong Zhang8e062632020-03-31 10:56:37 -0700464 EXPECT_EQ(0, numOfClients);
hkuang9c04b8d2020-01-22 10:03:21 -0800465}
466
467TEST_F(MediaTranscodingServiceTest, TestRegisterClientTwice) {
Chong Zhang8e062632020-03-31 10:56:37 -0700468 std::shared_ptr<ITranscodingClient> client;
hkuang9c04b8d2020-01-22 10:03:21 -0800469
Chong Zhang75222182020-04-29 14:43:42 -0700470 Status status = mService->registerClient(mClientCallback1, kClientName, kClientOpPackageName,
Chong Zhang182b06a2020-04-09 14:38:05 -0700471 kClientUseCallingUid, kClientUseCallingPid, &client);
hkuang9c04b8d2020-01-22 10:03:21 -0800472 EXPECT_TRUE(status.isOk());
473
Chong Zhang8e062632020-03-31 10:56:37 -0700474 // Validate the client.
475 EXPECT_TRUE(client != nullptr);
hkuang9c04b8d2020-01-22 10:03:21 -0800476
477 // Register the client again and expects failure.
Chong Zhang8e062632020-03-31 10:56:37 -0700478 std::shared_ptr<ITranscodingClient> client1;
Chong Zhang75222182020-04-29 14:43:42 -0700479 status = mService->registerClient(mClientCallback1, kClientName, kClientOpPackageName,
Chong Zhang182b06a2020-04-09 14:38:05 -0700480 kClientUseCallingUid, kClientUseCallingPid, &client1);
hkuang9c04b8d2020-01-22 10:03:21 -0800481 EXPECT_FALSE(status.isOk());
482
Chong Zhang8e062632020-03-31 10:56:37 -0700483 // Unregister the client.
484 status = client->unregister();
485 EXPECT_TRUE(status.isOk());
hkuang9c04b8d2020-01-22 10:03:21 -0800486}
487
Chong Zhang8e062632020-03-31 10:56:37 -0700488TEST_F(MediaTranscodingServiceTest, TestRegisterMultipleClients) {
Chong Zhang182b06a2020-04-09 14:38:05 -0700489 registerMultipleClients();
490 unregisterMultipleClients();
Chong Zhang8e062632020-03-31 10:56:37 -0700491}
Chong Zhang182b06a2020-04-09 14:38:05 -0700492
Chong Zhang75222182020-04-29 14:43:42 -0700493TEST_F(MediaTranscodingServiceTest, TestJobIdIndependence) {
494 registerMultipleClients();
495
496 // Submit 2 requests on client1 first.
hkuang72d105f2020-05-21 10:48:55 -0700497 EXPECT_TRUE(submit(mClient1, 0, "test_source_file", "test_destination_file"));
498 EXPECT_TRUE(submit(mClient1, 1, "test_source_file", "test_destination_file"));
Chong Zhang75222182020-04-29 14:43:42 -0700499
500 // Submit 2 requests on client2, jobId should be independent for each client.
hkuang72d105f2020-05-21 10:48:55 -0700501 EXPECT_TRUE(submit(mClient2, 0, "test_source_file", "test_destination_file"));
502 EXPECT_TRUE(submit(mClient2, 1, "test_source_file", "test_destination_file"));
Chong Zhang75222182020-04-29 14:43:42 -0700503
504 // Cancel all jobs.
505 EXPECT_TRUE(cancel(mClient1, 0));
506 EXPECT_TRUE(cancel(mClient1, 1));
507 EXPECT_TRUE(cancel(mClient2, 0));
508 EXPECT_TRUE(cancel(mClient2, 1));
509
510 unregisterMultipleClients();
511}
512
513TEST_F(MediaTranscodingServiceTest, TestSubmitCancelJobs) {
Chong Zhang182b06a2020-04-09 14:38:05 -0700514 registerMultipleClients();
515
516 // Test jobId assignment.
hkuang72d105f2020-05-21 10:48:55 -0700517 EXPECT_TRUE(submit(mClient1, 0, "test_source_file_0", "test_destination_file"));
518 EXPECT_TRUE(submit(mClient1, 1, "test_source_file_1", "test_destination_file"));
519 EXPECT_TRUE(submit(mClient1, 2, "test_source_file_2", "test_destination_file"));
Chong Zhang182b06a2020-04-09 14:38:05 -0700520
hkuang72d105f2020-05-21 10:48:55 -0700521 // Test submit bad request (no valid sourceFilePath) fails.
522 EXPECT_TRUE(submit<fail>(mClient1, 0, "", ""));
Chong Zhang182b06a2020-04-09 14:38:05 -0700523
Chong Zhang75222182020-04-29 14:43:42 -0700524 // Test cancel non-existent job fails.
525 EXPECT_TRUE(cancel<fail>(mClient1, 100));
Chong Zhang182b06a2020-04-09 14:38:05 -0700526
Chong Zhang75222182020-04-29 14:43:42 -0700527 // Job 0 should start immediately and finish in 2 seconds, followed by Job 1 start.
528 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
529 EXPECT_EQ(mClientCallback1->pop(kJobWithPaddingUs), EventTracker::Finished(CLIENT(1), 0));
530 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 1));
Chong Zhang182b06a2020-04-09 14:38:05 -0700531
Chong Zhang75222182020-04-29 14:43:42 -0700532 // Test cancel valid jobId in random order.
533 // Test cancel finished job fails.
534 EXPECT_TRUE(cancel(mClient1, 2));
535 EXPECT_TRUE(cancel<fail>(mClient1, 0));
536 EXPECT_TRUE(cancel(mClient1, 1));
Chong Zhang182b06a2020-04-09 14:38:05 -0700537
538 // Test cancel job again fails.
Chong Zhang75222182020-04-29 14:43:42 -0700539 EXPECT_TRUE(cancel<fail>(mClient1, 1));
Chong Zhang182b06a2020-04-09 14:38:05 -0700540
Chong Zhang75222182020-04-29 14:43:42 -0700541 // Test no more events arriving after cancel.
542 EXPECT_EQ(mClientCallback1->pop(kJobWithPaddingUs), EventTracker::NoEvent);
Chong Zhang182b06a2020-04-09 14:38:05 -0700543
544 unregisterMultipleClients();
545}
546
Chong Zhang75222182020-04-29 14:43:42 -0700547TEST_F(MediaTranscodingServiceTest, TestGetJobs) {
548 registerMultipleClients();
549
550 // Submit 3 requests.
hkuang72d105f2020-05-21 10:48:55 -0700551 EXPECT_TRUE(submit(mClient1, 0, "test_source_file_0", "test_destination_file_0"));
552 EXPECT_TRUE(submit(mClient1, 1, "test_source_file_1", "test_destination_file_1"));
553 EXPECT_TRUE(submit(mClient1, 2, "test_source_file_2", "test_destination_file_2"));
Chong Zhang75222182020-04-29 14:43:42 -0700554
555 // Test get jobs by id.
hkuang72d105f2020-05-21 10:48:55 -0700556 EXPECT_TRUE(getJob(mClient1, 2, "test_source_file_2", "test_destination_file_2"));
557 EXPECT_TRUE(getJob(mClient1, 1, "test_source_file_1", "test_destination_file_1"));
558 EXPECT_TRUE(getJob(mClient1, 0, "test_source_file_0", "test_destination_file_0"));
Chong Zhang75222182020-04-29 14:43:42 -0700559
560 // Test get job by invalid id fails.
hkuang72d105f2020-05-21 10:48:55 -0700561 EXPECT_TRUE(getJob<fail>(mClient1, 100, "", ""));
562 EXPECT_TRUE(getJob<fail>(mClient1, -1, "", ""));
Chong Zhang75222182020-04-29 14:43:42 -0700563
564 // Test get job after cancel fails.
565 EXPECT_TRUE(cancel(mClient1, 2));
hkuang72d105f2020-05-21 10:48:55 -0700566 EXPECT_TRUE(getJob<fail>(mClient1, 2, "", ""));
Chong Zhang75222182020-04-29 14:43:42 -0700567
568 // Job 0 should start immediately and finish in 2 seconds, followed by Job 1 start.
569 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
570 EXPECT_EQ(mClientCallback1->pop(kJobWithPaddingUs), EventTracker::Finished(CLIENT(1), 0));
571 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 1));
572
573 // Test get job after finish fails.
hkuang72d105f2020-05-21 10:48:55 -0700574 EXPECT_TRUE(getJob<fail>(mClient1, 0, "", ""));
Chong Zhang75222182020-04-29 14:43:42 -0700575
576 // Test get the remaining job 1.
hkuang72d105f2020-05-21 10:48:55 -0700577 EXPECT_TRUE(getJob(mClient1, 1, "test_source_file_1", "test_destination_file_1"));
Chong Zhang75222182020-04-29 14:43:42 -0700578
579 // Cancel remaining job 1.
580 EXPECT_TRUE(cancel(mClient1, 1));
581
582 unregisterMultipleClients();
583}
584
585TEST_F(MediaTranscodingServiceTest, TestSubmitCancelWithOfflineJobs) {
586 registerMultipleClients();
587
588 // Submit some offline jobs first.
Chong Zhangde60f062020-06-11 17:05:10 -0700589 EXPECT_TRUE(submit(mClient1, 0, "test_source_file_0", "test_destination_file_0",
590 TranscodingJobPriority::kUnspecified));
591 EXPECT_TRUE(submit(mClient1, 1, "test_source_file_1", "test_destination_file_1",
592 TranscodingJobPriority::kUnspecified));
Chong Zhang75222182020-04-29 14:43:42 -0700593
594 // Job 0 should start immediately.
595 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
596
597 // Submit more real-time jobs.
hkuang72d105f2020-05-21 10:48:55 -0700598 EXPECT_TRUE(submit(mClient1, 2, "test_source_file_2", "test_destination_file_2"));
599 EXPECT_TRUE(submit(mClient1, 3, "test_source_file_3", "test_destination_file_3"));
Chong Zhang75222182020-04-29 14:43:42 -0700600
601 // Job 0 should pause immediately and job 2 should start.
602 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Pause(CLIENT(1), 0));
603 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 2));
604
605 // Job 2 should finish in 2 seconds and job 3 should start.
606 EXPECT_EQ(mClientCallback1->pop(kJobWithPaddingUs), EventTracker::Finished(CLIENT(1), 2));
607 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 3));
608
609 // Cancel job 3 now
610 EXPECT_TRUE(cancel(mClient1, 3));
611
612 // Job 0 should resume and finish in 2 seconds, followed by job 1 start.
613 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Resume(CLIENT(1), 0));
614 EXPECT_EQ(mClientCallback1->pop(kJobWithPaddingUs), EventTracker::Finished(CLIENT(1), 0));
615 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 1));
616
617 // Cancel remaining job 1.
618 EXPECT_TRUE(cancel(mClient1, 1));
619
620 unregisterMultipleClients();
621}
622
Chong Zhang15c192a2020-05-05 16:24:00 -0700623TEST_F(MediaTranscodingServiceTest, TestClientUseAfterUnregister) {
624 std::shared_ptr<ITranscodingClient> client;
625
626 // Register a client, then unregister.
627 Status status = mService->registerClient(mClientCallback1, kClientName, kClientOpPackageName,
628 kClientUseCallingUid, kClientUseCallingPid, &client);
629 EXPECT_TRUE(status.isOk());
630
631 status = client->unregister();
632 EXPECT_TRUE(status.isOk());
633
634 // Test various operations on the client, should fail with ERROR_DISCONNECTED.
635 TranscodingJobParcel job;
636 bool result;
637 status = client->getJobWithId(0, &job, &result);
638 EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
639
640 status = client->cancelJob(0, &result);
641 EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
642
643 TranscodingRequestParcel request;
644 status = client->submitRequest(request, &job, &result);
645 EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
646}
647
Chong Zhang75222182020-04-29 14:43:42 -0700648TEST_F(MediaTranscodingServiceTest, TestTranscodingUidPolicy) {
649 ALOGD("TestTranscodingUidPolicy starting...");
650
651 EXPECT_TRUE(ShellHelper::RunCmd("input keyevent KEYCODE_WAKEUP"));
652 EXPECT_TRUE(ShellHelper::RunCmd("wm dismiss-keyguard"));
653 EXPECT_TRUE(ShellHelper::Stop(kClientPackageA));
654 EXPECT_TRUE(ShellHelper::Stop(kClientPackageB));
655 EXPECT_TRUE(ShellHelper::Stop(kClientPackageC));
656
657 registerMultipleClients();
658
659 ALOGD("Moving app A to top...");
660 EXPECT_TRUE(ShellHelper::Start(kClientPackageA, kTestActivityName));
661
662 // Submit 3 requests.
663 ALOGD("Submitting job to client1 (app A) ...");
hkuang72d105f2020-05-21 10:48:55 -0700664 EXPECT_TRUE(submit(mClient1, 0, "test_source_file_0", "test_destination_file_0"));
665 EXPECT_TRUE(submit(mClient1, 1, "test_source_file_1", "test_destination_file_1"));
666 EXPECT_TRUE(submit(mClient1, 2, "test_source_file_2", "test_destination_file_2"));
Chong Zhang75222182020-04-29 14:43:42 -0700667
668 // Job 0 should start immediately.
669 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 0));
670
671 ALOGD("Moving app B to top...");
672 EXPECT_TRUE(ShellHelper::Start(kClientPackageB, kTestActivityName));
673
674 // Job 0 should continue and finish in 2 seconds, then job 1 should start.
675 EXPECT_EQ(mClientCallback1->pop(kJobWithPaddingUs), EventTracker::Finished(CLIENT(1), 0));
676 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 1));
677
678 ALOGD("Submitting job to client2 (app B) ...");
hkuang72d105f2020-05-21 10:48:55 -0700679 EXPECT_TRUE(submit(mClient2, 0, "test_source_file_0", "test_destination_file_0"));
Chong Zhang75222182020-04-29 14:43:42 -0700680
681 // Client1's job should pause, client2's job should start.
682 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Pause(CLIENT(1), 1));
683 EXPECT_EQ(mClientCallback2->pop(kPaddingUs), EventTracker::Start(CLIENT(2), 0));
684
685 ALOGD("Moving app A back to top...");
686 EXPECT_TRUE(ShellHelper::Start(kClientPackageA, kTestActivityName));
687
688 // Client2's job should pause, client1's job 1 should resume.
689 EXPECT_EQ(mClientCallback2->pop(kPaddingUs), EventTracker::Pause(CLIENT(2), 0));
690 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Resume(CLIENT(1), 1));
691
692 // Client2's job 1 should finish in 2 seconds, then its job 2 should start.
693 EXPECT_EQ(mClientCallback1->pop(kJobWithPaddingUs), EventTracker::Finished(CLIENT(1), 1));
694 EXPECT_EQ(mClientCallback1->pop(kPaddingUs), EventTracker::Start(CLIENT(1), 2));
695
696 // After client2's jobs finish, client1's job should resume.
697 EXPECT_EQ(mClientCallback1->pop(kJobWithPaddingUs), EventTracker::Finished(CLIENT(1), 2));
698 EXPECT_EQ(mClientCallback2->pop(kPaddingUs), EventTracker::Resume(CLIENT(2), 0));
699
700 unregisterMultipleClients();
701
702 EXPECT_TRUE(ShellHelper::Stop(kClientPackageA));
703 EXPECT_TRUE(ShellHelper::Stop(kClientPackageB));
704 EXPECT_TRUE(ShellHelper::Stop(kClientPackageC));
705
706 ALOGD("TestTranscodingUidPolicy finished.");
707}
708
hkuang9c04b8d2020-01-22 10:03:21 -0800709} // namespace media
710} // namespace android