blob: 5f901cd4f61e6c882e94a50b0ee90c53ef8bcf14 [file] [log] [blame]
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "VtsHalUsbV1_2TargetTest"
18#include <android-base/logging.h>
19
20#include <android/hardware/usb/1.2/IUsb.h>
21#include <android/hardware/usb/1.2/IUsbCallback.h>
22#include <android/hardware/usb/1.2/types.h>
23
24#include <VtsHalHidlTargetCallbackBase.h>
Dan Shif15bd2d2020-04-03 12:57:13 -070025#include <gtest/gtest.h>
26#include <hidl/GtestPrinter.h>
27#include <hidl/ServiceManagement.h>
28
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -080029#include <log/log.h>
30#include <stdlib.h>
31#include <chrono>
32#include <condition_variable>
33#include <mutex>
34
35using ::android::sp;
36using ::android::hardware::hidl_array;
37using ::android::hardware::hidl_memory;
38using ::android::hardware::hidl_string;
39using ::android::hardware::hidl_vec;
40using ::android::hardware::Return;
41using ::android::hardware::Void;
42using ::android::hardware::usb::V1_0::PortDataRole;
43using ::android::hardware::usb::V1_0::PortMode;
44using ::android::hardware::usb::V1_0::PortPowerRole;
45using ::android::hardware::usb::V1_0::PortRole;
46using ::android::hardware::usb::V1_0::PortRoleType;
47using ::android::hardware::usb::V1_0::Status;
48using ::android::hardware::usb::V1_1::PortMode_1_1;
49using ::android::hardware::usb::V1_1::PortStatus_1_1;
50using ::android::hardware::usb::V1_2::ContaminantDetectionStatus;
51using ::android::hardware::usb::V1_2::ContaminantProtectionMode;
52using ::android::hardware::usb::V1_2::ContaminantProtectionStatus;
53using ::android::hardware::usb::V1_2::IUsb;
54using ::android::hardware::usb::V1_2::IUsbCallback;
55using ::android::hardware::usb::V1_2::PortStatus;
56using ::android::hidl::base::V1_0::IBase;
57
58constexpr char kCallbackNameNotifyPortStatusChange_1_2[] = "notifyPortStatusChange_1_2";
59const int kCallbackIdentifier = 2;
60
61// Worst case wait time 20secs
62#define WAIT_FOR_TIMEOUT std::chrono::milliseconds(20000)
63
64class UsbClientCallbackArgs {
65 public:
66 // The last conveyed status of the USB ports.
67 // Stores information of currentt_data_role, power_role for all the USB ports
68 PortStatus usb_last_port_status;
69
70 // Status of the last role switch operation.
71 Status usb_last_status;
72
73 // Identifier for the usb callback object.
74 // Stores the cookie of the last invoked usb callback object.
75 int last_usb_cookie;
76};
77
78// Callback class for the USB HIDL hal.
79// Usb Hal will call this object upon role switch or port query.
80class UsbCallback : public ::testing::VtsHalHidlTargetCallbackBase<UsbClientCallbackArgs>,
81 public IUsbCallback {
82 int cookie;
83
84 public:
85 UsbCallback(int cookie) : cookie(cookie){};
86
87 virtual ~UsbCallback() = default;
88
89 // V1_0 Callback method for the port status.
90 // This should not be called so not signalling the Test here assuming that
91 // the test thread will timeout
92 Return<void> notifyPortStatusChange(const hidl_vec<android::hardware::usb::V1_0::PortStatus>&
93 /* currentPortStatus */,
94 Status /* retval */) override {
95 return Void();
96 };
97
98 // V1_1 Callback method for the port status.
99 // This should not be called so not signalling the Test here assuming that
100 // the test thread will timeout
101 Return<void> notifyPortStatusChange_1_1(const hidl_vec<PortStatus_1_1>& /* currentPortStatus */,
102 Status /* retval */) override {
103 return Void();
104 }
105
106 // This callback method should be used.
107 Return<void> notifyPortStatusChange_1_2(const hidl_vec<PortStatus>& currentPortStatus,
108 Status retval) override {
109 UsbClientCallbackArgs arg;
110 if (retval == Status::SUCCESS) {
111 arg.usb_last_port_status.status_1_1.status.supportedModes =
112 currentPortStatus[0].status_1_1.status.supportedModes;
113 arg.usb_last_port_status.status_1_1.status.currentMode =
114 currentPortStatus[0].status_1_1.status.currentMode;
115 arg.usb_last_port_status.status_1_1.status.portName =
116 currentPortStatus[0].status_1_1.status.portName;
117 arg.usb_last_port_status.contaminantDetectionStatus =
118 currentPortStatus[0].contaminantDetectionStatus;
119 arg.usb_last_port_status.contaminantProtectionStatus =
120 currentPortStatus[0].contaminantProtectionStatus;
121 arg.usb_last_port_status.supportsEnableContaminantPresenceProtection =
122 currentPortStatus[0].supportsEnableContaminantPresenceProtection;
123 arg.usb_last_port_status.supportsEnableContaminantPresenceDetection =
124 currentPortStatus[0].supportsEnableContaminantPresenceDetection;
125 arg.usb_last_port_status.supportedContaminantProtectionModes =
126 currentPortStatus[0].supportedContaminantProtectionModes;
127 }
128 arg.usb_last_status = retval;
129 arg.last_usb_cookie = cookie;
130
131 NotifyFromCallback(kCallbackNameNotifyPortStatusChange_1_2, arg);
132 return Void();
133 }
134
135 // Callback method for the status of role switch operation.
136 // RoleSwitch operation has not changed since V1_0 so leaving
137 // the callback blank here.
138 Return<void> notifyRoleSwitchStatus(const hidl_string& /*portName*/,
139 const PortRole& /*newRole*/, Status /*retval*/) override {
140 return Void();
141 };
142};
143
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -0800144// The main test class for the USB hidl HAL
Dan Shif15bd2d2020-04-03 12:57:13 -0700145class UsbHidlTest : public ::testing::TestWithParam<std::string> {
146 public:
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -0800147 virtual void SetUp() override {
148 ALOGI(__FUNCTION__);
Dan Shif15bd2d2020-04-03 12:57:13 -0700149 usb = IUsb::getService(GetParam());
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -0800150 ASSERT_NE(usb, nullptr);
151
152 usb_cb_2 = new UsbCallback(kCallbackIdentifier);
153 ASSERT_NE(usb_cb_2, nullptr);
154 usb_cb_2->SetWaitTimeout(kCallbackNameNotifyPortStatusChange_1_2, WAIT_FOR_TIMEOUT);
155 Return<void> ret = usb->setCallback(usb_cb_2);
156 ASSERT_TRUE(ret.isOk());
157 }
158
159 virtual void TearDown() override { ALOGI("Teardown"); }
160
161 // USB hidl hal Proxy
162 sp<IUsb> usb;
163
164 // Callback objects for usb hidl
165 // Methods of these objects are called to notify port status updates.
166 sp<UsbCallback> usb_cb_1;
167 sp<UsbCallback> usb_cb_2;
168};
169
170/*
171 * Test to see if setCallback on V1_1 callback object succeeds.
172 * Callback oject is created and registered.
173 * Check to see if the hidl transaction succeeded.
174 */
Dan Shif15bd2d2020-04-03 12:57:13 -0700175TEST_P(UsbHidlTest, setCallback) {
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -0800176 usb_cb_1 = new UsbCallback(1);
177 ASSERT_NE(usb_cb_1, nullptr);
178 Return<void> ret = usb->setCallback(usb_cb_1);
179 ASSERT_TRUE(ret.isOk());
180}
181
182/*
183 * Check to see if querying type-c
184 * port status succeeds.
185 * HAL service should call notifyPortStatusChange_1_2
186 * instead of notifyPortStatusChange of V1_0/V1_1 interface
187 */
Dan Shif15bd2d2020-04-03 12:57:13 -0700188TEST_P(UsbHidlTest, queryPortStatus) {
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -0800189 Return<void> ret = usb->queryPortStatus();
190 ASSERT_TRUE(ret.isOk());
191 auto res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_2);
192 EXPECT_TRUE(res.no_timeout);
193 EXPECT_EQ(kCallbackIdentifier, res.args->last_usb_cookie);
194 EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status_1_1.status.currentMode);
195 EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status_1_1.status.supportedModes);
196 EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status);
197}
198
199/*
200 * supportedContaminantProtectionModes is immutable.
201 * Check if supportedContaminantProtectionModes changes across queryPortStatus
202 * call.
203 */
Dan Shif15bd2d2020-04-03 12:57:13 -0700204TEST_P(UsbHidlTest, checkSupportedContaminantProtectionModes) {
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -0800205 Return<void> ret = usb->queryPortStatus();
206 ASSERT_TRUE(ret.isOk());
207 auto res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_2);
208 EXPECT_TRUE(res.no_timeout);
209 EXPECT_EQ(kCallbackIdentifier, res.args->last_usb_cookie);
210 EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status_1_1.status.currentMode);
211 EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status_1_1.status.supportedModes);
212 EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status);
213
214 uint32_t supportedContaminantProtectionModes = static_cast<uint32_t>(
215 res.args->usb_last_port_status.supportedContaminantProtectionModes);
216 for (int runs = 1; runs <= 10; runs++) {
217 ret = usb->queryPortStatus();
218 ASSERT_TRUE(ret.isOk());
219 res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_2);
220 EXPECT_TRUE(res.no_timeout);
221 EXPECT_EQ(kCallbackIdentifier, res.args->last_usb_cookie);
222 EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status_1_1.status.currentMode);
223 EXPECT_EQ(PortMode::NONE, res.args->usb_last_port_status.status_1_1.status.supportedModes);
224 EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status);
225 EXPECT_EQ(supportedContaminantProtectionModes,
226 static_cast<uint32_t>(
227 res.args->usb_last_port_status.supportedContaminantProtectionModes));
228 }
229}
230
231/*
232 * When supportsEnableContaminantPresenceDetection is set false,
233 * enableContaminantPresenceDetection should not enable/disable
234 * contaminantPresenceProtection.
235 */
Dan Shif15bd2d2020-04-03 12:57:13 -0700236TEST_P(UsbHidlTest, presenceDetectionSupportedCheck) {
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -0800237 Return<void> ret = usb->queryPortStatus();
238 ASSERT_TRUE(ret.isOk());
239 auto res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_2);
240 EXPECT_TRUE(res.no_timeout);
241 EXPECT_EQ(kCallbackIdentifier, res.args->last_usb_cookie);
242 EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status);
243
244 if (!res.args->usb_last_port_status.supportsEnableContaminantPresenceDetection) {
245 for (int runs = 1; runs <= 10; runs++) {
246 bool currentStatus = !(res.args->usb_last_port_status.contaminantDetectionStatus ==
247 ContaminantDetectionStatus::DISABLED);
248
249 ret = usb->enableContaminantPresenceDetection(
250 res.args->usb_last_port_status.status_1_1.status.portName, !currentStatus);
251 ASSERT_TRUE(ret.isOk());
252
253 res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_2);
254 EXPECT_TRUE(res.no_timeout);
255 EXPECT_EQ(kCallbackIdentifier, res.args->last_usb_cookie);
256 EXPECT_EQ(currentStatus, !(res.args->usb_last_port_status.contaminantDetectionStatus ==
257 ContaminantDetectionStatus::DISABLED));
258 }
259 }
260}
261
262/*
263 * enableContaminantPresenceDetection should succeed atleast 90% when supported.
264 */
Dan Shif15bd2d2020-04-03 12:57:13 -0700265TEST_P(UsbHidlTest, contaminantPresenceDetectionStability) {
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -0800266 int successCount = 0;
267 bool currentStatus;
268 bool supported = true;
269
270 Return<void> ret = usb->queryPortStatus();
271 ASSERT_TRUE(ret.isOk());
272 auto res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_2);
273 EXPECT_TRUE(res.no_timeout);
274 EXPECT_EQ(kCallbackIdentifier, res.args->last_usb_cookie);
275 EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status);
276
277 if (!res.args->usb_last_port_status.supportsEnableContaminantPresenceDetection) return;
278
279 for (int count = 1; count <= 10; count++) {
280 currentStatus = !(res.args->usb_last_port_status.contaminantDetectionStatus ==
281 ContaminantDetectionStatus::DISABLED);
282
283 ret = usb->enableContaminantPresenceDetection(
284 res.args->usb_last_port_status.status_1_1.status.portName, !currentStatus);
285 ASSERT_TRUE(ret.isOk());
286 res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_2);
287 EXPECT_TRUE(res.no_timeout);
288 EXPECT_EQ(kCallbackIdentifier, res.args->last_usb_cookie);
289 if (!currentStatus == !(res.args->usb_last_port_status.contaminantDetectionStatus ==
290 ContaminantDetectionStatus::DISABLED))
291 successCount++;
292 }
293
294 if (!supported) EXPECT_GE(successCount, 9);
295}
296
297/*
298 * When supportsEnableContaminantPresenceProtection is set false,
299 * enableContaminantPresenceProtection should not enable/disable
300 * contaminantPresenceProtection.
301 */
Dan Shif15bd2d2020-04-03 12:57:13 -0700302TEST_P(UsbHidlTest, presenceProtectionSupportedCheck) {
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -0800303 Return<void> ret = usb->queryPortStatus();
304 ASSERT_TRUE(ret.isOk());
305 auto res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_2);
306 EXPECT_TRUE(res.no_timeout);
307 EXPECT_EQ(kCallbackIdentifier, res.args->last_usb_cookie);
308 EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status);
309
310 if (!res.args->usb_last_port_status.supportsEnableContaminantPresenceProtection) {
311 for (int runs = 1; runs <= 10; runs++) {
312 bool currentStatus = !(res.args->usb_last_port_status.contaminantProtectionStatus ==
313 ContaminantProtectionStatus::DISABLED);
314
315 ret = usb->enableContaminantPresenceProtection(
316 res.args->usb_last_port_status.status_1_1.status.portName, !currentStatus);
317 ASSERT_TRUE(ret.isOk());
318
319 res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_2);
320 EXPECT_TRUE(res.no_timeout);
321 EXPECT_EQ(kCallbackIdentifier, res.args->last_usb_cookie);
322 EXPECT_EQ(currentStatus, !(res.args->usb_last_port_status.contaminantProtectionStatus ==
323 ContaminantProtectionStatus::DISABLED));
324 }
325 }
326}
327
328/*
329 * enableContaminantPresenceProtection should succeed atleast 90% when supported.
330 */
Dan Shif15bd2d2020-04-03 12:57:13 -0700331TEST_P(UsbHidlTest, contaminantPresenceProtectionStability) {
Badhri Jagan Sridharanc846dc82019-01-18 00:40:25 -0800332 int successCount = 0;
333 bool currentStatus;
334 bool supported = true;
335
336 Return<void> ret = usb->queryPortStatus();
337 ASSERT_TRUE(ret.isOk());
338 auto res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_2);
339 EXPECT_TRUE(res.no_timeout);
340 EXPECT_EQ(kCallbackIdentifier, res.args->last_usb_cookie);
341 EXPECT_EQ(Status::SUCCESS, res.args->usb_last_status);
342
343 if (!res.args->usb_last_port_status.supportsEnableContaminantPresenceProtection) return;
344
345 for (int count = 1; count <= 10; count++) {
346 currentStatus = !(res.args->usb_last_port_status.contaminantProtectionStatus ==
347 ContaminantProtectionStatus::DISABLED);
348
349 ret = usb->enableContaminantPresenceProtection(
350 res.args->usb_last_port_status.status_1_1.status.portName, !currentStatus);
351 ASSERT_TRUE(ret.isOk());
352 res = usb_cb_2->WaitForCallback(kCallbackNameNotifyPortStatusChange_1_2);
353 EXPECT_TRUE(res.no_timeout);
354 EXPECT_EQ(kCallbackIdentifier, res.args->last_usb_cookie);
355 if (!currentStatus == !(res.args->usb_last_port_status.contaminantProtectionStatus ==
356 ContaminantProtectionStatus::DISABLED))
357 successCount++;
358 }
359
360 if (!supported) EXPECT_GE(successCount, 9);
361}
362
Dan Shif15bd2d2020-04-03 12:57:13 -0700363INSTANTIATE_TEST_SUITE_P(
364 PerInstance, UsbHidlTest,
365 testing::ValuesIn(android::hardware::getAllHalInstanceNames(IUsb::descriptor)),
366 android::hardware::PrintInstanceNameToString);