aboutsummaryrefslogtreecommitdiff
path: root/catapult/devil/devil/android/sdk/adb_wrapper.py
diff options
context:
space:
mode:
Diffstat (limited to 'catapult/devil/devil/android/sdk/adb_wrapper.py')
-rw-r--r--catapult/devil/devil/android/sdk/adb_wrapper.py89
1 files changed, 60 insertions, 29 deletions
diff --git a/catapult/devil/devil/android/sdk/adb_wrapper.py b/catapult/devil/devil/android/sdk/adb_wrapper.py
index 2fbe9638..13c0f520 100644
--- a/catapult/devil/devil/android/sdk/adb_wrapper.py
+++ b/catapult/devil/devil/android/sdk/adb_wrapper.py
@@ -34,6 +34,7 @@ logger = logging.getLogger(__name__)
ADB_KEYS_FILE = '/data/misc/adb/adb_keys'
+ADB_HOST_KEYS_DIR = os.path.join(os.path.expanduser('~'), '.android')
DEFAULT_TIMEOUT = 30
DEFAULT_RETRIES = 2
@@ -262,15 +263,22 @@ class AdbWrapper(object):
@classmethod
@decorators.WithTimeoutAndConditionalRetries(_ShouldRetryAdbCmd)
def _RunAdbCmd(cls, args, timeout=None, retries=None, device_serial=None,
- check_error=True, cpu_affinity=None,
- ensure_logs_on_timeout=False):
- timeout = timeout_retry.CurrentTimeoutThreadGroup().GetRemainingTime()
- if ensure_logs_on_timeout:
- timeout = 0.95 * timeout
+ check_error=True, cpu_affinity=None, additional_env=None):
+ if timeout:
+ remaining = timeout_retry.CurrentTimeoutThreadGroup().GetRemainingTime()
+ if remaining:
+ # Use a slightly smaller timeout than remaining time to ensure that we
+ # have time to collect output from the command.
+ timeout = 0.95 * remaining
+ else:
+ timeout = None
+ env = cls._ADB_ENV.copy()
+ if additional_env:
+ env.update(additional_env)
try:
status, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
cls._BuildAdbCmd(args, device_serial, cpu_affinity=cpu_affinity),
- timeout, env=cls._ADB_ENV)
+ timeout, env=env)
except OSError as e:
if e.errno in (errno.ENOENT, errno.ENOEXEC):
raise device_errors.NoAdbError(msg=str(e))
@@ -294,9 +302,7 @@ class AdbWrapper(object):
return output
# pylint: enable=unused-argument
- def _RunDeviceAdbCmd(
- self, args, timeout, retries, check_error=True,
- ensure_logs_on_timeout=False):
+ def _RunDeviceAdbCmd(self, args, timeout, retries, check_error=True):
"""Runs an adb command on the device associated with this object.
Args:
@@ -304,23 +310,27 @@ class AdbWrapper(object):
timeout: Timeout in seconds.
retries: Number of retries.
check_error: Check that the command doesn't return an error message. This
- does NOT check the exit status of shell commands.
+ does check the error status of adb but DOES NOT check the exit status
+ of shell commands.
Returns:
The output of the command.
"""
return self._RunAdbCmd(args, timeout=timeout, retries=retries,
device_serial=self._device_serial,
- check_error=check_error,
- ensure_logs_on_timeout=ensure_logs_on_timeout)
+ check_error=check_error)
- def _IterRunDeviceAdbCmd(self, args, iter_timeout, timeout):
+ def _IterRunDeviceAdbCmd(self, args, iter_timeout, timeout,
+ check_error=True):
"""Runs an adb command and returns an iterator over its output lines.
Args:
args: A list of arguments to adb.
iter_timeout: Timeout for each iteration in seconds.
timeout: Timeout for the entire command in seconds.
+ check_error: Check that the command succeeded. This does check the
+ error status of the adb command but DOES NOT check the exit status
+ of shell commands.
Yields:
The output of the command line by line.
@@ -329,7 +339,8 @@ class AdbWrapper(object):
self._BuildAdbCmd(args, self._device_serial),
iter_timeout=iter_timeout,
timeout=timeout,
- env=self._ADB_ENV)
+ env=self._ADB_ENV,
+ check_status=check_error)
def __eq__(self, other):
"""Consider instances equal if they refer to the same device.
@@ -367,10 +378,21 @@ class AdbWrapper(object):
cls._RunAdbCmd(['kill-server'], timeout=timeout, retries=retries)
@classmethod
- def StartServer(cls, timeout=DEFAULT_TIMEOUT, retries=DEFAULT_RETRIES):
+ def StartServer(cls, keys=None, timeout=DEFAULT_TIMEOUT,
+ retries=DEFAULT_RETRIES):
+ """Starts the ADB server.
+
+ Args:
+ keys: (optional) List of local ADB keys to use to auth with devices.
+ timeout: (optional) Timeout per try in seconds.
+ retries: (optional) Number of retries to attempt.
+ """
+ additional_env = {}
+ if keys:
+ additional_env['ADB_VENDOR_KEYS'] = ':'.join(keys)
# CPU affinity is used to reduce adb instability http://crbug.com/268450
cls._RunAdbCmd(['start-server'], timeout=timeout, retries=retries,
- cpu_affinity=0)
+ cpu_affinity=0, additional_env=additional_env)
@classmethod
def GetDevices(cls, timeout=DEFAULT_TIMEOUT, retries=DEFAULT_RETRIES):
@@ -507,17 +529,14 @@ class AdbWrapper(object):
return cmd_helper.StartCmd(
self._BuildAdbCmd(['shell'] + cmd, self._device_serial))
- def Shell(self, command, expect_status=0, ensure_logs_on_timeout=False,
- timeout=DEFAULT_TIMEOUT, retries=DEFAULT_RETRIES):
+ def Shell(self, command, expect_status=0, timeout=DEFAULT_TIMEOUT,
+ retries=DEFAULT_RETRIES):
"""Runs a shell command on the device.
Args:
command: A string with the shell command to run.
expect_status: (optional) Check that the command's exit status matches
this value. Default is 0. If set to None the test is skipped.
- ensure_logs_on_timeout: If True, will use a timeout that is 5% smaller
- than the remaining time on the thread watchdog for the internal adb
- command, which allows to retrive logs on timeout.
timeout: (optional) Timeout per try in seconds.
retries: (optional) Number of retries to attempt.
@@ -532,9 +551,7 @@ class AdbWrapper(object):
args = ['shell', command]
else:
args = ['shell', '( %s );echo %%$?' % command.rstrip()]
- output = self._RunDeviceAdbCmd(
- args, timeout, retries, check_error=False,
- ensure_logs_on_timeout=ensure_logs_on_timeout)
+ output = self._RunDeviceAdbCmd(args, timeout, retries, check_error=False)
if expect_status is not None:
output_end = output.rfind('%')
if output_end < 0:
@@ -607,7 +624,7 @@ class AdbWrapper(object):
def Logcat(self, clear=False, dump=False, filter_specs=None,
logcat_format=None, ring_buffer=None, iter_timeout=None,
- timeout=None, retries=DEFAULT_RETRIES):
+ check_error=True, timeout=None, retries=DEFAULT_RETRIES):
"""Get an iterable over the logcat output.
Args:
@@ -623,6 +640,7 @@ class AdbWrapper(object):
iter_timeout: If set and neither clear nor dump is set, the number of
seconds to wait between iterations. If no line is found before the
given number of seconds elapses, the iterable will yield None.
+ check_error: Whether to check the exit status of the logcat command.
timeout: (optional) If set, timeout per try in seconds. If clear or dump
is set, defaults to DEFAULT_TIMEOUT.
retries: (optional) If clear or dump is set, the number of retries to
@@ -648,10 +666,13 @@ class AdbWrapper(object):
cmd.extend(filter_specs)
if use_iter:
- return self._IterRunDeviceAdbCmd(cmd, iter_timeout, timeout)
+ return self._IterRunDeviceAdbCmd(
+ cmd, iter_timeout, timeout, check_error=check_error)
else:
timeout = timeout if timeout is not None else DEFAULT_TIMEOUT
- return self._RunDeviceAdbCmd(cmd, timeout, retries).splitlines()
+ output = self._RunDeviceAdbCmd(
+ cmd, timeout, retries, check_error=check_error)
+ return output.splitlines()
def Forward(self, local, remote, allow_rebind=False,
timeout=DEFAULT_TIMEOUT, retries=DEFAULT_RETRIES):
@@ -947,18 +968,28 @@ class AdbWrapper(object):
return self._RunDeviceAdbCmd(['emu'] + cmd, timeout, retries)
def DisableVerity(self, timeout=DEFAULT_TIMEOUT, retries=DEFAULT_RETRIES):
- """Disable Marshmallow's Verity security feature"""
+ """Disable Marshmallow's Verity security feature.
+
+ Returns:
+ The output of the disable-verity command as a string.
+ """
output = self._RunDeviceAdbCmd(['disable-verity'], timeout, retries)
if output and not _VERITY_DISABLE_RE.search(output):
raise device_errors.AdbCommandFailedError(
['disable-verity'], output, device_serial=self._device_serial)
+ return output
def EnableVerity(self, timeout=DEFAULT_TIMEOUT, retries=DEFAULT_RETRIES):
- """Enable Marshmallow's Verity security feature"""
+ """Enable Marshmallow's Verity security feature.
+
+ Returns:
+ The output of the enable-verity command as a string.
+ """
output = self._RunDeviceAdbCmd(['enable-verity'], timeout, retries)
if output and not _VERITY_ENABLE_RE.search(output):
raise device_errors.AdbCommandFailedError(
['enable-verity'], output, device_serial=self._device_serial)
+ return output
@property
def is_emulator(self):