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 package com.android.tradefed.testtype;
17 
18 import com.android.helper.aoa.UsbDevice;
19 import com.android.helper.aoa.UsbHelper;
20 import com.android.tradefed.config.OptionClass;
21 import com.android.tradefed.device.DeviceNotAvailableException;
22 import com.android.tradefed.device.ITestDevice;
23 import com.android.tradefed.device.TestDeviceState;
24 import com.android.tradefed.invoker.TestInformation;
25 import com.android.tradefed.log.LogUtil.CLog;
26 import com.android.tradefed.result.ITestInvocationListener;
27 import com.android.tradefed.result.error.DeviceErrorIdentifier;
28 import com.android.tradefed.util.IRunUtil;
29 import com.android.tradefed.util.RunUtil;
30 
31 import com.google.common.annotations.VisibleForTesting;
32 
33 /**
34  * An {@link IRemoteTest} that reset the device USB and checks whether the device comes back online
35  * afterwards.
36  */
37 @OptionClass(alias = "usb-reset-test")
38 public class UsbResetTest implements IRemoteTest {
39 
40     @Override
run(TestInformation testInfo, ITestInvocationListener listener)41     public void run(TestInformation testInfo, ITestInvocationListener listener)
42             throws DeviceNotAvailableException {
43         ITestDevice device = testInfo.getDevice();
44         try (UsbHelper usb = getUsbHelper()) {
45             String serial = device.getSerialNumber();
46             try (UsbDevice usbDevice = usb.getDevice(serial)) {
47                 if (usbDevice == null) {
48                     throw new DeviceNotAvailableException(
49                             String.format("Device '%s' not found during USB reset.", serial),
50                             serial,
51                             DeviceErrorIdentifier.DEVICE_UNAVAILABLE);
52                 } else {
53                     CLog.d("Resetting USB port for device '%s'", serial);
54                     usbDevice.reset();
55                     getRunUtil().sleep(500);
56 
57                     TestDeviceState state = device.getDeviceState();
58                     if (TestDeviceState.RECOVERY.equals(state)
59                             || device.isStateBootloaderOrFastbootd()) {
60                         CLog.d("Device state is '%s', attempting reboot.", state);
61                         device.reboot();
62                     } else {
63                         device.waitForDeviceOnline();
64                         // If device fails to reboot it will throw an exception and be left
65                         // unavailable
66                         // again.
67                         device.reboot();
68                     }
69                 }
70             }
71         }
72     }
73 
74     @VisibleForTesting
getUsbHelper()75     UsbHelper getUsbHelper() {
76         return new UsbHelper();
77     }
78 
79     @VisibleForTesting
getRunUtil()80     IRunUtil getRunUtil() {
81         return RunUtil.getDefault();
82     }
83 }
84