# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Provides an interface to communicate with the device via the adb command.

Assumes adb binary is currently on system path.
"""
# pylint: skip-file

import collections
import datetime
import inspect
import logging
import os
import random
import re
import shlex
import signal
import subprocess
import sys
import tempfile
import time

import cmd_helper
import constants
import system_properties
from utils import host_utils

try:
  from pylib import pexpect
except ImportError:
  pexpect = None

sys.path.append(os.path.join(
    constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner'))
import adb_interface
import am_instrument_parser
import errors

from pylib.device import device_blacklist
from pylib.device import device_errors

# Pattern to search for the next whole line of pexpect output and capture it
# into a match group. We can't use ^ and $ for line start end with pexpect,
# see http://www.noah.org/python/pexpect/#doc for explanation why.
PEXPECT_LINE_RE = re.compile('\n([^\r]*)\r')

# Set the adb shell prompt to be a unique marker that will [hopefully] not
# appear at the start of any line of a command's output.
SHELL_PROMPT = '~+~PQ\x17RS~+~'

# Java properties file
LOCAL_PROPERTIES_PATH = constants.DEVICE_LOCAL_PROPERTIES_PATH

# Property in /data/local.prop that controls Java assertions.
JAVA_ASSERT_PROPERTY = 'dalvik.vm.enableassertions'

# Keycode "enum" suitable for passing to AndroidCommands.SendKey().
KEYCODE_HOME = 3
KEYCODE_BACK = 4
KEYCODE_DPAD_UP = 19
KEYCODE_DPAD_DOWN = 20
KEYCODE_DPAD_RIGHT = 22
KEYCODE_ENTER = 66
KEYCODE_MENU = 82

MD5SUM_DEVICE_FOLDER = constants.TEST_EXECUTABLE_DIR + '/md5sum/'
MD5SUM_DEVICE_PATH = MD5SUM_DEVICE_FOLDER + 'md5sum_bin'

PIE_WRAPPER_PATH = constants.TEST_EXECUTABLE_DIR + '/run_pie'

CONTROL_USB_CHARGING_COMMANDS = [
  {
    # Nexus 4
    'witness_file': '/sys/module/pm8921_charger/parameters/disabled',
    'enable_command': 'echo 0 > /sys/module/pm8921_charger/parameters/disabled',
    'disable_command':
        'echo 1 > /sys/module/pm8921_charger/parameters/disabled',
  },
  {
    # Nexus 5
    # Setting the HIZ bit of the bq24192 causes the charger to actually ignore
    # energy coming from USB. Setting the power_supply offline just updates the
    # Android system to reflect that.
    'witness_file': '/sys/kernel/debug/bq24192/INPUT_SRC_CONT',
    'enable_command': (
        'echo 0x4A > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
        'echo 1 > /sys/class/power_supply/usb/online'),
    'disable_command': (
        'echo 0xCA > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
        'chmod 644 /sys/class/power_supply/usb/online && '
        'echo 0 > /sys/class/power_supply/usb/online'),
  },
]

class DeviceTempFile(object):
  def __init__(self, android_commands, prefix='temp_file', suffix=''):
    """Find an unused temporary file path in the devices external directory.

    When this object is closed, the file will be deleted on the device.
    """
    self.android_commands = android_commands
    while True:
      # TODO(cjhopman): This could actually return the same file in multiple
      # calls if the caller doesn't write to the files immediately. This is
      # expected to never happen.
      i = random.randint(0, 1000000)
      self.name = '%s/%s-%d-%010d%s' % (
          android_commands.GetExternalStorage(),
          prefix, int(time.time()), i, suffix)
      if not android_commands.FileExistsOnDevice(self.name):
        break

  def __enter__(self):
    return self

  def __exit__(self, type, value, traceback):
    self.close()

  def close(self):
    self.android_commands.RunShellCommand('rm ' + self.name)


def GetAVDs():
  """Returns a list of AVDs."""
  re_avd = re.compile('^[ ]+Name: ([a-zA-Z0-9_:.-]+)', re.MULTILINE)
  avds = re_avd.findall(cmd_helper.GetCmdOutput(['android', 'list', 'avd']))
  return avds

def ResetBadDevices():
  """Removes the blacklist that keeps track of bad devices for a current
     build.
  """
  device_blacklist.ResetBlacklist()

def ExtendBadDevices(devices):
  """Adds devices to the blacklist that keeps track of bad devices for a
     current build.

  The devices listed in the bad devices file will not be returned by
  GetAttachedDevices.

  Args:
    devices: list of bad devices to be added to the bad devices file.
  """
  device_blacklist.ExtendBlacklist(devices)


def GetAttachedDevices(hardware=True, emulator=True, offline=False):
  """Returns a list of attached, android devices and emulators.

  If a preferred device has been set with ANDROID_SERIAL, it will be first in
  the returned list. The arguments specify what devices to include in the list.

  Example output:

    * daemon not running. starting it now on port 5037 *
    * daemon started successfully *
    List of devices attached
    027c10494100b4d7        device
    emulator-5554   offline

  Args:
    hardware: Include attached actual devices that are online.
    emulator: Include emulators (i.e. AVD's) currently on host.
    offline: Include devices and emulators that are offline.

  Returns: List of devices.
  """
  adb_devices_output = cmd_helper.GetCmdOutput([constants.GetAdbPath(),
                                                'devices'])

  re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE)
  online_devices = re_device.findall(adb_devices_output)

  re_device = re.compile('^(emulator-[0-9]+)\tdevice', re.MULTILINE)
  emulator_devices = re_device.findall(adb_devices_output)

  re_device = re.compile('^([a-zA-Z0-9_:.-]+)\t(?:offline|unauthorized)$',
                         re.MULTILINE)
  offline_devices = re_device.findall(adb_devices_output)

  devices = []
  # First determine list of online devices (e.g. hardware and/or emulator).
  if hardware and emulator:
    devices = online_devices
  elif hardware:
    devices = [device for device in online_devices
               if device not in emulator_devices]
  elif emulator:
    devices = emulator_devices

  # Now add offline devices if offline is true
  if offline:
    devices = devices + offline_devices

  # Remove any devices in the blacklist.
  blacklist = device_blacklist.ReadBlacklist()
  if len(blacklist):
    logging.info('Avoiding bad devices %s', ' '.join(blacklist))
    devices = [device for device in devices if device not in blacklist]

  preferred_device = os.environ.get('ANDROID_SERIAL')
  if preferred_device in devices:
    devices.remove(preferred_device)
    devices.insert(0, preferred_device)
  return devices


def IsDeviceAttached(device):
  """Return true if the device is attached and online."""
  return device in GetAttachedDevices()


def _GetFilesFromRecursiveLsOutput(path, ls_output, re_file, utc_offset=None):
  """Gets a list of files from `ls` command output.

  Python's os.walk isn't used because it doesn't work over adb shell.

  Args:
    path: The path to list.
    ls_output: A list of lines returned by an `ls -lR` command.
    re_file: A compiled regular expression which parses a line into named groups
        consisting of at minimum "filename", "date", "time", "size" and
        optionally "timezone".
    utc_offset: A 5-character string of the form +HHMM or -HHMM, where HH is a
        2-digit string giving the number of UTC offset hours, and MM is a
        2-digit string giving the number of UTC offset minutes. If the input
        utc_offset is None, will try to look for the value of "timezone" if it
        is specified in re_file.

  Returns:
    A dict of {"name": (size, lastmod), ...} where:
      name: The file name relative to |path|'s directory.
      size: The file size in bytes (0 for directories).
      lastmod: The file last modification date in UTC.
  """
  re_directory = re.compile('^%s/(?P<dir>[^:]+):$' % re.escape(path))
  path_dir = os.path.dirname(path)

  current_dir = ''
  files = {}
  for line in ls_output:
    directory_match = re_directory.match(line)
    if directory_match:
      current_dir = directory_match.group('dir')
      continue
    file_match = re_file.match(line)
    if file_match:
      filename = os.path.join(current_dir, file_match.group('filename'))
      if filename.startswith(path_dir):
        filename = filename[len(path_dir) + 1:]
      lastmod = datetime.datetime.strptime(
          file_match.group('date') + ' ' + file_match.group('time')[:5],
          '%Y-%m-%d %H:%M')
      if not utc_offset and 'timezone' in re_file.groupindex:
        utc_offset = file_match.group('timezone')
      if isinstance(utc_offset, str) and len(utc_offset) == 5:
        utc_delta = datetime.timedelta(hours=int(utc_offset[1:3]),
                                       minutes=int(utc_offset[3:5]))
        if utc_offset[0:1] == '-':
          utc_delta = -utc_delta
        lastmod -= utc_delta
      files[filename] = (int(file_match.group('size')), lastmod)
  return files


def _ParseMd5SumOutput(md5sum_output):
  """Returns a list of tuples from the provided md5sum output.

  Args:
    md5sum_output: output directly from md5sum binary.

  Returns:
    List of namedtuples with attributes |hash| and |path|, where |path| is the
    absolute path to the file with an Md5Sum of |hash|.
  """
  HashAndPath = collections.namedtuple('HashAndPath', ['hash', 'path'])
  split_lines = [line.split('  ') for line in md5sum_output]
  return [HashAndPath._make(s) for s in split_lines if len(s) == 2]


def _HasAdbPushSucceeded(command_output):
  """Returns whether adb push has succeeded from the provided output."""
  # TODO(frankf): We should look at the return code instead of the command
  # output for many of the commands in this file.
  if not command_output:
    return True
  # Success looks like this: "3035 KB/s (12512056 bytes in 4.025s)"
  # Errors look like this: "failed to copy  ... "
  if not re.search('^[0-9]', command_output.splitlines()[-1]):
    logging.critical('PUSH FAILED: ' + command_output)
    return False
  return True


def GetLogTimestamp(log_line, year):
  """Returns the timestamp of the given |log_line| in the given year."""
  try:
    return datetime.datetime.strptime('%s-%s' % (year, log_line[:18]),
                                      '%Y-%m-%d %H:%M:%S.%f')
  except (ValueError, IndexError):
    logging.critical('Error reading timestamp from ' + log_line)
    return None


class AndroidCommands(object):
  """Helper class for communicating with Android device via adb."""

  def __init__(self, device=None):
    """Constructor.

    Args:
      device: If given, adb commands are only send to the device of this ID.
          Otherwise commands are sent to all attached devices.
    """
    self._adb = adb_interface.AdbInterface(constants.GetAdbPath())
    if device:
      self._adb.SetTargetSerial(device)
    self._device = device
    self._logcat = None
    self.logcat_process = None
    self._logcat_tmpoutfile = None
    self._pushed_files = []
    self._device_utc_offset = None
    self._potential_push_size = 0
    self._actual_push_size = 0
    self._external_storage = ''
    self._util_wrapper = ''
    self._system_properties = system_properties.SystemProperties(self.Adb())
    self._push_if_needed_cache = {}
    self._control_usb_charging_command = {
        'command': None,
        'cached': False,
    }
    self._protected_file_access_method_initialized = None
    self._privileged_command_runner = None
    self._pie_wrapper = None

  @property
  def system_properties(self):
    return self._system_properties

  def _LogShell(self, cmd):
    """Logs the adb shell command."""
    if self._device:
      device_repr = self._device[-4:]
    else:
      device_repr = '????'
    logging.info('[%s]> %s', device_repr, cmd)

  def Adb(self):
    """Returns our AdbInterface to avoid us wrapping all its methods."""
    # TODO(tonyg): Goal should be to git rid of this method by making this API
    # complete and alleviating the need.
    return self._adb

  def GetDevice(self):
    """Returns the device serial."""
    return self._device

  def IsOnline(self):
    """Checks whether the device is online.

    Returns:
      True if device is in 'device' mode, False otherwise.
    """
    # TODO(aurimas): revert to using adb get-state when android L adb is fixed.
    #out = self._adb.SendCommand('get-state')
    #return out.strip() == 'device'

    out = self._adb.SendCommand('devices')
    for line in out.split('\n'):
      if self._device in line and 'device' in line:
        return True
    return False

  def IsRootEnabled(self):
    """Checks if root is enabled on the device."""
    root_test_output = self.RunShellCommand('ls /root') or ['']
    return not 'Permission denied' in root_test_output[0]

  def EnableAdbRoot(self):
    """Enables adb root on the device.

    Returns:
      True: if output from executing adb root was as expected.
      False: otherwise.
    """
    if self.GetBuildType() == 'user':
      logging.warning("Can't enable root in production builds with type user")
      return False
    else:
      return_value = self._adb.EnableAdbRoot()
      # EnableAdbRoot inserts a call for wait-for-device only when adb logcat
      # output matches what is expected. Just to be safe add a call to
      # wait-for-device.
      self._adb.SendCommand('wait-for-device')
      return return_value

  def GetDeviceYear(self):
    """Returns the year information of the date on device."""
    return self.RunShellCommand('date +%Y')[0]

  def GetExternalStorage(self):
    if not self._external_storage:
      self._external_storage = self.RunShellCommand('echo $EXTERNAL_STORAGE')[0]
      if not self._external_storage:
        raise device_errors.CommandFailedError(
            ['shell', "'echo $EXTERNAL_STORAGE'"],
            'Unable to find $EXTERNAL_STORAGE')
    return self._external_storage

  def WaitForDevicePm(self, timeout=120):
    """Blocks until the device's package manager is available.

    To workaround http://b/5201039, we restart the shell and retry if the
    package manager isn't back after 120 seconds.

    Raises:
      errors.WaitForResponseTimedOutError after max retries reached.
    """
    last_err = None
    retries = 3
    while retries:
      try:
        self._adb.WaitForDevicePm(wait_time=timeout)
        return  # Success
      except errors.WaitForResponseTimedOutError as e:
        last_err = e
        logging.warning('Restarting and retrying after timeout: %s', e)
        retries -= 1
        self.RestartShell()
    raise last_err # Only reached after max retries, re-raise the last error.

  def RestartShell(self):
    """Restarts the shell on the device. Does not block for it to return."""
    self.RunShellCommand('stop')
    self.RunShellCommand('start')

  def Reboot(self, full_reboot=True):
    """Reboots the device and waits for the package manager to return.

    Args:
      full_reboot: Whether to fully reboot the device or just restart the shell.
    """
    # TODO(torne): hive can't reboot the device either way without breaking the
    # connection; work out if we can handle this better
    if os.environ.get('USING_HIVE'):
      logging.warning('Ignoring reboot request as we are on hive')
      return
    if full_reboot or not self.IsRootEnabled():
      self._adb.SendCommand('reboot')
      self._system_properties = system_properties.SystemProperties(self.Adb())
      timeout = 300
      retries = 1
      # Wait for the device to disappear.
      while retries < 10 and self.IsOnline():
        time.sleep(1)
        retries += 1
    else:
      self.RestartShell()
      timeout = 120
    # To run tests we need at least the package manager and the sd card (or
    # other external storage) to be ready.
    self.WaitForDevicePm(timeout)
    self.WaitForSdCardReady(timeout)

  def Shutdown(self):
    """Shuts down the device."""
    self._adb.SendCommand('reboot -p')
    self._system_properties = system_properties.SystemProperties(self.Adb())

  def Uninstall(self, package):
    """Uninstalls the specified package from the device.

    Args:
      package: Name of the package to remove.

    Returns:
      A status string returned by adb uninstall
    """
    uninstall_command = 'uninstall %s' % package

    self._LogShell(uninstall_command)
    return self._adb.SendCommand(uninstall_command, timeout_time=60)

  def Install(self, package_file_path, reinstall=False):
    """Installs the specified package to the device.

    Args:
      package_file_path: Path to .apk file to install.
      reinstall: Reinstall an existing apk, keeping the data.

    Returns:
      A status string returned by adb install
    """
    assert os.path.isfile(package_file_path), ('<%s> is not file' %
                                               package_file_path)

    install_cmd = ['install']

    if reinstall:
      install_cmd.append('-r')

    install_cmd.append(package_file_path)
    install_cmd = ' '.join(install_cmd)

    self._LogShell(install_cmd)
    return self._adb.SendCommand(install_cmd,
                                 timeout_time=2 * 60,
                                 retry_count=0)

  def ManagedInstall(self, apk_path, keep_data=False, package_name=None,
                     reboots_on_timeout=2):
    """Installs specified package and reboots device on timeouts.

    If package_name is supplied, checks if the package is already installed and
    doesn't reinstall if the apk md5sums match.

    Args:
      apk_path: Path to .apk file to install.
      keep_data: Reinstalls instead of uninstalling first, preserving the
        application data.
      package_name: Package name (only needed if keep_data=False).
      reboots_on_timeout: number of time to reboot if package manager is frozen.
    """
    # Check if package is already installed and up to date.
    if package_name:
      installed_apk_path = self.GetApplicationPath(package_name)
      if (installed_apk_path and
          not self.GetFilesChanged(apk_path, installed_apk_path,
                                   ignore_filenames=True)):
        logging.info('Skipped install: identical %s APK already installed' %
            package_name)
        return
    # Install.
    reboots_left = reboots_on_timeout
    while True:
      try:
        if not keep_data:
          assert package_name
          self.Uninstall(package_name)
        install_status = self.Install(apk_path, reinstall=keep_data)
        if 'Success' in install_status:
          return
        else:
          raise Exception('Install failure: %s' % install_status)
      except errors.WaitForResponseTimedOutError:
        print '@@@STEP_WARNINGS@@@'
        logging.info('Timeout on installing %s on device %s', apk_path,
                     self._device)

        if reboots_left <= 0:
          raise Exception('Install timed out')

        # Force a hard reboot on last attempt
        self.Reboot(full_reboot=(reboots_left == 1))
        reboots_left -= 1

  def MakeSystemFolderWritable(self):
    """Remounts the /system folder rw."""
    out = self._adb.SendCommand('remount')
    if out.strip() != 'remount succeeded':
      raise errors.MsgException('Remount failed: %s' % out)

  def RestartAdbdOnDevice(self):
    logging.info('Restarting adbd on the device...')
    with DeviceTempFile(self, suffix=".sh") as temp_script_file:
      host_script_path = os.path.join(constants.DIR_SOURCE_ROOT,
                                      'build',
                                      'android',
                                      'pylib',
                                      'restart_adbd.sh')
      self._adb.Push(host_script_path, temp_script_file.name)
      self.RunShellCommand('. %s' % temp_script_file.name)
      self._adb.SendCommand('wait-for-device')

  def RestartAdbServer(self):
    """Restart the adb server."""
    ret = self.KillAdbServer()
    if ret != 0:
      raise errors.MsgException('KillAdbServer: %d' % ret)

    ret = self.StartAdbServer()
    if ret != 0:
      raise errors.MsgException('StartAdbServer: %d' % ret)

  @staticmethod
  def KillAdbServer():
    """Kill adb server."""
    adb_cmd = [constants.GetAdbPath(), 'kill-server']
    ret = cmd_helper.RunCmd(adb_cmd)
    retry = 0
    while retry < 3:
      ret, _ = cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb'])
      if ret != 0:
        # pgrep didn't find adb, kill-server succeeded.
        return 0
      retry += 1
      time.sleep(retry)
    return ret

  def StartAdbServer(self):
    """Start adb server."""
    adb_cmd = ['taskset', '-c', '0', constants.GetAdbPath(), 'start-server']
    ret, _ = cmd_helper.GetCmdStatusAndOutput(adb_cmd)
    retry = 0
    while retry < 3:
      ret, _ = cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb'])
      if ret == 0:
        # pgrep found adb, start-server succeeded.
        # Waiting for device to reconnect before returning success.
        self._adb.SendCommand('wait-for-device')
        return 0
      retry += 1
      time.sleep(retry)
    return ret

  def WaitForSystemBootCompleted(self, wait_time):
    """Waits for targeted system's boot_completed flag to be set.

    Args:
      wait_time: time in seconds to wait

    Raises:
      WaitForResponseTimedOutError if wait_time elapses and flag still not
      set.
    """
    logging.info('Waiting for system boot completed...')
    self._adb.SendCommand('wait-for-device')
    # Now the device is there, but system not boot completed.
    # Query the sys.boot_completed flag with a basic command
    boot_completed = False
    attempts = 0
    wait_period = 5
    while not boot_completed and (attempts * wait_period) < wait_time:
      output = self.system_properties['sys.boot_completed']
      output = output.strip()
      if output == '1':
        boot_completed = True
      else:
        # If 'error: xxx' returned when querying the flag, it means
        # adb server lost the connection to the emulator, so restart the adb
        # server.
        if 'error:' in output:
          self.RestartAdbServer()
        time.sleep(wait_period)
        attempts += 1
    if not boot_completed:
      raise errors.WaitForResponseTimedOutError(
          'sys.boot_completed flag was not set after %s seconds' % wait_time)

  def WaitForSdCardReady(self, timeout_time):
    """Wait for the SD card ready before pushing data into it."""
    logging.info('Waiting for SD card ready...')
    sdcard_ready = False
    attempts = 0
    wait_period = 5
    external_storage = self.GetExternalStorage()
    while not sdcard_ready and attempts * wait_period < timeout_time:
      output = self.RunShellCommand('ls ' + external_storage)
      if output:
        sdcard_ready = True
      else:
        time.sleep(wait_period)
        attempts += 1
    if not sdcard_ready:
      raise errors.WaitForResponseTimedOutError(
          'SD card not ready after %s seconds' % timeout_time)

  def GetAndroidToolStatusAndOutput(self, command, lib_path=None, *args, **kw):
    """Runs a native Android binary, wrapping the command as necessary.

    This is a specialization of GetShellCommandStatusAndOutput, which is meant
    for running tools/android/ binaries and handle properly: (1) setting the
    lib path (for component=shared_library), (2) using the PIE wrapper on ICS.
    See crbug.com/373219 for more context.

    Args:
      command: String containing the command to send.
      lib_path: (optional) path to the folder containing the dependent libs.
      Same other arguments of GetCmdStatusAndOutput.
    """
    # The first time this command is run the device is inspected to check
    # whether a wrapper for running PIE executable is needed (only Android ICS)
    # or not. The results is cached, so the wrapper is pushed only once.
    if self._pie_wrapper is None:
      # None: did not check; '': did check and not needed; '/path': use /path.
      self._pie_wrapper = ''
      if self.GetBuildId().startswith('I'):  # Ixxxx = Android ICS.
        run_pie_dist_path = os.path.join(constants.GetOutDirectory(), 'run_pie')
        assert os.path.exists(run_pie_dist_path), 'Please build run_pie'
        # The PIE loader must be pushed manually (i.e. no PushIfNeeded) because
        # PushIfNeeded requires md5sum and md5sum requires the wrapper as well.
        command = 'push %s %s' % (run_pie_dist_path, PIE_WRAPPER_PATH)
        assert _HasAdbPushSucceeded(self._adb.SendCommand(command))
        self._pie_wrapper = PIE_WRAPPER_PATH

    if self._pie_wrapper:
      command = '%s %s' % (self._pie_wrapper, command)
    if lib_path:
      command = 'LD_LIBRARY_PATH=%s %s' % (lib_path, command)
    return self.GetShellCommandStatusAndOutput(command, *args, **kw)

  # It is tempting to turn this function into a generator, however this is not
  # possible without using a private (local) adb_shell instance (to ensure no
  # other command interleaves usage of it), which would defeat the main aim of
  # being able to reuse the adb shell instance across commands.
  def RunShellCommand(self, command, timeout_time=20, log_result=False):
    """Send a command to the adb shell and return the result.

    Args:
      command: String containing the shell command to send.
      timeout_time: Number of seconds to wait for command to respond before
        retrying, used by AdbInterface.SendShellCommand.
      log_result: Boolean to indicate whether we should log the result of the
                  shell command.

    Returns:
      list containing the lines of output received from running the command
    """
    self._LogShell(command)
    if "'" in command:
      command = command.replace('\'', '\'\\\'\'')
    result = self._adb.SendShellCommand(
        "'%s'" % command, timeout_time).splitlines()
    # TODO(b.kelemen): we should really be able to drop the stderr of the
    # command or raise an exception based on what the caller wants.
    result = [ l for l in result if not l.startswith('WARNING') ]
    if ['error: device not found'] == result:
      raise errors.DeviceUnresponsiveError('device not found')
    if log_result:
      self._LogShell('\n'.join(result))
    return result

  def GetShellCommandStatusAndOutput(self, command, timeout_time=20,
                                     log_result=False):
    """See RunShellCommand() above.

    Returns:
      The tuple (exit code, list of output lines).
    """
    lines = self.RunShellCommand(
        command + '; echo %$?', timeout_time, log_result)
    last_line = lines[-1]
    status_pos = last_line.rfind('%')
    assert status_pos >= 0
    status = int(last_line[status_pos + 1:])
    if status_pos == 0:
      lines = lines[:-1]
    else:
      lines = lines[:-1] + [last_line[:status_pos]]
    return (status, lines)

  def KillAll(self, process, signum=9, with_su=False):
    """Android version of killall, connected via adb.

    Args:
      process: name of the process to kill off.
      signum: signal to use, 9 (SIGKILL) by default.
      with_su: wether or not to use su to kill the processes.

    Returns:
      the number of processes killed
    """
    pids = self.ExtractPid(process)
    if pids:
      cmd = 'kill -%d %s' % (signum, ' '.join(pids))
      if with_su:
        self.RunShellCommandWithSU(cmd)
      else:
        self.RunShellCommand(cmd)
    return len(pids)

  def KillAllBlocking(self, process, timeout_sec, signum=9, with_su=False):
    """Blocking version of killall, connected via adb.

    This waits until no process matching the corresponding name appears in ps'
    output anymore.

    Args:
      process: name of the process to kill off
      timeout_sec: the timeout in seconds
      signum: same as |KillAll|
      with_su: same as |KillAll|
    Returns:
      the number of processes killed
    """
    processes_killed = self.KillAll(process, signum=signum, with_su=with_su)
    if processes_killed:
      elapsed = 0
      wait_period = 0.1
      # Note that this doesn't take into account the time spent in ExtractPid().
      while self.ExtractPid(process) and elapsed < timeout_sec:
        time.sleep(wait_period)
        elapsed += wait_period
      if elapsed >= timeout_sec:
        return processes_killed - self.ExtractPid(process)
    return processes_killed

  @staticmethod
  def _GetActivityCommand(package, activity, wait_for_completion, action,
                          category, data, extras, trace_file_name, force_stop,
                          flags):
    """Creates command to start |package|'s activity on the device.

    Args - as for StartActivity

    Returns:
      the command to run on the target to start the activity
    """
    cmd = 'am start -a %s' % action
    if force_stop:
      cmd += ' -S'
    if wait_for_completion:
      cmd += ' -W'
    if category:
      cmd += ' -c %s' % category
    if package and activity:
      cmd += ' -n %s/%s' % (package, activity)
    if data:
      cmd += ' -d "%s"' % data
    if extras:
      for key in extras:
        value = extras[key]
        if isinstance(value, str):
          cmd += ' --es'
        elif isinstance(value, bool):
          cmd += ' --ez'
        elif isinstance(value, int):
          cmd += ' --ei'
        else:
          raise NotImplementedError(
              'Need to teach StartActivity how to pass %s extras' % type(value))
        cmd += ' %s %s' % (key, value)
    if trace_file_name:
      cmd += ' --start-profiler ' + trace_file_name
    if flags:
      cmd += ' -f %s' % flags
    return cmd

  def StartActivity(self, package, activity, wait_for_completion=False,
                    action='android.intent.action.VIEW',
                    category=None, data=None,
                    extras=None, trace_file_name=None,
                    force_stop=False, flags=None):
    """Starts |package|'s activity on the device.

    Args:
      package: Name of package to start (e.g. 'com.google.android.apps.chrome').
      activity: Name of activity (e.g. '.Main' or
        'com.google.android.apps.chrome.Main').
      wait_for_completion: wait for the activity to finish launching (-W flag).
      action: string (e.g. "android.intent.action.MAIN"). Default is VIEW.
      category: string (e.g. "android.intent.category.HOME")
      data: Data string to pass to activity (e.g. 'http://www.example.com/').
      extras: Dict of extras to pass to activity. Values are significant.
      trace_file_name: If used, turns on and saves the trace to this file name.
      force_stop: force stop the target app before starting the activity (-S
        flag).
    Returns:
      The output of the underlying command as a list of lines.
    """
    cmd = self._GetActivityCommand(package, activity, wait_for_completion,
                                   action, category, data, extras,
                                   trace_file_name, force_stop, flags)
    return self.RunShellCommand(cmd)

  def StartActivityTimed(self, package, activity, wait_for_completion=False,
                         action='android.intent.action.VIEW',
                         category=None, data=None,
                         extras=None, trace_file_name=None,
                         force_stop=False, flags=None):
    """Starts |package|'s activity on the device, returning the start time

    Args - as for StartActivity

    Returns:
      A tuple containing:
        - the output of the underlying command as a list of lines, and
        - a timestamp string for the time at which the activity started
    """
    cmd = self._GetActivityCommand(package, activity, wait_for_completion,
                                   action, category, data, extras,
                                   trace_file_name, force_stop, flags)
    self.StartMonitoringLogcat()
    out = self.RunShellCommand('log starting activity; ' + cmd)
    activity_started_re = re.compile('.*starting activity.*')
    m = self.WaitForLogMatch(activity_started_re, None)
    assert m
    start_line = m.group(0)
    return (out, GetLogTimestamp(start_line, self.GetDeviceYear()))

  def StartCrashUploadService(self, package):
    # TODO(frankf): We really need a python wrapper around Intent
    # to be shared with StartActivity/BroadcastIntent.
    cmd = (
      'am startservice -a %s.crash.ACTION_FIND_ALL -n '
      '%s/%s.crash.MinidumpUploadService' %
      (constants.PACKAGE_INFO['chrome'].package,
       package,
       constants.PACKAGE_INFO['chrome'].package))
    am_output = self.RunShellCommandWithSU(cmd)
    assert am_output and 'Starting' in am_output[-1], (
        'Service failed to start: %s' % am_output)
    time.sleep(15)

  def BroadcastIntent(self, package, intent, *args):
    """Send a broadcast intent.

    Args:
      package: Name of package containing the intent.
      intent: Name of the intent.
      args: Optional extra arguments for the intent.
    """
    cmd = 'am broadcast -a %s.%s %s' % (package, intent, ' '.join(args))
    self.RunShellCommand(cmd)

  def GoHome(self):
    """Tell the device to return to the home screen. Blocks until completion."""
    self.RunShellCommand('am start -W '
        '-a android.intent.action.MAIN -c android.intent.category.HOME')

  def CloseApplication(self, package):
    """Attempt to close down the application, using increasing violence.

    Args:
      package: Name of the process to kill off, e.g.
      com.google.android.apps.chrome
    """
    self.RunShellCommand('am force-stop ' + package)

  def GetApplicationPath(self, package):
    """Get the installed apk path on the device for the given package.

    Args:
      package: Name of the package.

    Returns:
      Path to the apk on the device if it exists, None otherwise.
    """
    pm_path_output  = self.RunShellCommand('pm path ' + package)
    # The path output contains anything if and only if the package
    # exists.
    if pm_path_output:
      # pm_path_output is of the form: "package:/path/to/foo.apk"
      return pm_path_output[0].split(':')[1]
    else:
      return None

  def ClearApplicationState(self, package):
    """Closes and clears all state for the given |package|."""
    # Check that the package exists before clearing it. Necessary because
    # calling pm clear on a package that doesn't exist may never return.
    pm_path_output  = self.RunShellCommand('pm path ' + package)
    # The path output only contains anything if and only if the package exists.
    if pm_path_output:
      self.RunShellCommand('pm clear ' + package)

  def SendKeyEvent(self, keycode):
    """Sends keycode to the device.

    Args:
      keycode: Numeric keycode to send (see "enum" at top of file).
    """
    self.RunShellCommand('input keyevent %d' % keycode)

  def _RunMd5Sum(self, host_path, device_path):
    """Gets the md5sum of a host path and device path.

    Args:
      host_path: Path (file or directory) on the host.
      device_path: Path on the device.

    Returns:
      A tuple containing lists of the host and device md5sum results as
      created by _ParseMd5SumOutput().
    """
    md5sum_dist_path = os.path.join(constants.GetOutDirectory(),
                                    'md5sum_dist')
    assert os.path.exists(md5sum_dist_path), 'Please build md5sum.'
    md5sum_dist_mtime = os.stat(md5sum_dist_path).st_mtime
    if (md5sum_dist_path not in self._push_if_needed_cache or
        self._push_if_needed_cache[md5sum_dist_path] != md5sum_dist_mtime):
      command = 'push %s %s' % (md5sum_dist_path, MD5SUM_DEVICE_FOLDER)
      assert _HasAdbPushSucceeded(self._adb.SendCommand(command))
      self._push_if_needed_cache[md5sum_dist_path] = md5sum_dist_mtime

    (_, md5_device_output) = self.GetAndroidToolStatusAndOutput(
        self._util_wrapper + ' ' + MD5SUM_DEVICE_PATH + ' ' + device_path,
        lib_path=MD5SUM_DEVICE_FOLDER,
        timeout_time=2 * 60)
    device_hash_tuples = _ParseMd5SumOutput(md5_device_output)
    assert os.path.exists(host_path), 'Local path not found %s' % host_path
    md5sum_output = cmd_helper.GetCmdOutput(
        [os.path.join(constants.GetOutDirectory(), 'md5sum_bin_host'),
         host_path])
    host_hash_tuples = _ParseMd5SumOutput(md5sum_output.splitlines())
    return (host_hash_tuples, device_hash_tuples)

  def GetFilesChanged(self, host_path, device_path, ignore_filenames=False):
    """Compares the md5sum of a host path against a device path.

    Note: Ignores extra files on the device.

    Args:
      host_path: Path (file or directory) on the host.
      device_path: Path on the device.
      ignore_filenames: If True only the file contents are considered when
          checking whether a file has changed, otherwise the relative path
          must also match.

    Returns:
      A list of tuples of the form (host_path, device_path) for files whose
      md5sums do not match.
    """

    # Md5Sum resolves symbolic links in path names so the calculation of
    # relative path names from its output will need the real path names of the
    # base directories. Having calculated these they are used throughout the
    # function since this makes us less subject to any future changes to Md5Sum.
    real_host_path = os.path.realpath(host_path)
    real_device_path = self.RunShellCommand('realpath "%s"' % device_path)[0]

    host_hash_tuples, device_hash_tuples = self._RunMd5Sum(
        real_host_path, real_device_path)

    if len(host_hash_tuples) > len(device_hash_tuples):
      logging.info('%s files do not exist on the device' %
                   (len(host_hash_tuples) - len(device_hash_tuples)))

    host_rel = [(os.path.relpath(os.path.normpath(t.path), real_host_path),
                 t.hash)
                for t in host_hash_tuples]

    if os.path.isdir(real_host_path):
      def RelToRealPaths(rel_path):
        return (os.path.join(real_host_path, rel_path),
                os.path.join(real_device_path, rel_path))
    else:
      assert len(host_rel) == 1
      def RelToRealPaths(_):
        return (real_host_path, real_device_path)

    if ignore_filenames:
      # If we are ignoring file names, then we want to push any file for which
      # a file with an equivalent MD5 sum does not exist on the device.
      device_hashes = set([h.hash for h in device_hash_tuples])
      ShouldPush = lambda p, h: h not in device_hashes
    else:
      # Otherwise, we want to push any file on the host for which a file with
      # an equivalent MD5 sum does not exist at the same relative path on the
      # device.
      device_rel = dict([(os.path.relpath(os.path.normpath(t.path),
                                          real_device_path),
                          t.hash)
                         for t in device_hash_tuples])
      ShouldPush = lambda p, h: p not in device_rel or h != device_rel[p]

    return [RelToRealPaths(path) for path, host_hash in host_rel
            if ShouldPush(path, host_hash)]

  def PushIfNeeded(self, host_path, device_path):
    """Pushes |host_path| to |device_path|.

    Works for files and directories. This method skips copying any paths in
    |test_data_paths| that already exist on the device with the same hash.

    All pushed files can be removed by calling RemovePushedFiles().
    """
    MAX_INDIVIDUAL_PUSHES = 50
    if not os.path.exists(host_path):
      raise device_errors.CommandFailedError(
          'Local path not found %s' % host_path, device=str(self))

    # See if the file on the host changed since the last push (if any) and
    # return early if it didn't. Note that this shortcut assumes that the tests
    # on the device don't modify the files.
    if not os.path.isdir(host_path):
      if host_path in self._push_if_needed_cache:
        host_path_mtime = self._push_if_needed_cache[host_path]
        if host_path_mtime == os.stat(host_path).st_mtime:
          return

    size = host_utils.GetRecursiveDiskUsage(host_path)
    self._pushed_files.append(device_path)
    self._potential_push_size += size

    if os.path.isdir(host_path):
      self.RunShellCommand('mkdir -p "%s"' % device_path)

    changed_files = self.GetFilesChanged(host_path, device_path)
    logging.info('Found %d files that need to be pushed to %s',
        len(changed_files), device_path)
    if not changed_files:
      return

    def Push(host, device):
      # NOTE: We can't use adb_interface.Push() because it hardcodes a timeout
      # of 60 seconds which isn't sufficient for a lot of users of this method.
      push_command = 'push %s %s' % (host, device)
      self._LogShell(push_command)

      # Retry push with increasing backoff if the device is busy.
      retry = 0
      while True:
        output = self._adb.SendCommand(push_command, timeout_time=30 * 60)
        if _HasAdbPushSucceeded(output):
          if not os.path.isdir(host_path):
            self._push_if_needed_cache[host] = os.stat(host).st_mtime
          return
        if retry < 3:
          retry += 1
          wait_time = 5 * retry
          logging.error('Push failed, retrying in %d seconds: %s' %
                        (wait_time, output))
          time.sleep(wait_time)
        else:
          raise Exception('Push failed: %s' % output)

    diff_size = 0
    if len(changed_files) <= MAX_INDIVIDUAL_PUSHES:
      diff_size = sum(host_utils.GetRecursiveDiskUsage(f[0])
                      for f in changed_files)

    # TODO(craigdh): Replace this educated guess with a heuristic that
    # approximates the push time for each method.
    if len(changed_files) > MAX_INDIVIDUAL_PUSHES or diff_size > 0.5 * size:
      self._actual_push_size += size
      Push(host_path, device_path)
    else:
      for f in changed_files:
        Push(f[0], f[1])
      self._actual_push_size += diff_size

  def GetPushSizeInfo(self):
    """Get total size of pushes to the device done via PushIfNeeded()

    Returns:
      A tuple:
        1. Total size of push requests to PushIfNeeded (MB)
        2. Total size that was actually pushed (MB)
    """
    return (self._potential_push_size, self._actual_push_size)

  def GetFileContents(self, filename, log_result=False):
    """Gets contents from the file specified by |filename|."""
    return self.RunShellCommand('cat "%s" 2>/dev/null' % filename,
                                log_result=log_result)

  def SetFileContents(self, filename, contents):
    """Writes |contents| to the file specified by |filename|."""
    with tempfile.NamedTemporaryFile() as f:
      f.write(contents)
      f.flush()
      self._adb.Push(f.name, filename)

  def RunShellCommandWithSU(self, command, timeout_time=20, log_result=False):
    return self.RunShellCommand('su -c %s' % command, timeout_time, log_result)

  def CanAccessProtectedFileContents(self):
    """Returns True if Get/SetProtectedFileContents would work via "su" or adb
    shell running as root.

    Devices running user builds don't have adb root, but may provide "su" which
    can be used for accessing protected files.
    """
    return (self._GetProtectedFileCommandRunner() != None)

  def _GetProtectedFileCommandRunner(self):
    """Finds the best method to access protected files on the device.

    Returns:
      1. None when privileged files cannot be accessed on the device.
      2. Otherwise: A function taking a single parameter: a string with command
         line arguments. Running that function executes the command with
         the appropriate method.
    """
    if self._protected_file_access_method_initialized:
      return self._privileged_command_runner

    self._privileged_command_runner = None
    self._protected_file_access_method_initialized = True

    for cmd in [self.RunShellCommand, self.RunShellCommandWithSU]:
      # Get contents of the auxv vector for the init(8) process from a small
      # binary file that always exists on linux and is always read-protected.
      contents = cmd('cat /proc/1/auxv')
      # The leading 4 or 8-bytes of auxv vector is a_type. There are not many
      # reserved a_type values, hence byte 2 must always be '\0' for a realistic
      # auxv. See /usr/include/elf.h.
      if len(contents) > 0 and (contents[0][2] == '\0'):
        self._privileged_command_runner = cmd
        break
    return self._privileged_command_runner

  def GetProtectedFileContents(self, filename):
    """Gets contents from the protected file specified by |filename|.

    This is potentially less efficient than GetFileContents.
    """
    command = 'cat "%s" 2> /dev/null' % filename
    command_runner = self._GetProtectedFileCommandRunner()
    if command_runner:
      return command_runner(command)
    else:
      logging.warning('Could not access protected file: %s' % filename)
      return []

  def SetProtectedFileContents(self, filename, contents):
    """Writes |contents| to the protected file specified by |filename|.

    This is less efficient than SetFileContents.
    """
    with DeviceTempFile(self) as temp_file:
      with DeviceTempFile(self, suffix=".sh") as temp_script:
        # Put the contents in a temporary file
        self.SetFileContents(temp_file.name, contents)
        # Create a script to copy the file contents to its final destination
        self.SetFileContents(temp_script.name,
                             'cat %s > %s' % (temp_file.name, filename))

        command = 'sh %s' % temp_script.name
        command_runner = self._GetProtectedFileCommandRunner()
        if command_runner:
          return command_runner(command)
        else:
          logging.warning(
              'Could not set contents of protected file: %s' % filename)


  def RemovePushedFiles(self):
    """Removes all files pushed with PushIfNeeded() from the device."""
    for p in self._pushed_files:
      self.RunShellCommand('rm -r %s' % p, timeout_time=2 * 60)

  def ListPathContents(self, path):
    """Lists files in all subdirectories of |path|.

    Args:
      path: The path to list.

    Returns:
      A dict of {"name": (size, lastmod), ...}.
    """
    # Example output:
    # /foo/bar:
    # -rw-r----- user group   102 2011-05-12 12:29:54.131623387 +0100 baz.txt
    re_file = re.compile('^-(?P<perms>[^\s]+)\s+'
                         '(?P<user>[^\s]+)\s+'
                         '(?P<group>[^\s]+)\s+'
                         '(?P<size>[^\s]+)\s+'
                         '(?P<date>[^\s]+)\s+'
                         '(?P<time>[^\s]+)\s+'
                         '(?P<filename>[^\s]+)$')
    return _GetFilesFromRecursiveLsOutput(
        path, self.RunShellCommand('ls -lR %s' % path), re_file,
        self.GetUtcOffset())

  def GetUtcOffset(self):
    if not self._device_utc_offset:
      self._device_utc_offset = self.RunShellCommand('date +%z')[0]
    return self._device_utc_offset

  def SetJavaAssertsEnabled(self, enable):
    """Sets or removes the device java assertions property.

    Args:
      enable: If True the property will be set.

    Returns:
      True if the file was modified (reboot is required for it to take effect).
    """
    # First ensure the desired property is persisted.
    temp_props_file = tempfile.NamedTemporaryFile()
    properties = ''
    if self._adb.Pull(LOCAL_PROPERTIES_PATH, temp_props_file.name):
      with open(temp_props_file.name) as f:
        properties = f.read()
    re_search = re.compile(r'^\s*' + re.escape(JAVA_ASSERT_PROPERTY) +
                           r'\s*=\s*all\s*$', re.MULTILINE)
    if enable != bool(re.search(re_search, properties)):
      re_replace = re.compile(r'^\s*' + re.escape(JAVA_ASSERT_PROPERTY) +
                              r'\s*=\s*\w+\s*$', re.MULTILINE)
      properties = re.sub(re_replace, '', properties)
      if enable:
        properties += '\n%s=all\n' % JAVA_ASSERT_PROPERTY

      file(temp_props_file.name, 'w').write(properties)
      self._adb.Push(temp_props_file.name, LOCAL_PROPERTIES_PATH)

    # Next, check the current runtime value is what we need, and
    # if not, set it and report that a reboot is required.
    was_set = 'all' in self.system_properties[JAVA_ASSERT_PROPERTY]
    if was_set == enable:
      return False
    self.system_properties[JAVA_ASSERT_PROPERTY] = enable and 'all' or ''
    return True

  def GetBuildId(self):
    """Returns the build ID of the system (e.g. JRM79C)."""
    build_id = self.system_properties['ro.build.id']
    assert build_id
    return build_id

  def GetBuildType(self):
    """Returns the build type of the system (e.g. eng)."""
    build_type = self.system_properties['ro.build.type']
    assert build_type
    return build_type

  def GetBuildProduct(self):
    """Returns the build product of the device (e.g. maguro)."""
    build_product = self.system_properties['ro.build.product']
    assert build_product
    return build_product

  def GetProductName(self):
    """Returns the product name of the device (e.g. takju)."""
    name = self.system_properties['ro.product.name']
    assert name
    return name

  def GetBuildFingerprint(self):
    """Returns the build fingerprint of the device."""
    build_fingerprint = self.system_properties['ro.build.fingerprint']
    assert build_fingerprint
    return build_fingerprint

  def GetDescription(self):
    """Returns the description of the system.

    For example, "yakju-userdebug 4.1 JRN54F 364167 dev-keys".
    """
    description = self.system_properties['ro.build.description']
    assert description
    return description

  def GetProductModel(self):
    """Returns the name of the product model (e.g. "Galaxy Nexus") """
    model = self.system_properties['ro.product.model']
    assert model
    return model

  def GetWifiIP(self):
    """Returns the wifi IP on the device."""
    wifi_ip = self.system_properties['dhcp.wlan0.ipaddress']
    # Do not assert here. Devices (e.g. emulators) may not have a WifiIP.
    return wifi_ip

  def GetSubscriberInfo(self):
    """Returns the device subscriber info (e.g. GSM and device ID) as string."""
    iphone_sub = self.RunShellCommand('dumpsys iphonesubinfo')
    # Do not assert here. Devices (e.g. Nakasi on K) may not have iphonesubinfo.
    return '\n'.join(iphone_sub)

  def GetBatteryInfo(self):
    """Returns a {str: str} dict of battery info (e.g. status, level, etc)."""
    battery = self.RunShellCommand('dumpsys battery')
    assert battery
    battery_info = {}
    for line in battery[1:]:
      k, _, v = line.partition(': ')
      battery_info[k.strip()] = v.strip()
    return battery_info

  def GetSetupWizardStatus(self):
    """Returns the status of the device setup wizard (e.g. DISABLED)."""
    status = self.system_properties['ro.setupwizard.mode']
    # On some devices, the status is empty if not otherwise set. In such cases
    # the caller should expect an empty string to be returned.
    return status

  def StartMonitoringLogcat(self, clear=True, logfile=None, filters=None):
    """Starts monitoring the output of logcat, for use with WaitForLogMatch.

    Args:
      clear: If True the existing logcat output will be cleared, to avoiding
             matching historical output lurking in the log.
      filters: A list of logcat filters to be used.
    """
    if clear:
      self.RunShellCommand('logcat -c')
    args = []
    if self._adb._target_arg:
      args += shlex.split(self._adb._target_arg)
    args += ['logcat', '-v', 'threadtime']
    if filters:
      args.extend(filters)
    else:
      args.append('*:v')

    if logfile:
      logfile = NewLineNormalizer(logfile)

    # Spawn logcat and synchronize with it.
    for _ in range(4):
      self._logcat = pexpect.spawn(constants.GetAdbPath(), args, timeout=10,
                                   logfile=logfile)
      if not clear or self.SyncLogCat():
        break
      self._logcat.close(force=True)
    else:
      logging.critical('Error reading from logcat: ' + str(self._logcat.match))
      sys.exit(1)

  def SyncLogCat(self):
    """Synchronize with logcat.

    Synchronize with the monitored logcat so that WaitForLogMatch will only
    consider new message that are received after this point in time.

    Returns:
      True if the synchronization succeeded.
    """
    assert self._logcat
    tag = 'logcat_sync_%s' % time.time()
    self.RunShellCommand('log ' + tag)
    return self._logcat.expect([tag, pexpect.EOF, pexpect.TIMEOUT]) == 0

  def GetMonitoredLogCat(self):
    """Returns an "adb logcat" command as created by pexpected.spawn."""
    if not self._logcat:
      self.StartMonitoringLogcat(clear=False)
    return self._logcat

  def WaitForLogMatch(self, success_re, error_re, clear=False, timeout=10):
    """Blocks until a matching line is logged or a timeout occurs.

    Args:
      success_re: A compiled re to search each line for.
      error_re: A compiled re which, if found, terminates the search for
          |success_re|. If None is given, no error condition will be detected.
      clear: If True the existing logcat output will be cleared, defaults to
          false.
      timeout: Timeout in seconds to wait for a log match.

    Raises:
      pexpect.TIMEOUT after |timeout| seconds without a match for |success_re|
      or |error_re|.

    Returns:
      The re match object if |success_re| is matched first or None if |error_re|
      is matched first.
    """
    logging.info('<<< Waiting for logcat:' + str(success_re.pattern))
    t0 = time.time()
    while True:
      if not self._logcat:
        self.StartMonitoringLogcat(clear)
      try:
        while True:
          # Note this will block for upto the timeout _per log line_, so we need
          # to calculate the overall timeout remaining since t0.
          time_remaining = t0 + timeout - time.time()
          if time_remaining < 0:
            raise pexpect.TIMEOUT(self._logcat)
          self._logcat.expect(PEXPECT_LINE_RE, timeout=time_remaining)
          line = self._logcat.match.group(1)
          if error_re:
            error_match = error_re.search(line)
            if error_match:
              return None
          success_match = success_re.search(line)
          if success_match:
            return success_match
          logging.info('<<< Skipped Logcat Line:' + str(line))
      except pexpect.TIMEOUT:
        raise pexpect.TIMEOUT(
            'Timeout (%ds) exceeded waiting for pattern "%s" (tip: use -vv '
            'to debug)' %
            (timeout, success_re.pattern))
      except pexpect.EOF:
        # It seems that sometimes logcat can end unexpectedly. This seems
        # to happen during Chrome startup after a reboot followed by a cache
        # clean. I don't understand why this happens, but this code deals with
        # getting EOF in logcat.
        logging.critical('Found EOF in adb logcat. Restarting...')
        # Rerun spawn with original arguments. Note that self._logcat.args[0] is
        # the path of adb, so we don't want it in the arguments.
        self._logcat = pexpect.spawn(constants.GetAdbPath(),
                                     self._logcat.args[1:],
                                     timeout=self._logcat.timeout,
                                     logfile=self._logcat.logfile)

  def StartRecordingLogcat(self, clear=True, filters=None):
    """Starts recording logcat output to eventually be saved as a string.

    This call should come before some series of tests are run, with either
    StopRecordingLogcat or SearchLogcatRecord following the tests.

    Args:
      clear: True if existing log output should be cleared.
      filters: A list of logcat filters to be used.
    """
    if not filters:
      filters = ['*:v']
    if clear:
      self._adb.SendCommand('logcat -c')
    logcat_command = 'adb %s logcat -v threadtime %s' % (self._adb._target_arg,
                                                         ' '.join(filters))
    self._logcat_tmpoutfile = tempfile.NamedTemporaryFile(bufsize=0)
    self.logcat_process = subprocess.Popen(logcat_command, shell=True,
                                           stdout=self._logcat_tmpoutfile)

  def GetCurrentRecordedLogcat(self):
    """Return the current content of the logcat being recorded.
       Call this after StartRecordingLogcat() and before StopRecordingLogcat().
       This can be useful to perform timed polling/parsing.
    Returns:
       Current logcat output as a single string, or None if
       StopRecordingLogcat() was already called.
    """
    if not self._logcat_tmpoutfile:
      return None

    with open(self._logcat_tmpoutfile.name) as f:
      return f.read()

  def StopRecordingLogcat(self):
    """Stops an existing logcat recording subprocess and returns output.

    Returns:
      The logcat output as a string or an empty string if logcat was not
      being recorded at the time.
    """
    if not self.logcat_process:
      return ''
    # Cannot evaluate directly as 0 is a possible value.
    # Better to read the self.logcat_process.stdout before killing it,
    # Otherwise the communicate may return incomplete output due to pipe break.
    if self.logcat_process.poll() is None:
      self.logcat_process.kill()
    self.logcat_process.wait()
    self.logcat_process = None
    self._logcat_tmpoutfile.seek(0)
    output = self._logcat_tmpoutfile.read()
    self._logcat_tmpoutfile.close()
    self._logcat_tmpoutfile = None
    return output

  @staticmethod
  def SearchLogcatRecord(record, message, thread_id=None, proc_id=None,
                         log_level=None, component=None):
    """Searches the specified logcat output and returns results.

    This method searches through the logcat output specified by record for a
    certain message, narrowing results by matching them against any other
    specified criteria.  It returns all matching lines as described below.

    Args:
      record: A string generated by Start/StopRecordingLogcat to search.
      message: An output string to search for.
      thread_id: The thread id that is the origin of the message.
      proc_id: The process that is the origin of the message.
      log_level: The log level of the message.
      component: The name of the component that would create the message.

    Returns:
      A list of dictionaries represeting matching entries, each containing keys
      thread_id, proc_id, log_level, component, and message.
    """
    if thread_id:
      thread_id = str(thread_id)
    if proc_id:
      proc_id = str(proc_id)
    results = []
    reg = re.compile('(\d+)\s+(\d+)\s+([A-Z])\s+([A-Za-z]+)\s*:(.*)$',
                     re.MULTILINE)
    log_list = reg.findall(record)
    for (tid, pid, log_lev, comp, msg) in log_list:
      if ((not thread_id or thread_id == tid) and
          (not proc_id or proc_id == pid) and
          (not log_level or log_level == log_lev) and
          (not component or component == comp) and msg.find(message) > -1):
        match = dict({'thread_id': tid, 'proc_id': pid,
                      'log_level': log_lev, 'component': comp,
                      'message': msg})
        results.append(match)
    return results

  def ExtractPid(self, process_name):
    """Extracts Process Ids for a given process name from Android Shell.

    Args:
      process_name: name of the process on the device.

    Returns:
      List of all the process ids (as strings) that match the given name.
      If the name of a process exactly matches the given name, the pid of
      that process will be inserted to the front of the pid list.
    """
    pids = []
    for line in self.RunShellCommand('ps', log_result=False):
      data = line.split()
      try:
        if process_name in data[-1]:  # name is in the last column
          if process_name == data[-1]:
            pids.insert(0, data[1])  # PID is in the second column
          else:
            pids.append(data[1])
      except IndexError:
        pass
    return pids

  def GetIoStats(self):
    """Gets cumulative disk IO stats since boot (for all processes).

    Returns:
      Dict of {num_reads, num_writes, read_ms, write_ms} or None if there
      was an error.
    """
    IoStats = collections.namedtuple(
        'IoStats',
        ['device',
         'num_reads_issued',
         'num_reads_merged',
         'num_sectors_read',
         'ms_spent_reading',
         'num_writes_completed',
         'num_writes_merged',
         'num_sectors_written',
         'ms_spent_writing',
         'num_ios_in_progress',
         'ms_spent_doing_io',
         'ms_spent_doing_io_weighted',
        ])

    for line in self.GetFileContents('/proc/diskstats', log_result=False):
      fields = line.split()
      stats = IoStats._make([fields[2]] + [int(f) for f in fields[3:]])
      if stats.device == 'mmcblk0':
        return {
            'num_reads': stats.num_reads_issued,
            'num_writes': stats.num_writes_completed,
            'read_ms': stats.ms_spent_reading,
            'write_ms': stats.ms_spent_writing,
        }
    logging.warning('Could not find disk IO stats.')
    return None

  def GetMemoryUsageForPid(self, pid):
    """Returns the memory usage for given pid.

    Args:
      pid: The pid number of the specific process running on device.

    Returns:
      Dict of {metric:usage_kb}, for the process which has specified pid.
      The metric keys which may be included are: Size, Rss, Pss, Shared_Clean,
      Shared_Dirty, Private_Clean, Private_Dirty, VmHWM.
    """
    showmap = self.RunShellCommand('showmap %d' % pid)
    if not showmap or not showmap[-1].endswith('TOTAL'):
      logging.warning('Invalid output for showmap %s', str(showmap))
      return {}
    items = showmap[-1].split()
    if len(items) != 9:
      logging.warning('Invalid TOTAL for showmap %s', str(items))
      return {}
    usage_dict = collections.defaultdict(int)
    usage_dict.update({
        'Size': int(items[0].strip()),
        'Rss': int(items[1].strip()),
        'Pss': int(items[2].strip()),
        'Shared_Clean': int(items[3].strip()),
        'Shared_Dirty': int(items[4].strip()),
        'Private_Clean': int(items[5].strip()),
        'Private_Dirty': int(items[6].strip()),
    })
    peak_value_kb = 0
    for line in self.GetProtectedFileContents('/proc/%s/status' % pid):
      if not line.startswith('VmHWM:'):  # Format: 'VmHWM: +[0-9]+ kB'
        continue
      peak_value_kb = int(line.split(':')[1].strip().split(' ')[0])
      break
    usage_dict['VmHWM'] = peak_value_kb
    if not peak_value_kb:
      logging.warning('Could not find memory peak value for pid ' + str(pid))

    return usage_dict

  def ProcessesUsingDevicePort(self, device_port):
    """Lists processes using the specified device port on loopback interface.

    Args:
      device_port: Port on device we want to check.

    Returns:
      A list of (pid, process_name) tuples using the specified port.
    """
    tcp_results = self.RunShellCommand('cat /proc/net/tcp', log_result=False)
    tcp_address = '0100007F:%04X' % device_port
    pids = []
    for single_connect in tcp_results:
      connect_results = single_connect.split()
      # Column 1 is the TCP port, and Column 9 is the inode of the socket
      if connect_results[1] == tcp_address:
        socket_inode = connect_results[9]
        socket_name = 'socket:[%s]' % socket_inode
        lsof_results = self.RunShellCommand('lsof', log_result=False)
        for single_process in lsof_results:
          process_results = single_process.split()
          # Ignore the line if it has less than nine columns in it, which may
          # be the case when a process stops while lsof is executing.
          if len(process_results) <= 8:
            continue
          # Column 0 is the executable name
          # Column 1 is the pid
          # Column 8 is the Inode in use
          if process_results[8] == socket_name:
            pids.append((int(process_results[1]), process_results[0]))
        break
    logging.info('PidsUsingDevicePort: %s', pids)
    return pids

  def FileExistsOnDevice(self, file_name):
    """Checks whether the given file exists on the device.

    Args:
      file_name: Full path of file to check.

    Returns:
      True if the file exists, False otherwise.
    """
    assert '"' not in file_name, 'file_name cannot contain double quotes'
    try:
      status = self._adb.SendShellCommand(
          '\'test -e "%s"; echo $?\'' % (file_name))
      if 'test: not found' not in status:
        return int(status) == 0

      status = self._adb.SendShellCommand(
          '\'ls "%s" >/dev/null 2>&1; echo $?\'' % (file_name))
      return int(status) == 0
    except ValueError:
      if IsDeviceAttached(self._device):
        raise errors.DeviceUnresponsiveError('Device may be offline.')

      return False

  def IsFileWritableOnDevice(self, file_name):
    """Checks whether the given file (or directory) is writable on the device.

    Args:
      file_name: Full path of file/directory to check.

    Returns:
      True if writable, False otherwise.
    """
    assert '"' not in file_name, 'file_name cannot contain double quotes'
    try:
      status = self._adb.SendShellCommand(
          '\'test -w "%s"; echo $?\'' % (file_name))
      if 'test: not found' not in status:
        return int(status) == 0
      raise errors.AbortError('"test" binary not found. OS too old.')

    except ValueError:
      if IsDeviceAttached(self._device):
        raise errors.DeviceUnresponsiveError('Device may be offline.')

      return False

  @staticmethod
  def GetTimestamp():
    return time.strftime('%Y-%m-%d-%H%M%S', time.localtime())

  @staticmethod
  def EnsureHostDirectory(host_file):
    host_dir = os.path.dirname(os.path.abspath(host_file))
    if not os.path.exists(host_dir):
      os.makedirs(host_dir)

  def TakeScreenshot(self, host_file=None):
    """Saves a screenshot image to |host_file| on the host.

    Args:
      host_file: Absolute path to the image file to store on the host or None to
                 use an autogenerated file name.

    Returns:
      Resulting host file name of the screenshot.
    """
    host_file = os.path.abspath(host_file or
                                'screenshot-%s.png' % self.GetTimestamp())
    self.EnsureHostDirectory(host_file)
    device_file = '%s/screenshot.png' % self.GetExternalStorage()
    self.RunShellCommand(
        '/system/bin/screencap -p %s' % device_file)
    self.PullFileFromDevice(device_file, host_file)
    self.RunShellCommand('rm -f "%s"' % device_file)
    return host_file

  def PullFileFromDevice(self, device_file, host_file):
    """Download |device_file| on the device from to |host_file| on the host.

    Args:
      device_file: Absolute path to the file to retrieve from the device.
      host_file: Absolute path to the file to store on the host.
    """
    if not self._adb.Pull(device_file, host_file):
      raise device_errors.AdbCommandFailedError(
          ['pull', device_file, host_file], 'Failed to pull file from device.')
    assert os.path.exists(host_file)

  def SetUtilWrapper(self, util_wrapper):
    """Sets a wrapper prefix to be used when running a locally-built
    binary on the device (ex.: md5sum_bin).
    """
    self._util_wrapper = util_wrapper

  def RunUIAutomatorTest(self, test, test_package, timeout):
    """Runs a single uiautomator test.

    Args:
      test: Test class/method.
      test_package: Name of the test jar.
      timeout: Timeout time in seconds.

    Returns:
      An instance of am_instrument_parser.TestResult object.
    """
    cmd = 'uiautomator runtest %s -e class %s' % (test_package, test)
    self._LogShell(cmd)
    output = self._adb.SendShellCommand(cmd, timeout_time=timeout)
    # uiautomator doesn't fully conform to the instrumenation test runner
    # convention and doesn't terminate with INSTRUMENTATION_CODE.
    # Just assume the first result is valid.
    (test_results, _) = am_instrument_parser.ParseAmInstrumentOutput(output)
    if not test_results:
      raise errors.InstrumentationError(
          'no test results... device setup correctly?')
    return test_results[0]

  def DismissCrashDialogIfNeeded(self):
    """Dismiss the error/ANR dialog if present.

    Returns: Name of the crashed package if a dialog is focused,
             None otherwise.
    """
    re_focus = re.compile(
        r'\s*mCurrentFocus.*Application (Error|Not Responding): (\S+)}')

    def _FindFocusedWindow():
      match = None
      for line in self.RunShellCommand('dumpsys window windows'):
        match = re.match(re_focus, line)
        if match:
          break
      return match

    match = _FindFocusedWindow()
    if not match:
      return
    package = match.group(2)
    logging.warning('Trying to dismiss %s dialog for %s' % match.groups())
    self.SendKeyEvent(KEYCODE_DPAD_RIGHT)
    self.SendKeyEvent(KEYCODE_DPAD_RIGHT)
    self.SendKeyEvent(KEYCODE_ENTER)
    match = _FindFocusedWindow()
    if match:
      logging.error('Still showing a %s dialog for %s' % match.groups())
    return package

  def EfficientDeviceDirectoryCopy(self, source, dest):
    """ Copy a directory efficiently on the device

    Uses a shell script running on the target to copy new and changed files the
    source directory to the destination directory and remove added files. This
    is in some cases much faster than cp -r.

    Args:
      source: absolute path of source directory
      dest: absolute path of destination directory
    """
    logging.info('In EfficientDeviceDirectoryCopy %s %s', source, dest)
    with DeviceTempFile(self, suffix=".sh") as temp_script_file:
      host_script_path = os.path.join(constants.DIR_SOURCE_ROOT,
                                      'build',
                                      'android',
                                      'pylib',
                                      'efficient_android_directory_copy.sh')
      self._adb.Push(host_script_path, temp_script_file.name)
      out = self.RunShellCommand(
          'sh %s %s %s' % (temp_script_file.name, source, dest),
          timeout_time=120)
      if self._device:
        device_repr = self._device[-4:]
      else:
        device_repr = '????'
      for line in out:
        logging.info('[%s]> %s', device_repr, line)

  def _GetControlUsbChargingCommand(self):
    if self._control_usb_charging_command['cached']:
      return self._control_usb_charging_command['command']
    self._control_usb_charging_command['cached'] = True
    if not self.IsRootEnabled():
      return None
    for command in CONTROL_USB_CHARGING_COMMANDS:
      # Assert command is valid.
      assert 'disable_command' in command
      assert 'enable_command' in command
      assert 'witness_file' in command
      witness_file = command['witness_file']
      if self.FileExistsOnDevice(witness_file):
        self._control_usb_charging_command['command'] = command
        return command
    return None

  def CanControlUsbCharging(self):
    return self._GetControlUsbChargingCommand() is not None

  def DisableUsbCharging(self, timeout=10):
    command = self._GetControlUsbChargingCommand()
    if not command:
      raise Exception('Unable to act on usb charging.')
    disable_command = command['disable_command']
    t0 = time.time()
    # Do not loop directly on self.IsDeviceCharging to cut the number of calls
    # to the device.
    while True:
      if t0 + timeout - time.time() < 0:
        raise pexpect.TIMEOUT('Unable to disable USB charging in time: %s' % (
            self.GetBatteryInfo()))
      self.RunShellCommand(disable_command)
      if not self.IsDeviceCharging():
        break

  def EnableUsbCharging(self, timeout=10):
    command = self._GetControlUsbChargingCommand()
    if not command:
      raise Exception('Unable to act on usb charging.')
    disable_command = command['enable_command']
    t0 = time.time()
    # Do not loop directly on self.IsDeviceCharging to cut the number of calls
    # to the device.
    while True:
      if t0 + timeout - time.time() < 0:
        raise pexpect.TIMEOUT('Unable to enable USB charging in time.')
      self.RunShellCommand(disable_command)
      if self.IsDeviceCharging():
        break

  def IsDeviceCharging(self):
    for line in self.RunShellCommand('dumpsys battery'):
      if 'powered: ' in line:
        if line.split('powered: ')[1] == 'true':
          return True


class NewLineNormalizer(object):
  """A file-like object to normalize EOLs to '\n'.

  Pexpect runs adb within a pseudo-tty device (see
  http://www.noah.org/wiki/pexpect), so any '\n' printed by adb is written
  as '\r\n' to the logfile. Since adb already uses '\r\n' to terminate
  lines, the log ends up having '\r\r\n' at the end of each line. This
  filter replaces the above with a single '\n' in the data stream.
  """
  def __init__(self, output):
    self._output = output

  def write(self, data):
    data = data.replace('\r\r\n', '\n')
    self._output.write(data)

  def flush(self):
    self._output.flush()
