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 _RunFastbootCommand(self, cmd): 42 """Run a command line command using the fastboot android tool. 43 44 Args: 45 cmd: Command to run. Must be list of args, the first one being the command 46 47 Returns: 48 output of command. 49 50 Raises: 51 TypeError: If cmd is not of type list. 52 """ 53 if type(cmd) == list: 54 cmd = [self._fastboot_path.read(), '-s', self._device_serial] + cmd 55 else: 56 raise TypeError( 57 'Command for _RunFastbootCommand must be a list.') 58 status, output = cmd_helper.GetCmdStatusAndOutput(cmd) 59 if int(status) != 0: 60 raise device_errors.FastbootCommandFailedError( 61 cmd, output, status, self._device_serial) 62 return output 63 64 @decorators.WithTimeoutAndRetriesDefaults(_FLASH_TIMEOUT, 0) 65 def Flash(self, partition, image, timeout=None, retries=None): 66 """Flash partition with img. 67 68 Args: 69 partition: Partition to be flashed. 70 image: location of image to flash with. 71 """ 72 self._RunFastbootCommand(['flash', partition, image]) 73 74 @decorators.WithTimeoutAndRetriesFromInstance() 75 def Devices(self, timeout=None, retries=None): 76 """Outputs list of devices in fastboot mode.""" 77 output = self._RunFastbootCommand(['devices']) 78 return [line.split()[0] for line in output.splitlines()] 79 80 @decorators.WithTimeoutAndRetriesFromInstance() 81 def RebootBootloader(self, timeout=None, retries=None): 82 """Reboot from fastboot, into fastboot.""" 83 self._RunFastbootCommand(['reboot-bootloader']) 84 85 @decorators.WithTimeoutAndRetriesDefaults(_FLASH_TIMEOUT, 0) 86 def Reboot(self, timeout=None, retries=None): 87 """Reboot from fastboot to normal usage""" 88 self._RunFastbootCommand(['reboot']) 89 90 @decorators.WithTimeoutAndRetriesFromInstance() 91 def SetOemOffModeCharge(self, value, timeout=None, retries=None): 92 """Sets off mode charging 93 94 Args: 95 value: boolean value to set off-mode-charging on or off. 96 """ 97 self._RunFastbootCommand( 98 ['oem', 'off-mode-charge', str(int(value))]) 99