1 /* 2 * Copyright (C) 2017 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 #define LOG_TAG "VtsHalUsbV1_0TargetTest" 18 #include <android-base/logging.h> 19 20 #include <android/hardware/usb/1.0/types.h> 21 #include <android/hardware/usb/1.1/IUsb.h> 22 #include <android/hardware/usb/1.1/IUsbCallback.h> 23 #include <android/hardware/usb/1.1/types.h> 24 25 #include <VtsHalHidlTargetCallbackBase.h> 26 #include <VtsHalHidlTargetTestBase.h> 27 #include <VtsHalHidlTargetTestEnvBase.h> 28 #include <log/log.h> 29 #include <stdlib.h> 30 #include <chrono> 31 #include <condition_variable> 32 #include <mutex> 33 34 using ::android::hardware::usb::V1_1::IUsbCallback; 35 using ::android::hardware::usb::V1_0::IUsb; 36 using ::android::hardware::usb::V1_0::PortDataRole; 37 using ::android::hardware::usb::V1_0::PortMode; 38 using ::android::hardware::usb::V1_1::PortMode_1_1; 39 using ::android::hardware::usb::V1_0::PortPowerRole; 40 using ::android::hardware::usb::V1_0::PortRole; 41 using ::android::hardware::usb::V1_0::PortRoleType; 42 using ::android::hardware::usb::V1_0::PortStatus; 43 using ::android::hardware::usb::V1_1::PortStatus_1_1; 44 using ::android::hardware::usb::V1_0::Status; 45 using ::android::hidl::base::V1_0::IBase; 46 using ::android::hardware::hidl_array; 47 using ::android::hardware::hidl_memory; 48 using ::android::hardware::hidl_string; 49 using ::android::hardware::hidl_vec; 50 using ::android::hardware::Return; 51 using ::android::hardware::Void; 52 using ::android::sp; 53 54 constexpr char kCallbackNameNotifyPortStatusChange_1_1[] = "notifyPortStatusChange_1_1"; 55 56 // Worst case wait time 20secs 57 #define WAIT_FOR_TIMEOUT std::chrono::milliseconds(20000) 58 59 class UsbClientCallbackArgs { 60 public: 61 // The last conveyed status of the USB ports. 62 // Stores information of currentt_data_role, power_role for all the USB ports 63 PortStatus_1_1 usb_last_port_status; 64 65 // Status of the last role switch operation. 66 Status usb_last_status; 67 68 // Identifier for the usb callback object. 69 // Stores the cookie of the last invoked usb callback object. 70 int last_usb_cookie; 71 }; 72 73 // Callback class for the USB HIDL hal. 74 // Usb Hal will call this object upon role switch or port query. 75 class UsbCallback : public ::testing::VtsHalHidlTargetCallbackBase<UsbClientCallbackArgs>, 76 public IUsbCallback { 77 int cookie; 78 79 public: 80 UsbCallback(int cookie) : cookie(cookie){}; 81 82 virtual ~UsbCallback() = default; 83 84 // V1_0 Callback method for the port status. 85 // This should not be called so not signalling the Test here assuming that 86 // the test thread will timeout 87 Return<void> notifyPortStatusChange(const hidl_vec<PortStatus>& /* currentPortStatus */, 88 Status /*retval*/) override { 89 return Void(); 90 }; 91 92 // This callback methode should be used. 93 Return<void> notifyPortStatusChange_1_1(const hidl_vec<PortStatus_1_1>& currentPortStatus, 94 Status retval) override { 95 UsbClientCallbackArgs arg; 96 if (retval == Status::SUCCESS) { 97 arg.usb_last_port_status.status.supportedModes = 98 currentPortStatus[0].status.supportedModes; 99 arg.usb_last_port_status.status.currentMode = currentPortStatus[0].status.currentMode; 100 } 101 arg.usb_last_status = retval; 102 arg.last_usb_cookie = cookie; 103 104 NotifyFromCallback(kCallbackNameNotifyPortStatusChange_1_1, arg); 105 return Void(); 106 } 107 108 // Callback method for the status of role switch operation. 109 // RoleSwitch operation has not changed since V1_0 so leaving 110 // the callback blank here. 111 Return<void> notifyRoleSwitchStatus(const hidl_string& /*portName*/, 112 const PortRole& /*newRole*/, Status /*retval*/) override { 113 return Void(); 114 }; 115 }; 116 117 // Test environment for Usb HIDL HAL. 118 class UsbHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { 119 public: 120 // get the test environment singleton 121 static UsbHidlEnvironment* Instance() { 122 static UsbHidlEnvironment* instance = new UsbHidlEnvironment; 123 return instance; 124 } 125 126 virtual void registerTestServices() override { registerTestService<IUsb>(); } 127 }; 128 129 // The main test class for the USB hidl HAL 130 class UsbHidlTest : public ::testing::VtsHalHidlTargetTestBase { 131 public: 132 virtual void SetUp() override { 133 ALOGI(__FUNCTION__); 134 usb = ::testing::VtsHalHidlTargetTestBase::getService<IUsb>( 135 UsbHidlEnvironment::Instance()->getServiceName<IUsb>()); 136 ASSERT_NE(usb, nullptr); 137 138 usb_cb_2 = new UsbCallback(2); 139 ASSERT_NE(usb_cb_2, nullptr); 140 usb_cb_2->SetWaitTimeout(kCallbackNameNotifyPortStatusChange_1_1, WAIT_FOR_TIMEOUT); 141 Return<void> ret = usb->setCallback(usb_cb_2); 142 ASSERT_TRUE(ret.isOk()); 143 } 144 145 virtual void TearDown() override { ALOGI("Teardown"); } 146 147 // USB hidl hal Proxy 148 sp<IUsb> usb; 149 150 // Callback objects for usb hidl 151 // Methods of these objects are called to notify port status updates. 152 sp<UsbCallback> usb_cb_1; 153 sp<UsbCallback> usb_cb_2; 154 }; 155 156 /* 157 * Test to see if setCallback on V1_1 callback object succeeds. 158 * Callback oject is created and registered. 159 * Check to see if the hidl transaction succeeded. 160 */ 161 TEST_F(UsbHidlTest, setCallback) { 162 usb_cb_1 = new UsbCallback(1); 163 ASSERT_NE(usb_cb_1, nullptr); 164 Return<void> ret = usb->setCallback(usb_cb_1); 165 ASSERT_TRUE(ret.isOk()); 166 } 167 168 /* 169 * Check to see if querying type-c 170 * port status succeeds. 171 * HAL service should call notifyPortStatusChange_1_1 172 * instead of notifyPortStatusChange of V1_0 interface 173 */ 174 TEST_F(UsbHidlTest, queryPortStatus) { 175 Return<void> ret = usb->queryPortStatus(); 176 ASSERT_TRUE(ret.isOk()); 177 auto res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_1); 178 EXPECT_TRUE(res.no_timeout); 179 EXPECT_EQ(2, res.args->last_usb_cookie); 180 EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status.currentMode); 181 EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status.supportedModes); 182 EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status); 183 } 184 185 int main(int argc, char** argv) { 186 ::testing::AddGlobalTestEnvironment(UsbHidlEnvironment::Instance()); 187 ::testing::InitGoogleTest(&argc, argv); 188 UsbHidlEnvironment::Instance()->init(&argc, argv); 189 int status = RUN_ALL_TESTS(); 190 ALOGI("Test result = %d", status); 191 return status; 192 } 193