| # Copyright 2015 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """This module wraps Android's fastboot tool. |
| |
| This is a thin wrapper around the fastboot interface. Any additional complexity |
| should be delegated to a higher level (ex. FastbootUtils). |
| """ |
| # pylint: disable=unused-argument |
| |
| from devil import devil_env |
| from devil.android import decorators |
| from devil.android import device_errors |
| from devil.utils import cmd_helper |
| from devil.utils import lazy |
| |
| _DEFAULT_TIMEOUT = 30 |
| _DEFAULT_RETRIES = 3 |
| _FLASH_TIMEOUT = _DEFAULT_TIMEOUT * 10 |
| |
| |
| class Fastboot(object): |
| |
| _fastboot_path = lazy.WeakConstant( |
| lambda: devil_env.config.FetchPath('fastboot')) |
| |
| def __init__(self, device_serial, default_timeout=_DEFAULT_TIMEOUT, |
| default_retries=_DEFAULT_RETRIES): |
| """Initializes the FastbootWrapper. |
| |
| Args: |
| device_serial: The device serial number as a string. |
| """ |
| if not device_serial: |
| raise ValueError('A device serial must be specified') |
| self._device_serial = str(device_serial) |
| self._default_timeout = default_timeout |
| self._default_retries = default_retries |
| |
| def __str__(self): |
| return self._device_serial |
| |
| @classmethod |
| def _RunFastbootCommand(cls, cmd): |
| """Run a generic fastboot command. |
| |
| Args: |
| cmd: Command to run. Must be list of args, the first one being the command |
| |
| Returns: |
| output of command. |
| |
| Raises: |
| TypeError: If cmd is not of type list. |
| """ |
| if type(cmd) == list: |
| cmd = [cls._fastboot_path.read()] + cmd |
| else: |
| raise TypeError( |
| 'Command for _RunDeviceFastbootCommand must be a list.') |
| status, output = cmd_helper.GetCmdStatusAndOutput(cmd) |
| if int(status) != 0: |
| raise device_errors.FastbootCommandFailedError(cmd, output, status) |
| return output |
| |
| def _RunDeviceFastbootCommand(self, cmd): |
| """Run a fastboot command on the device associated with this object. |
| |
| Args: |
| cmd: Command to run. Must be list of args, the first one being the command |
| |
| Returns: |
| output of command. |
| |
| Raises: |
| TypeError: If cmd is not of type list. |
| """ |
| if type(cmd) == list: |
| cmd = ['-s', self._device_serial] + cmd |
| return self._RunFastbootCommand(cmd) |
| |
| @decorators.WithTimeoutAndRetriesDefaults(_FLASH_TIMEOUT, 0) |
| def Flash(self, partition, image, timeout=None, retries=None): |
| """Flash partition with img. |
| |
| Args: |
| partition: Partition to be flashed. |
| image: location of image to flash with. |
| """ |
| self._RunDeviceFastbootCommand(['flash', partition, image]) |
| |
| @classmethod |
| @decorators.WithTimeoutAndRetriesDefaults(_DEFAULT_TIMEOUT, _DEFAULT_RETRIES) |
| def Devices(cls, timeout=None, retries=None): |
| """Outputs list of devices in fastboot mode. |
| |
| Returns: |
| List of Fastboot objects, one for each device in fastboot. |
| """ |
| output = cls._RunFastbootCommand(['devices']) |
| return [Fastboot(line.split()[0]) for line in output.splitlines()] |
| |
| @decorators.WithTimeoutAndRetriesFromInstance() |
| def RebootBootloader(self, timeout=None, retries=None): |
| """Reboot from fastboot, into fastboot.""" |
| self._RunDeviceFastbootCommand(['reboot-bootloader']) |
| |
| @decorators.WithTimeoutAndRetriesDefaults(_FLASH_TIMEOUT, 0) |
| def Reboot(self, timeout=None, retries=None): |
| """Reboot from fastboot to normal usage""" |
| self._RunDeviceFastbootCommand(['reboot']) |
| |
| @decorators.WithTimeoutAndRetriesFromInstance() |
| def SetOemOffModeCharge(self, value, timeout=None, retries=None): |
| """Sets off mode charging |
| |
| Args: |
| value: boolean value to set off-mode-charging on or off. |
| """ |
| self._RunDeviceFastbootCommand( |
| ['oem', 'off-mode-charge', str(int(value))]) |