# Copyright (C) 2012 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import itertools
import logging
import os
import posixpath
import re
import sys
import threading
import time

from blinkpy.common import exit_codes
from blinkpy.common.path_finder import RELATIVE_WEB_TESTS
from blinkpy.common.path_finder import WEB_TESTS_LAST_COMPONENT
from blinkpy.common.path_finder import get_blink_dir
from blinkpy.common.path_finder import get_chromium_src_dir
from blinkpy.common.system.executive import ScriptError
from blinkpy.common.system.profiler import SingleFileOutputProfiler
from blinkpy.web_tests.breakpad.dump_reader_multipart import DumpReaderAndroid
from blinkpy.web_tests.models import test_run_results
from blinkpy.web_tests.port import base
from blinkpy.web_tests.port import linux
from blinkpy.web_tests.port import driver
from blinkpy.web_tests.port import factory
from blinkpy.web_tests.port import server_process

# These are stub globals used for android-specific modules. We
# don't import them unless we actually need a real Android port object,
# in order to not have the dependency on all of the android and catapult
# modules in non-Android ports.
# pylint: disable=invalid-name
battery_utils = None
device_errors = None
device_utils = None
devil_chromium = None
devil_env = None
intent = None
perf_control = None
# pylint: enable=invalid-name

_sanitize_android_tag = lambda t: t.replace('_', '-')

# product constants used by the wpt runner.
ANDROID_WEBLAYER = 'android_weblayer'
ANDROID_WEBVIEW = 'android_webview'
CHROME_ANDROID = 'chrome_android'

PRODUCTS = [ANDROID_WEBLAYER, ANDROID_WEBVIEW, CHROME_ANDROID]

PRODUCTS_TO_STEPNAMES = {
    ANDROID_WEBLAYER: 'weblayer_shell_wpt',
    ANDROID_WEBVIEW: 'system_webview_wpt',
    CHROME_ANDROID: 'chrome_public_wpt',
}

PRODUCTS_TO_BROWSER_TAGS = {
    product: _sanitize_android_tag(product)
    for product in PRODUCTS}

# Android web tests directory, which contains override expectation files
ANDROID_WEB_TESTS_DIR = os.path.join(get_blink_dir(), 'web_tests', 'android')

PRODUCTS_TO_EXPECTATION_FILE_PATHS = {
    ANDROID_WEBLAYER: os.path.join(
        ANDROID_WEB_TESTS_DIR, 'WeblayerWPTExpectations'),
    ANDROID_WEBVIEW: os.path.join(
        ANDROID_WEB_TESTS_DIR, 'WebviewWPTExpectations'),
    CHROME_ANDROID: os.path.join(
        ANDROID_WEB_TESTS_DIR, 'ChromiumWPTExpectations'),
}

# Disabled WPT tests on Android
ANDROID_DISABLED_TESTS = os.path.join(
    ANDROID_WEB_TESTS_DIR, 'AndroidWPTNeverFixTests')

_friendly_browser_names = {
    'weblayershell': 'weblayer',
    'systemwebviewshell': 'webview',
    'chromepublic': 'chromium'
}


def _import_android_packages_if_necessary():
    # pylint: disable=invalid-name
    global battery_utils
    global device_errors
    global device_utils
    global devil_chromium
    global devil_env
    global intent
    global perf_control
    # pylint: enable=invalid-name

    if not battery_utils:
        chromium_src_root = get_chromium_src_dir()
        devil_root = os.path.join(chromium_src_root, 'third_party', 'catapult',
                                  'devil')
        build_android_root = os.path.join(chromium_src_root, 'build',
                                          'android')
        sys.path.insert(0, devil_root)
        sys.path.insert(0, build_android_root)
        from importlib import import_module

        battery_utils = import_module('devil.android.battery_utils')
        devil_env = import_module('devil.devil_env')
        device_errors = import_module('devil.android.device_errors')
        device_utils = import_module('devil.android.device_utils')
        devil_chromium = import_module('devil_chromium')
        intent = import_module('devil.android.sdk.intent')
        perf_control = import_module('devil.android.perf.perf_control')


_log = logging.getLogger(__name__)

# The root directory for test resources, which has the same structure as the
# source root directory of Chromium.
# This path is defined in Chromium's base/test/test_support_android.cc.
DEVICE_SOURCE_ROOT_DIR = '/data/local/tmp/'

# The web tests directory on device, which has two usages:
# 1. as a virtual path in file urls that will be bridged to HTTP.
# 2. pointing to some files that are pushed to the device for tests that
# don't work on file-over-http (e.g. blob protocol tests).
DEVICE_WEB_TESTS_DIR = DEVICE_SOURCE_ROOT_DIR + RELATIVE_WEB_TESTS

KPTR_RESTRICT_PATH = '/proc/sys/kernel/kptr_restrict'

# All the test cases are still served to the test runner through file protocol,
# but we use a file-to-http feature to bridge the file request to host's http
# server to get the real test files and corresponding resources.
# See webkit/support/platform_support_android.cc for the other side of this bridge.
# WEB_TEST_PATH_PREFIX should be matched to the local directory name of
# web_tests because some tests and test_runner find test root directory
# with it.
PERF_TEST_PATH_PREFIX = '/PerformanceTests'
WEB_TESTS_PATH_PREFIX = '/' + WEB_TESTS_LAST_COMPONENT

# We start netcat processes for each of the three stdio streams. In doing so,
# we attempt to use ports starting from 10201. This starting value is
# completely arbitrary.
FIRST_NETCAT_PORT = 10201

# Timeout in seconds to wait for starting/stopping the driver.
DRIVER_START_STOP_TIMEOUT_SECS = 10

# Test resources that need to be accessed as files directly.
# Each item can be the relative path of a directory or a file.
TEST_RESOURCES_TO_PUSH = [
    # Blob tests need to access files directly.
    'editing/pasteboard/resources',
    'fast/files/resources',
    'http/tests/local/resources',
    'http/tests/local/formdata/resources',
    # User style URLs are accessed as local files in webkit_support.
    'http/tests/security/resources/cssStyle.css',
    # Media tests need to access audio/video as files.
    'media/content',
    'compositing/resources/video.mp4',
]


class DriverDetails(object):
    def __init__(self, apk):
        self._apk = apk

    def apk_name(self):
        return self._apk


# Information required when running web tests using content_shell as the test runner.
class ContentShellDriverDetails(DriverDetails):
    def __init__(self):
        super(ContentShellDriverDetails,
              self).__init__('apks/ContentShell.apk')

    def device_cache_directory(self):
        return self.device_directory() + 'cache/'

    def device_fonts_directory(self):
        return self.device_directory() + 'fonts/'

    def device_fifo_directory(self):
        return '/data/data/' + self.package_name() + '/files/'

    def package_name(self):
        return 'org.chromium.content_shell_apk'

    def activity_name(self):
        return self.package_name() + '/.ContentShellActivity'

    def library_name(self):
        return 'libcontent_shell_content_view.so'

    def command_line_file(self):
        return '/data/local/tmp/content-shell-command-line'

    def device_crash_dumps_directory(self):
        return '/data/local/tmp/content-shell-crash-dumps'

    def additional_command_line_flags(self, use_breakpad):
        flags = ['--encode-binary']
        if use_breakpad:
            flags.extend([
                '--enable-crash-reporter',
                '--crash-dumps-dir=%s' % self.device_crash_dumps_directory()
            ])
        return flags

    def device_directory(self):
        return DEVICE_SOURCE_ROOT_DIR + 'content_shell/'


# A class to encapsulate device status and information, such as the DeviceUtils
# instances and whether the device has been set up.
class AndroidDevices(object):
    # Percentage of battery a device needs to have in order for it to be considered
    # to participate in running the web tests.
    MINIMUM_BATTERY_PERCENTAGE = 30

    def __init__(self, default_devices=None, debug_logging=False):
        self._usable_devices = []
        self._default_devices = default_devices
        self._prepared_devices = []
        self._debug_logging = debug_logging

    def prepared_devices(self):
        return self._prepared_devices

    def usable_devices(self, executive):
        if self._usable_devices:
            return self._usable_devices

        if self._default_devices:
            self._usable_devices = [
                device_utils.DeviceUtils(d) for d in self._default_devices
            ]
            return self._usable_devices

        devices = device_utils.DeviceUtils.HealthyDevices()
        self._usable_devices = [
            d for d in devices if
            (battery_utils.BatteryUtils(d).GetBatteryInfo().get('level', 0) >=
             AndroidDevices.MINIMUM_BATTERY_PERCENTAGE and d.IsScreenOn())
        ]

        return self._usable_devices

    def get_device(self, executive, device_index):
        devices = self.usable_devices(executive)
        if device_index >= len(devices):
            raise AssertionError(
                'Device index exceeds number of usable devices.')

        return devices[device_index]

    def is_device_prepared(self, device_serial):
        return device_serial in self._prepared_devices

    def set_device_prepared(self, device_serial):
        self._prepared_devices.append(device_serial)


class AndroidPort(base.Port):
    port_name = 'android'

    # Avoid initializing the adb path [worker count]+1 times by storing it as a static member.
    _adb_path = None

    SUPPORTED_VERSIONS = ('android')

    FALLBACK_PATHS = {
        'kitkat':
        ['android'] + linux.LinuxPort.latest_platform_fallback_path()
    }

    BUILD_REQUIREMENTS_URL = 'https://www.chromium.org/developers/how-tos/android-build-instructions'

    def __init__(self, host, port_name='', apk='', product='', options=None, **kwargs):
        super(AndroidPort, self).__init__(
            host, port_name, options=options, **kwargs)
        self._operating_system = 'android'
        self._version = 'kitkat'
        fs = host.filesystem
        self._local_port = factory.PortFactory(host).get(**kwargs)
        if apk or product:
            self._driver_details = DriverDetails(apk)
            browser_type = fs.splitext(fs.basename(apk))[0].lower()
            self._browser_type = _friendly_browser_names.get(
                browser_type, browser_type)
            self._wpt_product_arg = product
        else:
            # The legacy test runner will be used to run web tests on Android.
            # So we need to initialize several port member variables.
            _import_android_packages_if_necessary()
            self._driver_details = ContentShellDriverDetails()
            self._browser_type = 'content_shell'
            self._debug_logging = self.get_option('android_logging')
            self.server_process_constructor = self._android_server_process_constructor
            self._wpt_product_arg = ''

            if not self.get_option('disable_breakpad'):
                self._dump_reader = DumpReaderAndroid(host, self._build_path())

            # Initialize the AndroidDevices class which tracks available devices.
            default_devices = None
            if hasattr(self._options, 'adb_devices') and len(
                    self._options.adb_devices):
                default_devices = self._options.adb_devices

            self._devices = AndroidDevices(default_devices,
                                           self._debug_logging)

            devil_chromium.Initialize(
                output_directory=self._build_path(),
                adb_path=self._path_from_chromium_base(
                    'third_party', 'android_sdk', 'public', 'platform-tools',
                    'adb'))

            devil_env.config.InitializeLogging(
                logging.DEBUG if self._debug_logging
                and self.get_option('debug_rwt_logging') else logging.WARNING)

            prepared_devices = self.get_option('prepared_devices', [])
            for serial in prepared_devices:
                self._devices.set_device_prepared(serial)

    def bot_expectations(self):
        # TODO(rmhasan) Add bot expectations to WPT metadata.
        return {}

    def expected_test(self, _):
        return

    def get_platform_tags(self):
        tags = {'android'}
        if self._wpt_product_arg:
            tags.add(_sanitize_android_tag(self._wpt_product_arg))
        return frozenset(tags)

    def default_smoke_test_only(self):
        return True

    def additional_driver_flags(self):
        return super(AndroidPort, self).additional_driver_flags() + \
            self._driver_details.additional_command_line_flags(use_breakpad=not self.get_option('disable_breakpad'))

    def _default_timeout_ms(self):
        # Android platform has less computing power than desktop platforms.
        # Using 10 seconds allows us to pass most slow tests which are not
        # marked as slow tests on desktop platforms.
        return 10000

    def driver_stop_timeout(self):
        # The driver doesn't respond to closing stdin, so we might as well stop the driver immediately.
        return 0.0

    def default_child_processes(self):
        usable_devices = self._devices.usable_devices(self._executive)
        if not usable_devices:
            raise test_run_results.TestRunException(
                exit_codes.NO_DEVICES_EXIT_STATUS,
                'Unable to find any attached Android devices.')
        return len(usable_devices)

    def check_build(self, needs_http, printer):
        exit_status = super(AndroidPort, self).check_build(needs_http, printer)
        if exit_status:
            return exit_status

        return self._check_devices(printer)

    def _check_devices(self, printer):

        # Push the executables and other files to the devices; doing this now
        # means we can do this in parallel in the manager process and not mix
        # this in with starting and stopping workers.

        lock = threading.Lock()

        def log_safely(msg, throttled=True):
            if throttled:
                callback = printer.write_throttled_update
            else:
                callback = printer.write_update
            with lock:
                callback('%s' % msg)

        def _setup_device_impl(device):
            log_safely('preparing device', throttled=False)

            if self._devices.is_device_prepared(device.serial):
                return

            device.EnableRoot()
            perf_control.PerfControl(device).SetPerfProfilingMode()

            # Required by webkit_support::GetWebKitRootDirFilePath().
            # Other directories will be created automatically by adb push.
            device.RunShellCommand(
                ['mkdir', '-p', DEVICE_SOURCE_ROOT_DIR + 'chrome'],
                check_return=True)

            # Allow the test driver to get full read and write access to the directory on the device,
            # as well as for the FIFOs. We'll need a world writable directory.
            device.RunShellCommand(
                ['mkdir', '-p',
                 self._driver_details.device_directory()],
                check_return=True)

            # Make sure that the disk cache on the device resets to a clean state.
            device.RunShellCommand(
                ['rm', '-rf',
                 self._driver_details.device_cache_directory()],
                check_return=True)

            device.EnableRoot()
            perf_control.PerfControl(device).SetPerfProfilingMode()

            # Required by webkit_support::GetWebKitRootDirFilePath().
            # Other directories will be created automatically by adb push.
            device.RunShellCommand(
                ['mkdir', '-p', DEVICE_SOURCE_ROOT_DIR + 'chrome'],
                check_return=True)

            # Allow the test driver to get full read and write access to the directory on the device,
            # as well as for the FIFOs. We'll need a world writable directory.
            device.RunShellCommand(
                ['mkdir', '-p',
                 self._driver_details.device_directory()],
                check_return=True)

            # Make sure that the disk cache on the device resets to a clean state.
            device.RunShellCommand(
                ['rm', '-rf',
                 self._driver_details.device_cache_directory()],
                check_return=True)

            device_path = lambda *p: posixpath.join(
                self._driver_details.device_directory(), *p)

            device.Install(self._path_to_driver())

            # Build up a list of what we want to push, including:
            host_device_tuples = []

            # - the custom font files
            # TODO(sergeyu): Rename these files, they can be used on platforms
            # other than Android.
            host_device_tuples.append(
                (self._build_path('test_fonts/android_main_fonts.xml'),
                 device_path('android_main_fonts.xml')))
            host_device_tuples.append(
                (self._build_path('test_fonts/android_fallback_fonts.xml'),
                 device_path('android_fallback_fonts.xml')))
            for font_file in self._get_font_files():
                host_device_tuples.append((font_file,
                                           device_path(
                                               'fonts',
                                               os.path.basename(font_file))))

            # - the test resources
            host_device_tuples.extend(
                (self.host.filesystem.join(self.web_tests_dir(), resource),
                 posixpath.join(DEVICE_WEB_TESTS_DIR, resource))
                for resource in TEST_RESOURCES_TO_PUSH)

            # ... and then push them to the device.
            device.PushChangedFiles(host_device_tuples)

            device.RunShellCommand(
                ['mkdir', '-p',
                 self._driver_details.device_fifo_directory()],
                check_return=True)

            device.RunShellCommand([
                'chmod', '-R', '777',
                self._driver_details.device_directory()
            ],
                                   check_return=True)
            device.RunShellCommand([
                'chmod', '-R', '777',
                self._driver_details.device_fifo_directory()
            ],
                                   check_return=True)

            # Mark this device as having been set up.
            self._devices.set_device_prepared(device.serial)

            log_safely('device prepared', throttled=False)

        def setup_device(device):
            try:
                _setup_device_impl(device)
            except (ScriptError, driver.DeviceFailure,
                    device_errors.CommandFailedError,
                    device_errors.CommandTimeoutError,
                    device_errors.DeviceUnreachableError) as error:
                with lock:
                    _log.warning('[%s] failed to prepare_device: %s',
                                 device.serial, error)

        devices = self._devices.usable_devices(self.host.executive)
        device_utils.DeviceUtils.parallel(devices).pMap(setup_device)

        if not self._devices.prepared_devices():
            _log.error('Could not prepare any devices for testing.')
            return exit_codes.NO_DEVICES_EXIT_STATUS
        return exit_codes.OK_EXIT_STATUS

    def setup_test_run(self):
        super(AndroidPort, self).setup_test_run()

        # By setting this on the options object, we can propagate the list
        # of prepared devices to the workers (it is read in __init__()).
        if self._devices._prepared_devices:
            self._options.prepared_devices = self._devices.prepared_devices()
        else:
            # We were called with --no-build, so assume the devices are up to date.
            self._options.prepared_devices = [
                d.get_serial()
                for d in self._devices.usable_devices(self.host.executive)
            ]

    def num_workers(self, requested_num_workers):
        return min(len(self._options.prepared_devices), requested_num_workers)

    def check_sys_deps(self):
        # _get_font_files() will throw if any of the required fonts is missing.
        self._get_font_files()
        return exit_codes.OK_EXIT_STATUS

    def requires_http_server(self):
        """Chromium Android runs tests on devices, and uses the HTTP server to
        serve the actual web tests to the test driver.
        """
        return True

    def start_http_server(self, additional_dirs, number_of_drivers):
        additional_dirs[PERF_TEST_PATH_PREFIX] = self._perf_tests_dir()
        additional_dirs[WEB_TESTS_PATH_PREFIX] = self.web_tests_dir()
        super(AndroidPort, self).start_http_server(additional_dirs,
                                                   number_of_drivers)

    def create_driver(self, worker_number, no_timeout=False):
        return ChromiumAndroidDriver(
            self,
            worker_number,
            driver_details=self._driver_details,
            android_devices=self._devices,
            # Force no timeout to avoid test driver timeouts before NRWT.
            no_timeout=True)

    def driver_cmd_line(self):
        # Override to return the actual test driver's command line.
        return self.create_driver(0)._android_driver_cmd_line([])

    def clobber_old_port_specific_results(self):
        if not self.get_option('disable_breakpad'):
            self._dump_reader.clobber_old_results()

    # Overridden protected methods.

    def _build_path(self, *comps):
        return self._local_port._build_path(*comps)

    def _build_path_with_target(self, target, *comps):
        return self._local_port._build_path_with_target(target, *comps)

    def path_to_apache(self):
        return self._local_port.path_to_apache()

    def path_to_apache_config_file(self):
        return self._local_port.path_to_apache_config_file()

    def _path_to_driver(self, target=None):
        return self._build_path_with_target(target,
                                            self._driver_details.apk_name())

    def _path_to_image_diff(self):
        return self._local_port._path_to_image_diff()

    def _shut_down_http_server(self, pid):
        return self._local_port._shut_down_http_server(pid)

    def _driver_class(self):
        return ChromiumAndroidDriver

    # Local private methods.

    @staticmethod
    def _android_server_process_constructor(port,
                                            server_name,
                                            cmd_line,
                                            env=None,
                                            more_logging=False):
        return server_process.ServerProcess(
            port,
            server_name,
            cmd_line,
            env,
            treat_no_data_as_crash=True,
            more_logging=more_logging)


class AndroidPerf(SingleFileOutputProfiler):
    _cached_perf_host_path = None
    _have_searched_for_perf_host = False

    def __init__(self,
                 host,
                 executable_path,
                 output_dir,
                 device,
                 symfs_path,
                 kallsyms_path,
                 identifier=None):
        super(AndroidPerf, self).__init__(host, executable_path, output_dir,
                                          'data', identifier)
        self._device = device
        self._perf_process = None
        self._symfs_path = symfs_path
        self._kallsyms_path = kallsyms_path

    def check_configuration(self):
        # Check that perf is installed
        if not self._device.PathExists('/system/bin/perf'):
            _log.error('Cannot find /system/bin/perf on device %s',
                       self._device.serial)
            return False

        # Check that the device is a userdebug build (or at least has the necessary libraries).
        if self._device.build_type != 'userdebug':
            _log.error(
                'Device %s is not flashed with a userdebug build of Android',
                self._device.serial)
            return False

        # FIXME: Check that the binary actually is perf-able (has stackframe pointers)?
        # objdump -s a function and make sure it modifies the fp?
        # Instruct users to rebuild after export GYP_DEFINES="profiling=1 $GYP_DEFINES"
        return True

    def print_setup_instructions(self):
        _log.error("""
perf on android requires a 'userdebug' build of Android, see:
http://source.android.com/source/building-devices.html"

The perf command can be built from:
https://android.googlesource.com/platform/external/linux-tools-perf/
and requires libefl, libebl, libdw, and libdwfl available in:
https://android.googlesource.com/platform/external/elfutils/

The test driver must be built with profiling=1, make sure you've done:
export GYP_DEFINES="profiling=1 $GYP_DEFINES"
update-webkit --chromium-android
build-webkit --chromium-android

Googlers should read:
http://goto.google.com/cr-android-perf-howto
""")

    def attach_to_pid(self, pid):
        assert pid
        assert self._perf_process is None
        # FIXME: This can't be a fixed timeout!
        cmd = [
            self._device.adb.GetAdbPath(), '-s', self._device.serial, 'shell',
            'perf', 'record', '-g', '-p', pid, 'sleep', 30
        ]
        self._perf_process = self._host.executive.popen(cmd)

    def _perf_version_string(self, perf_path):
        try:
            return self._host.executive.run_command([perf_path, '--version'])
        except:
            return None

    def _find_perfhost_binary(self):
        perfhost_version = self._perf_version_string('perfhost_linux')
        if perfhost_version:
            return 'perfhost_linux'
        perf_version = self._perf_version_string('perf')
        if perf_version:
            return 'perf'
        return None

    def _perfhost_path(self):
        if self._have_searched_for_perf_host:
            return self._cached_perf_host_path
        self._have_searched_for_perf_host = True
        self._cached_perf_host_path = self._find_perfhost_binary()
        return self._cached_perf_host_path

    def _first_ten_lines_of_profile(self, perf_output):
        match = re.search(r"^#[^\n]*\n((?: [^\n]*\n){1,10})", perf_output,
                          re.MULTILINE)
        return match.group(1) if match else None

    def profile_after_exit(self):
        perf_exitcode = self._perf_process.wait()
        if perf_exitcode != 0:
            _log.debug("Perf failed (exit code: %i), can't process results.",
                       perf_exitcode)
            return

        self._device.PullFile('/data/perf.data', self._output_path)

        perfhost_path = self._perfhost_path()
        perfhost_report_command = [
            'report',
            '--input',
            self._output_path,
            '--symfs',
            self._symfs_path,
            '--kallsyms',
            self._kallsyms_path,
        ]
        if perfhost_path:
            perfhost_args = ([perfhost_path] + perfhost_report_command +
                             ['--call-graph', 'none'])
            perf_output = self._host.executive.run_command(perfhost_args)
            # We could save off the full -g report to a file if users found that useful.
            _log.debug(self._first_ten_lines_of_profile(perf_output))
        else:
            _log.debug("""
Failed to find perfhost_linux binary, can't process samples from the device.

perfhost_linux can be built from:
https://android.googlesource.com/platform/external/linux-tools-perf/
also, modern versions of perf (available from apt-get install goobuntu-kernel-tools-common)
may also be able to process the perf.data files from the device.

Googlers should read:
http://goto.google.com/cr-android-perf-howto
for instructions on installing pre-built copies of perfhost_linux
http://crbug.com/165250 discusses making these pre-built binaries externally available.
""")

        perfhost_display_patch = perfhost_path if perfhost_path else 'perfhost_linux'
        _log.debug('To view the full profile, run:')
        _log.debug(
            ' '.join([perfhost_display_patch] + perfhost_report_command))


class ChromiumAndroidDriver(driver.Driver):
    def __init__(self,
                 port,
                 worker_number,
                 driver_details,
                 android_devices,
                 no_timeout=False):
        super(ChromiumAndroidDriver, self).__init__(port, worker_number,
                                                    no_timeout)
        self._write_stdin_process = None
        self._read_stdout_process = None
        self._read_stderr_process = None
        self._original_kptr_restrict = None

        self._android_devices = android_devices
        self._device = android_devices.get_device(
            port._executive,  # pylint: disable=protected-access
            worker_number)
        self._driver_details = driver_details
        self._debug_logging = self._port._debug_logging
        self._created_cmd_line = False
        self._device_failed = False

        # FIXME: If we taught ProfileFactory about "target" devices we could
        # just use the logic in Driver instead of duplicating it here.
        if self._port.get_option('profile'):
            # FIXME: This should be done once, instead of per-driver!
            symfs_path = self._find_or_create_symfs()
            kallsyms_path = self._update_kallsyms_cache(symfs_path)
            # FIXME: We should pass this some sort of "Bridge" object abstraction around ADB instead of a path/device pair.
            self._profiler = AndroidPerf(self._port.host,
                                         self._port._path_to_driver(),
                                         self._port.artifacts_directory(),
                                         self._device, symfs_path,
                                         kallsyms_path)
            # FIXME: This is a layering violation and should be moved to Port.check_sys_deps
            # once we have an abstraction around an adb_path/device_serial pair to make it
            # easy to make these class methods on AndroidPerf.
            if not self._profiler.check_configuration():
                self._profiler.print_setup_instructions()
                sys.exit(1)
        else:
            self._profiler = None

    def __del__(self):
        self._teardown_performance()
        self._clean_up_cmd_line()
        super(ChromiumAndroidDriver, self).__del__()

    def _update_kallsyms_cache(self, output_dir):
        kallsyms_name = '%s-kallsyms' % self._device.serial
        kallsyms_cache_path = self._port.host.filesystem.join(
            output_dir, kallsyms_name)

        self._device.EnableRoot()

        saved_kptr_restrict = self._device.ReadFile(KPTR_RESTRICT_PATH).strip()
        self._device.WriteFile(KPTR_RESTRICT_PATH, '0')

        _log.debug('Updating kallsyms file (%s) from device',
                   kallsyms_cache_path)
        self._device.PullFile('/proc/kallsysm', kallsyms_cache_path)
        self._device.WriteFile(KPTR_RESTRICT_PATH, saved_kptr_restrict)

        return kallsyms_cache_path

    def _find_or_create_symfs(self):
        env = self._port.host.environ.copy()
        fs = self._port.host.filesystem

        if 'ANDROID_SYMFS' in env:
            symfs_path = env['ANDROID_SYMFS']
        else:
            symfs_path = fs.join(self._port.artifacts_directory(), 'symfs')
            _log.debug('ANDROID_SYMFS not set, using %s', symfs_path)

        # find the installed path, and the path of the symboled built library
        # FIXME: We should get the install path from the device!
        symfs_library_path = fs.join(
            symfs_path,
            'data/app-lib/%s-1/%s' % (self._driver_details.package_name(),
                                      self._driver_details.library_name()))
        built_library_path = self._port._build_path(
            'lib', self._driver_details.library_name())
        assert fs.exists(built_library_path)

        # FIXME: Ideally we'd check the sha1's first and make a soft-link instead
        # of copying (since we probably never care about windows).
        _log.debug('Updating symfs library (%s) from built copy (%s)',
                   symfs_library_path, built_library_path)
        fs.maybe_make_directory(fs.dirname(symfs_library_path))
        fs.copyfile(built_library_path, symfs_library_path)

        return symfs_path

    def _log_error(self, message):
        _log.error('[%s] %s', self._device.serial, message)

    def _log_warning(self, message):
        _log.warning('[%s] %s', self._device.serial, message)

    def _log_debug(self, message):
        if self._debug_logging:
            _log.debug('[%s] %s', self._device.serial, message)

    def _abort(self, message):
        self._device_failed = True
        raise driver.DeviceFailure('[%s] %s' % (self._device.serial, message))

    def _get_last_stacktrace(self):
        try:
            tombstones = self._device.RunShellCommand(
                'ls -n /data/tombstones/tombstone_*',
                check_return=True,
                shell=True)
        except device_errors.CommandFailedError as exc:
            # FIXME: crbug.com/321489 ... figure out why we sometimes get
            #   permission denied.
            self._log_error(
                'The driver crashed, but we were unable to read a tombstone: %s'
                % str(exc))
            return ''

        last_tombstone = None
        for tombstone in tombstones:
            # Format of fields:
            # 0          1      2      3     4          5     6
            # permission uid    gid    size  date       time  filename
            # -rw------- 1000   1000   45859 2011-04-13 06:00 tombstone_00
            fields = tombstone.split()
            if len(fields) != 7:
                self._log_warning(
                    "unexpected line in tombstone output, skipping: '%s'" %
                    tombstone)
                continue

            if (not last_tombstone or fields[4] + fields[5] >=
                    last_tombstone[4] + last_tombstone[5]):
                last_tombstone = fields
            else:
                break

        if not last_tombstone:
            self._log_error(
                'The driver crashed, but we could not find any valid tombstone!'
            )
            return ''

        # Use Android tool vendor/google/tools/stack to convert the raw
        # stack trace into a human readable format, if needed.
        # It takes a long time, so don't do it here.
        tombstone_contents = self._device.ReadFile(
            '/data/tombstones/%s' % last_tombstone[6])
        return '%s\n%s' % (' '.join(last_tombstone), tombstone_contents)

    def _get_logcat(self):
        return '\n'.join(
            self._device.adb.Logcat(dump=True, logcat_format='threadtime'))

    def _teardown_performance(self):
        perf_control.PerfControl(self._device).SetDefaultPerfMode()

    def _get_crash_log(self, stdout, stderr, newer_than):
        if not stdout:
            stdout = ''
        stdout += '********* [%s] Logcat:\n%s' % (self._device.serial,
                                                  self._get_logcat())
        if not stderr:
            stderr = ''
        stderr += '********* [%s] Tombstone file:\n%s' % (
            self._device.serial, self._get_last_stacktrace())

        if not self._port.get_option('disable_breakpad'):
            crashes = self._pull_crash_dumps_from_device()
            for crash in crashes:
                stack = self._port._dump_reader._get_stack_from_dump(crash)  # pylint: disable=protected-access
                try:
                    stack_str = stack.encode('ascii', 'replace')
                except Exception as e:
                    stack_str = '<No Stack> (%s)' % e
                stderr += '********* [%s] breakpad minidump %s:\n%s' % (
                    self._port.host.filesystem.basename(crash),
                    self._device.serial, stack_str)

        return super(ChromiumAndroidDriver, self)._get_crash_log(
            stdout, stderr, newer_than)

    def cmd_line(self, per_test_args):
        # The returned command line is used to start _server_process. In our case, it's an interactive 'adb shell'.
        # The command line passed to the driver process is returned by _driver_cmd_line() instead.
        return [
            self._device.adb.GetAdbPath(), '-s', self._device.serial, 'shell'
        ]

    def _android_driver_cmd_line(self, per_test_args):
        return driver.Driver.cmd_line(self, per_test_args)

    @staticmethod
    def _loop_with_timeout(condition, timeout_secs):
        deadline = time.time() + timeout_secs
        while time.time() < deadline:
            if condition():
                return True
        return False

    def start(self, per_test_args, deadline):
        # We override the default start() so that we can call _android_driver_cmd_line()
        # instead of cmd_line().
        new_cmd_line = self._android_driver_cmd_line(per_test_args)

        # Since _android_driver_cmd_line() is different than cmd_line() we need to provide
        # our own mechanism for detecting when the process should be stopped.
        if self._current_cmd_line is None:
            self._current_android_cmd_line = None
        if new_cmd_line != self._current_android_cmd_line:
            self.stop()
        self._current_android_cmd_line = new_cmd_line

        super(ChromiumAndroidDriver, self).start(per_test_args, deadline)

    def _start(self, per_test_args):
        if not self._android_devices.is_device_prepared(self._device.serial):
            raise driver.DeviceFailure(
                '%s is not prepared in _start()' % self._device.serial)

        for retries in range(3):
            try:
                if self._start_once(per_test_args):
                    return
            except ScriptError as error:
                self._abort('ScriptError("%s") in _start()' % error)

            self._log_error(
                'Failed to start the content_shell application. Retries=%d. Log:\n%s'
                % (retries, self._get_logcat()))
            self.stop()
            time.sleep(2)
        self._abort(
            'Failed to start the content_shell application multiple times. Giving up.'
        )

    def _start_once(self, per_test_args):
        super(ChromiumAndroidDriver, self)._start(
            per_test_args, wait_for_ready=False)

        self._device.adb.Logcat(clear=True)

        self._create_device_crash_dumps_directory()

        # Read back the shell prompt to ensure adb shell is ready.
        deadline = time.time() + DRIVER_START_STOP_TIMEOUT_SECS
        self._server_process.start()
        self._read_prompt(deadline)
        self._log_debug('Interactive shell started')

        # Start a netcat process to which the test driver will connect to write stdout.
        self._read_stdout_process, stdout_port = self._start_netcat(
            'ReadStdout', read_from_stdin=False)
        self._log_debug('Redirecting stdout to port %d' % stdout_port)

        # Start a netcat process to which the test driver will connect to write stderr.
        self._read_stderr_process, stderr_port = self._start_netcat(
            'ReadStderr', first_port=stdout_port + 1, read_from_stdin=False)
        self._log_debug('Redirecting stderr to port %d' % stderr_port)

        # Start a netcat process to which the test driver will connect to read stdin.
        self._write_stdin_process, stdin_port = self._start_netcat(
            'WriteStdin', first_port=stderr_port + 1)
        self._log_debug('Redirecting stdin to port %d' % stdin_port)

        # Combine the stdin, stdout, and stderr pipes into self._server_process.
        self._replace_server_process_streams()

        # We delay importing forwarder as long as possible because it uses fcntl,
        # which isn't available on windows.
        from devil.android import forwarder

        self._log_debug('Starting forwarder')
        forwarder.Forwarder.Map([(p, p) for p in base.Port.SERVER_PORTS],
                                self._device)
        forwarder.Forwarder.Map(
            [(forwarder.DYNAMIC_DEVICE_PORT, p)
             for p in (stdout_port, stderr_port, stdin_port)], self._device)

        cmd_line_file_path = self._driver_details.command_line_file()
        original_cmd_line_file_path = cmd_line_file_path + '.orig'
        if (self._device.PathExists(cmd_line_file_path)
                and not self._device.PathExists(original_cmd_line_file_path)):
            # We check for both the normal path and the backup because we do not want to step
            # on the backup. Otherwise, we'd clobber the backup whenever we changed the
            # command line during the run.
            self._device.RunShellCommand(
                ['mv', cmd_line_file_path, original_cmd_line_file_path],
                check_return=True)

        stream_port_args = [
            '--android-stderr-port=%s' %
            forwarder.Forwarder.DevicePortForHostPort(stderr_port),
            '--android-stdin-port=%s' %
            forwarder.Forwarder.DevicePortForHostPort(stdin_port),
            '--android-stdout-port=%s' %
            forwarder.Forwarder.DevicePortForHostPort(stdout_port),
        ]
        cmd_line_contents = self._android_driver_cmd_line(per_test_args +
                                                          stream_port_args)
        self._device.WriteFile(self._driver_details.command_line_file(),
                               ' '.join(cmd_line_contents))
        self._log_debug(
            'Command-line file contents: %s' % ' '.join(cmd_line_contents))
        self._created_cmd_line = True

        try:
            self._device.StartActivity(
                intent.Intent(
                    component=self._driver_details.activity_name(),
                    extras={'RunInSubThread': None}))
        except device_errors.CommandFailedError as exc:
            self._log_error(
                'Failed to start the content_shell application. Exception:\n' +
                str(exc))
            return False

        # The test driver might crash during startup.
        if not self._wait_for_server_process_output(self._server_process,
                                                    deadline, '#READY'):
            return False

        self._log_debug('content_shell is ready')
        return True

    def _create_device_crash_dumps_directory(self):
        self._device.RunShellCommand(
            ['rm', '-rf',
             self._driver_details.device_crash_dumps_directory()],
            check_return=True)
        self._device.RunShellCommand(
            ['mkdir',
             self._driver_details.device_crash_dumps_directory()],
            check_return=True)
        self._device.RunShellCommand([
            'chmod', '-R', '777',
            self._driver_details.device_crash_dumps_directory()
        ],
                                     check_return=True)

    def _start_netcat(self,
                      server_name,
                      first_port=FIRST_NETCAT_PORT,
                      read_from_stdin=True):
        for i in itertools.count(first_port, 65536):
            nc_cmd = ['nc', '-l', str(i)]
            if not read_from_stdin:
                nc_cmd.append('-d')
            proc = self._port.server_process_constructor(
                self._port, server_name, nc_cmd)
            proc.start()
            self._port.host.executive.wait_limited(
                proc.pid(), limit_in_seconds=1)
            if self._port.host.executive.check_running_pid(proc.pid()):
                return (proc, i)

        raise Exception(
            'Unable to find a port for netcat process %s' % server_name)

    def _replace_server_process_streams(self):
        # pylint: disable=protected-access
        self._server_process.replace_input(
            self._write_stdin_process._proc.stdin)
        self._server_process.replace_outputs(
            self._read_stdout_process._proc.stdout,
            self._read_stderr_process._proc.stdout)

    def _pid_on_target(self):
        pids = self._device.GetPids(self._driver_details.package_name())
        return pids.get(self._driver_details.package_name())

    def stop(self):
        if not self._device_failed:
            # Do not try to stop the application if there's something wrong with the device; adb may hang.
            # FIXME: crbug.com/305040. Figure out if it's really hanging (and why).
            self._device.ForceStop(self._driver_details.package_name())

        if self._write_stdin_process:
            self._write_stdin_process.kill()
            self._write_stdin_process = None

        if self._read_stdout_process:
            self._read_stdout_process.kill()
            self._read_stdout_process = None

        if self._read_stderr_process:
            self._read_stderr_process.kill()
            self._read_stderr_process = None

        # We delay importing forwarder as long as possible because it uses fcntl,
        # which isn't available on windows.
        from devil.android import forwarder

        forwarder.Forwarder.KillDevice(self._device)
        forwarder.Forwarder.KillHost()

        super(ChromiumAndroidDriver, self).stop()

        self._clean_up_cmd_line()

    def _pull_crash_dumps_from_device(self):
        result = []
        if not self._device.PathExists(
                self._driver_details.device_crash_dumps_directory()):
            return result
        dumps = self._device.ListDirectory(
            self._driver_details.device_crash_dumps_directory())
        for dump in dumps:
            device_dump = '%s/%s' % (
                self._driver_details.device_crash_dumps_directory(), dump)
            local_dump = self._port.host.filesystem.join(
                self._port._dump_reader.crash_dumps_directory(), dump)  # pylint: disable=protected-access

            # FIXME: crbug.com/321489. Figure out why these commands would fail ...
            try:
                self._device.RunShellCommand(['chmod', '777', device_dump],
                                             check_return=True)
                self._device.PullFile(device_dump, local_dump)
                self._device.RunShellCommand(['rm', '-f', device_dump],
                                             check_return=True)
            except device_errors.CommandFailedError:
                pass

            if self._port.host.filesystem.exists(local_dump):
                result.append(local_dump)
        return result

    def _clean_up_cmd_line(self):
        if not self._created_cmd_line:
            return

        cmd_line_file_path = self._driver_details.command_line_file()
        original_cmd_line_file_path = cmd_line_file_path + '.orig'
        if self._device.PathExists(original_cmd_line_file_path):
            self._device.RunShellCommand(
                ['mv', original_cmd_line_file_path, cmd_line_file_path],
                check_return=True)
        elif self._device.PathExists(cmd_line_file_path):
            self._device.RunShellCommand(['rm', cmd_line_file_path],
                                         check_return=True)
        self._created_cmd_line = False

    def _command_from_driver_input(self, driver_input):
        command = super(ChromiumAndroidDriver,
                        self)._command_from_driver_input(driver_input)
        if command.startswith('/'):
            command = 'http://127.0.0.1:8000' + WEB_TESTS_PATH_PREFIX + \
                '/' + self._port.relative_test_filename(command)
        return command

    def _read_prompt(self, deadline):
        last_char = ''
        while True:
            current_char = self._server_process.read_stdout(deadline, 1)
            if current_char == ' ':
                if last_char in ('#', '$'):
                    return
            last_char = current_char
