Home | History | Annotate | Download | only in sdk
      1 # Copyright 2015 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 """This module wraps Android's fastboot tool.
      6 
      7 This is a thin wrapper around the fastboot interface. Any additional complexity
      8 should be delegated to a higher level (ex. FastbootUtils).
      9 """
     10 # pylint: disable=unused-argument
     11 
     12 from devil import devil_env
     13 from devil.android import decorators
     14 from devil.android import device_errors
     15 from devil.utils import cmd_helper
     16 from devil.utils import lazy
     17 
     18 _DEFAULT_TIMEOUT = 30
     19 _DEFAULT_RETRIES = 3
     20 _FLASH_TIMEOUT = _DEFAULT_TIMEOUT * 10
     21 
     22 
     23 class Fastboot(object):
     24 
     25   _fastboot_path = lazy.WeakConstant(
     26       lambda: devil_env.config.FetchPath('fastboot'))
     27 
     28   def __init__(self, device_serial, default_timeout=_DEFAULT_TIMEOUT,
     29                default_retries=_DEFAULT_RETRIES):
     30     """Initializes the FastbootWrapper.
     31 
     32     Args:
     33       device_serial: The device serial number as a string.
     34     """
     35     if not device_serial:
     36       raise ValueError('A device serial must be specified')
     37     self._device_serial = str(device_serial)
     38     self._default_timeout = default_timeout
     39     self._default_retries = default_retries
     40 
     41   def __str__(self):
     42     return self._device_serial
     43 
     44   @classmethod
     45   def _RunFastbootCommand(cls, cmd):
     46     """Run a generic fastboot command.
     47 
     48     Args:
     49       cmd: Command to run. Must be list of args, the first one being the command
     50 
     51     Returns:
     52       output of command.
     53 
     54     Raises:
     55       TypeError: If cmd is not of type list.
     56     """
     57     if isinstance(cmd, list):
     58       cmd = [cls._fastboot_path.read()] + cmd
     59     else:
     60       raise TypeError(
     61           'Command for _RunDeviceFastbootCommand must be a list.')
     62     status, output = cmd_helper.GetCmdStatusAndOutput(cmd)
     63     if int(status) != 0:
     64       raise device_errors.FastbootCommandFailedError(cmd, output, status)
     65     return output
     66 
     67   def _RunDeviceFastbootCommand(self, cmd):
     68     """Run a fastboot command on the device associated with this object.
     69 
     70     Args:
     71       cmd: Command to run. Must be list of args, the first one being the command
     72 
     73     Returns:
     74       output of command.
     75 
     76     Raises:
     77       TypeError: If cmd is not of type list.
     78     """
     79     if isinstance(cmd, list):
     80       cmd = ['-s', self._device_serial] + cmd
     81     return self._RunFastbootCommand(cmd)
     82 
     83   @decorators.WithTimeoutAndRetriesDefaults(_FLASH_TIMEOUT, 0)
     84   def Flash(self, partition, image, timeout=None, retries=None):
     85     """Flash partition with img.
     86 
     87     Args:
     88       partition: Partition to be flashed.
     89       image: location of image to flash with.
     90     """
     91     self._RunDeviceFastbootCommand(['flash', partition, image])
     92 
     93   @classmethod
     94   @decorators.WithTimeoutAndRetriesDefaults(_DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
     95   def Devices(cls, timeout=None, retries=None):
     96     """Outputs list of devices in fastboot mode.
     97 
     98     Returns:
     99       List of Fastboot objects, one for each device in fastboot.
    100     """
    101     output = cls._RunFastbootCommand(['devices'])
    102     return [Fastboot(line.split()[0]) for line in output.splitlines()]
    103 
    104   @decorators.WithTimeoutAndRetriesFromInstance()
    105   def RebootBootloader(self, timeout=None, retries=None):
    106     """Reboot from fastboot, into fastboot."""
    107     self._RunDeviceFastbootCommand(['reboot-bootloader'])
    108 
    109   @decorators.WithTimeoutAndRetriesDefaults(_FLASH_TIMEOUT, 0)
    110   def Reboot(self, timeout=None, retries=None):
    111     """Reboot from fastboot to normal usage"""
    112     self._RunDeviceFastbootCommand(['reboot'])
    113 
    114   @decorators.WithTimeoutAndRetriesFromInstance()
    115   def SetOemOffModeCharge(self, value, timeout=None, retries=None):
    116     """Sets off mode charging
    117 
    118     Args:
    119       value: boolean value to set off-mode-charging on or off.
    120     """
    121     self._RunDeviceFastbootCommand(
    122         ['oem', 'off-mode-charge', str(int(value))])
    123