| 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 |