blob: 923341023b5fb64d952f6aa1b16229f014c01b6e [file] [log] [blame]
hkuang26587cb2020-01-16 10:36:08 -08001/*
2 * Copyright (C) 2020 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 TranscodingClientManager
18
19// #define LOG_NDEBUG 0
20#define LOG_TAG "TranscodingClientManagerTest"
21
Chong Zhang6d58e4b2020-03-31 09:41:10 -070022#include <aidl/android/media/BnTranscodingClientCallback.h>
hkuang26587cb2020-01-16 10:36:08 -080023#include <aidl/android/media/IMediaTranscodingService.h>
hkuang26587cb2020-01-16 10:36:08 -080024#include <android-base/logging.h>
25#include <android/binder_manager.h>
26#include <android/binder_process.h>
27#include <gtest/gtest.h>
Chong Zhangbc062482020-10-14 16:43:53 -070028#include <media/ControllerClientInterface.h>
hkuang26587cb2020-01-16 10:36:08 -080029#include <media/TranscodingClientManager.h>
Chong Zhang6d58e4b2020-03-31 09:41:10 -070030#include <media/TranscodingRequest.h>
hkuang26587cb2020-01-16 10:36:08 -080031#include <utils/Log.h>
32
Chong Zhang6d58e4b2020-03-31 09:41:10 -070033#include <list>
34
hkuang26587cb2020-01-16 10:36:08 -080035namespace android {
36
37using Status = ::ndk::ScopedAStatus;
Chong Zhang6d58e4b2020-03-31 09:41:10 -070038using ::aidl::android::media::BnTranscodingClientCallback;
39using ::aidl::android::media::IMediaTranscodingService;
40using ::aidl::android::media::TranscodingErrorCode;
Chong Zhang6d58e4b2020-03-31 09:41:10 -070041using ::aidl::android::media::TranscodingRequestParcel;
42using ::aidl::android::media::TranscodingResultParcel;
Chong Zhangbc062482020-10-14 16:43:53 -070043using ::aidl::android::media::TranscodingSessionParcel;
44using ::aidl::android::media::TranscodingSessionPriority;
hkuang26587cb2020-01-16 10:36:08 -080045
Chong Zhang3f23e982020-09-24 14:03:41 -070046constexpr pid_t kInvalidClientPid = -5;
47constexpr pid_t kInvalidClientUid = -10;
Chong Zhang8e062632020-03-31 10:56:37 -070048constexpr const char* kInvalidClientName = "";
49constexpr const char* kInvalidClientPackage = "";
hkuang26587cb2020-01-16 10:36:08 -080050
Chong Zhang8e062632020-03-31 10:56:37 -070051constexpr const char* kClientName = "TestClientName";
52constexpr const char* kClientPackage = "TestClientPackage";
Chong Zhangebd86d32021-03-29 11:30:56 -070053constexpr uid_t OFFLINE_UID = -1;
hkuang26587cb2020-01-16 10:36:08 -080054
Chong Zhangbc062482020-10-14 16:43:53 -070055#define SESSION(n) (n)
Chong Zhang15c192a2020-05-05 16:24:00 -070056
Chong Zhang6d58e4b2020-03-31 09:41:10 -070057struct TestClientCallback : public BnTranscodingClientCallback {
58 TestClientCallback() { ALOGI("TestClientCallback Created"); }
hkuang26587cb2020-01-16 10:36:08 -080059
Chong Zhang6d58e4b2020-03-31 09:41:10 -070060 virtual ~TestClientCallback() { ALOGI("TestClientCallback destroyed"); };
61
hkuang19253092020-06-01 09:10:49 -070062 Status openFileDescriptor(const std::string& /*in_fileUri*/, const std::string& /*in_mode*/,
63 ::ndk::ScopedFileDescriptor* /*_aidl_return*/) override {
64 return Status::ok();
65 }
66
Chong Zhangbc062482020-10-14 16:43:53 -070067 Status onTranscodingStarted(int32_t /*in_sessionId*/) override { return Status::ok(); }
hkuang96471b82020-06-08 11:12:46 -070068
Chong Zhangbc062482020-10-14 16:43:53 -070069 Status onTranscodingPaused(int32_t /*in_sessionId*/) override { return Status::ok(); }
hkuang96471b82020-06-08 11:12:46 -070070
Chong Zhangbc062482020-10-14 16:43:53 -070071 Status onTranscodingResumed(int32_t /*in_sessionId*/) override { return Status::ok(); }
hkuang96471b82020-06-08 11:12:46 -070072
Chong Zhangbc062482020-10-14 16:43:53 -070073 Status onTranscodingFinished(int32_t in_sessionId,
Chong Zhang6d58e4b2020-03-31 09:41:10 -070074 const TranscodingResultParcel& in_result) override {
Chong Zhangbc062482020-10-14 16:43:53 -070075 EXPECT_EQ(in_sessionId, in_result.sessionId);
76 mEventQueue.push_back(Finished(in_sessionId));
hkuang26587cb2020-01-16 10:36:08 -080077 return Status::ok();
78 }
79
Chong Zhangbc062482020-10-14 16:43:53 -070080 Status onTranscodingFailed(int32_t in_sessionId,
81 TranscodingErrorCode /*in_errorCode */) override {
82 mEventQueue.push_back(Failed(in_sessionId));
hkuang26587cb2020-01-16 10:36:08 -080083 return Status::ok();
84 }
85
Chong Zhangbc062482020-10-14 16:43:53 -070086 Status onAwaitNumberOfSessionsChanged(int32_t /* in_sessionId */,
87 int32_t /* in_oldAwaitNumber */,
88 int32_t /* in_newAwaitNumber */) override {
hkuang26587cb2020-01-16 10:36:08 -080089 return Status::ok();
90 }
91
Chong Zhangbc062482020-10-14 16:43:53 -070092 Status onProgressUpdate(int32_t /* in_sessionId */, int32_t /* in_progress */) override {
hkuang26587cb2020-01-16 10:36:08 -080093 return Status::ok();
94 }
95
Chong Zhang6d58e4b2020-03-31 09:41:10 -070096 struct Event {
97 enum {
98 NoEvent,
99 Finished,
100 Failed,
101 } type;
Chong Zhangbc062482020-10-14 16:43:53 -0700102 SessionIdType sessionId;
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700103 };
104
105 static constexpr Event NoEvent = {Event::NoEvent, 0};
106#define DECLARE_EVENT(action) \
Chong Zhangbc062482020-10-14 16:43:53 -0700107 static Event action(SessionIdType sessionId) { return {Event::action, sessionId}; }
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700108
109 DECLARE_EVENT(Finished);
110 DECLARE_EVENT(Failed);
111
112 const Event& popEvent() {
113 if (mEventQueue.empty()) {
114 mPoppedEvent = NoEvent;
115 } else {
116 mPoppedEvent = *mEventQueue.begin();
117 mEventQueue.pop_front();
118 }
119 return mPoppedEvent;
120 }
hkuang26587cb2020-01-16 10:36:08 -0800121
Chong Zhang8e062632020-03-31 10:56:37 -0700122private:
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700123 Event mPoppedEvent;
124 std::list<Event> mEventQueue;
125
126 TestClientCallback(const TestClientCallback&) = delete;
127 TestClientCallback& operator=(const TestClientCallback&) = delete;
128};
129
130bool operator==(const TestClientCallback::Event& lhs, const TestClientCallback::Event& rhs) {
Chong Zhangbc062482020-10-14 16:43:53 -0700131 return lhs.type == rhs.type && lhs.sessionId == rhs.sessionId;
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700132}
133
Chong Zhangbc062482020-10-14 16:43:53 -0700134struct TestController : public ControllerClientInterface {
135 TestController() { ALOGI("TestController Created"); }
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700136
Chong Zhangbc062482020-10-14 16:43:53 -0700137 virtual ~TestController() { ALOGI("TestController Destroyed"); }
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700138
Chong Zhangebd86d32021-03-29 11:30:56 -0700139 bool submit(ClientIdType clientId, SessionIdType sessionId, uid_t /*callingUid*/,
140 uid_t clientUid, const TranscodingRequestParcel& request,
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700141 const std::weak_ptr<ITranscodingClientCallback>& clientCallback) override {
Chong Zhangbc062482020-10-14 16:43:53 -0700142 SessionKeyType sessionKey = std::make_pair(clientId, sessionId);
143 if (mSessions.count(sessionKey) > 0) {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700144 return false;
145 }
146
147 // This is the secret name we'll check, to test error propagation from
Chong Zhangbc062482020-10-14 16:43:53 -0700148 // the controller back to client.
hkuang72d105f2020-05-21 10:48:55 -0700149 if (request.sourceFilePath == "bad_source_file") {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700150 return false;
151 }
152
Chong Zhangebd86d32021-03-29 11:30:56 -0700153 if (request.priority == TranscodingSessionPriority::kUnspecified) {
154 clientUid = OFFLINE_UID;
155 }
156
Chong Zhangbc062482020-10-14 16:43:53 -0700157 mSessions[sessionKey].request = request;
158 mSessions[sessionKey].callback = clientCallback;
Chong Zhangebd86d32021-03-29 11:30:56 -0700159 mSessions[sessionKey].allClientUids.insert(clientUid);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700160
Chong Zhangbc062482020-10-14 16:43:53 -0700161 mLastSession = sessionKey;
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700162 return true;
163 }
164
Chong Zhangebd86d32021-03-29 11:30:56 -0700165 bool addClientUid(ClientIdType clientId, SessionIdType sessionId, uid_t clientUid) override {
166 SessionKeyType sessionKey = std::make_pair(clientId, sessionId);
167
168 if (mSessions.count(sessionKey) == 0) {
169 return false;
170 }
171 if (mSessions[sessionKey].allClientUids.count(clientUid) > 0) {
172 return false;
173 }
174 mSessions[sessionKey].allClientUids.insert(clientUid);
175 return true;
176 }
177
178 bool getClientUids(ClientIdType clientId, SessionIdType sessionId,
179 std::vector<int32_t>* out_clientUids) override {
180 SessionKeyType sessionKey = std::make_pair(clientId, sessionId);
181
182 if (mSessions.count(sessionKey) == 0) {
183 return false;
184 }
185 out_clientUids->clear();
186 for (uid_t uid : mSessions[sessionKey].allClientUids) {
187 if (uid != OFFLINE_UID) {
188 out_clientUids->push_back(uid);
189 }
190 }
191 return true;
192 }
193
Chong Zhangbc062482020-10-14 16:43:53 -0700194 bool cancel(ClientIdType clientId, SessionIdType sessionId) override {
195 SessionKeyType sessionKey = std::make_pair(clientId, sessionId);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700196
Chong Zhangbc062482020-10-14 16:43:53 -0700197 if (mSessions.count(sessionKey) == 0) {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700198 return false;
199 }
Chong Zhangbc062482020-10-14 16:43:53 -0700200 mSessions.erase(sessionKey);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700201 return true;
202 }
203
Chong Zhangbc062482020-10-14 16:43:53 -0700204 bool getSession(ClientIdType clientId, SessionIdType sessionId,
205 TranscodingRequestParcel* request) override {
206 SessionKeyType sessionKey = std::make_pair(clientId, sessionId);
207 if (mSessions.count(sessionKey) == 0) {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700208 return false;
209 }
210
Chong Zhangbc062482020-10-14 16:43:53 -0700211 *(TranscodingRequest*)request = mSessions[sessionKey].request;
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700212 return true;
213 }
214
Chong Zhangbc062482020-10-14 16:43:53 -0700215 void finishLastSession() {
216 auto it = mSessions.find(mLastSession);
217 if (it == mSessions.end()) {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700218 return;
219 }
220 {
221 auto clientCallback = it->second.callback.lock();
222 if (clientCallback != nullptr) {
223 clientCallback->onTranscodingFinished(
Chong Zhangbc062482020-10-14 16:43:53 -0700224 mLastSession.second,
225 TranscodingResultParcel({mLastSession.second, 0, std::nullopt}));
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700226 }
227 }
Chong Zhangbc062482020-10-14 16:43:53 -0700228 mSessions.erase(it);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700229 }
230
Chong Zhangbc062482020-10-14 16:43:53 -0700231 void abortLastSession() {
232 auto it = mSessions.find(mLastSession);
233 if (it == mSessions.end()) {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700234 return;
235 }
236 {
237 auto clientCallback = it->second.callback.lock();
238 if (clientCallback != nullptr) {
Chong Zhangbc062482020-10-14 16:43:53 -0700239 clientCallback->onTranscodingFailed(mLastSession.second,
Chong Zhang7ae4e2f2020-04-17 15:24:34 -0700240 TranscodingErrorCode::kUnknown);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700241 }
242 }
Chong Zhangbc062482020-10-14 16:43:53 -0700243 mSessions.erase(it);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700244 }
245
Chong Zhangbc062482020-10-14 16:43:53 -0700246 struct Session {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700247 TranscodingRequest request;
248 std::weak_ptr<ITranscodingClientCallback> callback;
Chong Zhangebd86d32021-03-29 11:30:56 -0700249 std::unordered_set<uid_t> allClientUids;
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700250 };
251
Chong Zhangbc062482020-10-14 16:43:53 -0700252 typedef std::pair<ClientIdType, SessionIdType> SessionKeyType;
253 std::map<SessionKeyType, Session> mSessions;
254 SessionKeyType mLastSession;
hkuang26587cb2020-01-16 10:36:08 -0800255};
256
257class TranscodingClientManagerTest : public ::testing::Test {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700258public:
259 TranscodingClientManagerTest()
Chong Zhangbc062482020-10-14 16:43:53 -0700260 : mController(new TestController()),
261 mClientManager(new TranscodingClientManager(mController)) {
hkuang5172cab2020-01-31 12:40:28 -0800262 ALOGD("TranscodingClientManagerTest created");
263 }
hkuang26587cb2020-01-16 10:36:08 -0800264
265 void SetUp() override {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700266 mClientCallback1 = ::ndk::SharedRefBase::make<TestClientCallback>();
267 mClientCallback2 = ::ndk::SharedRefBase::make<TestClientCallback>();
268 mClientCallback3 = ::ndk::SharedRefBase::make<TestClientCallback>();
hkuang26587cb2020-01-16 10:36:08 -0800269 }
270
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700271 void TearDown() override { ALOGI("TranscodingClientManagerTest tear down"); }
hkuang26587cb2020-01-16 10:36:08 -0800272
273 ~TranscodingClientManagerTest() { ALOGD("TranscodingClientManagerTest destroyed"); }
274
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700275 void addMultipleClients() {
Chong Zhang0579c6f2020-10-05 12:03:34 -0700276 EXPECT_EQ(
277 mClientManager->addClient(mClientCallback1, kClientName, kClientPackage, &mClient1),
278 OK);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700279 EXPECT_NE(mClient1, nullptr);
280
Chong Zhang0579c6f2020-10-05 12:03:34 -0700281 EXPECT_EQ(
282 mClientManager->addClient(mClientCallback2, kClientName, kClientPackage, &mClient2),
283 OK);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700284 EXPECT_NE(mClient2, nullptr);
285
Chong Zhang0579c6f2020-10-05 12:03:34 -0700286 EXPECT_EQ(
287 mClientManager->addClient(mClientCallback3, kClientName, kClientPackage, &mClient3),
288 OK);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700289 EXPECT_NE(mClient3, nullptr);
290
291 EXPECT_EQ(mClientManager->getNumOfClients(), 3);
292 }
293
294 void unregisterMultipleClients() {
295 EXPECT_TRUE(mClient1->unregister().isOk());
296 EXPECT_TRUE(mClient2->unregister().isOk());
297 EXPECT_TRUE(mClient3->unregister().isOk());
298 EXPECT_EQ(mClientManager->getNumOfClients(), 0);
299 }
300
Chong Zhangbc062482020-10-14 16:43:53 -0700301 std::shared_ptr<TestController> mController;
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700302 std::shared_ptr<TranscodingClientManager> mClientManager;
303 std::shared_ptr<ITranscodingClient> mClient1;
304 std::shared_ptr<ITranscodingClient> mClient2;
305 std::shared_ptr<ITranscodingClient> mClient3;
306 std::shared_ptr<TestClientCallback> mClientCallback1;
307 std::shared_ptr<TestClientCallback> mClientCallback2;
308 std::shared_ptr<TestClientCallback> mClientCallback3;
hkuang26587cb2020-01-16 10:36:08 -0800309};
310
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700311TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientCallback) {
312 // Add a client with null callback and expect failure.
Chong Zhang8e062632020-03-31 10:56:37 -0700313 std::shared_ptr<ITranscodingClient> client;
Chong Zhang0579c6f2020-10-05 12:03:34 -0700314 status_t err = mClientManager->addClient(nullptr, kClientName, kClientPackage, &client);
Chong Zhang15c192a2020-05-05 16:24:00 -0700315 EXPECT_EQ(err, IMediaTranscodingService::ERROR_ILLEGAL_ARGUMENT);
hkuang26587cb2020-01-16 10:36:08 -0800316}
Chong Zhang3f23e982020-09-24 14:03:41 -0700317//
318//TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientPid) {
319// // Add a client with invalid Pid and expect failure.
320// std::shared_ptr<ITranscodingClient> client;
321// status_t err = mClientManager->addClient(mClientCallback1,
322// kClientName, kClientPackage, &client);
323// EXPECT_EQ(err, IMediaTranscodingService::ERROR_ILLEGAL_ARGUMENT);
324//}
hkuang26587cb2020-01-16 10:36:08 -0800325
Chong Zhang8e062632020-03-31 10:56:37 -0700326TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientName) {
327 // Add a client with invalid name and expect failure.
328 std::shared_ptr<ITranscodingClient> client;
Chong Zhang0579c6f2020-10-05 12:03:34 -0700329 status_t err = mClientManager->addClient(mClientCallback1, kInvalidClientName, kClientPackage,
330 &client);
Chong Zhang15c192a2020-05-05 16:24:00 -0700331 EXPECT_EQ(err, IMediaTranscodingService::ERROR_ILLEGAL_ARGUMENT);
hkuang26587cb2020-01-16 10:36:08 -0800332}
333
334TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientPackageName) {
Chong Zhang8e062632020-03-31 10:56:37 -0700335 // Add a client with invalid packagename and expect failure.
336 std::shared_ptr<ITranscodingClient> client;
Chong Zhang0579c6f2020-10-05 12:03:34 -0700337 status_t err = mClientManager->addClient(mClientCallback1, kClientName, kInvalidClientPackage,
338 &client);
Chong Zhang15c192a2020-05-05 16:24:00 -0700339 EXPECT_EQ(err, IMediaTranscodingService::ERROR_ILLEGAL_ARGUMENT);
hkuang26587cb2020-01-16 10:36:08 -0800340}
341
342TEST_F(TranscodingClientManagerTest, TestAddingValidClient) {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700343 // Add a valid client, should succeed.
Chong Zhang8e062632020-03-31 10:56:37 -0700344 std::shared_ptr<ITranscodingClient> client;
Chong Zhang0579c6f2020-10-05 12:03:34 -0700345 status_t err =
346 mClientManager->addClient(mClientCallback1, kClientName, kClientPackage, &client);
Chong Zhang8e062632020-03-31 10:56:37 -0700347 EXPECT_EQ(err, OK);
348 EXPECT_NE(client.get(), nullptr);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700349 EXPECT_EQ(mClientManager->getNumOfClients(), 1);
hkuang26587cb2020-01-16 10:36:08 -0800350
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700351 // Unregister client, should succeed.
Chong Zhang8e062632020-03-31 10:56:37 -0700352 Status status = client->unregister();
353 EXPECT_TRUE(status.isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700354 EXPECT_EQ(mClientManager->getNumOfClients(), 0);
hkuang26587cb2020-01-16 10:36:08 -0800355}
356
357TEST_F(TranscodingClientManagerTest, TestAddingDupliacteClient) {
Chong Zhang8e062632020-03-31 10:56:37 -0700358 std::shared_ptr<ITranscodingClient> client;
Chong Zhang0579c6f2020-10-05 12:03:34 -0700359 status_t err =
360 mClientManager->addClient(mClientCallback1, kClientName, kClientPackage, &client);
Chong Zhang8e062632020-03-31 10:56:37 -0700361 EXPECT_EQ(err, OK);
362 EXPECT_NE(client.get(), nullptr);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700363 EXPECT_EQ(mClientManager->getNumOfClients(), 1);
hkuang26587cb2020-01-16 10:36:08 -0800364
Chong Zhang8e062632020-03-31 10:56:37 -0700365 std::shared_ptr<ITranscodingClient> dupClient;
Chong Zhang0579c6f2020-10-05 12:03:34 -0700366 err = mClientManager->addClient(mClientCallback1, "dupClient", "dupPackage", &dupClient);
Chong Zhang15c192a2020-05-05 16:24:00 -0700367 EXPECT_EQ(err, IMediaTranscodingService::ERROR_ALREADY_EXISTS);
Chong Zhang8e062632020-03-31 10:56:37 -0700368 EXPECT_EQ(dupClient.get(), nullptr);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700369 EXPECT_EQ(mClientManager->getNumOfClients(), 1);
hkuang26587cb2020-01-16 10:36:08 -0800370
Chong Zhang8e062632020-03-31 10:56:37 -0700371 Status status = client->unregister();
372 EXPECT_TRUE(status.isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700373 EXPECT_EQ(mClientManager->getNumOfClients(), 0);
hkuang26587cb2020-01-16 10:36:08 -0800374
Chong Zhang3f23e982020-09-24 14:03:41 -0700375 err = mClientManager->addClient(mClientCallback1, "dupClient", "dupPackage", &dupClient);
Chong Zhang8e062632020-03-31 10:56:37 -0700376 EXPECT_EQ(err, OK);
377 EXPECT_NE(dupClient.get(), nullptr);
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700378 EXPECT_EQ(mClientManager->getNumOfClients(), 1);
hkuang26587cb2020-01-16 10:36:08 -0800379
Chong Zhang8e062632020-03-31 10:56:37 -0700380 status = dupClient->unregister();
381 EXPECT_TRUE(status.isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700382 EXPECT_EQ(mClientManager->getNumOfClients(), 0);
hkuang26587cb2020-01-16 10:36:08 -0800383}
384
385TEST_F(TranscodingClientManagerTest, TestAddingMultipleClient) {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700386 addMultipleClients();
387 unregisterMultipleClients();
388}
hkuang26587cb2020-01-16 10:36:08 -0800389
Chong Zhangbc062482020-10-14 16:43:53 -0700390TEST_F(TranscodingClientManagerTest, TestSubmitCancelGetSessions) {
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700391 addMultipleClients();
hkuang26587cb2020-01-16 10:36:08 -0800392
Chong Zhangbc062482020-10-14 16:43:53 -0700393 // Test sessionId assignment.
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700394 TranscodingRequestParcel request;
hkuang72d105f2020-05-21 10:48:55 -0700395 request.sourceFilePath = "test_source_file_0";
396 request.destinationFilePath = "test_desintaion_file_0";
Chong Zhangbc062482020-10-14 16:43:53 -0700397 TranscodingSessionParcel session;
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700398 bool result;
Chong Zhangbc062482020-10-14 16:43:53 -0700399 EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700400 EXPECT_TRUE(result);
Chong Zhangbc062482020-10-14 16:43:53 -0700401 EXPECT_EQ(session.sessionId, SESSION(0));
hkuang26587cb2020-01-16 10:36:08 -0800402
hkuang72d105f2020-05-21 10:48:55 -0700403 request.sourceFilePath = "test_source_file_1";
404 request.destinationFilePath = "test_desintaion_file_1";
Chong Zhangbc062482020-10-14 16:43:53 -0700405 EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700406 EXPECT_TRUE(result);
Chong Zhangbc062482020-10-14 16:43:53 -0700407 EXPECT_EQ(session.sessionId, SESSION(1));
hkuang26587cb2020-01-16 10:36:08 -0800408
hkuang72d105f2020-05-21 10:48:55 -0700409 request.sourceFilePath = "test_source_file_2";
410 request.destinationFilePath = "test_desintaion_file_2";
Chong Zhangbc062482020-10-14 16:43:53 -0700411 EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700412 EXPECT_TRUE(result);
Chong Zhangbc062482020-10-14 16:43:53 -0700413 EXPECT_EQ(session.sessionId, SESSION(2));
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700414
hkuang72d105f2020-05-21 10:48:55 -0700415 // Test submit bad request (no valid sourceFilePath) fails.
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700416 TranscodingRequestParcel badRequest;
hkuang72d105f2020-05-21 10:48:55 -0700417 badRequest.sourceFilePath = "bad_source_file";
418 badRequest.destinationFilePath = "bad_destination_file";
Chong Zhangbc062482020-10-14 16:43:53 -0700419 EXPECT_TRUE(mClient1->submitRequest(badRequest, &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700420 EXPECT_FALSE(result);
421
Chong Zhang3f23e982020-09-24 14:03:41 -0700422 // Test submit with bad pid/uid.
423 badRequest.sourceFilePath = "test_source_file_3";
424 badRequest.destinationFilePath = "test_desintaion_file_3";
425 badRequest.clientPid = kInvalidClientPid;
426 badRequest.clientUid = kInvalidClientUid;
Chong Zhangbc062482020-10-14 16:43:53 -0700427 EXPECT_TRUE(mClient1->submitRequest(badRequest, &session, &result).isOk());
Chong Zhang3f23e982020-09-24 14:03:41 -0700428 EXPECT_FALSE(result);
429
Chong Zhangbc062482020-10-14 16:43:53 -0700430 // Test get sessions by id.
431 EXPECT_TRUE(mClient1->getSessionWithId(SESSION(2), &session, &result).isOk());
432 EXPECT_EQ(session.sessionId, SESSION(2));
433 EXPECT_EQ(session.request.sourceFilePath, "test_source_file_2");
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700434 EXPECT_TRUE(result);
435
Chong Zhangbc062482020-10-14 16:43:53 -0700436 // Test get sessions by invalid id fails.
437 EXPECT_TRUE(mClient1->getSessionWithId(SESSION(100), &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700438 EXPECT_FALSE(result);
439
Chong Zhangbc062482020-10-14 16:43:53 -0700440 // Test cancel non-existent session fail.
441 EXPECT_TRUE(mClient2->cancelSession(SESSION(100), &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700442 EXPECT_FALSE(result);
443
Chong Zhangbc062482020-10-14 16:43:53 -0700444 // Test cancel valid sessionId in arbitrary order.
445 EXPECT_TRUE(mClient1->cancelSession(SESSION(2), &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700446 EXPECT_TRUE(result);
447
Chong Zhangbc062482020-10-14 16:43:53 -0700448 EXPECT_TRUE(mClient1->cancelSession(SESSION(0), &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700449 EXPECT_TRUE(result);
450
Chong Zhangbc062482020-10-14 16:43:53 -0700451 EXPECT_TRUE(mClient1->cancelSession(SESSION(1), &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700452 EXPECT_TRUE(result);
453
Chong Zhangbc062482020-10-14 16:43:53 -0700454 // Test cancel session again fails.
455 EXPECT_TRUE(mClient1->cancelSession(SESSION(1), &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700456 EXPECT_FALSE(result);
457
Chong Zhangbc062482020-10-14 16:43:53 -0700458 // Test get session after cancel fails.
459 EXPECT_TRUE(mClient1->getSessionWithId(SESSION(2), &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700460 EXPECT_FALSE(result);
461
Chong Zhangbc062482020-10-14 16:43:53 -0700462 // Test sessionId independence for each client.
463 EXPECT_TRUE(mClient2->submitRequest(request, &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700464 EXPECT_TRUE(result);
Chong Zhangbc062482020-10-14 16:43:53 -0700465 EXPECT_EQ(session.sessionId, SESSION(0));
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700466
Chong Zhangbc062482020-10-14 16:43:53 -0700467 EXPECT_TRUE(mClient2->submitRequest(request, &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700468 EXPECT_TRUE(result);
Chong Zhangbc062482020-10-14 16:43:53 -0700469 EXPECT_EQ(session.sessionId, SESSION(1));
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700470
471 unregisterMultipleClients();
472}
473
474TEST_F(TranscodingClientManagerTest, TestClientCallback) {
475 addMultipleClients();
476
477 TranscodingRequestParcel request;
hkuang72d105f2020-05-21 10:48:55 -0700478 request.sourceFilePath = "test_source_file_name";
479 request.destinationFilePath = "test_destination_file_name";
Chong Zhangbc062482020-10-14 16:43:53 -0700480 TranscodingSessionParcel session;
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700481 bool result;
Chong Zhangbc062482020-10-14 16:43:53 -0700482 EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700483 EXPECT_TRUE(result);
Chong Zhangbc062482020-10-14 16:43:53 -0700484 EXPECT_EQ(session.sessionId, SESSION(0));
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700485
Chong Zhangbc062482020-10-14 16:43:53 -0700486 mController->finishLastSession();
487 EXPECT_EQ(mClientCallback1->popEvent(), TestClientCallback::Finished(session.sessionId));
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700488
Chong Zhangbc062482020-10-14 16:43:53 -0700489 EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700490 EXPECT_TRUE(result);
Chong Zhangbc062482020-10-14 16:43:53 -0700491 EXPECT_EQ(session.sessionId, SESSION(1));
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700492
Chong Zhangbc062482020-10-14 16:43:53 -0700493 mController->abortLastSession();
494 EXPECT_EQ(mClientCallback1->popEvent(), TestClientCallback::Failed(session.sessionId));
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700495
Chong Zhangbc062482020-10-14 16:43:53 -0700496 EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700497 EXPECT_TRUE(result);
Chong Zhangbc062482020-10-14 16:43:53 -0700498 EXPECT_EQ(session.sessionId, SESSION(2));
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700499
Chong Zhangbc062482020-10-14 16:43:53 -0700500 EXPECT_TRUE(mClient2->submitRequest(request, &session, &result).isOk());
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700501 EXPECT_TRUE(result);
Chong Zhangbc062482020-10-14 16:43:53 -0700502 EXPECT_EQ(session.sessionId, SESSION(0));
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700503
Chong Zhangbc062482020-10-14 16:43:53 -0700504 mController->finishLastSession();
505 EXPECT_EQ(mClientCallback2->popEvent(), TestClientCallback::Finished(session.sessionId));
Chong Zhang6d58e4b2020-03-31 09:41:10 -0700506
507 unregisterMultipleClients();
hkuang26587cb2020-01-16 10:36:08 -0800508}
509
Chong Zhang15c192a2020-05-05 16:24:00 -0700510TEST_F(TranscodingClientManagerTest, TestUseAfterUnregister) {
511 // Add a client.
512 std::shared_ptr<ITranscodingClient> client;
Chong Zhang0579c6f2020-10-05 12:03:34 -0700513 status_t err =
514 mClientManager->addClient(mClientCallback1, kClientName, kClientPackage, &client);
Chong Zhang15c192a2020-05-05 16:24:00 -0700515 EXPECT_EQ(err, OK);
516 EXPECT_NE(client.get(), nullptr);
517
518 // Submit 2 requests, 1 offline and 1 realtime.
519 TranscodingRequestParcel request;
Chong Zhangbc062482020-10-14 16:43:53 -0700520 TranscodingSessionParcel session;
Chong Zhang15c192a2020-05-05 16:24:00 -0700521 bool result;
522
hkuang72d105f2020-05-21 10:48:55 -0700523 request.sourceFilePath = "test_source_file_0";
524 request.destinationFilePath = "test_destination_file_0";
Chong Zhangbc062482020-10-14 16:43:53 -0700525 request.priority = TranscodingSessionPriority::kUnspecified;
526 EXPECT_TRUE(client->submitRequest(request, &session, &result).isOk() && result);
527 EXPECT_EQ(session.sessionId, SESSION(0));
Chong Zhang15c192a2020-05-05 16:24:00 -0700528
hkuang72d105f2020-05-21 10:48:55 -0700529 request.sourceFilePath = "test_source_file_1";
530 request.destinationFilePath = "test_destination_file_1";
Chong Zhangbc062482020-10-14 16:43:53 -0700531 request.priority = TranscodingSessionPriority::kNormal;
532 EXPECT_TRUE(client->submitRequest(request, &session, &result).isOk() && result);
533 EXPECT_EQ(session.sessionId, SESSION(1));
Chong Zhang15c192a2020-05-05 16:24:00 -0700534
535 // Unregister client, should succeed.
536 Status status = client->unregister();
537 EXPECT_TRUE(status.isOk());
538
539 // Test submit new request after unregister, should fail with ERROR_DISCONNECTED.
hkuang72d105f2020-05-21 10:48:55 -0700540 request.sourceFilePath = "test_source_file_2";
541 request.destinationFilePath = "test_destination_file_2";
Chong Zhangbc062482020-10-14 16:43:53 -0700542 request.priority = TranscodingSessionPriority::kNormal;
543 status = client->submitRequest(request, &session, &result);
Chong Zhang15c192a2020-05-05 16:24:00 -0700544 EXPECT_FALSE(status.isOk());
545 EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
546
Chong Zhangbc062482020-10-14 16:43:53 -0700547 // Test cancel sessions after unregister, should fail with ERROR_DISCONNECTED
548 // regardless of realtime or offline session, or whether the sessionId is valid.
549 status = client->cancelSession(SESSION(0), &result);
Chong Zhang15c192a2020-05-05 16:24:00 -0700550 EXPECT_FALSE(status.isOk());
551 EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
552
Chong Zhangbc062482020-10-14 16:43:53 -0700553 status = client->cancelSession(SESSION(1), &result);
Chong Zhang15c192a2020-05-05 16:24:00 -0700554 EXPECT_FALSE(status.isOk());
555 EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
556
Chong Zhangbc062482020-10-14 16:43:53 -0700557 status = client->cancelSession(SESSION(2), &result);
Chong Zhang15c192a2020-05-05 16:24:00 -0700558 EXPECT_FALSE(status.isOk());
559 EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
560
Chong Zhangbc062482020-10-14 16:43:53 -0700561 // Test get sessions, should fail with ERROR_DISCONNECTED regardless of realtime
562 // or offline session, or whether the sessionId is valid.
563 status = client->getSessionWithId(SESSION(0), &session, &result);
Chong Zhang15c192a2020-05-05 16:24:00 -0700564 EXPECT_FALSE(status.isOk());
565 EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
566
Chong Zhangbc062482020-10-14 16:43:53 -0700567 status = client->getSessionWithId(SESSION(1), &session, &result);
Chong Zhang15c192a2020-05-05 16:24:00 -0700568 EXPECT_FALSE(status.isOk());
569 EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
570
Chong Zhangbc062482020-10-14 16:43:53 -0700571 status = client->getSessionWithId(SESSION(2), &session, &result);
Chong Zhang15c192a2020-05-05 16:24:00 -0700572 EXPECT_FALSE(status.isOk());
573 EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
574}
575
Chong Zhangebd86d32021-03-29 11:30:56 -0700576TEST_F(TranscodingClientManagerTest, TestAddGetClientUidsInvalidArgs) {
577 addMultipleClients();
578
579 bool result;
Chong Zhang18ec5322021-04-02 10:18:06 -0700580 std::optional<std::vector<int32_t>> clientUids;
Chong Zhangebd86d32021-03-29 11:30:56 -0700581 TranscodingRequestParcel request;
582 TranscodingSessionParcel session;
583 uid_t ownUid = ::getuid();
584
585 // Add/Get clients with invalid session id fails.
586 EXPECT_TRUE(mClient1->addClientUid(-1, ownUid, &result).isOk());
587 EXPECT_FALSE(result);
588 EXPECT_TRUE(mClient1->addClientUid(SESSION(0), ownUid, &result).isOk());
589 EXPECT_FALSE(result);
Chong Zhang18ec5322021-04-02 10:18:06 -0700590 EXPECT_TRUE(mClient1->getClientUids(-1, &clientUids).isOk());
591 EXPECT_EQ(clientUids, std::nullopt);
592 EXPECT_TRUE(mClient1->getClientUids(SESSION(0), &clientUids).isOk());
593 EXPECT_EQ(clientUids, std::nullopt);
Chong Zhangebd86d32021-03-29 11:30:56 -0700594
595 unregisterMultipleClients();
596}
597
598TEST_F(TranscodingClientManagerTest, TestAddGetClientUids) {
599 addMultipleClients();
600
601 bool result;
Chong Zhang18ec5322021-04-02 10:18:06 -0700602 std::optional<std::vector<int32_t>> clientUids;
Chong Zhangebd86d32021-03-29 11:30:56 -0700603 TranscodingRequestParcel request;
604 TranscodingSessionParcel session;
605 uid_t ownUid = ::getuid();
606
607 // Submit one real-time session.
608 request.sourceFilePath = "test_source_file_0";
609 request.destinationFilePath = "test_desintaion_file_0";
610 request.priority = TranscodingSessionPriority::kNormal;
611 EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
612 EXPECT_TRUE(result);
613
614 // Should have own uid in client uid list.
Chong Zhang18ec5322021-04-02 10:18:06 -0700615 EXPECT_TRUE(mClient1->getClientUids(SESSION(0), &clientUids).isOk());
616 EXPECT_NE(clientUids, std::nullopt);
617 EXPECT_EQ(clientUids->size(), 1);
618 EXPECT_EQ((*clientUids)[0], ownUid);
Chong Zhangebd86d32021-03-29 11:30:56 -0700619
620 // Adding invalid client uid should fail.
621 EXPECT_TRUE(mClient1->addClientUid(SESSION(0), kInvalidClientUid, &result).isOk());
622 EXPECT_FALSE(result);
623
624 // Adding own uid again should fail.
625 EXPECT_TRUE(mClient1->addClientUid(SESSION(0), ownUid, &result).isOk());
626 EXPECT_FALSE(result);
627
628 // Submit one offline session.
629 request.sourceFilePath = "test_source_file_1";
630 request.destinationFilePath = "test_desintaion_file_1";
631 request.priority = TranscodingSessionPriority::kUnspecified;
632 EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
633 EXPECT_TRUE(result);
634
635 // Should not have own uid in client uid list.
Chong Zhang18ec5322021-04-02 10:18:06 -0700636 EXPECT_TRUE(mClient1->getClientUids(SESSION(1), &clientUids).isOk());
637 EXPECT_NE(clientUids, std::nullopt);
638 EXPECT_EQ(clientUids->size(), 0);
Chong Zhangebd86d32021-03-29 11:30:56 -0700639
640 // Add own uid (with IMediaTranscodingService::USE_CALLING_UID) again, should succeed.
641 EXPECT_TRUE(
642 mClient1->addClientUid(SESSION(1), IMediaTranscodingService::USE_CALLING_UID, &result)
643 .isOk());
644 EXPECT_TRUE(result);
Chong Zhang18ec5322021-04-02 10:18:06 -0700645 EXPECT_TRUE(mClient1->getClientUids(SESSION(1), &clientUids).isOk());
646 EXPECT_NE(clientUids, std::nullopt);
647 EXPECT_EQ(clientUids->size(), 1);
648 EXPECT_EQ((*clientUids)[0], ownUid);
Chong Zhangebd86d32021-03-29 11:30:56 -0700649
650 // Add more uids, should succeed.
651 int32_t kFakeUid = ::getuid() ^ 0x1;
652 EXPECT_TRUE(mClient1->addClientUid(SESSION(1), kFakeUid, &result).isOk());
653 EXPECT_TRUE(result);
Chong Zhang18ec5322021-04-02 10:18:06 -0700654 EXPECT_TRUE(mClient1->getClientUids(SESSION(1), &clientUids).isOk());
655 EXPECT_NE(clientUids, std::nullopt);
Chong Zhangebd86d32021-03-29 11:30:56 -0700656 std::unordered_set<uid_t> uidSet;
Chong Zhang18ec5322021-04-02 10:18:06 -0700657 uidSet.insert(clientUids->begin(), clientUids->end());
Chong Zhangebd86d32021-03-29 11:30:56 -0700658 EXPECT_EQ(uidSet.size(), 2);
659 EXPECT_EQ(uidSet.count(ownUid), 1);
660 EXPECT_EQ(uidSet.count(kFakeUid), 1);
661
662 unregisterMultipleClients();
663}
664
Chong Zhang8e062632020-03-31 10:56:37 -0700665} // namespace android