OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 # Copyright 2015 The Chromium Authors. All rights reserved. | |
3 # Use of this source code is governed by a BSD-style license that can be | |
4 # found in the LICENSE file. | |
5 | |
6 import argparse | |
7 import fcntl | |
8 import logging | |
9 import re | |
10 import sys | |
11 | |
12 from devil.android import device_errors | |
13 from devil.utils import lsusb | |
14 from devil.utils import run_tests_helper | |
15 | |
16 _INDENTATION_RE = re.compile(r'^( *)') | |
17 _LSUSB_BUS_DEVICE_RE = re.compile(r'^Bus (\d{3}) Device (\d{3}):') | |
18 _LSUSB_ENTRY_RE = re.compile(r'^ *([^ ]+) +([^ ]+) *([^ ].*)?$') | |
19 _LSUSB_GROUP_RE = re.compile(r'^ *([^ ]+.*):$') | |
20 | |
21 _USBDEVFS_RESET = ord('U') << 8 | 20 | |
22 | |
23 | |
24 def reset_usb(bus, device): | |
25 """Reset the USB device with the given bus and device.""" | |
26 usb_file_path = '/dev/bus/usb/%03d/%03d' % (bus, device) | |
27 with open(usb_file_path, 'w') as usb_file: | |
28 logging.debug('fcntl.ioctl(%s, %d)', usb_file_path, _USBDEVFS_RESET) | |
29 fcntl.ioctl(usb_file, _USBDEVFS_RESET) | |
30 | |
31 | |
32 def reset_android_usb(serial): | |
33 """Reset the USB device for the given Android device.""" | |
34 lsusb_info = lsusb.lsusb() | |
35 | |
36 bus = None | |
37 device = None | |
38 for device_info in lsusb_info: | |
39 device_serial = lsusb.get_lsusb_serial(device_info) | |
40 if device_serial == serial: | |
41 bus = int(device_info.get('bus')) | |
42 device = int(device_info.get('device')) | |
43 | |
44 if bus and device: | |
45 reset_usb(bus, device) | |
46 else: | |
47 raise device_errors.DeviceUnreachableError( | |
48 'Unable to determine bus or device for device %s' % serial) | |
49 | |
50 | |
51 def reset_all_android_devices(): | |
52 """Reset all USB devices that look like an Android device.""" | |
53 _reset_all_matching(lambda i: bool(lsusb.get_lsusb_serial(i))) | |
54 | |
55 | |
56 def _reset_all_matching(condition): | |
57 lsusb_info = lsusb.lsusb() | |
58 for device_info in lsusb_info: | |
59 if int(device_info.get('device')) != 1 and condition(device_info): | |
60 bus = int(device_info.get('bus')) | |
61 device = int(device_info.get('device')) | |
62 try: | |
63 reset_usb(bus, device) | |
64 serial = lsusb.get_lsusb_serial(device_info) | |
65 if serial: | |
66 logging.info('Reset USB device (bus: %03d, device: %03d, serial: %s)', | |
67 bus, device, serial) | |
68 else: | |
69 logging.info('Reset USB device (bus: %03d, device: %03d)', | |
70 bus, device) | |
71 except IOError: | |
72 logging.error( | |
73 'Failed to reset USB device (bus: %03d, device: %03d)', | |
74 bus, device) | |
75 | |
76 | |
77 def main(): | |
78 parser = argparse.ArgumentParser() | |
79 parser.add_argument('-v', '--verbose', action='count') | |
80 parser.add_argument('-s', '--serial') | |
81 parser.add_argument('--bus', type=int) | |
82 parser.add_argument('--device', type=int) | |
83 args = parser.parse_args() | |
84 | |
85 run_tests_helper.SetLogLevel(args.verbose) | |
86 | |
87 if args.serial: | |
88 reset_android_usb(args.serial) | |
89 elif args.bus and args.device: | |
90 reset_usb(args.bus, args.device) | |
91 else: | |
92 parser.error('Unable to determine target. ' | |
93 'Specify --serial or BOTH --bus and --device.') | |
94 | |
95 return 0 | |
96 | |
97 | |
98 if __name__ == '__main__': | |
99 sys.exit(main()) | |
100 | |
OLD | NEW |