Home | History | Annotate | Download | only in android
      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 """
      6 Exception classes raised by AdbWrapper and DeviceUtils.
      7 """
      8 
      9 from devil import base_error
     10 from devil.utils import cmd_helper
     11 from devil.utils import parallelizer
     12 
     13 
     14 class 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 
     24 class _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 
     46 class 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 
     56 class 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 
     66 class 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 
     73 class 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 
     95 class CommandTimeoutError(base_error.BaseError):
     96   """Exception for command timeouts."""
     97   pass
     98 
     99 
    100 class DeviceUnreachableError(base_error.BaseError):
    101   """Exception for device unreachable failures."""
    102   pass
    103 
    104 
    105 class 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 
    113 class 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 
    128 class 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 
    136 class 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