adb_wrapper.py revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson# Copyright 2013 The Chromium Authors. All rights reserved. 2e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson# Use of this source code is governed by a BSD-style license that can be 3e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson# found in the LICENSE file. 4e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 5e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson"""This module wraps Android's adb tool. 6e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 7e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian ParkinsonThis is a thin wrapper around the adb interface. Any additional complexity 8e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonshould be delegated to a higher level (ex. DeviceUtils). 9e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson""" 10e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 11e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport errno 12e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport os 13e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 14e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonfrom pylib import cmd_helper 15e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonfrom pylib.device import decorators 16e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonfrom pylib.device import device_errors 17e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 18e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 19e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson_DEFAULT_TIMEOUT = 30 20e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson_DEFAULT_RETRIES = 2 21e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 22e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 23e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsondef _VerifyLocalFileExists(path): 24e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Verifies a local file exists. 25e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 26e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 27e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson path: Path to the local file. 28e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 29e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Raises: 30e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson IOError: If the file doesn't exist. 31e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 32e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if not os.path.exists(path): 33e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson raise IOError(errno.ENOENT, os.strerror(errno.ENOENT), path) 34e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 35e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 36e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonclass AdbWrapper(object): 37e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """A wrapper around a local Android Debug Bridge executable.""" 38e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 39e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def __init__(self, device_serial): 40e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Initializes the AdbWrapper. 41e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 42e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 43e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson device_serial: The device serial number as a string. 44e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 45e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson self._device_serial = str(device_serial) 46e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 47e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson # pylint: disable=W0613 48e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson @classmethod 49e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson @decorators.WithTimeoutAndRetries 50e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def _RunAdbCmd(cls, arg_list, timeout=None, retries=None, check_error=True): 51e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd = ['adb'] + arg_list 52e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson exit_code, output = cmd_helper.GetCmdStatusAndOutput(cmd) 53e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if exit_code != 0: 54e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson raise device_errors.CommandFailedError( 55e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd, 'returned non-zero exit code %s, output: %s' % 56e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson (exit_code, output)) 57e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson # This catches some errors, including when the device drops offline; 58e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson # unfortunately adb is very inconsistent with error reporting so many 59e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson # command failures present differently. 60e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if check_error and output[:len('error:')] == 'error:': 61e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson raise device_errors.CommandFailedError(arg_list, output) 62e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return output 63e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson # pylint: enable=W0613 64e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 65e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def _DeviceAdbCmd(self, arg_list, timeout, retries, check_error=True): 66e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Runs an adb command on the device associated with this object. 67e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 68e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 69e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson arg_list: A list of arguments to adb. 70e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: Timeout in seconds. 71e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: Number of retries. 72e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson check_error: Check that the command doesn't return an error message. This 73e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson does NOT check the return code of shell commands. 74e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 75e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Returns: 76e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson The output of the command. 77e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 78e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return self._RunAdbCmd( 79e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson ['-s', self._device_serial] + arg_list, timeout=timeout, 80e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries=retries, check_error=check_error) 81e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 82e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def __eq__(self, other): 83e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Consider instances equal if they refer to the same device. 84e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 85e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 86e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson other: The instance to compare equality with. 87e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 88e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Returns: 89e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson True if the instances are considered equal, false otherwise. 90e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 91e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return self._device_serial == str(other) 92e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 93e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def __str__(self): 94e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """The string representation of an instance. 95e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 96e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Returns: 97e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson The device serial number as a string. 98e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 99e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return self._device_serial 100e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 101e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def __repr__(self): 102e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return '%s(\'%s\')' % (self.__class__.__name__, self) 103e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 104e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson # TODO(craigdh): Determine the filter criteria that should be supported. 105e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson @classmethod 106e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def GetDevices(cls, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES): 107e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Get the list of active attached devices. 108e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 109e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 110e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 111e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 112e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 113e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Yields: 114e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson AdbWrapper instances. 115e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 116e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson output = cls._RunAdbCmd(['devices'], timeout=timeout, retries=retries) 117e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson lines = [line.split() for line in output.split('\n')] 118e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return [AdbWrapper(line[0]) for line in lines 119e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if len(line) == 2 and line[1] == 'device'] 120e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 121e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def GetDeviceSerial(self): 122e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Gets the device serial number associated with this object. 123e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 124e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Returns: 125e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Device serial number as a string. 126e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 127e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return self._device_serial 128e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 129e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Push(self, local, remote, timeout=60*5, retries=_DEFAULT_RETRIES): 130e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Pushes a file from the host to the device. 131e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 132e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 133e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson local: Path on the host filesystem. 134e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson remote: Path on the device filesystem. 135e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 136e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 137e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 138e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson _VerifyLocalFileExists(local) 139e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson self._DeviceAdbCmd(['push', local, remote], timeout, retries) 140e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 141e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Pull(self, remote, local, timeout=60*5, retries=_DEFAULT_RETRIES): 142e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Pulls a file from the device to the host. 143e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 144e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 145e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson remote: Path on the device filesystem. 146e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson local: Path on the host filesystem. 147e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 148e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 149e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 150e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson self._DeviceAdbCmd(['pull', remote, local], timeout, retries) 151e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson _VerifyLocalFileExists(local) 152e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 153e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Shell(self, command, expect_rc=None, timeout=_DEFAULT_TIMEOUT, 154e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries=_DEFAULT_RETRIES): 155e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Runs a shell command on the device. 156e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 157e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 158e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson command: The shell command to run. 159e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson expect_rc: (optional) If set checks that the command's return code matches 160e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson this value. 161e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 162e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 163e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 164e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Returns: 165e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson The output of the shell command as a string. 166e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 167e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Raises: 168e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson device_errors.CommandFailedError: If the return code doesn't match 169e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson |expect_rc|. 170e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 171e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if expect_rc is None: 172e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson actual_command = command 173e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson else: 174e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson actual_command = '%s; echo $?;' % command 175e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson output = self._DeviceAdbCmd( 176e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson ['shell', actual_command], timeout, retries, check_error=False) 177e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if expect_rc is not None: 178e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson output_end = output.rstrip().rfind('\n') + 1 179e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson rc = output[output_end:].strip() 180e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson output = output[:output_end] 181e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if int(rc) != expect_rc: 182e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson raise device_errors.CommandFailedError( 183e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson ['shell', command], 184e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 'shell command exited with code: %s' % rc, 185e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson self._device_serial) 186e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return output 187e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 188e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Logcat(self, filter_spec=None, timeout=_DEFAULT_TIMEOUT, 189e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries=_DEFAULT_RETRIES): 190e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Get the logcat output. 191e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 192e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 193e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson filter_spec: (optional) Spec to filter the logcat. 194e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 195e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 196e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 197e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Returns: 198e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson logcat output as a string. 199e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 200e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd = ['logcat'] 201e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if filter_spec is not None: 202e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.append(filter_spec) 203e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return self._DeviceAdbCmd(cmd, timeout, retries, check_error=False) 204e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 205e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Forward(self, local, remote, timeout=_DEFAULT_TIMEOUT, 206e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries=_DEFAULT_RETRIES): 207e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Forward socket connections from the local socket to the remote socket. 208e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 209e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Sockets are specified by one of: 210e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson tcp:<port> 211e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson localabstract:<unix domain socket name> 212e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson localreserved:<unix domain socket name> 213e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson localfilesystem:<unix domain socket name> 214e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson dev:<character device name> 215e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson jdwp:<process pid> (remote only) 216e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 217e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 218e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson local: The host socket. 219e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson remote: The device socket. 220e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 221e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 222e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 223e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson self._DeviceAdbCmd(['forward', str(local), str(remote)], timeout, retries) 224e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 225e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def JDWP(self, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES): 226e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """List of PIDs of processes hosting a JDWP transport. 227e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 228e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 229e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 230e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 231e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 232e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Returns: 233e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson A list of PIDs as strings. 234e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 235e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return [a.strip() for a in 236e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson self._DeviceAdbCmd(['jdwp'], timeout, retries).split('\n')] 237e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 238e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Install(self, apk_path, forward_lock=False, reinstall=False, 239e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson sd_card=False, timeout=60*2, retries=_DEFAULT_RETRIES): 240e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Install an apk on the device. 241e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 242e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 243e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson apk_path: Host path to the APK file. 244e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson forward_lock: (optional) If set forward-locks the app. 245e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson reinstall: (optional) If set reinstalls the app, keeping its data. 246e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson sd_card: (optional) If set installs on the SD card. 247e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 248e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 249e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 250e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson _VerifyLocalFileExists(apk_path) 251e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd = ['install'] 252e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if forward_lock: 253e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.append('-l') 254e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if reinstall: 255e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.append('-r') 256e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if sd_card: 257e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.append('-s') 258e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.append(apk_path) 259e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson output = self._DeviceAdbCmd(cmd, timeout, retries) 260e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if 'Success' not in output: 261e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson raise device_errors.CommandFailedError(cmd, output) 262e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 263e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Uninstall(self, package, keep_data=False, timeout=_DEFAULT_TIMEOUT, 264e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries=_DEFAULT_RETRIES): 265e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Remove the app |package| from the device. 266e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 267e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 268e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson package: The package to uninstall. 269e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson keep_data: (optional) If set keep the data and cache directories. 270e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 271e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 272e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 273e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd = ['uninstall'] 274e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if keep_data: 275e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.append('-k') 276e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.append(package) 277e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson output = self._DeviceAdbCmd(cmd, timeout, retries) 278e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if 'Failure' in output: 279e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson raise device_errors.CommandFailedError(cmd, output) 280e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 281e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Backup(self, path, packages=None, apk=False, shared=False, 282e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson nosystem=True, include_all=False, timeout=_DEFAULT_TIMEOUT, 283e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries=_DEFAULT_RETRIES): 284e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Write an archive of the device's data to |path|. 285e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 286e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 287e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson path: Local path to store the backup file. 288e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson packages: List of to packages to be backed up. 289e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson apk: (optional) If set include the .apk files in the archive. 290e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson shared: (optional) If set buckup the device's SD card. 291e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson nosystem: (optional) If set exclude system applications. 292e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson include_all: (optional) If set back up all installed applications and 293e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson |packages| is optional. 294e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 295e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 296e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 297e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd = ['backup', path] 298e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if apk: 299e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.append('-apk') 300e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if shared: 301e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.append('-shared') 302e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if nosystem: 303e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.append('-nosystem') 304e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if include_all: 305e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.append('-all') 306e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if packages: 307e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd.extend(packages) 308e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson assert bool(packages) ^ bool(include_all), ( 309e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 'Provide \'packages\' or set \'include_all\' but not both.') 310e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson ret = self._DeviceAdbCmd(cmd, timeout, retries) 311e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson _VerifyLocalFileExists(path) 312e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return ret 313e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 314e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Restore(self, path, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES): 315e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Restore device contents from the backup archive. 316e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 317e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 318e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson path: Host path to the backup archive. 319e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 320e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 321e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 322e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson _VerifyLocalFileExists(path) 323e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson self._DeviceAdbCmd(['restore'] + [path], timeout, retries) 324e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 325e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def WaitForDevice(self, timeout=60*5, retries=_DEFAULT_RETRIES): 326e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Block until the device is online. 327e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 328e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 329e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 330e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 331e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 332e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson self._DeviceAdbCmd(['wait-for-device'], timeout, retries) 333e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 334e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def GetState(self, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES): 335e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Get device state. 336e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 337e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 338e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 339e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 340e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 341e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Returns: 342e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson One of 'offline', 'bootloader', or 'device'. 343e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 344e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return self._DeviceAdbCmd(['get-state'], timeout, retries).strip() 345e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 346e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def GetDevPath(self, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES): 347e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Gets the device path. 348e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 349e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 350e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 351e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 352e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 353e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Returns: 354e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson The device path (e.g. usb:3-4) 355e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 356e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson return self._DeviceAdbCmd(['get-devpath'], timeout, retries) 357e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 358e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Remount(self, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES): 359e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Remounts the /system partition on the device read-write.""" 360e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson self._DeviceAdbCmd(['remount'], timeout, retries) 361e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 362e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Reboot(self, to_bootloader=False, timeout=60*5, 363e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries=_DEFAULT_RETRIES): 364e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Reboots the device. 365e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 366e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 367e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson to_bootloader: (optional) If set reboots to the bootloader. 368e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 369e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 370e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 371e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if to_bootloader: 372e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd = ['reboot-bootloader'] 373e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson else: 374e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson cmd = ['reboot'] 375e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson self._DeviceAdbCmd(cmd, timeout, retries) 376e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 377e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson def Root(self, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES): 378e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """Restarts the adbd daemon with root permissions, if possible. 379e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 380e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson Args: 381e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson timeout: (optional) Timeout per try in seconds. 382e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson retries: (optional) Number of retries to attempt. 383e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson """ 384e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson output = self._DeviceAdbCmd(['root'], timeout, retries) 385e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson if 'cannot' in output: 386e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson raise device_errors.CommandFailedError(['root'], output) 387e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson 388e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson