1 /*
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 
22 #include <aidl/android/media/BnTranscodingClientCallback.h>
23 #include <aidl/android/media/IMediaTranscodingService.h>
24 #include <android-base/logging.h>
25 #include <android/binder_manager.h>
26 #include <android/binder_process.h>
27 #include <gtest/gtest.h>
28 #include <media/ControllerClientInterface.h>
29 #include <media/TranscodingClientManager.h>
30 #include <media/TranscodingRequest.h>
31 #include <utils/Log.h>
32 
33 #include <list>
34 
35 namespace android {
36 
37 using Status = ::ndk::ScopedAStatus;
38 using ::aidl::android::media::BnTranscodingClientCallback;
39 using ::aidl::android::media::IMediaTranscodingService;
40 using ::aidl::android::media::TranscodingErrorCode;
41 using ::aidl::android::media::TranscodingRequestParcel;
42 using ::aidl::android::media::TranscodingResultParcel;
43 using ::aidl::android::media::TranscodingSessionParcel;
44 using ::aidl::android::media::TranscodingSessionPriority;
45 
46 constexpr pid_t kInvalidClientPid = -5;
47 constexpr pid_t kInvalidClientUid = -10;
48 constexpr const char* kInvalidClientName = "";
49 constexpr const char* kInvalidClientPackage = "";
50 
51 constexpr const char* kClientName = "TestClientName";
52 constexpr const char* kClientPackage = "TestClientPackage";
53 constexpr uid_t OFFLINE_UID = -1;
54 
55 #define SESSION(n) (n)
56 
57 struct TestClientCallback : public BnTranscodingClientCallback {
TestClientCallbackandroid::TestClientCallback58     TestClientCallback() { ALOGI("TestClientCallback Created"); }
59 
~TestClientCallbackandroid::TestClientCallback60     virtual ~TestClientCallback() { ALOGI("TestClientCallback destroyed"); };
61 
openFileDescriptorandroid::TestClientCallback62     Status openFileDescriptor(const std::string& /*in_fileUri*/, const std::string& /*in_mode*/,
63                               ::ndk::ScopedFileDescriptor* /*_aidl_return*/) override {
64         return Status::ok();
65     }
66 
onTranscodingStartedandroid::TestClientCallback67     Status onTranscodingStarted(int32_t /*in_sessionId*/) override { return Status::ok(); }
68 
onTranscodingPausedandroid::TestClientCallback69     Status onTranscodingPaused(int32_t /*in_sessionId*/) override { return Status::ok(); }
70 
onTranscodingResumedandroid::TestClientCallback71     Status onTranscodingResumed(int32_t /*in_sessionId*/) override { return Status::ok(); }
72 
onTranscodingFinishedandroid::TestClientCallback73     Status onTranscodingFinished(int32_t in_sessionId,
74                                  const TranscodingResultParcel& in_result) override {
75         EXPECT_EQ(in_sessionId, in_result.sessionId);
76         mEventQueue.push_back(Finished(in_sessionId));
77         return Status::ok();
78     }
79 
onTranscodingFailedandroid::TestClientCallback80     Status onTranscodingFailed(int32_t in_sessionId,
81                                TranscodingErrorCode /*in_errorCode */) override {
82         mEventQueue.push_back(Failed(in_sessionId));
83         return Status::ok();
84     }
85 
onAwaitNumberOfSessionsChangedandroid::TestClientCallback86     Status onAwaitNumberOfSessionsChanged(int32_t /* in_sessionId */,
87                                           int32_t /* in_oldAwaitNumber */,
88                                           int32_t /* in_newAwaitNumber */) override {
89         return Status::ok();
90     }
91 
onProgressUpdateandroid::TestClientCallback92     Status onProgressUpdate(int32_t /* in_sessionId */, int32_t /* in_progress */) override {
93         return Status::ok();
94     }
95 
96     struct Event {
97         enum {
98             NoEvent,
99             Finished,
100             Failed,
101         } type;
102         SessionIdType sessionId;
103     };
104 
105     static constexpr Event NoEvent = {Event::NoEvent, 0};
106 #define DECLARE_EVENT(action) \
107     static Event action(SessionIdType sessionId) { return {Event::action, sessionId}; }
108 
109     DECLARE_EVENT(Finished);
110     DECLARE_EVENT(Failed);
111 
popEventandroid::TestClientCallback112     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     }
121 
122 private:
123     Event mPoppedEvent;
124     std::list<Event> mEventQueue;
125 
126     TestClientCallback(const TestClientCallback&) = delete;
127     TestClientCallback& operator=(const TestClientCallback&) = delete;
128 };
129 
operator ==(const TestClientCallback::Event & lhs,const TestClientCallback::Event & rhs)130 bool operator==(const TestClientCallback::Event& lhs, const TestClientCallback::Event& rhs) {
131     return lhs.type == rhs.type && lhs.sessionId == rhs.sessionId;
132 }
133 
134 struct TestController : public ControllerClientInterface {
TestControllerandroid::TestController135     TestController() { ALOGI("TestController Created"); }
136 
~TestControllerandroid::TestController137     virtual ~TestController() { ALOGI("TestController Destroyed"); }
138 
submitandroid::TestController139     bool submit(ClientIdType clientId, SessionIdType sessionId, uid_t /*callingUid*/,
140                 uid_t clientUid, const TranscodingRequestParcel& request,
141                 const std::weak_ptr<ITranscodingClientCallback>& clientCallback) override {
142         SessionKeyType sessionKey = std::make_pair(clientId, sessionId);
143         if (mSessions.count(sessionKey) > 0) {
144             return false;
145         }
146 
147         // This is the secret name we'll check, to test error propagation from
148         // the controller back to client.
149         if (request.sourceFilePath == "bad_source_file") {
150             return false;
151         }
152 
153         if (request.priority == TranscodingSessionPriority::kUnspecified) {
154             clientUid = OFFLINE_UID;
155         }
156 
157         mSessions[sessionKey].request = request;
158         mSessions[sessionKey].callback = clientCallback;
159         mSessions[sessionKey].allClientUids.insert(clientUid);
160 
161         mLastSession = sessionKey;
162         return true;
163     }
164 
addClientUidandroid::TestController165     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 
getClientUidsandroid::TestController178     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 
cancelandroid::TestController194     bool cancel(ClientIdType clientId, SessionIdType sessionId) override {
195         SessionKeyType sessionKey = std::make_pair(clientId, sessionId);
196 
197         if (mSessions.count(sessionKey) == 0) {
198             return false;
199         }
200         mSessions.erase(sessionKey);
201         return true;
202     }
203 
getSessionandroid::TestController204     bool getSession(ClientIdType clientId, SessionIdType sessionId,
205                     TranscodingRequestParcel* request) override {
206         SessionKeyType sessionKey = std::make_pair(clientId, sessionId);
207         if (mSessions.count(sessionKey) == 0) {
208             return false;
209         }
210 
211         *(TranscodingRequest*)request = mSessions[sessionKey].request;
212         return true;
213     }
214 
finishLastSessionandroid::TestController215     void finishLastSession() {
216         auto it = mSessions.find(mLastSession);
217         if (it == mSessions.end()) {
218             return;
219         }
220         {
221             auto clientCallback = it->second.callback.lock();
222             if (clientCallback != nullptr) {
223                 clientCallback->onTranscodingFinished(
224                         mLastSession.second,
225                         TranscodingResultParcel({mLastSession.second, 0, std::nullopt}));
226             }
227         }
228         mSessions.erase(it);
229     }
230 
abortLastSessionandroid::TestController231     void abortLastSession() {
232         auto it = mSessions.find(mLastSession);
233         if (it == mSessions.end()) {
234             return;
235         }
236         {
237             auto clientCallback = it->second.callback.lock();
238             if (clientCallback != nullptr) {
239                 clientCallback->onTranscodingFailed(mLastSession.second,
240                                                     TranscodingErrorCode::kUnknown);
241             }
242         }
243         mSessions.erase(it);
244     }
245 
246     struct Session {
247         TranscodingRequest request;
248         std::weak_ptr<ITranscodingClientCallback> callback;
249         std::unordered_set<uid_t> allClientUids;
250     };
251 
252     typedef std::pair<ClientIdType, SessionIdType> SessionKeyType;
253     std::map<SessionKeyType, Session> mSessions;
254     SessionKeyType mLastSession;
255 };
256 
257 class TranscodingClientManagerTest : public ::testing::Test {
258 public:
TranscodingClientManagerTest()259     TranscodingClientManagerTest()
260           : mController(new TestController()),
261             mClientManager(new TranscodingClientManager(mController)) {
262         ALOGD("TranscodingClientManagerTest created");
263     }
264 
SetUp()265     void SetUp() override {
266         mClientCallback1 = ::ndk::SharedRefBase::make<TestClientCallback>();
267         mClientCallback2 = ::ndk::SharedRefBase::make<TestClientCallback>();
268         mClientCallback3 = ::ndk::SharedRefBase::make<TestClientCallback>();
269     }
270 
TearDown()271     void TearDown() override { ALOGI("TranscodingClientManagerTest tear down"); }
272 
~TranscodingClientManagerTest()273     ~TranscodingClientManagerTest() { ALOGD("TranscodingClientManagerTest destroyed"); }
274 
addMultipleClients()275     void addMultipleClients() {
276         EXPECT_EQ(
277                 mClientManager->addClient(mClientCallback1, kClientName, kClientPackage, &mClient1),
278                 OK);
279         EXPECT_NE(mClient1, nullptr);
280 
281         EXPECT_EQ(
282                 mClientManager->addClient(mClientCallback2, kClientName, kClientPackage, &mClient2),
283                 OK);
284         EXPECT_NE(mClient2, nullptr);
285 
286         EXPECT_EQ(
287                 mClientManager->addClient(mClientCallback3, kClientName, kClientPackage, &mClient3),
288                 OK);
289         EXPECT_NE(mClient3, nullptr);
290 
291         EXPECT_EQ(mClientManager->getNumOfClients(), 3);
292     }
293 
unregisterMultipleClients()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 
301     std::shared_ptr<TestController> mController;
302     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;
309 };
310 
TEST_F(TranscodingClientManagerTest,TestAddingWithInvalidClientCallback)311 TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientCallback) {
312     // Add a client with null callback and expect failure.
313     std::shared_ptr<ITranscodingClient> client;
314     status_t err = mClientManager->addClient(nullptr, kClientName, kClientPackage, &client);
315     EXPECT_EQ(err, IMediaTranscodingService::ERROR_ILLEGAL_ARGUMENT);
316 }
317 //
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 //}
325 
TEST_F(TranscodingClientManagerTest,TestAddingWithInvalidClientName)326 TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientName) {
327     // Add a client with invalid name and expect failure.
328     std::shared_ptr<ITranscodingClient> client;
329     status_t err = mClientManager->addClient(mClientCallback1, kInvalidClientName, kClientPackage,
330                                              &client);
331     EXPECT_EQ(err, IMediaTranscodingService::ERROR_ILLEGAL_ARGUMENT);
332 }
333 
TEST_F(TranscodingClientManagerTest,TestAddingWithInvalidClientPackageName)334 TEST_F(TranscodingClientManagerTest, TestAddingWithInvalidClientPackageName) {
335     // Add a client with invalid packagename and expect failure.
336     std::shared_ptr<ITranscodingClient> client;
337     status_t err = mClientManager->addClient(mClientCallback1, kClientName, kInvalidClientPackage,
338                                              &client);
339     EXPECT_EQ(err, IMediaTranscodingService::ERROR_ILLEGAL_ARGUMENT);
340 }
341 
TEST_F(TranscodingClientManagerTest,TestAddingValidClient)342 TEST_F(TranscodingClientManagerTest, TestAddingValidClient) {
343     // Add a valid client, should succeed.
344     std::shared_ptr<ITranscodingClient> client;
345     status_t err =
346             mClientManager->addClient(mClientCallback1, kClientName, kClientPackage, &client);
347     EXPECT_EQ(err, OK);
348     EXPECT_NE(client.get(), nullptr);
349     EXPECT_EQ(mClientManager->getNumOfClients(), 1);
350 
351     // Unregister client, should succeed.
352     Status status = client->unregister();
353     EXPECT_TRUE(status.isOk());
354     EXPECT_EQ(mClientManager->getNumOfClients(), 0);
355 }
356 
TEST_F(TranscodingClientManagerTest,TestAddingDupliacteClient)357 TEST_F(TranscodingClientManagerTest, TestAddingDupliacteClient) {
358     std::shared_ptr<ITranscodingClient> client;
359     status_t err =
360             mClientManager->addClient(mClientCallback1, kClientName, kClientPackage, &client);
361     EXPECT_EQ(err, OK);
362     EXPECT_NE(client.get(), nullptr);
363     EXPECT_EQ(mClientManager->getNumOfClients(), 1);
364 
365     std::shared_ptr<ITranscodingClient> dupClient;
366     err = mClientManager->addClient(mClientCallback1, "dupClient", "dupPackage", &dupClient);
367     EXPECT_EQ(err, IMediaTranscodingService::ERROR_ALREADY_EXISTS);
368     EXPECT_EQ(dupClient.get(), nullptr);
369     EXPECT_EQ(mClientManager->getNumOfClients(), 1);
370 
371     Status status = client->unregister();
372     EXPECT_TRUE(status.isOk());
373     EXPECT_EQ(mClientManager->getNumOfClients(), 0);
374 
375     err = mClientManager->addClient(mClientCallback1, "dupClient", "dupPackage", &dupClient);
376     EXPECT_EQ(err, OK);
377     EXPECT_NE(dupClient.get(), nullptr);
378     EXPECT_EQ(mClientManager->getNumOfClients(), 1);
379 
380     status = dupClient->unregister();
381     EXPECT_TRUE(status.isOk());
382     EXPECT_EQ(mClientManager->getNumOfClients(), 0);
383 }
384 
TEST_F(TranscodingClientManagerTest,TestAddingMultipleClient)385 TEST_F(TranscodingClientManagerTest, TestAddingMultipleClient) {
386     addMultipleClients();
387     unregisterMultipleClients();
388 }
389 
TEST_F(TranscodingClientManagerTest,TestSubmitCancelGetSessions)390 TEST_F(TranscodingClientManagerTest, TestSubmitCancelGetSessions) {
391     addMultipleClients();
392 
393     // Test sessionId assignment.
394     TranscodingRequestParcel request;
395     request.sourceFilePath = "test_source_file_0";
396     request.destinationFilePath = "test_desintaion_file_0";
397     TranscodingSessionParcel session;
398     bool result;
399     EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
400     EXPECT_TRUE(result);
401     EXPECT_EQ(session.sessionId, SESSION(0));
402 
403     request.sourceFilePath = "test_source_file_1";
404     request.destinationFilePath = "test_desintaion_file_1";
405     EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
406     EXPECT_TRUE(result);
407     EXPECT_EQ(session.sessionId, SESSION(1));
408 
409     request.sourceFilePath = "test_source_file_2";
410     request.destinationFilePath = "test_desintaion_file_2";
411     EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
412     EXPECT_TRUE(result);
413     EXPECT_EQ(session.sessionId, SESSION(2));
414 
415     // Test submit bad request (no valid sourceFilePath) fails.
416     TranscodingRequestParcel badRequest;
417     badRequest.sourceFilePath = "bad_source_file";
418     badRequest.destinationFilePath = "bad_destination_file";
419     EXPECT_TRUE(mClient1->submitRequest(badRequest, &session, &result).isOk());
420     EXPECT_FALSE(result);
421 
422     // 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;
427     EXPECT_TRUE(mClient1->submitRequest(badRequest, &session, &result).isOk());
428     EXPECT_FALSE(result);
429 
430     // 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");
434     EXPECT_TRUE(result);
435 
436     // Test get sessions by invalid id fails.
437     EXPECT_TRUE(mClient1->getSessionWithId(SESSION(100), &session, &result).isOk());
438     EXPECT_FALSE(result);
439 
440     // Test cancel non-existent session fail.
441     EXPECT_TRUE(mClient2->cancelSession(SESSION(100), &result).isOk());
442     EXPECT_FALSE(result);
443 
444     // Test cancel valid sessionId in arbitrary order.
445     EXPECT_TRUE(mClient1->cancelSession(SESSION(2), &result).isOk());
446     EXPECT_TRUE(result);
447 
448     EXPECT_TRUE(mClient1->cancelSession(SESSION(0), &result).isOk());
449     EXPECT_TRUE(result);
450 
451     EXPECT_TRUE(mClient1->cancelSession(SESSION(1), &result).isOk());
452     EXPECT_TRUE(result);
453 
454     // Test cancel session again fails.
455     EXPECT_TRUE(mClient1->cancelSession(SESSION(1), &result).isOk());
456     EXPECT_FALSE(result);
457 
458     // Test get session after cancel fails.
459     EXPECT_TRUE(mClient1->getSessionWithId(SESSION(2), &session, &result).isOk());
460     EXPECT_FALSE(result);
461 
462     // Test sessionId independence for each client.
463     EXPECT_TRUE(mClient2->submitRequest(request, &session, &result).isOk());
464     EXPECT_TRUE(result);
465     EXPECT_EQ(session.sessionId, SESSION(0));
466 
467     EXPECT_TRUE(mClient2->submitRequest(request, &session, &result).isOk());
468     EXPECT_TRUE(result);
469     EXPECT_EQ(session.sessionId, SESSION(1));
470 
471     unregisterMultipleClients();
472 }
473 
TEST_F(TranscodingClientManagerTest,TestClientCallback)474 TEST_F(TranscodingClientManagerTest, TestClientCallback) {
475     addMultipleClients();
476 
477     TranscodingRequestParcel request;
478     request.sourceFilePath = "test_source_file_name";
479     request.destinationFilePath = "test_destination_file_name";
480     TranscodingSessionParcel session;
481     bool result;
482     EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
483     EXPECT_TRUE(result);
484     EXPECT_EQ(session.sessionId, SESSION(0));
485 
486     mController->finishLastSession();
487     EXPECT_EQ(mClientCallback1->popEvent(), TestClientCallback::Finished(session.sessionId));
488 
489     EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
490     EXPECT_TRUE(result);
491     EXPECT_EQ(session.sessionId, SESSION(1));
492 
493     mController->abortLastSession();
494     EXPECT_EQ(mClientCallback1->popEvent(), TestClientCallback::Failed(session.sessionId));
495 
496     EXPECT_TRUE(mClient1->submitRequest(request, &session, &result).isOk());
497     EXPECT_TRUE(result);
498     EXPECT_EQ(session.sessionId, SESSION(2));
499 
500     EXPECT_TRUE(mClient2->submitRequest(request, &session, &result).isOk());
501     EXPECT_TRUE(result);
502     EXPECT_EQ(session.sessionId, SESSION(0));
503 
504     mController->finishLastSession();
505     EXPECT_EQ(mClientCallback2->popEvent(), TestClientCallback::Finished(session.sessionId));
506 
507     unregisterMultipleClients();
508 }
509 
TEST_F(TranscodingClientManagerTest,TestUseAfterUnregister)510 TEST_F(TranscodingClientManagerTest, TestUseAfterUnregister) {
511     // Add a client.
512     std::shared_ptr<ITranscodingClient> client;
513     status_t err =
514             mClientManager->addClient(mClientCallback1, kClientName, kClientPackage, &client);
515     EXPECT_EQ(err, OK);
516     EXPECT_NE(client.get(), nullptr);
517 
518     // Submit 2 requests, 1 offline and 1 realtime.
519     TranscodingRequestParcel request;
520     TranscodingSessionParcel session;
521     bool result;
522 
523     request.sourceFilePath = "test_source_file_0";
524     request.destinationFilePath = "test_destination_file_0";
525     request.priority = TranscodingSessionPriority::kUnspecified;
526     EXPECT_TRUE(client->submitRequest(request, &session, &result).isOk() && result);
527     EXPECT_EQ(session.sessionId, SESSION(0));
528 
529     request.sourceFilePath = "test_source_file_1";
530     request.destinationFilePath = "test_destination_file_1";
531     request.priority = TranscodingSessionPriority::kNormal;
532     EXPECT_TRUE(client->submitRequest(request, &session, &result).isOk() && result);
533     EXPECT_EQ(session.sessionId, SESSION(1));
534 
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.
540     request.sourceFilePath = "test_source_file_2";
541     request.destinationFilePath = "test_destination_file_2";
542     request.priority = TranscodingSessionPriority::kNormal;
543     status = client->submitRequest(request, &session, &result);
544     EXPECT_FALSE(status.isOk());
545     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
546 
547     // 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);
550     EXPECT_FALSE(status.isOk());
551     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
552 
553     status = client->cancelSession(SESSION(1), &result);
554     EXPECT_FALSE(status.isOk());
555     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
556 
557     status = client->cancelSession(SESSION(2), &result);
558     EXPECT_FALSE(status.isOk());
559     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
560 
561     // 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);
564     EXPECT_FALSE(status.isOk());
565     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
566 
567     status = client->getSessionWithId(SESSION(1), &session, &result);
568     EXPECT_FALSE(status.isOk());
569     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
570 
571     status = client->getSessionWithId(SESSION(2), &session, &result);
572     EXPECT_FALSE(status.isOk());
573     EXPECT_EQ(status.getServiceSpecificError(), IMediaTranscodingService::ERROR_DISCONNECTED);
574 }
575 
TEST_F(TranscodingClientManagerTest,TestAddGetClientUidsInvalidArgs)576 TEST_F(TranscodingClientManagerTest, TestAddGetClientUidsInvalidArgs) {
577     addMultipleClients();
578 
579     bool result;
580     std::optional<std::vector<int32_t>> clientUids;
581     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);
590     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);
594 
595     unregisterMultipleClients();
596 }
597 
TEST_F(TranscodingClientManagerTest,TestAddGetClientUids)598 TEST_F(TranscodingClientManagerTest, TestAddGetClientUids) {
599     addMultipleClients();
600 
601     bool result;
602     std::optional<std::vector<int32_t>> clientUids;
603     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.
615     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);
619 
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.
636     EXPECT_TRUE(mClient1->getClientUids(SESSION(1), &clientUids).isOk());
637     EXPECT_NE(clientUids, std::nullopt);
638     EXPECT_EQ(clientUids->size(), 0);
639 
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);
645     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);
649 
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);
654     EXPECT_TRUE(mClient1->getClientUids(SESSION(1), &clientUids).isOk());
655     EXPECT_NE(clientUids, std::nullopt);
656     std::unordered_set<uid_t> uidSet;
657     uidSet.insert(clientUids->begin(), clientUids->end());
658     EXPECT_EQ(uidSet.size(), 2);
659     EXPECT_EQ(uidSet.count(ownUid), 1);
660     EXPECT_EQ(uidSet.count(kFakeUid), 1);
661 
662     unregisterMultipleClients();
663 }
664 
665 }  // namespace android
666