blob: 723bd77d577d2dc6d9ee49b4294c752a5efff5ec [file] [log] [blame]
Chong Zhang66469272020-06-04 16:51:55 -07001/*
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
17// Unit Test for MediaTranscodingService.
18
19#include <aidl/android/media/BnTranscodingClientCallback.h>
20#include <aidl/android/media/IMediaTranscodingService.h>
21#include <aidl/android/media/ITranscodingClient.h>
22#include <aidl/android/media/ITranscodingClientCallback.h>
Chong Zhang66469272020-06-04 16:51:55 -070023#include <aidl/android/media/TranscodingRequestParcel.h>
Chong Zhangbc062482020-10-14 16:43:53 -070024#include <aidl/android/media/TranscodingSessionParcel.h>
25#include <aidl/android/media/TranscodingSessionPriority.h>
Chong Zhang66469272020-06-04 16:51:55 -070026#include <android-base/logging.h>
27#include <android/binder_manager.h>
28#include <android/binder_process.h>
29#include <binder/PermissionController.h>
30#include <cutils/multiuser.h>
31#include <fcntl.h>
32#include <gtest/gtest.h>
33#include <sys/stat.h>
34#include <sys/types.h>
35#include <utils/Log.h>
36
37#include <iostream>
38#include <list>
39
40#include "SimulatedTranscoder.h"
41
42namespace android {
43
44namespace media {
45
46using Status = ::ndk::ScopedAStatus;
47using aidl::android::media::BnTranscodingClientCallback;
48using aidl::android::media::IMediaTranscodingService;
49using aidl::android::media::ITranscodingClient;
50using aidl::android::media::ITranscodingClientCallback;
Chong Zhang66469272020-06-04 16:51:55 -070051using aidl::android::media::TranscodingRequestParcel;
Chong Zhangbc062482020-10-14 16:43:53 -070052using aidl::android::media::TranscodingSessionParcel;
53using aidl::android::media::TranscodingSessionPriority;
Chong Zhang456787f2021-02-18 16:47:08 -080054using aidl::android::media::TranscodingTestConfig;
Chong Zhang66469272020-06-04 16:51:55 -070055using aidl::android::media::TranscodingVideoTrackFormat;
56
57constexpr int32_t kClientUseCallingPid = IMediaTranscodingService::USE_CALLING_PID;
58
59constexpr uid_t kClientUid = 5000;
60#define UID(n) (kClientUid + (n))
61
Chong Zhang3f23e982020-09-24 14:03:41 -070062constexpr pid_t kClientPid = 10000;
63#define PID(n) (kClientPid + (n))
64
Chong Zhang66469272020-06-04 16:51:55 -070065constexpr int32_t kClientId = 0;
66#define CLIENT(n) (kClientId + (n))
67
68constexpr const char* kClientName = "TestClient";
69constexpr const char* kClientPackageA = "com.android.tests.transcoding.testapp.A";
70constexpr const char* kClientPackageB = "com.android.tests.transcoding.testapp.B";
71constexpr const char* kClientPackageC = "com.android.tests.transcoding.testapp.C";
72
Chong Zhangb55c5452020-06-26 14:32:12 -070073constexpr const char* kTestActivityName = "/com.android.tests.transcoding.MainActivity";
74
Chong Zhang66469272020-06-04 16:51:55 -070075static status_t getUidForPackage(String16 packageName, userid_t userId, /*inout*/ uid_t& uid) {
76 PermissionController pc;
77 uid = pc.getPackageUid(packageName, 0);
78 if (uid <= 0) {
Tomasz Wasilczyk03fc55f2023-08-11 17:05:05 +000079 ALOGE("Unknown package: '%s'", String8(packageName).c_str());
Chong Zhang66469272020-06-04 16:51:55 -070080 return BAD_VALUE;
81 }
82
83 if (userId < 0) {
84 ALOGE("Invalid user: %d", userId);
85 return BAD_VALUE;
86 }
87
88 uid = multiuser_get_uid(userId, uid);
89 return NO_ERROR;
90}
91
92struct ShellHelper {
93 static bool RunCmd(const std::string& cmdStr) {
94 int ret = system(cmdStr.c_str());
95 if (ret != 0) {
96 ALOGE("Failed to run cmd: %s, exitcode %d", cmdStr.c_str(), ret);
97 return false;
98 }
99 return true;
100 }
101
102 static bool Start(const char* packageName, const char* activityName) {
103 return RunCmd("am start -W " + std::string(packageName) + std::string(activityName) +
104 " &> /dev/null");
105 }
106
107 static bool Stop(const char* packageName) {
108 return RunCmd("am force-stop " + std::string(packageName));
109 }
110};
111
112struct EventTracker {
113 struct Event {
114 enum { NoEvent, Start, Pause, Resume, Finished, Failed } type;
115 int64_t clientId;
Chong Zhangbc062482020-10-14 16:43:53 -0700116 int32_t sessionId;
Chong Zhang66469272020-06-04 16:51:55 -0700117 };
118
Chong Zhangbc062482020-10-14 16:43:53 -0700119#define DECLARE_EVENT(action) \
120 static Event action(int32_t clientId, int32_t sessionId) { \
121 return {Event::action, clientId, sessionId}; \
Chong Zhang66469272020-06-04 16:51:55 -0700122 }
123
124 DECLARE_EVENT(Start);
125 DECLARE_EVENT(Pause);
126 DECLARE_EVENT(Resume);
127 DECLARE_EVENT(Finished);
128 DECLARE_EVENT(Failed);
129
130 static constexpr Event NoEvent = {Event::NoEvent, 0, 0};
131
132 static std::string toString(const Event& event) {
133 std::string eventStr;
134 switch (event.type) {
135 case Event::Start:
136 eventStr = "Start";
137 break;
138 case Event::Pause:
139 eventStr = "Pause";
140 break;
141 case Event::Resume:
142 eventStr = "Resume";
143 break;
144 case Event::Finished:
145 eventStr = "Finished";
146 break;
147 case Event::Failed:
148 eventStr = "Failed";
149 break;
150 default:
151 return "NoEvent";
152 }
Chong Zhangbc062482020-10-14 16:43:53 -0700153 return "session {" + std::to_string(event.clientId) + ", " +
154 std::to_string(event.sessionId) + "}: " + eventStr;
Chong Zhang66469272020-06-04 16:51:55 -0700155 }
156
157 // Pop 1 event from front, wait for up to timeoutUs if empty.
158 const Event& pop(int64_t timeoutUs = 0) {
159 std::unique_lock lock(mLock);
160
161 if (mEventQueue.empty() && timeoutUs > 0) {
162 mCondition.wait_for(lock, std::chrono::microseconds(timeoutUs));
163 }
164
165 if (mEventQueue.empty()) {
166 mPoppedEvent = NoEvent;
167 } else {
168 mPoppedEvent = *mEventQueue.begin();
169 mEventQueue.pop_front();
170 }
171
172 return mPoppedEvent;
173 }
174
Chong Zhangf9077512020-09-21 21:02:06 -0700175 bool waitForSpecificEventAndPop(const Event& target, std::list<Event>* outEvents,
176 int64_t timeoutUs = 0) {
177 std::unique_lock lock(mLock);
178
179 auto startTime = std::chrono::system_clock::now();
Chong Zhangbbb4eac2020-11-18 11:12:06 -0800180 int64_t remainingUs = timeoutUs;
Chong Zhangf9077512020-09-21 21:02:06 -0700181
182 std::list<Event>::iterator it;
183 while (((it = std::find(mEventQueue.begin(), mEventQueue.end(), target)) ==
184 mEventQueue.end()) &&
Chong Zhangbbb4eac2020-11-18 11:12:06 -0800185 remainingUs > 0) {
186 std::cv_status status =
187 mCondition.wait_for(lock, std::chrono::microseconds(remainingUs));
Chong Zhangf9077512020-09-21 21:02:06 -0700188 if (status == std::cv_status::timeout) {
189 break;
190 }
191 std::chrono::microseconds elapsedTime = std::chrono::system_clock::now() - startTime;
Chong Zhangbbb4eac2020-11-18 11:12:06 -0800192 remainingUs = timeoutUs - elapsedTime.count();
Chong Zhangf9077512020-09-21 21:02:06 -0700193 }
194
195 if (it == mEventQueue.end()) {
196 return false;
197 }
198 *outEvents = std::list<Event>(mEventQueue.begin(), std::next(it));
199 mEventQueue.erase(mEventQueue.begin(), std::next(it));
200 return true;
201 }
202
Chong Zhang66469272020-06-04 16:51:55 -0700203 // Push 1 event to back.
Chong Zhangb55c5452020-06-26 14:32:12 -0700204 void append(const Event& event,
205 const TranscodingErrorCode err = TranscodingErrorCode::kNoError) {
Chong Zhang66469272020-06-04 16:51:55 -0700206 ALOGD("%s", toString(event).c_str());
207
208 std::unique_lock lock(mLock);
209
210 mEventQueue.push_back(event);
Chong Zhang87d199c2021-03-01 19:02:18 -0800211 if (err != TranscodingErrorCode::kNoError) {
212 mLastErrQueue.push_back(err);
213 }
Chong Zhang66469272020-06-04 16:51:55 -0700214 mCondition.notify_one();
215 }
216
Chong Zhang98b8a372020-07-08 17:27:37 -0700217 void updateProgress(int progress) {
218 std::unique_lock lock(mLock);
219 mLastProgress = progress;
220 mUpdateCount++;
221 }
222
Chong Zhangf9077512020-09-21 21:02:06 -0700223 int getUpdateCount(int* lastProgress) {
Chong Zhang98b8a372020-07-08 17:27:37 -0700224 std::unique_lock lock(mLock);
225 *lastProgress = mLastProgress;
226 return mUpdateCount;
227 }
228
Chong Zhangb55c5452020-06-26 14:32:12 -0700229 TranscodingErrorCode getLastError() {
230 std::unique_lock lock(mLock);
Chong Zhang87d199c2021-03-01 19:02:18 -0800231 if (mLastErrQueue.empty()) {
232 return TranscodingErrorCode::kNoError;
233 }
234 TranscodingErrorCode err = mLastErrQueue.front();
235 mLastErrQueue.pop_front();
236 return err;
Chong Zhangb55c5452020-06-26 14:32:12 -0700237 }
238
Chong Zhang66469272020-06-04 16:51:55 -0700239private:
240 std::mutex mLock;
241 std::condition_variable mCondition;
242 Event mPoppedEvent;
243 std::list<Event> mEventQueue;
Chong Zhang87d199c2021-03-01 19:02:18 -0800244 std::list<TranscodingErrorCode> mLastErrQueue;
Chong Zhang98b8a372020-07-08 17:27:37 -0700245 int mUpdateCount = 0;
246 int mLastProgress = -1;
Chong Zhang66469272020-06-04 16:51:55 -0700247};
248
249// Operators for GTest macros.
250bool operator==(const EventTracker::Event& lhs, const EventTracker::Event& rhs) {
Chong Zhangbc062482020-10-14 16:43:53 -0700251 return lhs.type == rhs.type && lhs.clientId == rhs.clientId && lhs.sessionId == rhs.sessionId;
Chong Zhang66469272020-06-04 16:51:55 -0700252}
253
254std::ostream& operator<<(std::ostream& str, const EventTracker::Event& v) {
255 str << EventTracker::toString(v);
256 return str;
257}
258
Chong Zhang3f23e982020-09-24 14:03:41 -0700259static constexpr bool success = true;
260static constexpr bool fail = false;
261
Steven Moreland58c938e2021-08-02 22:02:14 +0000262struct TestClientCallback : public BnTranscodingClientCallback, public EventTracker {
Chong Zhang3f23e982020-09-24 14:03:41 -0700263 TestClientCallback(const char* packageName, int32_t id)
264 : mClientId(id), mClientPid(PID(id)), mClientUid(UID(id)), mPackageName(packageName) {
265 ALOGI("TestClientCallback %d created: pid %d, uid %d", id, PID(id), UID(id));
266
267 // Use package uid if that's available.
268 uid_t packageUid;
269 if (getUidForPackage(String16(packageName), 0 /*userId*/, packageUid) == NO_ERROR) {
270 mClientUid = packageUid;
271 }
Chong Zhang66469272020-06-04 16:51:55 -0700272 }
273
274 virtual ~TestClientCallback() { ALOGI("TestClientCallback %d destroyed", mClientId); }
275
276 Status openFileDescriptor(const std::string& in_fileUri, const std::string& in_mode,
277 ::ndk::ScopedFileDescriptor* _aidl_return) override {
278 ALOGD("@@@ openFileDescriptor: %s", in_fileUri.c_str());
279 int fd;
280 if (in_mode == "w" || in_mode == "rw") {
Chong Zhangb55c5452020-06-26 14:32:12 -0700281 int kOpenFlags;
282 if (in_mode == "w") {
283 // Write-only, create file if non-existent, truncate existing file.
284 kOpenFlags = O_WRONLY | O_CREAT | O_TRUNC;
285 } else {
286 // Read-Write, create if non-existent, no truncate (service will truncate if needed)
287 kOpenFlags = O_RDWR | O_CREAT;
288 }
Chong Zhang66469272020-06-04 16:51:55 -0700289 // User R+W permission.
290 constexpr int kFileMode = S_IRUSR | S_IWUSR;
291 fd = open(in_fileUri.c_str(), kOpenFlags, kFileMode);
292 } else {
293 fd = open(in_fileUri.c_str(), O_RDONLY);
294 }
295 _aidl_return->set(fd);
296 return Status::ok();
297 }
298
Chong Zhangbc062482020-10-14 16:43:53 -0700299 Status onTranscodingStarted(int32_t in_sessionId) override {
300 append(EventTracker::Start(mClientId, in_sessionId));
Chong Zhang66469272020-06-04 16:51:55 -0700301 return Status::ok();
302 }
303
Chong Zhangbc062482020-10-14 16:43:53 -0700304 Status onTranscodingPaused(int32_t in_sessionId) override {
305 append(EventTracker::Pause(mClientId, in_sessionId));
Chong Zhang66469272020-06-04 16:51:55 -0700306 return Status::ok();
307 }
308
Chong Zhangbc062482020-10-14 16:43:53 -0700309 Status onTranscodingResumed(int32_t in_sessionId) override {
310 append(EventTracker::Resume(mClientId, in_sessionId));
Chong Zhang66469272020-06-04 16:51:55 -0700311 return Status::ok();
312 }
313
314 Status onTranscodingFinished(
Chong Zhangbc062482020-10-14 16:43:53 -0700315 int32_t in_sessionId,
Chong Zhang66469272020-06-04 16:51:55 -0700316 const ::aidl::android::media::TranscodingResultParcel& /* in_result */) override {
Chong Zhangbc062482020-10-14 16:43:53 -0700317 append(Finished(mClientId, in_sessionId));
Chong Zhang66469272020-06-04 16:51:55 -0700318 return Status::ok();
319 }
320
Chong Zhangbc062482020-10-14 16:43:53 -0700321 Status onTranscodingFailed(int32_t in_sessionId,
Chong Zhangb55c5452020-06-26 14:32:12 -0700322 ::aidl::android::media::TranscodingErrorCode in_errorCode) override {
Chong Zhangbc062482020-10-14 16:43:53 -0700323 append(Failed(mClientId, in_sessionId), in_errorCode);
Chong Zhang66469272020-06-04 16:51:55 -0700324 return Status::ok();
325 }
326
Chong Zhangbc062482020-10-14 16:43:53 -0700327 Status onAwaitNumberOfSessionsChanged(int32_t /* in_sessionId */,
328 int32_t /* in_oldAwaitNumber */,
329 int32_t /* in_newAwaitNumber */) override {
Chong Zhang66469272020-06-04 16:51:55 -0700330 return Status::ok();
331 }
332
Chong Zhangbc062482020-10-14 16:43:53 -0700333 Status onProgressUpdate(int32_t /* in_sessionId */, int32_t in_progress) override {
Chong Zhang98b8a372020-07-08 17:27:37 -0700334 updateProgress(in_progress);
Chong Zhang66469272020-06-04 16:51:55 -0700335 return Status::ok();
336 }
337
Chong Zhang3f23e982020-09-24 14:03:41 -0700338 Status registerClient(const char* packageName,
339 const std::shared_ptr<IMediaTranscodingService>& service) {
340 // Override the default uid if the package uid is found.
341 uid_t uid;
342 if (getUidForPackage(String16(packageName), 0 /*userId*/, uid) == NO_ERROR) {
343 mClientUid = uid;
344 }
345
346 ALOGD("registering %s with uid %d", packageName, mClientUid);
347
348 std::shared_ptr<ITranscodingClient> client;
Steven Moreland58c938e2021-08-02 22:02:14 +0000349 Status status = service->registerClient(ref<TestClientCallback>(), kClientName, packageName,
350 &client);
Chong Zhang3f23e982020-09-24 14:03:41 -0700351
352 mClient = status.isOk() ? client : nullptr;
353 return status;
354 }
355
356 Status unregisterClient() {
357 Status status;
358 if (mClient != nullptr) {
359 status = mClient->unregister();
360 mClient = nullptr;
361 }
362 return status;
363 }
364
365 template <bool expectation = success>
Chong Zhangbc062482020-10-14 16:43:53 -0700366 bool submit(int32_t sessionId, const char* sourceFilePath, const char* destinationFilePath,
367 TranscodingSessionPriority priority = TranscodingSessionPriority::kNormal,
Chong Zhang456787f2021-02-18 16:47:08 -0800368 int bitrateBps = -1, int overridePid = -1, int overrideUid = -1,
369 int sessionDurationMs = -1) {
Chong Zhang3f23e982020-09-24 14:03:41 -0700370 constexpr bool shouldSucceed = (expectation == success);
371 bool result;
372 TranscodingRequestParcel request;
Chong Zhangbc062482020-10-14 16:43:53 -0700373 TranscodingSessionParcel session;
Chong Zhang3f23e982020-09-24 14:03:41 -0700374
375 request.sourceFilePath = sourceFilePath;
376 request.destinationFilePath = destinationFilePath;
377 request.priority = priority;
378 request.clientPid = (overridePid == -1) ? mClientPid : overridePid;
379 request.clientUid = (overrideUid == -1) ? mClientUid : overrideUid;
Chong Zhangcf3f8ee2020-10-29 18:38:37 -0700380 request.clientPackageName = (overrideUid == -1) ? mPackageName : "";
Chong Zhang3f23e982020-09-24 14:03:41 -0700381 if (bitrateBps > 0) {
382 request.requestedVideoTrackFormat.emplace(TranscodingVideoTrackFormat());
383 request.requestedVideoTrackFormat->bitrateBps = bitrateBps;
384 }
Chong Zhang456787f2021-02-18 16:47:08 -0800385 if (sessionDurationMs > 0) {
386 request.isForTesting = true;
387 request.testConfig.emplace(TranscodingTestConfig());
388 request.testConfig->processingTotalTimeMs = sessionDurationMs;
389 }
Chong Zhangbc062482020-10-14 16:43:53 -0700390 Status status = mClient->submitRequest(request, &session, &result);
Chong Zhang3f23e982020-09-24 14:03:41 -0700391
392 EXPECT_TRUE(status.isOk());
393 EXPECT_EQ(result, shouldSucceed);
394 if (shouldSucceed) {
Chong Zhangbc062482020-10-14 16:43:53 -0700395 EXPECT_EQ(session.sessionId, sessionId);
Chong Zhang3f23e982020-09-24 14:03:41 -0700396 }
397
Chong Zhangbc062482020-10-14 16:43:53 -0700398 return status.isOk() && (result == shouldSucceed) &&
399 (!shouldSucceed || session.sessionId == sessionId);
Chong Zhang3f23e982020-09-24 14:03:41 -0700400 }
401
402 template <bool expectation = success>
Chong Zhangbc062482020-10-14 16:43:53 -0700403 bool cancel(int32_t sessionId) {
Chong Zhang3f23e982020-09-24 14:03:41 -0700404 constexpr bool shouldSucceed = (expectation == success);
405 bool result;
Chong Zhangbc062482020-10-14 16:43:53 -0700406 Status status = mClient->cancelSession(sessionId, &result);
Chong Zhang3f23e982020-09-24 14:03:41 -0700407
408 EXPECT_TRUE(status.isOk());
409 EXPECT_EQ(result, shouldSucceed);
410
411 return status.isOk() && (result == shouldSucceed);
412 }
413
414 template <bool expectation = success>
Chong Zhangbc062482020-10-14 16:43:53 -0700415 bool getSession(int32_t sessionId, const char* sourceFilePath,
416 const char* destinationFilePath) {
Chong Zhang3f23e982020-09-24 14:03:41 -0700417 constexpr bool shouldSucceed = (expectation == success);
418 bool result;
Chong Zhangbc062482020-10-14 16:43:53 -0700419 TranscodingSessionParcel session;
420 Status status = mClient->getSessionWithId(sessionId, &session, &result);
Chong Zhang3f23e982020-09-24 14:03:41 -0700421
422 EXPECT_TRUE(status.isOk());
423 EXPECT_EQ(result, shouldSucceed);
424 if (shouldSucceed) {
Chong Zhangbc062482020-10-14 16:43:53 -0700425 EXPECT_EQ(session.sessionId, sessionId);
426 EXPECT_EQ(session.request.sourceFilePath, sourceFilePath);
Chong Zhang3f23e982020-09-24 14:03:41 -0700427 }
428
429 return status.isOk() && (result == shouldSucceed) &&
Chong Zhangbc062482020-10-14 16:43:53 -0700430 (!shouldSucceed || (session.sessionId == sessionId &&
431 session.request.sourceFilePath == sourceFilePath &&
432 session.request.destinationFilePath == destinationFilePath));
Chong Zhang3f23e982020-09-24 14:03:41 -0700433 }
434
Chong Zhangebd86d32021-03-29 11:30:56 -0700435 template <bool expectation = success>
436 bool addClientUid(int32_t sessionId, uid_t clientUid) {
437 constexpr bool shouldSucceed = (expectation == success);
438 bool result;
439 Status status = mClient->addClientUid(sessionId, clientUid, &result);
440
441 EXPECT_TRUE(status.isOk());
442 EXPECT_EQ(result, shouldSucceed);
443
444 return status.isOk() && (result == shouldSucceed);
445 }
446
447 template <bool expectation = success>
448 bool getClientUids(int32_t sessionId, std::vector<int32_t>* clientUids) {
449 constexpr bool shouldSucceed = (expectation == success);
Chong Zhang18ec5322021-04-02 10:18:06 -0700450 std::optional<std::vector<int32_t>> aidl_return;
451 Status status = mClient->getClientUids(sessionId, &aidl_return);
Chong Zhangebd86d32021-03-29 11:30:56 -0700452
453 EXPECT_TRUE(status.isOk());
Chong Zhang18ec5322021-04-02 10:18:06 -0700454 bool success = (aidl_return != std::nullopt);
455 if (success) {
456 *clientUids = *aidl_return;
457 }
458 EXPECT_EQ(success, shouldSucceed);
Chong Zhangebd86d32021-03-29 11:30:56 -0700459
Chong Zhang18ec5322021-04-02 10:18:06 -0700460 return status.isOk() && (success == shouldSucceed);
Chong Zhangebd86d32021-03-29 11:30:56 -0700461 }
462
Chong Zhang66469272020-06-04 16:51:55 -0700463 int32_t mClientId;
Chong Zhang3f23e982020-09-24 14:03:41 -0700464 pid_t mClientPid;
465 uid_t mClientUid;
466 std::string mPackageName;
467 std::shared_ptr<ITranscodingClient> mClient;
Chong Zhang66469272020-06-04 16:51:55 -0700468};
469
470class MediaTranscodingServiceTestBase : public ::testing::Test {
471public:
472 MediaTranscodingServiceTestBase() { ALOGI("MediaTranscodingServiceTestBase created"); }
473
474 virtual ~MediaTranscodingServiceTestBase() {
475 ALOGI("MediaTranscodingServiceTestBase destroyed");
476 }
477
478 void SetUp() override {
479 // Need thread pool to receive callbacks, otherwise oneway callbacks are
480 // silently ignored.
481 ABinderProcess_startThreadPool();
Hangyu Kuang2e1e8d12021-07-01 00:35:04 +0000482 ::ndk::SpAIBinder binder(AServiceManager_waitForService("media.transcoding"));
Chong Zhang66469272020-06-04 16:51:55 -0700483 mService = IMediaTranscodingService::fromBinder(binder);
484 if (mService == nullptr) {
485 ALOGE("Failed to connect to the media.trascoding service.");
486 return;
487 }
Chong Zhang4fe34f92020-10-06 15:47:28 -0700488
Chong Zhang3f23e982020-09-24 14:03:41 -0700489 mClient1 = ::ndk::SharedRefBase::make<TestClientCallback>(kClientPackageA, 1);
490 mClient2 = ::ndk::SharedRefBase::make<TestClientCallback>(kClientPackageB, 2);
491 mClient3 = ::ndk::SharedRefBase::make<TestClientCallback>(kClientPackageC, 3);
Chong Zhang66469272020-06-04 16:51:55 -0700492 }
493
Chong Zhang3f23e982020-09-24 14:03:41 -0700494 Status registerOneClient(const std::shared_ptr<TestClientCallback>& callback) {
495 ALOGD("registering %s with uid %d", callback->mPackageName.c_str(), callback->mClientUid);
Chong Zhang66469272020-06-04 16:51:55 -0700496
497 std::shared_ptr<ITranscodingClient> client;
Chong Zhang3f23e982020-09-24 14:03:41 -0700498 Status status =
499 mService->registerClient(callback, kClientName, callback->mPackageName, &client);
500
501 if (status.isOk()) {
502 callback->mClient = client;
503 } else {
504 callback->mClient = nullptr;
505 }
506 return status;
Chong Zhang66469272020-06-04 16:51:55 -0700507 }
508
509 void registerMultipleClients() {
510 // Register 3 clients.
Chong Zhang3f23e982020-09-24 14:03:41 -0700511 EXPECT_TRUE(registerOneClient(mClient1).isOk());
512 EXPECT_TRUE(registerOneClient(mClient2).isOk());
513 EXPECT_TRUE(registerOneClient(mClient3).isOk());
Chong Zhang66469272020-06-04 16:51:55 -0700514
515 // Check the number of clients.
516 int32_t numOfClients;
517 Status status = mService->getNumOfClients(&numOfClients);
518 EXPECT_TRUE(status.isOk());
Chong Zhang4fe34f92020-10-06 15:47:28 -0700519 EXPECT_GE(numOfClients, 3);
Chong Zhang66469272020-06-04 16:51:55 -0700520 }
521
522 void unregisterMultipleClients() {
Chong Zhang66469272020-06-04 16:51:55 -0700523 // Unregister the clients.
Chong Zhang3f23e982020-09-24 14:03:41 -0700524 EXPECT_TRUE(mClient1->unregisterClient().isOk());
525 EXPECT_TRUE(mClient2->unregisterClient().isOk());
526 EXPECT_TRUE(mClient3->unregisterClient().isOk());
Chong Zhang66469272020-06-04 16:51:55 -0700527 }
528
Chong Zhang2a3c9672021-03-31 15:36:32 -0700529 const char* prepareOutputFile(const char* path) {
530 deleteFile(path);
531 return path;
532 }
533
Chong Zhang66469272020-06-04 16:51:55 -0700534 void deleteFile(const char* path) { unlink(path); }
535
Chong Zhang2a3c9672021-03-31 15:36:32 -0700536 void dismissKeyguard() {
537 EXPECT_TRUE(ShellHelper::RunCmd("input keyevent KEYCODE_WAKEUP"));
538 EXPECT_TRUE(ShellHelper::RunCmd("wm dismiss-keyguard"));
539 }
540
541 void stopAppPackages() {
542 EXPECT_TRUE(ShellHelper::Stop(kClientPackageA));
543 EXPECT_TRUE(ShellHelper::Stop(kClientPackageB));
544 EXPECT_TRUE(ShellHelper::Stop(kClientPackageC));
545 }
546
Chong Zhang66469272020-06-04 16:51:55 -0700547 std::shared_ptr<IMediaTranscodingService> mService;
Chong Zhang3f23e982020-09-24 14:03:41 -0700548 std::shared_ptr<TestClientCallback> mClient1;
549 std::shared_ptr<TestClientCallback> mClient2;
550 std::shared_ptr<TestClientCallback> mClient3;
Chong Zhang66469272020-06-04 16:51:55 -0700551};
552
553} // namespace media
554} // namespace android