blob: ae99d3980d95efc42c00e488c6f4b0f20f6eaba8 [file] [log] [blame]
# 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))])