15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/python2.4
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright 2008, The Android Open Source Project
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Licensed under the Apache License, Version 2.0 (the "License");
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# you may not use this file except in compliance with the License.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# You may obtain a copy of the License at
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#     http://www.apache.org/licenses/LICENSE-2.0
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Unless required by applicable law or agreed to in writing, software
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# distributed under the License is distributed on an "AS IS" BASIS,
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# See the License for the specific language governing permissions and
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# limitations under the License.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Provides an interface to communicate with the device via the adb command.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Assumes adb binary is currently on system path.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Python imports
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import string
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import time
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# local imports
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import am_instrument_parser
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import errors
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import logger
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import run_command
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AdbInterface:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Helper class for communicating with Android device via adb."""
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # argument to pass to adb, to direct command to specific device
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  _target_arg = ""
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DEVICE_TRACE_DIR = "/data/test_results/"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def SetEmulatorTarget(self):
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Direct all future commands to the only running emulator."""
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._target_arg = "-e"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def SetDeviceTarget(self):
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Direct all future commands to the only connected USB device."""
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._target_arg = "-d"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def SetTargetSerial(self, serial):
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Direct all future commands to Android target with the given serial."""
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._target_arg = "-s %s" % serial
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def SendCommand(self, command_string, timeout_time=20, retry_count=3):
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Send a command via adb.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command_string: adb command to run
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      timeout_time: number of seconds to wait for command to respond before
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retrying
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      retry_count: number of times to retry command before raising
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        WaitForResponseTimedOutError
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Returns:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      string output of command
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Raises:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WaitForResponseTimedOutError if device does not respond to command within time
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    adb_cmd = "adb %s %s" % (self._target_arg, command_string)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger.SilentLog("about to run %s" % adb_cmd)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return run_command.RunCommand(adb_cmd, timeout_time=timeout_time,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  retry_count=retry_count)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def SendShellCommand(self, cmd, timeout_time=20, retry_count=3):
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Send a adb shell command.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cmd: adb shell command to run
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      timeout_time: number of seconds to wait for command to respond before
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        retrying
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      retry_count: number of times to retry command before raising
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        WaitForResponseTimedOutError
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Returns:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      string output of command
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Raises:
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WaitForResponseTimedOutError: if device does not respond to command
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.SendCommand("shell %s" % cmd, timeout_time=timeout_time,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            retry_count=retry_count)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def BugReport(self, path):
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Dumps adb bugreport to the file specified by the path.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path: Path of the file where adb bugreport is dumped to.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bug_output = self.SendShellCommand("bugreport", timeout_time=60)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bugreport_file = open(path, "w")
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bugreport_file.write(bug_output)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bugreport_file.close()
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Push(self, src, dest):
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Pushes the file src onto the device at dest.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      src: file path of host file to push
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dest: destination absolute file path on device
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.SendCommand("push %s %s" % (src, dest), timeout_time=60)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Pull(self, src, dest):
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Pulls the file src on the device onto dest on the host.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      src: absolute file path of file on device to pull
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dest: destination file path on host
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Returns:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      True if success and False otherwise.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Create the base dir if it doesn't exist already
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not os.path.exists(os.path.dirname(dest)):
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      os.makedirs(os.path.dirname(dest))
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if self.DoesFileExist(src):
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendCommand("pull %s %s" % (src, dest), timeout_time=60)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return True
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger.Log("ADB Pull Failed: Source file %s does not exist." % src)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return False
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def DoesFileExist(self, src):
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Checks if the given path exists on device target.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      src: file path to be checked.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Returns:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      True if file exists
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output = self.SendShellCommand("ls %s" % src)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error = "No such file or directory"
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if error in output:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return False
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return True
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def EnableAdbRoot(self):
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Enable adb root on device."""
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output = self.SendCommand("root")
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if "adbd is already running as root" in output:
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return True
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elif "restarting adbd as root" in output:
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # device will disappear from adb, wait for it to come back
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendCommand("wait-for-device")
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return True
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger.Log("Unrecognized output from adb root: %s" % output)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return False
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def StartInstrumentationForPackage(
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self, package_name, runner_name, timeout_time=60*10,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      no_window_animation=False, instrumentation_args={}):
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Run instrumentation test for given package and runner.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Equivalent to StartInstrumentation, except instrumentation path is
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    separated into its package and runner components.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instrumentation_path = "%s/%s" % (package_name, runner_name)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.StartInstrumentation(instrumentation_path, timeout_time=timeout_time,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     no_window_animation=no_window_animation,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     instrumentation_args=instrumentation_args)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def StartInstrumentation(
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self, instrumentation_path, timeout_time=60*10, no_window_animation=False,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile=False, instrumentation_args={}, silent_log=False):
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Runs an instrumentation class on the target.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Returns a dictionary containing the key value pairs from the
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instrumentations result bundle and a list of TestResults. Also handles the
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    interpreting of error output from the device and raises the necessary
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    exceptions.
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instrumentation_path: string. It should be the fully classified package
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name, and instrumentation test runner, separated by "/"
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        e.g. com.android.globaltimelaunch/.GlobalTimeLaunch
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      timeout_time: Timeout value for the am command.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      no_window_animation: boolean, Whether you want window animations enabled
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        or disabled
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile: If True, profiling will be turned on for the instrumentation.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instrumentation_args: Dictionary of key value bundle arguments to pass to
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instrumentation.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      silent_log: If True, the invocation of the instrumentation test runner
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        will not be logged.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Returns:
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (test_results, inst_finished_bundle)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_results: a list of TestResults
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inst_finished_bundle (dict): Key/value pairs contained in the bundle that
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        is passed into ActivityManager.finishInstrumentation(). Included in this
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bundle is the return code of the Instrumentation process, any error
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        codes reported by the activity manager, and any results explicitly added
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        by the instrumentation code.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     Raises:
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       WaitForResponseTimedOutError: if timeout occurred while waiting for
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         response to adb instrument command
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       DeviceUnresponsiveError: if device system process is not responding
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       InstrumentationError: if instrumentation failed to run
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_string = self._BuildInstrumentationCommandPath(
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instrumentation_path, no_window_animation=no_window_animation,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        profile=profile, raw_mode=True,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instrumentation_args=instrumentation_args)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if silent_log:
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger.SilentLog(command_string)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger.Log(command_string)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (test_results, inst_finished_bundle) = (
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        am_instrument_parser.ParseAmInstrumentOutput(
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            self.SendShellCommand(command_string, timeout_time=timeout_time,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  retry_count=2)))
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if "code" not in inst_finished_bundle:
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger.Log('No code available. inst_finished_bundle contains: %s '
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 % inst_finished_bundle)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raise errors.InstrumentationError("no test results... device setup "
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        "correctly?")
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if inst_finished_bundle["code"] == "0":
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      long_msg_result = "no error message"
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if "longMsg" in inst_finished_bundle:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        long_msg_result = inst_finished_bundle["longMsg"]
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        logger.Log("Error! Test run failed: %s" % long_msg_result)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raise errors.InstrumentationError(long_msg_result)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if "INSTRUMENTATION_ABORTED" in inst_finished_bundle:
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger.Log("INSTRUMENTATION ABORTED!")
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raise errors.DeviceUnresponsiveError
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (test_results, inst_finished_bundle)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def StartInstrumentationNoResults(
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self, package_name, runner_name, no_window_animation=False,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raw_mode=False, instrumentation_args={}):
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Runs instrumentation and dumps output to stdout.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Equivalent to StartInstrumentation, but will dump instrumentation
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'normal' output to stdout, instead of parsing return results. Command will
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    never timeout.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    adb_command_string = self.PreviewInstrumentationCommand(
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        package_name, runner_name, no_window_animation=no_window_animation,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        raw_mode=raw_mode, instrumentation_args=instrumentation_args)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger.Log(adb_command_string)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    run_command.RunCommand(adb_command_string, return_output=False)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def PreviewInstrumentationCommand(
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self, package_name, runner_name, no_window_animation=False,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raw_mode=False, instrumentation_args={}):
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Returns a string of adb command that will be executed."""
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inst_command_string = self._BuildInstrumentationCommand(
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        package_name, runner_name, no_window_animation=no_window_animation,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        raw_mode=raw_mode, instrumentation_args=instrumentation_args)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_string = "adb %s shell %s" % (self._target_arg, inst_command_string)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return command_string
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def _BuildInstrumentationCommand(
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self, package, runner_name, no_window_animation=False, profile=False,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raw_mode=True, instrumentation_args={}):
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instrumentation_path = "%s/%s" % (package, runner_name)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self._BuildInstrumentationCommandPath(
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instrumentation_path, no_window_animation=no_window_animation,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        profile=profile, raw_mode=raw_mode,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        instrumentation_args=instrumentation_args)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def _BuildInstrumentationCommandPath(
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self, instrumentation_path, no_window_animation=False, profile=False,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raw_mode=True, instrumentation_args={}):
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_string = "am instrument"
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if no_window_animation:
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command_string += " --no_window_animation"
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if profile:
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self._CreateTraceDir()
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command_string += (
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          " -p %s/%s.dmtrace" %
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (self.DEVICE_TRACE_DIR, instrumentation_path.split(".")[-1]))
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for key, value in instrumentation_args.items():
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command_string += " -e %s '%s'" % (key, value)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if raw_mode:
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command_string += " -r"
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_string += " -w %s" % instrumentation_path
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return command_string
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def _CreateTraceDir(self):
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ls_response = self.SendShellCommand("ls /data/trace")
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ls_response.strip("#").strip(string.whitespace) != "":
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendShellCommand("create /data/trace", "mkdir /data/trace")
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendShellCommand("make /data/trace world writeable",
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            "chmod 777 /data/trace")
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def WaitForDevicePm(self, wait_time=120):
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Waits for targeted device's package manager to be up.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wait_time: time in seconds to wait
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Raises:
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WaitForResponseTimedOutError if wait_time elapses and pm still does not
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      respond.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger.Log("Waiting for device package manager...")
321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    self.SendCommand("wait-for-device", timeout_time=wait_time, retry_count=0)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Now the device is there, but may not be running.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Query the package manager with a basic command
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    try:
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self._WaitForShellCommandContents("pm path android", "package:",
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        wait_time)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    except errors.WaitForResponseTimedOutError:
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raise errors.WaitForResponseTimedOutError(
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "Package manager did not respond after %s seconds" % wait_time)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def WaitForInstrumentation(self, package_name, runner_name, wait_time=120):
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Waits for given instrumentation to be present on device
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wait_time: time in seconds to wait
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Raises:
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WaitForResponseTimedOutError if wait_time elapses and instrumentation
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      still not present.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instrumentation_path = "%s/%s" % (package_name, runner_name)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger.Log("Waiting for instrumentation to be present")
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Query the package manager
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    try:
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command = "pm list instrumentation | grep %s" % instrumentation_path
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self._WaitForShellCommandContents(command, "instrumentation:", wait_time,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        raise_abort=False)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    except errors.WaitForResponseTimedOutError :
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger.Log(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "Could not find instrumentation %s on device. Does the "
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "instrumentation in test's AndroidManifest.xml match definition"
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "in test_defs.xml?" % instrumentation_path)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raise
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def WaitForProcess(self, name, wait_time=120):
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Wait until a process is running on the device.
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name: the process name as it appears in `ps`
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wait_time: time in seconds to wait
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Raises:
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WaitForResponseTimedOutError if wait_time elapses and the process is
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          still not running
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger.Log("Waiting for process %s" % name)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.SendCommand("wait-for-device")
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._WaitForShellCommandContents("ps", name, wait_time)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def WaitForProcessEnd(self, name, wait_time=120):
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Wait until a process is no longer running on the device.
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name: the process name as it appears in `ps`
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wait_time: time in seconds to wait
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Raises:
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WaitForResponseTimedOutError if wait_time elapses and the process is
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          still running
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger.Log("Waiting for process %s to end" % name)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._WaitForShellCommandContents("ps", name, wait_time, invert=True)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def _WaitForShellCommandContents(self, command, expected, wait_time,
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   raise_abort=True, invert=False):
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Wait until the response to a command contains a given output.
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Assumes that a only successful execution of "adb shell <command>" contains
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    the substring expected. Assumes that a device is present.
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command: adb shell command to execute
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected: the string that should appear to consider the
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          command successful.
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wait_time: time in seconds to wait
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raise_abort: if False, retry when executing the command raises an
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          AbortError, rather than failing.
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      invert: if True, wait until the command output no longer contains the
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          expected contents.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Raises:
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WaitForResponseTimedOutError: If wait_time elapses and the command has not
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          returned an output containing expected yet.
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Query the device with the command
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    success = False
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    attempts = 0
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wait_period = 5
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while not success and (attempts*wait_period) < wait_time:
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # assume the command will always contain expected in the success case
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      try:
412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        output = self.SendShellCommand(command, retry_count=1,
413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                       timeout_time=wait_time)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((not invert and expected in output)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            or (invert and expected not in output)):
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          success = True
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      except errors.AbortError, e:
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if raise_abort:
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          raise
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        # ignore otherwise
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if not success:
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        time.sleep(wait_period)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        attempts += 1
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not success:
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raise errors.WaitForResponseTimedOutError()
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def WaitForBootComplete(self, wait_time=120):
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Waits for targeted device's bootcomplete flag to be set.
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wait_time: time in seconds to wait
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Raises:
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WaitForResponseTimedOutError if wait_time elapses and pm still does not
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      respond.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger.Log("Waiting for boot complete...")
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.SendCommand("wait-for-device")
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Now the device is there, but may not be running.
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Query the package manager with a basic command
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    boot_complete = False
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    attempts = 0
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wait_period = 5
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while not boot_complete and (attempts*wait_period) < wait_time:
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output = self.SendShellCommand("getprop dev.bootcomplete", retry_count=1)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output = output.strip()
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if output == "1":
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        boot_complete = True
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else:
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        time.sleep(wait_period)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        attempts += 1
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not boot_complete:
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raise errors.WaitForResponseTimedOutError(
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "dev.bootcomplete flag was not set after %s seconds" % wait_time)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Sync(self, retry_count=3, runtime_restart=False):
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Perform a adb sync.
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Blocks until device package manager is responding.
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      retry_count: number of times to retry sync before failing
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      runtime_restart: stop runtime during sync and restart afterwards, useful
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for syncing system libraries (core, framework etc)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Raises:
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WaitForResponseTimedOutError if package manager does not respond
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AbortError if unrecoverable error occurred
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output = ""
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error = None
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if runtime_restart:
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendShellCommand("setprop ro.monkey 1", retry_count=retry_count)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # manual rest bootcomplete flag
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendShellCommand("setprop dev.bootcomplete 0",
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            retry_count=retry_count)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendShellCommand("stop", retry_count=retry_count)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    try:
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output = self.SendCommand("sync", retry_count=retry_count)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    except errors.AbortError, e:
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error = e
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output = e.msg
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if "Read-only file system" in output:
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger.SilentLog(output)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger.Log("Remounting read-only filesystem")
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendCommand("remount")
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output = self.SendCommand("sync", retry_count=retry_count)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elif "No space left on device" in output:
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger.SilentLog(output)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger.Log("Restarting device runtime")
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendShellCommand("stop", retry_count=retry_count)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output = self.SendCommand("sync", retry_count=retry_count)
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendShellCommand("start", retry_count=retry_count)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    elif error is not None:
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # exception occurred that cannot be recovered from
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raise error
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger.SilentLog(output)
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if runtime_restart:
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # start runtime and wait till boot complete flag is set
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendShellCommand("start", retry_count=retry_count)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.WaitForBootComplete()
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # press the MENU key, this will disable key guard if runtime is started
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # with ro.monkey set to 1
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.SendShellCommand("input keyevent 82", retry_count=retry_count)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.WaitForDevicePm()
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return output
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def GetSerialNumber(self):
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Returns the serial number of the targeted device."""
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self.SendCommand("get-serialno").strip()
515