• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Probject
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 #define LOG_TAG "UsbAidlTest"
18 #include <android-base/logging.h>
19 
20 #include <aidl/android/hardware/usb/IUsb.h>
21 #include <aidl/android/hardware/usb/IUsbCallback.h>
22 #include <aidl/android/hardware/usb/BnUsbCallback.h>
23 #include <aidl/android/hardware/usb/PortDataRole.h>
24 #include <aidl/android/hardware/usb/PortMode.h>
25 #include <aidl/android/hardware/usb/PortPowerRole.h>
26 #include <aidl/android/hardware/usb/PortRole.h>
27 #include <aidl/android/hardware/usb/PortStatus.h>
28 #include <aidl/android/hardware/usb/Status.h>
29 #include <aidl/Vintf.h>
30 #include <aidl/Gtest.h>
31 
32 #include <android/binder_auto_utils.h>
33 #include <android/binder_manager.h>
34 #include <android/binder_process.h>
35 #include <gtest/gtest.h>
36 
37 #include <log/log.h>
38 #include <stdlib.h>
39 #include <chrono>
40 #include <condition_variable>
41 #include <mutex>
42 
43 #define TIMEOUT_PERIOD 10
44 
45 using ::aidl::android::hardware::usb::AltModeData;
46 using ::aidl::android::hardware::usb::BnUsbCallback;
47 using ::aidl::android::hardware::usb::ComplianceWarning;
48 using ::aidl::android::hardware::usb::DisplayPortAltModePinAssignment;
49 using ::aidl::android::hardware::usb::DisplayPortAltModeStatus;
50 using ::aidl::android::hardware::usb::IUsb;
51 using ::aidl::android::hardware::usb::IUsbCallback;
52 using ::aidl::android::hardware::usb::LinkTrainingStatus;
53 using ::aidl::android::hardware::usb::PlugOrientation;
54 using ::aidl::android::hardware::usb::PortDataRole;
55 using ::aidl::android::hardware::usb::PortMode;
56 using ::aidl::android::hardware::usb::PortPowerRole;
57 using ::aidl::android::hardware::usb::PortRole;
58 using ::aidl::android::hardware::usb::PortStatus;
59 using ::aidl::android::hardware::usb::Status;
60 using ::aidl::android::hardware::usb::UsbDataStatus;
61 
62 using ::ndk::ScopedAStatus;
63 using ::ndk::SpAIBinder;
64 using std::vector;
65 using std::shared_ptr;
66 using std::string;
67 
68 // The main test class for the USB aidl hal
69 class UsbAidlTest : public testing::TestWithParam<std::string> {
70  public:
71   // Callback class for the USB aidl hal.
72   // Usb Hal will call this object upon role switch or port query.
73   class UsbCallback : public BnUsbCallback {
74     UsbAidlTest& parent_;
75     int cookie;
76 
77    public:
UsbCallback(UsbAidlTest & parent,int cookie)78     UsbCallback(UsbAidlTest& parent, int cookie)
79         : parent_(parent), cookie(cookie){};
80 
81     virtual ~UsbCallback() = default;
82 
83     // Callback method for the port status.
notifyPortStatusChange(const vector<PortStatus> & currentPortStatus,Status retval)84     ScopedAStatus notifyPortStatusChange(const vector<PortStatus>& currentPortStatus,
85                                          Status retval) override {
86       if (retval == Status::SUCCESS && currentPortStatus.size() > 0) {
87         parent_.usb_last_port_status.portName =
88             currentPortStatus[0].portName.c_str();
89         parent_.usb_last_port_status.currentDataRole =
90             currentPortStatus[0].currentDataRole;
91         parent_.usb_last_port_status.currentPowerRole =
92             currentPortStatus[0].currentPowerRole;
93         parent_.usb_last_port_status.currentMode =
94             currentPortStatus[0].currentMode;
95       }
96       parent_.usb_last_cookie = cookie;
97       return ScopedAStatus::ok();
98     }
99 
100     // Callback method for the status of role switch operation.
notifyRoleSwitchStatus(const string &,const PortRole & newRole,Status retval,int64_t transactionId)101     ScopedAStatus notifyRoleSwitchStatus(const string& /*portName*/, const PortRole& newRole,
102                                          Status retval, int64_t transactionId) override {
103       parent_.usb_last_status = retval;
104       parent_.usb_last_cookie = cookie;
105       parent_.usb_last_port_role = newRole;
106       parent_.usb_role_switch_done = true;
107       parent_.last_transactionId = transactionId;
108       parent_.notify();
109       return ScopedAStatus::ok();
110     }
111 
112     // Callback method for the status of enableUsbData operation
notifyEnableUsbDataStatus(const string &,bool,Status,int64_t transactionId)113     ScopedAStatus notifyEnableUsbDataStatus(const string& /*portName*/, bool /*enable*/,
114                                             Status /*retval*/, int64_t transactionId) override {
115       parent_.last_transactionId = transactionId;
116       parent_.usb_last_cookie = cookie;
117       parent_.enable_usb_data_done = true;
118       parent_.notify();
119       return ScopedAStatus::ok();
120     }
121 
122     // Callback method for the status of enableUsbData operation
notifyEnableUsbDataWhileDockedStatus(const string &,Status,int64_t transactionId)123     ScopedAStatus notifyEnableUsbDataWhileDockedStatus(const string& /*portName*/,
124                                                        Status /*retval*/,
125                                                        int64_t transactionId) override {
126       parent_.last_transactionId = transactionId;
127       parent_.usb_last_cookie = cookie;
128       parent_.enable_usb_data_while_docked_done = true;
129       parent_.notify();
130       return ScopedAStatus::ok();
131     }
132 
133     // Callback method for the status of enableContaminantPresenceDetection
notifyContaminantEnabledStatus(const string &,bool,Status,int64_t transactionId)134     ScopedAStatus notifyContaminantEnabledStatus(const string& /*portName*/, bool /*enable*/,
135                                                  Status /*retval*/, int64_t transactionId) override {
136       parent_.last_transactionId = transactionId;
137       parent_.usb_last_cookie = cookie;
138       parent_.enable_contaminant_done = true;
139       parent_.notify();
140       return ScopedAStatus::ok();
141     }
142 
143     // Callback method for the status of queryPortStatus operation
notifyQueryPortStatus(const string &,Status,int64_t transactionId)144     ScopedAStatus notifyQueryPortStatus(const string& /*portName*/, Status /*retval*/,
145                                         int64_t transactionId) override {
146       parent_.last_transactionId = transactionId;
147       parent_.notify();
148       return ScopedAStatus::ok();
149     }
150 
151     // Callback method for the status of limitPowerTransfer operation
notifyLimitPowerTransferStatus(const string &,bool,Status,int64_t transactionId)152     ScopedAStatus notifyLimitPowerTransferStatus(const string& /*portName*/, bool /*limit*/,
153                                                  Status /*retval*/, int64_t transactionId) override {
154       parent_.last_transactionId = transactionId;
155       parent_.usb_last_cookie = cookie;
156       parent_.limit_power_transfer_done = true;
157       parent_.notify();
158       return ScopedAStatus::ok();
159     }
160 
161     // Callback method for the status of resetUsbPortStatus operation
notifyResetUsbPortStatus(const string &,Status,int64_t transactionId)162     ScopedAStatus notifyResetUsbPortStatus(const string& /*portName*/, Status /*retval*/,
163                                         int64_t transactionId) override {
164       ALOGI("enter notifyResetUsbPortStatus");
165       parent_.last_transactionId = transactionId;
166       parent_.usb_last_cookie = cookie;
167       parent_.reset_usb_port_done = true;
168       parent_.notify();
169       return ScopedAStatus::ok();
170     }
171   };
172 
SetUp()173   virtual void SetUp() override {
174     ALOGI("Setup");
175     usb = IUsb::fromBinder(
176                 SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
177     ASSERT_NE(usb, nullptr);
178 
179     usb_cb_2 = ::ndk::SharedRefBase::make<UsbCallback>(*this, 2);
180     ASSERT_NE(usb_cb_2, nullptr);
181     const auto& ret = usb->setCallback(usb_cb_2);
182     ASSERT_TRUE(ret.isOk());
183   }
184 
TearDown()185   virtual void TearDown() override { ALOGI("Teardown"); }
186 
187   // Used as a mechanism to inform the test about data/event callback.
notify()188   inline void notify() {
189     std::unique_lock<std::mutex> lock(usb_mtx);
190     usb_count++;
191     usb_cv.notify_one();
192   }
193 
194   // Test code calls this function to wait for data/event callback.
wait()195   inline std::cv_status wait() {
196     std::unique_lock<std::mutex> lock(usb_mtx);
197 
198     std::cv_status status = std::cv_status::no_timeout;
199     auto now = std::chrono::system_clock::now();
200     while (usb_count == 0) {
201       status =
202           usb_cv.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
203       if (status == std::cv_status::timeout) {
204         ALOGI("timeout");
205         return status;
206       }
207     }
208     usb_count--;
209     return status;
210   }
211 
212   // USB aidl hal Proxy
213   shared_ptr<IUsb> usb;
214 
215   // Callback objects for usb aidl
216   // Methods of these objects are called to notify port status updates.
217   shared_ptr<IUsbCallback> usb_cb_1, usb_cb_2;
218 
219   // The last conveyed status of the USB ports.
220   // Stores information of currentt_data_role, power_role for all the USB ports
221   PortStatus usb_last_port_status;
222 
223   // Status of the last role switch operation.
224   Status usb_last_status;
225 
226   // Port role information of the last role switch operation.
227   PortRole usb_last_port_role;
228 
229   // Flag to indicate the invocation of role switch callback.
230   bool usb_role_switch_done;
231 
232   // Flag to indicate the invocation of notifyContaminantEnabledStatus callback.
233   bool enable_contaminant_done;
234 
235   // Flag to indicate the invocation of notifyEnableUsbDataStatus callback.
236   bool enable_usb_data_done;
237 
238   // Flag to indicate the invocation of notifyEnableUsbDataWhileDockedStatus callback.
239   bool enable_usb_data_while_docked_done;
240 
241   // Flag to indicate the invocation of notifyLimitPowerTransferStatus callback.
242   bool limit_power_transfer_done;
243 
244   // Flag to indicate the invocation of notifyResetUsbPort callback.
245   bool reset_usb_port_done;
246 
247   // Stores the cookie of the last invoked usb callback object.
248   int usb_last_cookie;
249 
250   // Last transaction ID that was recorded.
251   int64_t last_transactionId;
252   // synchronization primitives to coordinate between main test thread
253   // and the callback thread.
254   std::mutex usb_mtx;
255   std::condition_variable usb_cv;
256   int usb_count = 0;
257 
258   // Stores usb version
259   int32_t usb_version;
260 };
261 
262 /*
263  * Test to see if setCallback succeeds.
264  * Callback object is created and registered.
265  */
TEST_P(UsbAidlTest,setCallback)266 TEST_P(UsbAidlTest, setCallback) {
267   ALOGI("UsbAidlTest setCallback start");
268   usb_cb_1 = ::ndk::SharedRefBase::make<UsbCallback>(*this, 1);
269   ASSERT_NE(usb_cb_1, nullptr);
270   const auto& ret = usb->setCallback(usb_cb_1);
271   ASSERT_TRUE(ret.isOk());
272   ALOGI("UsbAidlTest setCallback end");
273 }
274 
275 /*
276  * Check to see if querying type-c
277  * port status succeeds.
278  * The callback parameters are checked to see if the transaction id
279  * matches.
280  */
TEST_P(UsbAidlTest,queryPortStatus)281 TEST_P(UsbAidlTest, queryPortStatus) {
282   ALOGI("UsbAidlTest queryPortStatus start");
283   int64_t transactionId = rand() % 10000;
284   const auto& ret = usb->queryPortStatus(transactionId);
285   ASSERT_TRUE(ret.isOk());
286   EXPECT_EQ(std::cv_status::no_timeout, wait());
287   EXPECT_EQ(2, usb_last_cookie);
288   EXPECT_EQ(transactionId, last_transactionId);
289   ALOGI("UsbAidlTest queryPortStatus end: %s", usb_last_port_status.portName.c_str());
290 }
291 
292 /*
293  * Query port status to Check to see whether only one of DISABLED_DOCK,
294  * DISABLED_DOCK_DEVICE_MODE, DISABLED_DOCK_HOST_MODE is set at the most.
295  * The callback parameters are checked to see if the transaction id
296  * matches.
297  */
TEST_P(UsbAidlTest,DisabledDataStatusCheck)298 TEST_P(UsbAidlTest, DisabledDataStatusCheck) {
299   int disabledCount = 0;
300 
301   ALOGI("UsbAidlTest DataStatusCheck  start");
302   auto retVersion = usb->getInterfaceVersion(&usb_version);
303   ASSERT_TRUE(retVersion.isOk()) << retVersion;
304   if (usb_version < 2) {
305     ALOGI("UsbAidlTest skipping DataStatusCheck on older interface versions");
306     GTEST_SKIP();
307   }
308   int64_t transactionId = rand() % 10000;
309   const auto& ret = usb->queryPortStatus(transactionId);
310   ASSERT_TRUE(ret.isOk());
311   EXPECT_EQ(std::cv_status::no_timeout, wait());
312   EXPECT_EQ(2, usb_last_cookie);
313   EXPECT_EQ(transactionId, last_transactionId);
314   ALOGI("UsbAidlTest DataStatusCheck portName: %s", usb_last_port_status.portName.c_str());
315   if (usb_last_port_status.usbDataStatus.size() > 1) {
316     for (UsbDataStatus dataStatus : usb_last_port_status.usbDataStatus) {
317       if (dataStatus == UsbDataStatus::DISABLED_DOCK ||
318           dataStatus == UsbDataStatus::DISABLED_DOCK_DEVICE_MODE ||
319           dataStatus == UsbDataStatus::DISABLED_DOCK_HOST_MODE) {
320         disabledCount++;
321       }
322     }
323   }
324   EXPECT_GE(1, disabledCount);
325   ALOGI("UsbAidlTest DataStatusCheck end");
326 }
327 
328 /*
329  * Trying to switch a non-existent port should fail.
330  * This test case tried to switch the port with empty
331  * name which is expected to fail.
332  * The callback parameters are checked to see if the transaction id
333  * matches.
334  */
TEST_P(UsbAidlTest,switchEmptyPort)335 TEST_P(UsbAidlTest, switchEmptyPort) {
336   ALOGI("UsbAidlTest switchEmptyPort start");
337   PortRole role;
338   role.set<PortRole::powerRole>(PortPowerRole::SOURCE);
339   int64_t transactionId = rand() % 10000;
340   const auto& ret = usb->switchRole("", role, transactionId);
341   ASSERT_TRUE(ret.isOk());
342   EXPECT_EQ(std::cv_status::no_timeout, wait());
343   EXPECT_EQ(Status::ERROR, usb_last_status);
344   EXPECT_EQ(transactionId, last_transactionId);
345   EXPECT_EQ(2, usb_last_cookie);
346   ALOGI("UsbAidlTest switchEmptyPort end");
347 }
348 
349 /*
350  * Test switching the power role of usb port.
351  * Test case queries the usb ports present in device.
352  * If there is at least one usb port, a power role switch
353  * to SOURCE is attempted for the port.
354  * The callback parameters are checked to see if the transaction id
355  * matches.
356  */
TEST_P(UsbAidlTest,switchPowerRole)357 TEST_P(UsbAidlTest, switchPowerRole) {
358   ALOGI("UsbAidlTest switchPowerRole start");
359   PortRole role;
360   role.set<PortRole::powerRole>(PortPowerRole::SOURCE);
361   int64_t transactionId = rand() % 10000;
362   const auto& ret = usb->queryPortStatus(transactionId);
363   ASSERT_TRUE(ret.isOk());
364   EXPECT_EQ(std::cv_status::no_timeout, wait());
365   EXPECT_EQ(2, usb_last_cookie);
366   EXPECT_EQ(transactionId, last_transactionId);
367 
368   if (!usb_last_port_status.portName.empty()) {
369     string portBeingSwitched = usb_last_port_status.portName;
370     ALOGI("switchPower role portname:%s", portBeingSwitched.c_str());
371     usb_role_switch_done = false;
372     transactionId = rand() % 10000;
373     const auto& ret = usb->switchRole(portBeingSwitched, role, transactionId);
374     ASSERT_TRUE(ret.isOk());
375 
376     std::cv_status waitStatus = wait();
377     while (waitStatus == std::cv_status::no_timeout &&
378            usb_role_switch_done == false)
379       waitStatus = wait();
380 
381     EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
382     EXPECT_EQ(2, usb_last_cookie);
383     EXPECT_EQ(transactionId, last_transactionId);
384   }
385   ALOGI("UsbAidlTest switchPowerRole end");
386 }
387 
388 /*
389  * Test switching the data role of usb port.
390  * Test case queries the usb ports present in device.
391  * If there is at least one usb port, a data role switch
392  * to device is attempted for the port.
393  * The callback parameters are checked to see if transaction id
394  * matches.
395  */
TEST_P(UsbAidlTest,switchDataRole)396 TEST_P(UsbAidlTest, switchDataRole) {
397   ALOGI("UsbAidlTest switchDataRole start");
398   PortRole role;
399   role.set<PortRole::dataRole>(PortDataRole::DEVICE);
400   int64_t transactionId = rand() % 10000;
401   const auto& ret = usb->queryPortStatus(transactionId);
402   ASSERT_TRUE(ret.isOk());
403   EXPECT_EQ(std::cv_status::no_timeout, wait());
404   EXPECT_EQ(2, usb_last_cookie);
405   EXPECT_EQ(transactionId, last_transactionId);
406 
407   if (!usb_last_port_status.portName.empty()) {
408     string portBeingSwitched = usb_last_port_status.portName;
409     ALOGI("portname:%s", portBeingSwitched.c_str());
410     usb_role_switch_done = false;
411     transactionId = rand() % 10000;
412     const auto& ret = usb->switchRole(portBeingSwitched, role, transactionId);
413     ASSERT_TRUE(ret.isOk());
414 
415     std::cv_status waitStatus = wait();
416     while (waitStatus == std::cv_status::no_timeout &&
417            usb_role_switch_done == false)
418       waitStatus = wait();
419 
420     EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
421     EXPECT_EQ(2, usb_last_cookie);
422     EXPECT_EQ(transactionId, last_transactionId);
423   }
424   ALOGI("UsbAidlTest switchDataRole end");
425 }
426 
427 /*
428  * Test enabling contaminant presence detection of the port.
429  * Test case queries the usb ports present in device.
430  * If there is at least one usb port, enabling contaminant detection
431  * is attempted for the port.
432  * The callback parameters are checked to see if transaction id
433  * matches.
434  */
TEST_P(UsbAidlTest,enableContaminantPresenceDetection)435 TEST_P(UsbAidlTest, enableContaminantPresenceDetection) {
436   ALOGI("UsbAidlTest enableContaminantPresenceDetection start");
437   int64_t transactionId = rand() % 10000;
438   const auto& ret = usb->queryPortStatus(transactionId);
439   ASSERT_TRUE(ret.isOk());
440   EXPECT_EQ(std::cv_status::no_timeout, wait());
441   EXPECT_EQ(2, usb_last_cookie);
442   EXPECT_EQ(transactionId, last_transactionId);
443 
444   if (!usb_last_port_status.portName.empty()) {
445     ALOGI("portname:%s", usb_last_port_status.portName.c_str());
446     enable_contaminant_done = false;
447     transactionId = rand() % 10000;
448     const auto& ret = usb->enableContaminantPresenceDetection(usb_last_port_status.portName,
449                                                               true, transactionId);
450     ASSERT_TRUE(ret.isOk());
451 
452     std::cv_status waitStatus = wait();
453     while (waitStatus == std::cv_status::no_timeout &&
454            enable_contaminant_done == false)
455       waitStatus = wait();
456 
457     EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
458     EXPECT_EQ(2, usb_last_cookie);
459     EXPECT_EQ(transactionId, last_transactionId);
460   }
461   ALOGI("UsbAidlTest enableContaminantPresenceDetection end");
462 }
463 
464 /*
465  * Test enabling Usb data of the port.
466  * Test case queries the usb ports present in device.
467  * If there is at least one usb port, enabling Usb data is attempted
468  * for the port.
469  * The callback parameters are checked to see if transaction id
470  * matches.
471  */
TEST_P(UsbAidlTest,enableUsbData)472 TEST_P(UsbAidlTest, enableUsbData) {
473   ALOGI("UsbAidlTest enableUsbData start");
474   int64_t transactionId = rand() % 10000;
475   const auto& ret = usb->queryPortStatus(transactionId);
476   ASSERT_TRUE(ret.isOk());
477   EXPECT_EQ(std::cv_status::no_timeout, wait());
478   EXPECT_EQ(2, usb_last_cookie);
479   EXPECT_EQ(transactionId, last_transactionId);
480 
481   if (!usb_last_port_status.portName.empty()) {
482     ALOGI("portname:%s", usb_last_port_status.portName.c_str());
483     enable_usb_data_done = false;
484     transactionId = rand() % 10000;
485     const auto& ret = usb->enableUsbData(usb_last_port_status.portName, true, transactionId);
486     ASSERT_TRUE(ret.isOk());
487 
488     std::cv_status waitStatus = wait();
489     while (waitStatus == std::cv_status::no_timeout &&
490            enable_usb_data_done == false)
491       waitStatus = wait();
492 
493     EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
494     EXPECT_EQ(2, usb_last_cookie);
495     EXPECT_EQ(transactionId, last_transactionId);
496   }
497   ALOGI("UsbAidlTest enableUsbData end");
498 }
499 
500 /*
501  * Test enabling Usb data while being docked.
502  * Test case queries the usb ports present in device.
503  * If there is at least one usb port, enabling Usb data while docked
504  * is attempted for the port.
505  * The callback parameters are checked to see if transaction id
506  * matches.
507  */
TEST_P(UsbAidlTest,enableUsbDataWhileDocked)508 TEST_P(UsbAidlTest, enableUsbDataWhileDocked) {
509   ALOGI("UsbAidlTest enableUsbDataWhileDocked start");
510   int64_t transactionId = rand() % 10000;
511   const auto& ret = usb->queryPortStatus(transactionId);
512   ASSERT_TRUE(ret.isOk());
513   EXPECT_EQ(std::cv_status::no_timeout, wait());
514   EXPECT_EQ(2, usb_last_cookie);
515   EXPECT_EQ(transactionId, last_transactionId);
516 
517   if (!usb_last_port_status.portName.empty()) {
518     ALOGI("portname:%s", usb_last_port_status.portName.c_str());
519     enable_usb_data_while_docked_done = false;
520     transactionId = rand() % 10000;
521     const auto& ret = usb->enableUsbDataWhileDocked(usb_last_port_status.portName, transactionId);
522     ASSERT_TRUE(ret.isOk());
523 
524     std::cv_status waitStatus = wait();
525     while (waitStatus == std::cv_status::no_timeout &&
526            enable_usb_data_while_docked_done == false)
527       waitStatus = wait();
528 
529     EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
530     EXPECT_EQ(2, usb_last_cookie);
531     EXPECT_EQ(transactionId, last_transactionId);
532   }
533   ALOGI("UsbAidlTest enableUsbDataWhileDocked end");
534 }
535 
536 /*
537  * Test enabling Usb data of the port.
538  * Test case queries the usb ports present in device.
539  * If there is at least one usb port, relaxing limit power transfer
540  * is attempted for the port.
541  * The callback parameters are checked to see if transaction id
542  * matches.
543  */
TEST_P(UsbAidlTest,limitPowerTransfer)544 TEST_P(UsbAidlTest, limitPowerTransfer) {
545   ALOGI("UsbAidlTest limitPowerTransfer start");
546   int64_t transactionId = rand() % 10000;
547   const auto& ret = usb->queryPortStatus(transactionId);
548   ASSERT_TRUE(ret.isOk());
549   EXPECT_EQ(std::cv_status::no_timeout, wait());
550   EXPECT_EQ(2, usb_last_cookie);
551   EXPECT_EQ(transactionId, last_transactionId);
552 
553   if (!usb_last_port_status.portName.empty()) {
554     ALOGI("portname:%s", usb_last_port_status.portName.c_str());
555     limit_power_transfer_done = false;
556     transactionId = rand() % 10000;
557     const auto& ret = usb->limitPowerTransfer(usb_last_port_status.portName, false, transactionId);
558     ASSERT_TRUE(ret.isOk());
559 
560     std::cv_status waitStatus = wait();
561     while (waitStatus == std::cv_status::no_timeout &&
562            limit_power_transfer_done == false)
563       waitStatus = wait();
564 
565     EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
566     EXPECT_EQ(2, usb_last_cookie);
567     EXPECT_EQ(transactionId, last_transactionId);
568   }
569   ALOGI("UsbAidlTest limitPowerTransfer end");
570 }
571 
572 /*
573  * Test reset Usb data of the port.
574  * Test case queries the usb ports present in device.
575  * If there is at least one usb port, reset Usb data for the port.
576  * The callback parameters are checked to see if transaction id
577  * matches.
578  */
TEST_P(UsbAidlTest,DISABLED_resetUsbPort)579 TEST_P(UsbAidlTest, DISABLED_resetUsbPort) {
580   ALOGI("UsbAidlTest resetUsbPort start");
581   int64_t transactionId = rand() % 10000;
582   const auto& ret = usb->queryPortStatus(transactionId);
583   ASSERT_TRUE(ret.isOk());
584   EXPECT_EQ(std::cv_status::no_timeout, wait());
585   EXPECT_EQ(2, usb_last_cookie);
586   EXPECT_EQ(transactionId, last_transactionId);
587 
588   if (!usb_last_port_status.portName.empty()) {
589     ALOGI("portname:%s", usb_last_port_status.portName.c_str());
590     reset_usb_port_done = false;
591     transactionId = rand() % 10000;
592     const auto& ret = usb->resetUsbPort(usb_last_port_status.portName, transactionId);
593     ASSERT_TRUE(ret.isOk());
594     ALOGI("UsbAidlTest resetUsbPort ret.isOk");
595 
596     std::cv_status waitStatus = wait();
597     while (waitStatus == std::cv_status::no_timeout &&
598            reset_usb_port_done == false)
599       waitStatus = wait();
600 
601     ALOGI("UsbAidlTest resetUsbPort wait()");
602     EXPECT_EQ(std::cv_status::no_timeout, waitStatus);
603     EXPECT_EQ(2, usb_last_cookie);
604     EXPECT_EQ(transactionId, last_transactionId);
605   }
606   ALOGI("UsbAidlTest resetUsbPort end");
607 }
608 
609 /*
610  * Test charger compliance warning
611  * The test asserts that complianceWarnings is
612  * empty when the feature is not supported. i.e.
613  * supportsComplianceWarning is false.
614  */
TEST_P(UsbAidlTest,nonCompliantChargerStatus)615 TEST_P(UsbAidlTest, nonCompliantChargerStatus) {
616   ALOGI("UsbAidlTest nonCompliantChargerStatus start");
617   auto retVersion = usb->getInterfaceVersion(&usb_version);
618   ASSERT_TRUE(retVersion.isOk()) << retVersion;
619   if (usb_version < 2) {
620     ALOGI("UsbAidlTest skipping nonCompliantChargerStatus on older interface versions");
621     GTEST_SKIP();
622   }
623   int64_t transactionId = rand() % 10000;
624   const auto& ret = usb->queryPortStatus(transactionId);
625   ASSERT_TRUE(ret.isOk());
626   EXPECT_EQ(std::cv_status::no_timeout, wait());
627   EXPECT_EQ(2, usb_last_cookie);
628   EXPECT_EQ(transactionId, last_transactionId);
629 
630   if (!usb_last_port_status.supportsComplianceWarnings) {
631     EXPECT_TRUE(usb_last_port_status.complianceWarnings.empty());
632   }
633 
634   ALOGI("UsbAidlTest nonCompliantChargerStatus end");
635 }
636 
637 /*
638  * Test charger compliance warning values
639  * The test asserts that complianceWarning values
640  * are valid.
641  */
TEST_P(UsbAidlTest,nonCompliantChargerValues)642 TEST_P(UsbAidlTest, nonCompliantChargerValues) {
643   ALOGI("UsbAidlTest nonCompliantChargerValues start");
644   auto retVersion = usb->getInterfaceVersion(&usb_version);
645   ASSERT_TRUE(retVersion.isOk()) << retVersion;
646   if (usb_version < 2) {
647     ALOGI("UsbAidlTest skipping nonCompliantChargerValues on older interface versions");
648     GTEST_SKIP();
649   }
650   int64_t transactionId = rand() % 10000;
651   const auto& ret = usb->queryPortStatus(transactionId);
652   ASSERT_TRUE(ret.isOk());
653   EXPECT_EQ(std::cv_status::no_timeout, wait());
654   EXPECT_EQ(2, usb_last_cookie);
655   EXPECT_EQ(transactionId, last_transactionId);
656 
657   // Current compliance values range from [1, 4]
658   if (usb_last_port_status.supportsComplianceWarnings) {
659     for (auto warning : usb_last_port_status.complianceWarnings) {
660       EXPECT_TRUE((int)warning >= (int)ComplianceWarning::OTHER);
661       EXPECT_TRUE((int)warning <= (int)ComplianceWarning::MISSING_RP);
662     }
663   }
664 
665   ALOGI("UsbAidlTest nonCompliantChargerValues end");
666 }
667 
668 /*
669  * Test PlugOrientation Values are within range in PortStatus
670  */
TEST_P(UsbAidlTest,plugOrientationValues)671 TEST_P(UsbAidlTest, plugOrientationValues) {
672   ALOGI("UsbAidlTest plugOrientationValues start");
673   auto retVersion = usb->getInterfaceVersion(&usb_version);
674   ASSERT_TRUE(retVersion.isOk()) << retVersion;
675   if (usb_version < 2) {
676     ALOGI("UsbAidlTest skipping plugOrientationValues on older interface versions");
677     GTEST_SKIP();
678   }
679   int64_t transactionId = rand() % 10000;
680   const auto& ret = usb->queryPortStatus(transactionId);
681   ASSERT_TRUE(ret.isOk());
682   EXPECT_EQ(std::cv_status::no_timeout, wait());
683   EXPECT_EQ(2, usb_last_cookie);
684   EXPECT_EQ(transactionId, last_transactionId);
685 
686   EXPECT_TRUE((int)usb_last_port_status.plugOrientation >= (int)PlugOrientation::UNKNOWN);
687   EXPECT_TRUE((int)usb_last_port_status.plugOrientation <= (int)PlugOrientation::PLUGGED_FLIPPED);
688 }
689 
690 /*
691  * Test DisplayPortAltMode Values when DisplayPort Alt Mode
692  * is active.
693  */
TEST_P(UsbAidlTest,dpAltModeValues)694 TEST_P(UsbAidlTest, dpAltModeValues) {
695   ALOGI("UsbAidlTest dpAltModeValues start");
696   auto retVersion = usb->getInterfaceVersion(&usb_version);
697   ASSERT_TRUE(retVersion.isOk()) << retVersion;
698   if (usb_version < 2) {
699     ALOGI("UsbAidlTest skipping dpAltModeValues on older interface versions");
700     GTEST_SKIP();
701   }
702   int64_t transactionId = rand() % 10000;
703   const auto& ret = usb->queryPortStatus(transactionId);
704   ASSERT_TRUE(ret.isOk());
705   EXPECT_EQ(std::cv_status::no_timeout, wait());
706   EXPECT_EQ(2, usb_last_cookie);
707   EXPECT_EQ(transactionId, last_transactionId);
708 
709   // Discover DisplayPort Alt Mode
710   for (AltModeData altMode : usb_last_port_status.supportedAltModes) {
711     if (altMode.getTag() == AltModeData::displayPortAltModeData) {
712       AltModeData::DisplayPortAltModeData displayPortAltModeData =
713               altMode.get<AltModeData::displayPortAltModeData>();
714       EXPECT_TRUE((int)displayPortAltModeData.partnerSinkStatus >=
715                   (int)DisplayPortAltModeStatus::UNKNOWN);
716       EXPECT_TRUE((int)displayPortAltModeData.partnerSinkStatus <=
717                   (int)DisplayPortAltModeStatus::ENABLED);
718 
719       EXPECT_TRUE((int)displayPortAltModeData.cableStatus >=
720                   (int)DisplayPortAltModeStatus::UNKNOWN);
721       EXPECT_TRUE((int)displayPortAltModeData.cableStatus <=
722                   (int)DisplayPortAltModeStatus::ENABLED);
723 
724       EXPECT_TRUE((int)displayPortAltModeData.pinAssignment >=
725                   (int)DisplayPortAltModePinAssignment::NONE);
726       EXPECT_TRUE((int)displayPortAltModeData.pinAssignment <=
727                   (int)DisplayPortAltModePinAssignment::F);
728 
729       EXPECT_TRUE((int)displayPortAltModeData.linkTrainingStatus >=
730                   (int)LinkTrainingStatus::UNKNOWN);
731       EXPECT_TRUE((int)displayPortAltModeData.pinAssignment <= (int)LinkTrainingStatus::FAILURE);
732     }
733   }
734 
735   ALOGI("UsbAidlTest dpAltModeValues end");
736 }
737 
738 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UsbAidlTest);
739 INSTANTIATE_TEST_SUITE_P(
740         PerInstance, UsbAidlTest,
741         testing::ValuesIn(::android::getAidlHalInstanceNames(IUsb::descriptor)),
742         ::android::PrintInstanceNameToString);
743 
main(int argc,char ** argv)744 int main(int argc, char** argv) {
745     ::testing::InitGoogleTest(&argc, argv);
746     ABinderProcess_setThreadPoolMaxThreadCount(1);
747     ABinderProcess_startThreadPool();
748     return RUN_ALL_TESTS();
749 }
750