1be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Copyright 2015 The Chromium Authors. All rights reserved. 2be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Use of this source code is governed by a BSD-style license that can be 3be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# found in the LICENSE file. 4be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 5be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik"""Provides a variety of device interactions based on fastboot.""" 6be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# pylint: disable=unused-argument 7be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 8a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikimport collections 9be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport contextlib 10be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport fnmatch 11be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport logging 12be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport os 13be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport re 14be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 15be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikfrom devil.android import decorators 16be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikfrom devil.android import device_errors 17be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikfrom devil.android.sdk import fastboot 18be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikfrom devil.utils import timeout_retry 19be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 20ee838d1c4002134ff5af32da272140586c4d31deJohn Recklogger = logging.getLogger(__name__) 21ee838d1c4002134ff5af32da272140586c4d31deJohn Reck 22be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik_DEFAULT_TIMEOUT = 30 23be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik_DEFAULT_RETRIES = 3 24be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik_FASTBOOT_REBOOT_TIMEOUT = 10 * _DEFAULT_TIMEOUT 25a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik_KNOWN_PARTITIONS = collections.OrderedDict([ 26a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik ('bootloader', {'image': 'bootloader*.img', 'restart': True}), 27a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik ('radio', {'image': 'radio*.img', 'restart': True}), 28a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik ('boot', {'image': 'boot.img'}), 29a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik ('recovery', {'image': 'recovery.img'}), 30a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik ('system', {'image': 'system.img'}), 31a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik ('userdata', {'image': 'userdata.img', 'wipe_only': True}), 32a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik ('cache', {'image': 'cache.img', 'wipe_only': True}), 33a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik ('vendor', {'image': 'vendor*.img', 'optional': True}), 34a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik ]) 35a23c9e9f6fc22fe5611def685e1984062b13b560Chris CraikALL_PARTITIONS = _KNOWN_PARTITIONS.keys() 36a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 37a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 38a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikdef _FindAndVerifyPartitionsAndImages(partitions, directory): 39a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik """Validate partitions and images. 40a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 41a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik Validate all partition names and partition directories. Cannot stop mid 42a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik flash so its important to validate everything first. 43a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 44a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik Args: 45a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik Partitions: partitions to be tested. 46a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik directory: directory containing the images. 47a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 48a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik Returns: 49a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik Dictionary with exact partition, image name mapping. 50a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik """ 51a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 52a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik files = os.listdir(directory) 53a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik return_dict = collections.OrderedDict() 54a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 55a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik def find_file(pattern): 56a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik for filename in files: 57a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik if fnmatch.fnmatch(filename, pattern): 58a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik return os.path.join(directory, filename) 59a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik return None 60a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik for partition in partitions: 61a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik partition_info = _KNOWN_PARTITIONS[partition] 62a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik image_file = find_file(partition_info['image']) 63a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik if image_file: 64a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik return_dict[partition] = image_file 65a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik elif not partition_info.get('optional'): 66a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik raise device_errors.FastbootCommandFailedError( 67a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 'Failed to flash device. Could not find image for %s.', 68a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik partition_info['image']) 69a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik return return_dict 70be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 71be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 72be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikclass FastbootUtils(object): 73be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 74be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik _FASTBOOT_WAIT_TIME = 1 75be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik _BOARD_VERIFICATION_FILE = 'android-info.txt' 76be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 77be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def __init__(self, device, fastbooter=None, default_timeout=_DEFAULT_TIMEOUT, 78be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik default_retries=_DEFAULT_RETRIES): 79be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """FastbootUtils constructor. 80be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 81be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Example Usage to flash a device: 82be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik fastboot = fastboot_utils.FastbootUtils(device) 83be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik fastboot.FlashDevice('/path/to/build/directory') 84be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 85be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Args: 86be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik device: A DeviceUtils instance. 87be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik fastbooter: Optional fastboot object. If none is passed, one will 88be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik be created. 89be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik default_timeout: An integer containing the default number of seconds to 90be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik wait for an operation to complete if no explicit value is provided. 91be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik default_retries: An integer containing the default number or times an 92be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik operation should be retried on failure if no explicit value is provided. 93be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 94be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self._device = device 95be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self._board = device.product_board 96be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self._serial = str(device) 97be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self._default_timeout = default_timeout 98be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self._default_retries = default_retries 99be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if fastbooter: 100be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.fastboot = fastbooter 101be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else: 102be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.fastboot = fastboot.Fastboot(self._serial) 103be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 104be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik @decorators.WithTimeoutAndRetriesFromInstance() 105be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def WaitForFastbootMode(self, timeout=None, retries=None): 106be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Wait for device to boot into fastboot mode. 107be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 108be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik This waits for the device serial to show up in fastboot devices output. 109be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 110be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def fastboot_mode(): 111be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return self._serial in self.fastboot.Devices() 112be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 113be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik timeout_retry.WaitFor(fastboot_mode, wait_period=self._FASTBOOT_WAIT_TIME) 114be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 115be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik @decorators.WithTimeoutAndRetriesFromInstance( 116be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik min_default_timeout=_FASTBOOT_REBOOT_TIMEOUT) 117be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def EnableFastbootMode(self, timeout=None, retries=None): 118be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Reboots phone into fastboot mode. 119be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 120be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Roots phone if needed, then reboots phone into fastboot mode and waits. 121be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 122be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self._device.EnableRoot() 123be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self._device.adb.Reboot(to_bootloader=True) 124be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.WaitForFastbootMode() 125be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 126be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik @decorators.WithTimeoutAndRetriesFromInstance( 127be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik min_default_timeout=_FASTBOOT_REBOOT_TIMEOUT) 128a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik def Reboot( 129a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik self, bootloader=False, wait_for_reboot=True, timeout=None, retries=None): 130be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Reboots out of fastboot mode. 131be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 132be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik It reboots the phone either back into fastboot, or to a regular boot. It 133be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik then blocks until the device is ready. 134be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 135be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Args: 136be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik bootloader: If set to True, reboots back into bootloader. 137be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 138be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if bootloader: 139be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.fastboot.RebootBootloader() 140be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.WaitForFastbootMode() 141be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else: 142be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.fastboot.Reboot() 143a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik if wait_for_reboot: 144a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik self._device.WaitUntilFullyBooted(timeout=_FASTBOOT_REBOOT_TIMEOUT) 145be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 146be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def _VerifyBoard(self, directory): 147be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Validate as best as possible that the android build matches the device. 148be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 149be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Goes through build files and checks if the board name is mentioned in the 150be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik |self._BOARD_VERIFICATION_FILE| or in the build archive. 151be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 152be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Args: 153be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik directory: directory where build files are located. 154be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 155be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik files = os.listdir(directory) 156be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik board_regex = re.compile(r'require board=(\w+)') 157be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if self._BOARD_VERIFICATION_FILE in files: 158be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik with open(os.path.join(directory, self._BOARD_VERIFICATION_FILE)) as f: 159be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik for line in f: 160be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik m = board_regex.match(line) 161be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if m: 162be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik board_name = m.group(1) 163be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if board_name == self._board: 164be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return True 165be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik elif board_name: 166be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return False 167be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else: 168ee838d1c4002134ff5af32da272140586c4d31deJohn Reck logger.warning('No board type found in %s.', 169ee838d1c4002134ff5af32da272140586c4d31deJohn Reck self._BOARD_VERIFICATION_FILE) 170be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else: 171ee838d1c4002134ff5af32da272140586c4d31deJohn Reck logger.warning('%s not found. Unable to use it to verify device.', 172ee838d1c4002134ff5af32da272140586c4d31deJohn Reck self._BOARD_VERIFICATION_FILE) 173be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 174be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik zip_regex = re.compile(r'.*%s.*\.zip' % re.escape(self._board)) 175be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik for f in files: 176be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if zip_regex.match(f): 177be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return True 178be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 179be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return False 180be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 181be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def _FlashPartitions(self, partitions, directory, wipe=False, force=False): 182be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Flashes all given partiitons with all given images. 183be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 184be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Args: 185be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik partitions: List of partitions to flash. 186be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik directory: Directory where all partitions can be found. 187be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik wipe: If set to true, will automatically detect if cache and userdata 188be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik partitions are sent, and if so ignore them. 189be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik force: boolean to decide to ignore board name safety checks. 190be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 191be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Raises: 192be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik device_errors.CommandFailedError(): If image cannot be found or if bad 193be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik partition name is give. 194be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 195be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if not self._VerifyBoard(directory): 196be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if force: 197ee838d1c4002134ff5af32da272140586c4d31deJohn Reck logger.warning('Could not verify build is meant to be installed on ' 198ee838d1c4002134ff5af32da272140586c4d31deJohn Reck 'the current device type, but force flag is set. ' 199ee838d1c4002134ff5af32da272140586c4d31deJohn Reck 'Flashing device. Possibly dangerous operation.') 200be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else: 201be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik raise device_errors.CommandFailedError( 202be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'Could not verify build is meant to be installed on the current ' 203be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'device type. Run again with force=True to force flashing with an ' 204be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'unverified board.') 205be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 206a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik flash_image_files = _FindAndVerifyPartitionsAndImages(partitions, directory) 207a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik partitions = flash_image_files.keys() 208be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik for partition in partitions: 209a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik if _KNOWN_PARTITIONS[partition].get('wipe_only') and not wipe: 210ee838d1c4002134ff5af32da272140586c4d31deJohn Reck logger.info( 211be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'Not flashing in wipe mode. Skipping partition %s.', partition) 212be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else: 213ee838d1c4002134ff5af32da272140586c4d31deJohn Reck logger.info( 214be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'Flashing %s with %s', partition, flash_image_files[partition]) 215be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.fastboot.Flash(partition, flash_image_files[partition]) 216a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik if _KNOWN_PARTITIONS[partition].get('restart', False): 217be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.Reboot(bootloader=True) 218be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 219be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik @contextlib.contextmanager 220a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik def FastbootMode(self, wait_for_reboot=True, timeout=None, retries=None): 221be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Context manager that enables fastboot mode, and reboots after. 222be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 223be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Example usage: 224be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik with FastbootMode(): 225be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Flash Device 226be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik # Anything that runs after flashing. 227be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 228be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.EnableFastbootMode() 229be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.fastboot.SetOemOffModeCharge(False) 230be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik try: 231be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik yield self 232be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik finally: 233be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self.fastboot.SetOemOffModeCharge(True) 234a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik self.Reboot(wait_for_reboot=wait_for_reboot) 235be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 236be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik def FlashDevice(self, directory, partitions=None, wipe=False): 237be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Flash device with build in |directory|. 238be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 239be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Directory must contain bootloader, radio, boot, recovery, system, userdata, 240be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik and cache .img files from an android build. This is a dangerous operation so 241be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik use with care. 242be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 243be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Args: 244be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik fastboot: A FastbootUtils instance. 245be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik directory: Directory with build files. 246be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik wipe: Wipes cache and userdata if set to true. 247be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik partitions: List of partitions to flash. Defaults to all. 248be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 249be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if partitions is None: 250be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik partitions = ALL_PARTITIONS 251a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik # If a device is wiped, then it will no longer have adb keys so it cannot be 252a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik # communicated with to verify that it is rebooted. It is up to the user of 253a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik # this script to ensure that the adb keys are set on the device after using 254a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik # this to wipe a device. 255a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik with self.FastbootMode(wait_for_reboot=not wipe): 256be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik self._FlashPartitions(partitions, directory, wipe=wipe) 257