1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5""" 6Exception classes raised by AdbWrapper and DeviceUtils. 7""" 8 9from devil import base_error 10from devil.utils import cmd_helper 11from devil.utils import parallelizer 12 13 14class CommandFailedError(base_error.BaseError): 15 """Exception for command failures.""" 16 17 def __init__(self, message, device_serial=None): 18 if device_serial is not None: 19 message = '(device: %s) %s' % (device_serial, message) 20 self.device_serial = device_serial 21 super(CommandFailedError, self).__init__(message) 22 23 24class _BaseCommandFailedError(CommandFailedError): 25 """Base Exception for adb and fastboot command failures.""" 26 27 def __init__(self, args, output, status=None, device_serial=None, 28 message=None): 29 self.args = args 30 self.output = output 31 self.status = status 32 if not message: 33 adb_cmd = ' '.join(cmd_helper.SingleQuote(arg) for arg in self.args) 34 message = ['adb %s: failed ' % adb_cmd] 35 if status: 36 message.append('with exit status %s ' % self.status) 37 if output: 38 message.append('and output:\n') 39 message.extend('- %s\n' % line for line in output.splitlines()) 40 else: 41 message.append('and no output.') 42 message = ''.join(message) 43 super(_BaseCommandFailedError, self).__init__(message, device_serial) 44 45 46class AdbCommandFailedError(_BaseCommandFailedError): 47 """Exception for adb command failures.""" 48 49 def __init__(self, args, output, status=None, device_serial=None, 50 message=None): 51 super(AdbCommandFailedError, self).__init__( 52 args, output, status=status, message=message, 53 device_serial=device_serial) 54 55 56class FastbootCommandFailedError(_BaseCommandFailedError): 57 """Exception for fastboot command failures.""" 58 59 def __init__(self, args, output, status=None, device_serial=None, 60 message=None): 61 super(FastbootCommandFailedError, self).__init__( 62 args, output, status=status, message=message, 63 device_serial=device_serial) 64 65 66class DeviceVersionError(CommandFailedError): 67 """Exception for device version failures.""" 68 69 def __init__(self, message, device_serial=None): 70 super(DeviceVersionError, self).__init__(message, device_serial) 71 72 73class AdbShellCommandFailedError(AdbCommandFailedError): 74 """Exception for shell command failures run via adb.""" 75 76 def __init__(self, command, output, status, device_serial=None): 77 self.command = command 78 message = ['shell command run via adb failed on the device:\n', 79 ' command: %s\n' % command] 80 message.append(' exit status: %s\n' % status) 81 if output: 82 message.append(' output:\n') 83 if isinstance(output, basestring): 84 output_lines = output.splitlines() 85 else: 86 output_lines = output 87 message.extend(' - %s\n' % line for line in output_lines) 88 else: 89 message.append(" output: ''\n") 90 message = ''.join(message) 91 super(AdbShellCommandFailedError, self).__init__( 92 ['shell', command], output, status, device_serial, message) 93 94 95class CommandTimeoutError(base_error.BaseError): 96 """Exception for command timeouts.""" 97 pass 98 99 100class DeviceUnreachableError(base_error.BaseError): 101 """Exception for device unreachable failures.""" 102 pass 103 104 105class NoDevicesError(base_error.BaseError): 106 """Exception for having no devices attached.""" 107 108 def __init__(self): 109 super(NoDevicesError, self).__init__( 110 'No devices attached.', is_infra_error=True) 111 112 113class MultipleDevicesError(base_error.BaseError): 114 """Exception for having multiple attached devices without selecting one.""" 115 116 def __init__(self, devices): 117 parallel_devices = parallelizer.Parallelizer(devices) 118 descriptions = parallel_devices.pMap( 119 lambda d: d.build_description).pGet(None) 120 msg = ('More than one device available. Use -d/--device to select a device ' 121 'by serial.\n\nAvailable devices:\n') 122 for d, desc in zip(devices, descriptions): 123 msg += ' %s (%s)\n' % (d, desc) 124 125 super(MultipleDevicesError, self).__init__(msg, is_infra_error=True) 126 127 128class NoAdbError(base_error.BaseError): 129 """Exception for being unable to find ADB.""" 130 131 def __init__(self, msg=None): 132 super(NoAdbError, self).__init__( 133 msg or 'Unable to find adb.', is_infra_error=True) 134 135 136class DeviceChargingError(CommandFailedError): 137 """Exception for device charging errors.""" 138 139 def __init__(self, message, device_serial=None): 140 super(DeviceChargingError, self).__init__(message, device_serial) 141