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 import os 13 14 from devil import devil_env 15 from devil.android import decorators 16 from devil.android import device_errors 17 from devil.utils import cmd_helper 18 from devil.utils import lazy 19 20 _DEFAULT_TIMEOUT = 30 21 _DEFAULT_RETRIES = 3 22 _FLASH_TIMEOUT = _DEFAULT_TIMEOUT * 10 23 24 25 class Fastboot(object): 26 27 _fastboot_path = lazy.WeakConstant(lambda: os.path.join( 28 devil_env.config.LocalPath('android_sdk'), 'platform-tools', 'fastboot')) 29 30 def __init__(self, device_serial, default_timeout=_DEFAULT_TIMEOUT, 31 default_retries=_DEFAULT_RETRIES): 32 """Initializes the FastbootWrapper. 33 34 Args: 35 device_serial: The device serial number as a string. 36 """ 37 if not device_serial: 38 raise ValueError('A device serial must be specified') 39 self._device_serial = str(device_serial) 40 self._default_timeout = default_timeout 41 self._default_retries = default_retries 42 43 def _RunFastbootCommand(self, cmd): 44 """Run a command line command using the fastboot android tool. 45 46 Args: 47 cmd: Command to run. Must be list of args, the first one being the command 48 49 Returns: 50 output of command. 51 52 Raises: 53 TypeError: If cmd is not of type list. 54 """ 55 if type(cmd) == list: 56 cmd = [self._fastboot_path.read(), '-s', self._device_serial] + cmd 57 else: 58 raise TypeError( 59 'Command for _RunFastbootCommand must be a list.') 60 status, output = cmd_helper.GetCmdStatusAndOutput(cmd) 61 if int(status) != 0: 62 raise device_errors.FastbootCommandFailedError( 63 cmd, output, status, self._device_serial) 64 return output 65 66 @decorators.WithTimeoutAndRetriesDefaults(_FLASH_TIMEOUT, 0) 67 def Flash(self, partition, image, timeout=None, retries=None): 68 """Flash partition with img. 69 70 Args: 71 partition: Partition to be flashed. 72 image: location of image to flash with. 73 """ 74 self._RunFastbootCommand(['flash', partition, image]) 75 76 @decorators.WithTimeoutAndRetriesFromInstance() 77 def Devices(self, timeout=None, retries=None): 78 """Outputs list of devices in fastboot mode.""" 79 output = self._RunFastbootCommand(['devices']) 80 return [line.split()[0] for line in output.splitlines()] 81 82 @decorators.WithTimeoutAndRetriesFromInstance() 83 def RebootBootloader(self, timeout=None, retries=None): 84 """Reboot from fastboot, into fastboot.""" 85 self._RunFastbootCommand(['reboot-bootloader']) 86 87 @decorators.WithTimeoutAndRetriesDefaults(_FLASH_TIMEOUT, 0) 88 def Reboot(self, timeout=None, retries=None): 89 """Reboot from fastboot to normal usage""" 90 self._RunFastbootCommand(['reboot']) 91 92 @decorators.WithTimeoutAndRetriesFromInstance() 93 def SetOemOffModeCharge(self, value, timeout=None, retries=None): 94 """Sets off mode charging 95 96 Args: 97 value: boolean value to set off-mode-charging on or off. 98 """ 99 self._RunFastbootCommand( 100 ['oem', 'off-mode-charge', str(int(value))]) 101