#!/usr/bin/env python
# Copyright 2017 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.

# Using colorama.Fore/Back/Style members
# pylint: disable=no-member

from __future__ import print_function

import argparse
import collections
import json
import logging
import os
import pipes
import posixpath
import random
import re
import shlex
import sys
import tempfile
import textwrap

import adb_command_line
import devil_chromium
from devil import devil_env
from devil.android import apk_helper
from devil.android import device_errors
from devil.android import device_utils
from devil.android import flag_changer
from devil.android.sdk import adb_wrapper
from devil.android.sdk import intent
from devil.android.sdk import version_codes
from devil.utils import run_tests_helper

with devil_env.SysPath(os.path.join(os.path.dirname(__file__), '..', '..',
                                    'third_party', 'colorama', 'src')):
  import colorama

from incremental_install import installer
from pylib import constants
from pylib.symbols import deobfuscator
from pylib.utils import simpleperf
from pylib.utils import app_bundle_utils

with devil_env.SysPath(os.path.join(os.path.dirname(__file__), '..', '..',
                                    'build', 'android', 'gyp')):
  import bundletool

# Matches messages only on pre-L (Dalvik) that are spammy and unimportant.
_DALVIK_IGNORE_PATTERN = re.compile('|'.join([
    r'^Added shared lib',
    r'^Could not find ',
    r'^DexOpt:',
    r'^GC_',
    r'^Late-enabling CheckJNI',
    r'^Link of class',
    r'^No JNI_OnLoad found in',
    r'^Trying to load lib',
    r'^Unable to resolve superclass',
    r'^VFY:',
    r'^WAIT_',
    ]))

BASE_MODULE = 'base'


def _Colorize(text, style=''):
  return (style
      + text
      + colorama.Style.RESET_ALL)


def _InstallApk(devices, apk, install_dict):
  def install(device):
    if install_dict:
      installer.Install(device, install_dict, apk=apk)
    else:
      device.Install(apk, allow_downgrade=True, reinstall=True)

  logging.info('Installing %sincremental apk.', '' if install_dict else 'non-')
  device_utils.DeviceUtils.parallel(devices).pMap(install)


# A named tuple containing the information needed to convert a bundle into
# an installable .apks archive.
# Fields:
#   bundle_path: Path to input bundle file.
#   bundle_apk_path: Path to output bundle .apks archive file.
#   aapt2_path: Path to aapt2 tool.
#   keystore_path: Path to keystore file.
#   keystore_password: Password for the keystore file.
#   keystore_alias: Signing key name alias within the keystore file.
#   system_image_locales: List of Chromium locales to include in system .apks.
BundleGenerationInfo = collections.namedtuple(
    'BundleGenerationInfo',
    'bundle_path,bundle_apks_path,aapt2_path,keystore_path,keystore_password,'
    'keystore_alias,system_image_locales')


def _GenerateBundleApks(info,
                        output_path,
                        minimal=False,
                        minimal_sdk_version=None,
                        mode=None):
  """Generate an .apks archive from a bundle on demand.

  Args:
    info: A BundleGenerationInfo instance.
    output_path: Path of output .apks archive.
    minimal: Create the minimal set of apks possible (english-only).
    minimal_sdk_version: When minimal=True, use this sdkVersion.
    mode: Build mode, either None, or one of app_bundle_utils.BUILD_APKS_MODES.
  """
  app_bundle_utils.GenerateBundleApks(
      info.bundle_path,
      output_path,
      info.aapt2_path,
      info.keystore_path,
      info.keystore_password,
      info.keystore_alias,
      system_image_locales=info.system_image_locales,
      mode=mode,
      minimal=minimal,
      minimal_sdk_version=minimal_sdk_version)


def _InstallBundle(devices, bundle_apks, package_name, command_line_flags_file,
                   modules, fake_modules):
  # Path Chrome creates after validating fake modules. This needs to be cleared
  # for pushed fake modules to be picked up.
  SPLITCOMPAT_PATH = '/data/data/' + package_name + '/files/splitcompat'
  # Chrome command line flag needed for fake modules to work.
  FAKE_FEATURE_MODULE_INSTALL = '--fake-feature-module-install'

  def ShouldWarnFakeFeatureModuleInstallFlag(device):
    if command_line_flags_file:
      changer = flag_changer.FlagChanger(device, command_line_flags_file)
      return FAKE_FEATURE_MODULE_INSTALL not in changer.GetCurrentFlags()
    return False

  def ClearFakeModules(device):
    if device.PathExists(SPLITCOMPAT_PATH, as_root=True):
      device.RemovePath(
          SPLITCOMPAT_PATH, force=True, recursive=True, as_root=True)
      logging.info('Removed %s', SPLITCOMPAT_PATH)
    else:
      logging.info('Skipped removing nonexistent %s', SPLITCOMPAT_PATH)

  def Install(device):
    ClearFakeModules(device)
    if fake_modules and ShouldWarnFakeFeatureModuleInstallFlag(device):
      # Print warning if command line is not set up for fake modules.
      msg = ('Command line has no %s: Fake modules will be ignored.' %
             FAKE_FEATURE_MODULE_INSTALL)
      print(_Colorize(msg, colorama.Fore.YELLOW + colorama.Style.BRIGHT))

    device.Install(
        bundle_apks,
        modules=modules,
        fake_modules=fake_modules,
        allow_downgrade=True)

  # Basic checks for |modules| and |fake_modules|.
  # * |fake_modules| cannot include 'base'.
  # * If |fake_modules| is given, ensure |modules| includes 'base'.
  # * They must be disjoint (checked by device.Install).
  modules_set = set(modules) if modules else set()
  fake_modules_set = set(fake_modules) if fake_modules else set()
  if BASE_MODULE in fake_modules_set:
    raise Exception('\'-f {}\' is disallowed.'.format(BASE_MODULE))
  if fake_modules_set and BASE_MODULE not in modules_set:
    raise Exception(
        '\'-f FAKE\' must be accompanied by \'-m {}\''.format(BASE_MODULE))

  logging.info('Installing bundle.')
  device_utils.DeviceUtils.parallel(devices).pMap(Install)


def _UninstallApk(devices, install_dict, package_name):
  def uninstall(device):
    if install_dict:
      installer.Uninstall(device, package_name)
    else:
      device.Uninstall(package_name)
  device_utils.DeviceUtils.parallel(devices).pMap(uninstall)


def _IsWebViewProvider(apk_helper_instance):
  meta_data = apk_helper_instance.GetAllMetadata()
  meta_data_keys = [pair[0] for pair in meta_data]
  return 'com.android.webview.WebViewLibrary' in meta_data_keys


def _SetWebViewProvider(devices, package_name):

  def switch_provider(device):
    if device.build_version_sdk < version_codes.NOUGAT:
      logging.error('No need to switch provider on pre-Nougat devices (%s)',
                    device.serial)
    else:
      device.SetWebViewImplementation(package_name)

  device_utils.DeviceUtils.parallel(devices).pMap(switch_provider)


def _NormalizeProcessName(debug_process_name, package_name):
  if not debug_process_name:
    debug_process_name = package_name
  elif debug_process_name.startswith(':'):
    debug_process_name = package_name + debug_process_name
  elif '.' not in debug_process_name:
    debug_process_name = package_name + ':' + debug_process_name
  return debug_process_name


def _LaunchUrl(devices, package_name, argv=None, command_line_flags_file=None,
               url=None, apk=None, wait_for_java_debugger=False,
               debug_process_name=None, nokill=None):
  if argv and command_line_flags_file is None:
    raise Exception('This apk does not support any flags.')
  if url:
    # TODO(agrieve): Launch could be changed to require only package name by
    #     parsing "dumpsys package" rather than relying on the apk.
    if not apk:
      raise Exception('Launching with URL is not supported when using '
                      '--package-name. Use --apk-path instead.')
    view_activity = apk.GetViewActivityName()
    if not view_activity:
      raise Exception('APK does not support launching with URLs.')

  debug_process_name = _NormalizeProcessName(debug_process_name, package_name)

  def launch(device):
    # --persistent is required to have Settings.Global.DEBUG_APP be set, which
    # we currently use to allow reading of flags. https://crbug.com/784947
    if not nokill:
      cmd = ['am', 'set-debug-app', '--persistent', debug_process_name]
      if wait_for_java_debugger:
        cmd[-1:-1] = ['-w']
      # Ignore error since it will fail if apk is not debuggable.
      device.RunShellCommand(cmd, check_return=False)

      # The flags are first updated with input args.
      if command_line_flags_file:
        changer = flag_changer.FlagChanger(device, command_line_flags_file)
        flags = []
        if argv:
          adb_command_line.CheckBuildTypeSupportsFlags(device,
                                                       command_line_flags_file)
          flags = shlex.split(argv)
        try:
          changer.ReplaceFlags(flags)
        except device_errors.AdbShellCommandFailedError:
          logging.exception('Failed to set flags')

    if url is None:
      # Simulate app icon click if no url is present.
      cmd = [
          'am', 'start', '-p', package_name, '-c',
          'android.intent.category.LAUNCHER', '-a', 'android.intent.action.MAIN'
      ]
      device.RunShellCommand(cmd, check_return=True)
    else:
      launch_intent = intent.Intent(action='android.intent.action.VIEW',
                                    activity=view_activity, data=url,
                                    package=package_name)
      device.StartActivity(launch_intent)
  device_utils.DeviceUtils.parallel(devices).pMap(launch)
  if wait_for_java_debugger:
    print('Waiting for debugger to attach to process: ' +
          _Colorize(debug_process_name, colorama.Fore.YELLOW))


def _ChangeFlags(devices, argv, command_line_flags_file):
  if argv is None:
    _DisplayArgs(devices, command_line_flags_file)
  else:
    flags = shlex.split(argv)
    def update(device):
      adb_command_line.CheckBuildTypeSupportsFlags(device,
                                                   command_line_flags_file)
      changer = flag_changer.FlagChanger(device, command_line_flags_file)
      changer.ReplaceFlags(flags)
    device_utils.DeviceUtils.parallel(devices).pMap(update)


def _TargetCpuToTargetArch(target_cpu):
  if target_cpu == 'x64':
    return 'x86_64'
  if target_cpu == 'mipsel':
    return 'mips'
  return target_cpu


def _RunGdb(device, package_name, debug_process_name, pid, output_directory,
            target_cpu, port, ide, verbose):
  if not pid:
    debug_process_name = _NormalizeProcessName(debug_process_name, package_name)
    pid = device.GetApplicationPids(debug_process_name, at_most_one=True)
  if not pid:
    # Attaching gdb makes the app run so slow that it takes *minutes* to start
    # up (as of 2018). Better to just fail than to start & attach.
    raise Exception('App not running.')

  gdb_script_path = os.path.dirname(__file__) + '/adb_gdb'
  cmd = [
      gdb_script_path,
      '--package-name=%s' % package_name,
      '--output-directory=%s' % output_directory,
      '--adb=%s' % adb_wrapper.AdbWrapper.GetAdbPath(),
      '--device=%s' % device.serial,
      '--pid=%s' % pid,
      '--port=%d' % port,
  ]
  if ide:
    cmd.append('--ide')
  # Enable verbose output of adb_gdb if it's set for this script.
  if verbose:
    cmd.append('--verbose')
  if target_cpu:
    cmd.append('--target-arch=%s' % _TargetCpuToTargetArch(target_cpu))
  logging.warning('Running: %s', ' '.join(pipes.quote(x) for x in cmd))
  print(_Colorize('All subsequent output is from adb_gdb script.',
                  colorama.Fore.YELLOW))
  os.execv(gdb_script_path, cmd)


def _PrintPerDeviceOutput(devices, results, single_line=False):
  for d, result in zip(devices, results):
    if not single_line and d is not devices[0]:
      sys.stdout.write('\n')
    sys.stdout.write(
          _Colorize('{} ({}):'.format(d, d.build_description),
                    colorama.Fore.YELLOW))
    sys.stdout.write(' ' if single_line else '\n')
    yield result


def _RunMemUsage(devices, package_name, query_app=False):
  cmd_args = ['dumpsys', 'meminfo']
  if not query_app:
    cmd_args.append('--local')

  def mem_usage_helper(d):
    ret = []
    for process in sorted(_GetPackageProcesses(d, package_name)):
      meminfo = d.RunShellCommand(cmd_args + [str(process.pid)])
      ret.append((process.name, '\n'.join(meminfo)))
    return ret

  parallel_devices = device_utils.DeviceUtils.parallel(devices)
  all_results = parallel_devices.pMap(mem_usage_helper).pGet(None)
  for result in _PrintPerDeviceOutput(devices, all_results):
    if not result:
      print('No processes found.')
    else:
      for name, usage in sorted(result):
        print(_Colorize('==== Output of "dumpsys meminfo %s" ====' % name,
                        colorama.Fore.GREEN))
        print(usage)


def _DuHelper(device, path_spec, run_as=None):
  """Runs "du -s -k |path_spec|" on |device| and returns parsed result.

  Args:
    device: A DeviceUtils instance.
    path_spec: The list of paths to run du on. May contain shell expansions
        (will not be escaped).
    run_as: Package name to run as, or None to run as shell user. If not None
        and app is not android:debuggable (run-as fails), then command will be
        run as root.

  Returns:
    A dict of path->size in KiB containing all paths in |path_spec| that exist
    on device. Paths that do not exist are silently ignored.
  """
  # Example output for: du -s -k /data/data/org.chromium.chrome/{*,.*}
  # 144     /data/data/org.chromium.chrome/cache
  # 8       /data/data/org.chromium.chrome/files
  # <snip>
  # du: .*: No such file or directory

  # The -d flag works differently across android version, so use -s instead.
  # Without the explicit 2>&1, stderr and stdout get combined at random :(.
  cmd_str = 'du -s -k ' + path_spec + ' 2>&1'
  lines = device.RunShellCommand(cmd_str, run_as=run_as, shell=True,
                                 check_return=False)
  output = '\n'.join(lines)
  # run-as: Package 'com.android.chrome' is not debuggable
  if output.startswith('run-as:'):
    # check_return=False needed for when some paths in path_spec do not exist.
    lines = device.RunShellCommand(cmd_str, as_root=True, shell=True,
                                   check_return=False)
  ret = {}
  try:
    for line in lines:
      # du: .*: No such file or directory
      if line.startswith('du:'):
        continue
      size, subpath = line.split(None, 1)
      ret[subpath] = int(size)
    return ret
  except ValueError:
    logging.error('du command was: %s', cmd_str)
    logging.error('Failed to parse du output:\n%s', output)
    raise


def _RunDiskUsage(devices, package_name):
  # Measuring dex size is a bit complicated:
  # https://source.android.com/devices/tech/dalvik/jit-compiler
  #
  # For KitKat and below:
  #   dumpsys package contains:
  #     dataDir=/data/data/org.chromium.chrome
  #     codePath=/data/app/org.chromium.chrome-1.apk
  #     resourcePath=/data/app/org.chromium.chrome-1.apk
  #     nativeLibraryPath=/data/app-lib/org.chromium.chrome-1
  #   To measure odex:
  #     ls -l /data/dalvik-cache/data@app@org.chromium.chrome-1.apk@classes.dex
  #
  # For Android L and M (and maybe for N+ system apps):
  #   dumpsys package contains:
  #     codePath=/data/app/org.chromium.chrome-1
  #     resourcePath=/data/app/org.chromium.chrome-1
  #     legacyNativeLibraryDir=/data/app/org.chromium.chrome-1/lib
  #   To measure odex:
  #     # Option 1:
  #  /data/dalvik-cache/arm/data@app@org.chromium.chrome-1@base.apk@classes.dex
  #  /data/dalvik-cache/arm/data@app@org.chromium.chrome-1@base.apk@classes.vdex
  #     ls -l /data/dalvik-cache/profiles/org.chromium.chrome
  #         (these profiles all appear to be 0 bytes)
  #     # Option 2:
  #     ls -l /data/app/org.chromium.chrome-1/oat/arm/base.odex
  #
  # For Android N+:
  #   dumpsys package contains:
  #     dataDir=/data/user/0/org.chromium.chrome
  #     codePath=/data/app/org.chromium.chrome-UuCZ71IE-i5sZgHAkU49_w==
  #     resourcePath=/data/app/org.chromium.chrome-UuCZ71IE-i5sZgHAkU49_w==
  #     legacyNativeLibraryDir=/data/app/org.chromium.chrome-GUID/lib
  #     Instruction Set: arm
  #       path: /data/app/org.chromium.chrome-UuCZ71IE-i5sZgHAkU49_w==/base.apk
  #       status: /data/.../oat/arm/base.odex[status=kOatUpToDate, compilation_f
  #       ilter=quicken]
  #     Instruction Set: arm64
  #       path: /data/app/org.chromium.chrome-UuCZ71IE-i5sZgHAkU49_w==/base.apk
  #       status: /data/.../oat/arm64/base.odex[status=..., compilation_filter=q
  #       uicken]
  #   To measure odex:
  #     ls -l /data/app/.../oat/arm/base.odex
  #     ls -l /data/app/.../oat/arm/base.vdex (optional)
  #   To measure the correct odex size:
  #     cmd package compile -m speed org.chromium.chrome  # For webview
  #     cmd package compile -m speed-profile org.chromium.chrome  # For others
  def disk_usage_helper(d):
    package_output = '\n'.join(d.RunShellCommand(
        ['dumpsys', 'package', package_name], check_return=True))
    # Does not return error when apk is not installed.
    if not package_output or 'Unable to find package:' in package_output:
      return None

    # Ignore system apks that have updates installed.
    package_output = re.sub(r'Hidden system packages:.*?^\b', '',
                            package_output, flags=re.S | re.M)

    try:
      data_dir = re.search(r'dataDir=(.*)', package_output).group(1)
      code_path = re.search(r'codePath=(.*)', package_output).group(1)
      lib_path = re.search(r'(?:legacyN|n)ativeLibrary(?:Dir|Path)=(.*)',
                           package_output).group(1)
    except AttributeError:
      raise Exception('Error parsing dumpsys output: ' + package_output)

    if code_path.startswith('/system'):
      logging.warning('Measurement of system image apks can be innacurate')

    compilation_filters = set()
    # Match "compilation_filter=value", where a line break can occur at any spot
    # (refer to examples above).
    awful_wrapping = r'\s*'.join('compilation_filter=')
    for m in re.finditer(awful_wrapping + r'([\s\S]+?)[\],]', package_output):
      compilation_filters.add(re.sub(r'\s+', '', m.group(1)))
    compilation_filter = ','.join(sorted(compilation_filters))

    data_dir_sizes = _DuHelper(d, '%s/{*,.*}' % data_dir, run_as=package_name)
    # Measure code_cache separately since it can be large.
    code_cache_sizes = {}
    code_cache_dir = next(
        (k for k in data_dir_sizes if k.endswith('/code_cache')), None)
    if code_cache_dir:
      data_dir_sizes.pop(code_cache_dir)
      code_cache_sizes = _DuHelper(d, '%s/{*,.*}' % code_cache_dir,
                                   run_as=package_name)

    apk_path_spec = code_path
    if not apk_path_spec.endswith('.apk'):
      apk_path_spec += '/*.apk'
    apk_sizes = _DuHelper(d, apk_path_spec)
    if lib_path.endswith('/lib'):
      # Shows architecture subdirectory.
      lib_sizes = _DuHelper(d, '%s/{*,.*}' % lib_path)
    else:
      lib_sizes = _DuHelper(d, lib_path)

    # Look at all possible locations for odex files.
    odex_paths = []
    for apk_path in apk_sizes:
      mangled_apk_path = apk_path[1:].replace('/', '@')
      apk_basename = posixpath.basename(apk_path)[:-4]
      for ext in ('dex', 'odex', 'vdex', 'art'):
        # Easier to check all architectures than to determine active ones.
        for arch in ('arm', 'arm64', 'x86', 'x86_64', 'mips', 'mips64'):
          odex_paths.append(
              '%s/oat/%s/%s.%s' % (code_path, arch, apk_basename, ext))
          # No app could possibly have more than 6 dex files.
          for suffix in ('', '2', '3', '4', '5'):
            odex_paths.append('/data/dalvik-cache/%s/%s@classes%s.%s' % (
                arch, mangled_apk_path, suffix, ext))
            # This path does not have |arch|, so don't repeat it for every arch.
            if arch == 'arm':
              odex_paths.append('/data/dalvik-cache/%s@classes%s.dex' % (
                  mangled_apk_path, suffix))

    odex_sizes = _DuHelper(d, ' '.join(pipes.quote(p) for p in odex_paths))

    return (data_dir_sizes, code_cache_sizes, apk_sizes, lib_sizes, odex_sizes,
            compilation_filter)

  def print_sizes(desc, sizes):
    print('%s: %d KiB' % (desc, sum(sizes.itervalues())))
    for path, size in sorted(sizes.iteritems()):
      print('    %s: %s KiB' % (path, size))

  parallel_devices = device_utils.DeviceUtils.parallel(devices)
  all_results = parallel_devices.pMap(disk_usage_helper).pGet(None)
  for result in _PrintPerDeviceOutput(devices, all_results):
    if not result:
      print('APK is not installed.')
      continue

    (data_dir_sizes, code_cache_sizes, apk_sizes, lib_sizes, odex_sizes,
     compilation_filter) = result
    total = sum(sum(sizes.itervalues()) for sizes in result[:-1])

    print_sizes('Apk', apk_sizes)
    print_sizes('App Data (non-code cache)', data_dir_sizes)
    print_sizes('App Data (code cache)', code_cache_sizes)
    print_sizes('Native Libs', lib_sizes)
    show_warning = compilation_filter and 'speed' not in compilation_filter
    compilation_filter = compilation_filter or 'n/a'
    print_sizes('odex (compilation_filter=%s)' % compilation_filter, odex_sizes)
    if show_warning:
      logging.warning('For a more realistic odex size, run:')
      logging.warning('    %s compile-dex [speed|speed-profile]', sys.argv[0])
    print('Total: %s KiB (%.1f MiB)' % (total, total / 1024.0))


class _LogcatProcessor(object):
  ParsedLine = collections.namedtuple(
      'ParsedLine',
      ['date', 'invokation_time', 'pid', 'tid', 'priority', 'tag', 'message'])

  def __init__(self, device, package_name, deobfuscate=None, verbose=False):
    self._device = device
    self._package_name = package_name
    self._verbose = verbose
    self._deobfuscator = deobfuscate
    self._primary_pid = None
    self._my_pids = set()
    self._seen_pids = set()
    self._UpdateMyPids()

  def _UpdateMyPids(self):
    # We intentionally do not clear self._my_pids to make sure that the
    # ProcessLine method below also includes lines from processes which may
    # have already exited.
    self._primary_pid = None
    for process in _GetPackageProcesses(self._device, self._package_name):
      # We take only the first "main" process found in order to account for
      # possibly forked() processes.
      if ':' not in process.name and self._primary_pid is None:
        self._primary_pid = process.pid
      self._my_pids.add(process.pid)

  def _GetPidStyle(self, pid, dim=False):
    if pid == self._primary_pid:
      return colorama.Fore.WHITE
    elif pid in self._my_pids:
      # TODO(wnwen): Use one separate persistent color per process, pop LRU
      return colorama.Fore.YELLOW
    elif dim:
      return colorama.Style.DIM
    return ''

  def _GetPriorityStyle(self, priority, dim=False):
    # pylint:disable=no-self-use
    if dim:
      return ''
    style = colorama.Fore.BLACK
    if priority == 'E' or priority == 'F':
      style += colorama.Back.RED
    elif priority == 'W':
      style += colorama.Back.YELLOW
    elif priority == 'I':
      style += colorama.Back.GREEN
    elif priority == 'D':
      style += colorama.Back.BLUE
    return style

  def _ParseLine(self, line):
    tokens = line.split(None, 6)

    def consume_token_or_default(default):
      return tokens.pop(0) if len(tokens) > 0 else default

    date = consume_token_or_default('')
    invokation_time = consume_token_or_default('')
    pid = int(consume_token_or_default(-1))
    tid = int(consume_token_or_default(-1))
    priority = consume_token_or_default('')
    tag = consume_token_or_default('')
    original_message = consume_token_or_default('')

    # Example:
    #   09-19 06:35:51.113  9060  9154 W GCoreFlp: No location...
    #   09-19 06:01:26.174  9060 10617 I Auth    : [ReflectiveChannelBinder]...
    # Parsing "GCoreFlp:" vs "Auth    :", we only want tag to contain the word,
    # and we don't want to keep the colon for the message.
    if tag and tag[-1] == ':':
      tag = tag[:-1]
    elif len(original_message) > 2:
      original_message = original_message[2:]
    return self.ParsedLine(
        date, invokation_time, pid, tid, priority, tag, original_message)

  def _PrintParsedLine(self, parsed_line, dim=False):
    tid_style = colorama.Style.NORMAL
    # Make the main thread bright.
    if not dim and parsed_line.pid == parsed_line.tid:
      tid_style = colorama.Style.BRIGHT
    pid_style = self._GetPidStyle(parsed_line.pid, dim)
    # We have to pad before adding color as that changes the width of the tag.
    pid_str = _Colorize('{:5}'.format(parsed_line.pid), pid_style)
    tid_str = _Colorize('{:5}'.format(parsed_line.tid), tid_style)
    tag = _Colorize('{:8}'.format(parsed_line.tag),
                    pid_style + ('' if dim else colorama.Style.BRIGHT))
    priority = _Colorize(parsed_line.priority,
                         self._GetPriorityStyle(parsed_line.priority))
    messages = [parsed_line.message]
    if self._deobfuscator:
      messages = self._deobfuscator.TransformLines(messages)
    for message in messages:
      message = _Colorize(message, pid_style)
      sys.stdout.write('{} {} {} {} {} {}: {}\n'.format(
          parsed_line.date, parsed_line.invokation_time, pid_str, tid_str,
          priority, tag, message))

  def ProcessLine(self, line, fast=False):
    if not line or line.startswith('------'):
      return
    log = self._ParseLine(line)
    if log.pid not in self._seen_pids:
      self._seen_pids.add(log.pid)
      if not fast:
        self._UpdateMyPids()

    owned_pid = log.pid in self._my_pids
    if fast and not owned_pid:
      return
    if owned_pid and not self._verbose and log.tag == 'dalvikvm':
      if _DALVIK_IGNORE_PATTERN.match(log.message):
        return

    if owned_pid or self._verbose or (
        log.priority == 'F' or  # Java crash dump
        log.tag == 'ActivityManager' or  # Android system
        log.tag == 'DEBUG'):  # Native crash dump
      self._PrintParsedLine(log, not owned_pid)


def _RunLogcat(device, package_name, mapping_path, verbose):
  deobfuscate = None
  if mapping_path:
    try:
      deobfuscate = deobfuscator.Deobfuscator(mapping_path)
    except OSError:
      sys.stderr.write('Error executing "bin/java_deobfuscate". '
                       'Did you forget to build it?\n')
      sys.exit(1)

  try:
    logcat_processor = _LogcatProcessor(
        device, package_name, deobfuscate, verbose)
    nonce = 'apk_wrappers.py nonce={}'.format(random.random())
    device.RunShellCommand(['log', nonce])
    fast = True
    for line in device.adb.Logcat(logcat_format='threadtime'):
      try:
        logcat_processor.ProcessLine(line, fast)
      except:
        sys.stderr.write('Failed to process line: ' + line + '\n')
        # Skip stack trace for the common case of the adb server being
        # restarted.
        if 'unexpected EOF' in line:
          sys.exit(1)
        raise
      if fast and nonce in line:
        fast = False
  except KeyboardInterrupt:
    pass  # Don't show stack trace upon Ctrl-C
  finally:
    if mapping_path:
      deobfuscate.Close()


def _GetPackageProcesses(device, package_name):
  return [
      p for p in device.ListProcesses(package_name)
      if p.name == package_name or p.name.startswith(package_name + ':')]


def _RunPs(devices, package_name):
  parallel_devices = device_utils.DeviceUtils.parallel(devices)
  all_processes = parallel_devices.pMap(
      lambda d: _GetPackageProcesses(d, package_name)).pGet(None)
  for processes in _PrintPerDeviceOutput(devices, all_processes):
    if not processes:
      print('No processes found.')
    else:
      proc_map = collections.defaultdict(list)
      for p in processes:
        proc_map[p.name].append(str(p.pid))
      for name, pids in sorted(proc_map.items()):
        print(name, ','.join(pids))


def _RunShell(devices, package_name, cmd):
  if cmd:
    parallel_devices = device_utils.DeviceUtils.parallel(devices)
    outputs = parallel_devices.RunShellCommand(
        cmd, run_as=package_name).pGet(None)
    for output in _PrintPerDeviceOutput(devices, outputs):
      for line in output:
        print(line)
  else:
    adb_path = adb_wrapper.AdbWrapper.GetAdbPath()
    cmd = [adb_path, '-s', devices[0].serial, 'shell']
    # Pre-N devices do not support -t flag.
    if devices[0].build_version_sdk >= version_codes.NOUGAT:
      cmd += ['-t', 'run-as', package_name]
    else:
      print('Upon entering the shell, run:')
      print('run-as', package_name)
      print()
    os.execv(adb_path, cmd)


def _RunCompileDex(devices, package_name, compilation_filter):
  cmd = ['cmd', 'package', 'compile', '-f', '-m', compilation_filter,
         package_name]
  parallel_devices = device_utils.DeviceUtils.parallel(devices)
  outputs = parallel_devices.RunShellCommand(cmd, timeout=120).pGet(None)
  for output in _PrintPerDeviceOutput(devices, outputs):
    for line in output:
      print(line)


def _RunProfile(device, package_name, host_build_directory, pprof_out_path,
                process_specifier, thread_specifier, extra_args):
  simpleperf.PrepareDevice(device)
  device_simpleperf_path = simpleperf.InstallSimpleperf(device, package_name)
  with tempfile.NamedTemporaryFile() as fh:
    host_simpleperf_out_path = fh.name

    with simpleperf.RunSimpleperf(device, device_simpleperf_path, package_name,
                                  process_specifier, thread_specifier,
                                  extra_args, host_simpleperf_out_path):
      sys.stdout.write('Profiler is running; press Enter to stop...')
      sys.stdin.read(1)
      sys.stdout.write('Post-processing data...')
      sys.stdout.flush()

    simpleperf.ConvertSimpleperfToPprof(host_simpleperf_out_path,
                                        host_build_directory, pprof_out_path)
    print(textwrap.dedent("""
        Profile data written to %(s)s.

        To view profile as a call graph in browser:
          pprof -web %(s)s

        To print the hottest methods:
          pprof -top %(s)s

        pprof has many useful customization options; `pprof --help` for details.
        """ % {'s': pprof_out_path}))


def _GenerateAvailableDevicesMessage(devices):
  devices_obj = device_utils.DeviceUtils.parallel(devices)
  descriptions = devices_obj.pMap(lambda d: d.build_description).pGet(None)
  msg = 'Available devices:\n'
  for d, desc in zip(devices, descriptions):
    msg += '  %s (%s)\n' % (d, desc)
  return msg


# TODO(agrieve):add "--all" in the MultipleDevicesError message and use it here.
def _GenerateMissingAllFlagMessage(devices):
  return ('More than one device available. Use --all to select all devices, ' +
          'or use --device to select a device by serial.\n\n' +
          _GenerateAvailableDevicesMessage(devices))


def _DisplayArgs(devices, command_line_flags_file):
  def flags_helper(d):
    changer = flag_changer.FlagChanger(d, command_line_flags_file)
    return changer.GetCurrentFlags()

  parallel_devices = device_utils.DeviceUtils.parallel(devices)
  outputs = parallel_devices.pMap(flags_helper).pGet(None)
  print('Existing flags per-device (via /data/local/tmp/{}):'.format(
      command_line_flags_file))
  for flags in _PrintPerDeviceOutput(devices, outputs, single_line=True):
    quoted_flags = ' '.join(pipes.quote(f) for f in flags)
    print(quoted_flags or 'No flags set.')


def _DeviceCachePath(device, output_directory):
  file_name = 'device_cache_%s.json' % device.serial
  return os.path.join(output_directory, file_name)


def _LoadDeviceCaches(devices, output_directory):
  if not output_directory:
    return
  for d in devices:
    cache_path = _DeviceCachePath(d, output_directory)
    if os.path.exists(cache_path):
      logging.debug('Using device cache: %s', cache_path)
      with open(cache_path) as f:
        d.LoadCacheData(f.read())
      # Delete the cached file so that any exceptions cause it to be cleared.
      os.unlink(cache_path)
    else:
      logging.debug('No cache present for device: %s', d)


def _SaveDeviceCaches(devices, output_directory):
  if not output_directory:
    return
  for d in devices:
    cache_path = _DeviceCachePath(d, output_directory)
    with open(cache_path, 'w') as f:
      f.write(d.DumpCacheData())
      logging.info('Wrote device cache: %s', cache_path)


class _Command(object):
  name = None
  description = None
  long_description = None
  needs_package_name = False
  needs_output_directory = False
  needs_apk_path = False
  supports_incremental = False
  accepts_command_line_flags = False
  accepts_args = False
  need_device_args = True
  all_devices_by_default = False
  calls_exec = False
  supports_multiple_devices = True

  def __init__(self, from_wrapper_script, is_bundle):
    self._parser = None
    self._from_wrapper_script = from_wrapper_script
    self.args = None
    self.apk_helper = None
    self.install_dict = None
    self.devices = None
    self.is_bundle = is_bundle
    self.bundle_generation_info = None
    # Only support  incremental install from APK wrapper scripts.
    if is_bundle or not from_wrapper_script:
      self.supports_incremental = False

  def RegisterBundleGenerationInfo(self, bundle_generation_info):
    self.bundle_generation_info = bundle_generation_info

  def _RegisterExtraArgs(self, subp):
    pass

  def RegisterArgs(self, parser):
    subp = parser.add_parser(
        self.name, help=self.description,
        description=self.long_description or self.description,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    self._parser = subp
    subp.set_defaults(command=self)
    if self.need_device_args:
      subp.add_argument('--all',
                        action='store_true',
                        default=self.all_devices_by_default,
                        help='Operate on all connected devices.',)
      subp.add_argument('-d',
                        '--device',
                        action='append',
                        default=[],
                        dest='devices',
                        help='Target device for script to work on. Enter '
                            'multiple times for multiple devices.')
    subp.add_argument('-v',
                      '--verbose',
                      action='count',
                      default=0,
                      dest='verbose_count',
                      help='Verbose level (multiple times for more)')
    group = subp.add_argument_group('%s arguments' % self.name)

    if self.needs_package_name:
      # Three cases to consider here, since later code assumes
      #  self.args.package_name always exists, even if None:
      #
      # - Called from a bundle wrapper script, the package_name is already
      #   set through parser.set_defaults(), so don't call add_argument()
      #   to avoid overriding its value.
      #
      # - Called from an apk wrapper script. The --package-name argument
      #   should not appear, but self.args.package_name will be gleaned from
      #   the --apk-path file later.
      #
      # - Called directly, then --package-name is required on the command-line.
      #
      if not self.is_bundle:
        group.add_argument(
            '--package-name',
            help=argparse.SUPPRESS if self._from_wrapper_script else (
                "App's package name."))

    if self.needs_apk_path or self.needs_package_name:
      # Adding this argument to the subparser would override the set_defaults()
      # value set by on the parent parser (even if None).
      if not self._from_wrapper_script and not self.is_bundle:
        group.add_argument('--apk-path',
                           required=self.needs_apk_path,
                           help='Path to .apk')

    if self.supports_incremental:
      group.add_argument('--incremental',
                          action='store_true',
                          default=False,
                          help='Always install an incremental apk.')
      group.add_argument('--non-incremental',
                          action='store_true',
                          default=False,
                          help='Always install a non-incremental apk.')

    # accepts_command_line_flags and accepts_args are mutually exclusive.
    # argparse will throw if they are both set.
    if self.accepts_command_line_flags:
      group.add_argument(
          '--args', help='Command-line flags. Use = to assign args.')

    if self.accepts_args:
      group.add_argument(
          '--args', help='Extra arguments. Use = to assign args')

    if not self._from_wrapper_script and self.accepts_command_line_flags:
      # Provided by wrapper scripts.
      group.add_argument(
          '--command-line-flags-file',
          help='Name of the command-line flags file')

    self._RegisterExtraArgs(group)

  def ProcessArgs(self, args):
    self.args = args
    # Ensure these keys always exist. They are set by wrapper scripts, but not
    # always added when not using wrapper scripts.
    args.__dict__.setdefault('apk_path', None)
    args.__dict__.setdefault('incremental_json', None)

    incremental_apk_path = None
    if args.incremental_json and not (self.supports_incremental and
                                      args.non_incremental):
      with open(args.incremental_json) as f:
        install_dict = json.load(f)
        incremental_apk_path = os.path.join(args.output_directory,
                                            install_dict['apk_path'])
        if not os.path.exists(incremental_apk_path):
          incremental_apk_path = None

    if self.supports_incremental:
      if args.incremental and args.non_incremental:
        self._parser.error('Must use only one of --incremental and '
                           '--non-incremental')
      elif args.non_incremental:
        if not args.apk_path:
          self._parser.error('Apk has not been built.')
      elif args.incremental:
        if not incremental_apk_path:
          self._parser.error('Incremental apk has not been built.')
        args.apk_path = None

      if args.apk_path and incremental_apk_path:
        self._parser.error('Both incremental and non-incremental apks exist. '
                           'Select using --incremental or --non-incremental')

    if ((self.needs_apk_path and not self.is_bundle) or args.apk_path or
        incremental_apk_path):
      if args.apk_path:
        self.apk_helper = apk_helper.ToHelper(args.apk_path)
      elif incremental_apk_path:
        self.install_dict = install_dict
        self.apk_helper = apk_helper.ToHelper(incremental_apk_path)
      else:
        self._parser.error('Apk is not built.')

    if self.needs_package_name and not args.package_name:
      if self.apk_helper:
        args.package_name = self.apk_helper.GetPackageName()
      elif self._from_wrapper_script:
        self._parser.error('Apk is not built.')
      else:
        self._parser.error('One of --package-name or --apk-path is required.')

    self.devices = []
    if self.need_device_args:
      # See https://crbug.com/887964 regarding bundle support in apk_helper.
      abis = None
      if not self.is_bundle and self.apk_helper is not None:
        abis = self.apk_helper.GetAbis()
      self.devices = device_utils.DeviceUtils.HealthyDevices(
          device_arg=args.devices,
          enable_device_files_cache=bool(args.output_directory),
          default_retries=0,
          abis=abis)
      # TODO(agrieve): Device cache should not depend on output directory.
      #     Maybe put int /tmp?
      _LoadDeviceCaches(self.devices, args.output_directory)

      try:
        if len(self.devices) > 1:
          if not self.supports_multiple_devices:
            self._parser.error(device_errors.MultipleDevicesError(self.devices))
          if not args.all and not args.devices:
            self._parser.error(_GenerateMissingAllFlagMessage(self.devices))
        # Save cache now if command will not get a chance to afterwards.
        if self.calls_exec:
          _SaveDeviceCaches(self.devices, args.output_directory)
      except:
        _SaveDeviceCaches(self.devices, args.output_directory)
        raise


class _DevicesCommand(_Command):
  name = 'devices'
  description = 'Describe attached devices.'
  all_devices_by_default = True

  def Run(self):
    print(_GenerateAvailableDevicesMessage(self.devices))


class _PackageInfoCommand(_Command):
  name = 'package-info'
  # TODO(ntfschr): Support this by figuring out how to construct
  # self.apk_helper for bundles (http://crbug.com/952443).
  description = 'Show various attributes of this APK.'
  need_device_args = False
  needs_package_name = True
  needs_apk_path = True

  def Run(self):
    # Format all (even ints) as strings, to handle cases where APIs return None
    print('Package name: "%s"' % self.args.package_name)
    print('versionCode: %s' % self.apk_helper.GetVersionCode())
    print('versionName: "%s"' % self.apk_helper.GetVersionName())
    print('minSdkVersion: %s' % self.apk_helper.GetMinSdkVersion())
    print('targetSdkVersion: %s' % self.apk_helper.GetTargetSdkVersion())
    print('Supported ABIs: %r' % self.apk_helper.GetAbis())


class _InstallCommand(_Command):
  name = 'install'
  description = 'Installs the APK or bundle to one or more devices.'
  needs_apk_path = True
  supports_incremental = True

  def _RegisterExtraArgs(self, group):
    if self.is_bundle:
      group.add_argument(
          '-m',
          '--module',
          action='append',
          help='Module to install. Can be specified multiple times. ' +
          'One of them has to be \'{}\''.format(BASE_MODULE))
      group.add_argument(
          '-f',
          '--fake',
          action='append',
          help='Fake bundle module install. Can be specified multiple times. '
          'Requires \'-m {0}\' to be given, and \'-f {0}\' is illegal.'.format(
              BASE_MODULE))

  def Run(self):
    if self.is_bundle:
      # Store .apks file beside the .aab file so that it gets cached.
      output_path = self.bundle_generation_info.bundle_apks_path
      _GenerateBundleApks(self.bundle_generation_info, output_path)
      _InstallBundle(self.devices, output_path, self.args.package_name,
                     self.args.command_line_flags_file, self.args.module,
                     self.args.fake)
    else:
      _InstallApk(self.devices, self.apk_helper, self.install_dict)


class _UninstallCommand(_Command):
  name = 'uninstall'
  description = 'Removes the APK or bundle from one or more devices.'
  needs_package_name = True

  def Run(self):
    _UninstallApk(self.devices, self.install_dict, self.args.package_name)


class _SetWebViewProviderCommand(_Command):
  name = 'set-webview-provider'
  description = ("Sets the device's WebView provider to this APK's "
                 "package name.")
  needs_package_name = True

  def Run(self):
    if self.is_bundle:
      # TODO(ntfschr): Support this by figuring out how to construct
      # self.apk_helper for bundles (http://crbug.com/952443).
      raise Exception(
          'Switching WebView providers not supported for bundles yet!')
    if not _IsWebViewProvider(self.apk_helper):
      raise Exception('This package does not have a WebViewLibrary meta-data '
                      'tag. Are you sure it contains a WebView implementation?')
    _SetWebViewProvider(self.devices, self.args.package_name)


class _LaunchCommand(_Command):
  name = 'launch'
  description = ('Sends a launch intent for the APK or bundle after first '
                 'writing the command-line flags file.')
  needs_package_name = True
  accepts_command_line_flags = True
  all_devices_by_default = True

  def _RegisterExtraArgs(self, group):
    group.add_argument('-w', '--wait-for-java-debugger', action='store_true',
                       help='Pause execution until debugger attaches. Applies '
                            'only to the main process. To have renderers wait, '
                            'use --args="--renderer-wait-for-java-debugger"')
    group.add_argument('--debug-process-name',
                       help='Name of the process to debug. '
                            'E.g. "privileged_process0", or "foo.bar:baz"')
    group.add_argument('--nokill', action='store_true',
                       help='Do not set the debug-app, nor set command-line '
                            'flags. Useful to load a URL without having the '
                             'app restart.')
    group.add_argument('url', nargs='?', help='A URL to launch with.')

  def Run(self):
    if self.args.url and self.is_bundle:
      # TODO(digit): Support this, maybe by using 'dumpsys' as described
      # in the _LaunchUrl() comment.
      raise Exception('Launching with URL not supported for bundles yet!')
    _LaunchUrl(self.devices, self.args.package_name, argv=self.args.args,
               command_line_flags_file=self.args.command_line_flags_file,
               url=self.args.url, apk=self.apk_helper,
               wait_for_java_debugger=self.args.wait_for_java_debugger,
               debug_process_name=self.args.debug_process_name,
               nokill=self.args.nokill)


class _StopCommand(_Command):
  name = 'stop'
  description = 'Force-stops the app.'
  needs_package_name = True
  all_devices_by_default = True

  def Run(self):
    device_utils.DeviceUtils.parallel(self.devices).ForceStop(
        self.args.package_name)


class _ClearDataCommand(_Command):
  name = 'clear-data'
  descriptions = 'Clears all app data.'
  needs_package_name = True
  all_devices_by_default = True

  def Run(self):
    device_utils.DeviceUtils.parallel(self.devices).ClearApplicationState(
        self.args.package_name)


class _ArgvCommand(_Command):
  name = 'argv'
  description = 'Display and optionally update command-line flags file.'
  needs_package_name = True
  accepts_command_line_flags = True
  all_devices_by_default = True

  def Run(self):
    _ChangeFlags(self.devices, self.args.args,
                 self.args.command_line_flags_file)


class _GdbCommand(_Command):
  name = 'gdb'
  description = 'Runs //build/android/adb_gdb with apk-specific args.'
  long_description = description + """

To attach to a process other than the APK's main process, use --pid=1234.
To list all PIDs, use the "ps" command.

If no apk process is currently running, sends a launch intent.
"""
  needs_package_name = True
  needs_output_directory = True
  calls_exec = True
  supports_multiple_devices = False

  def Run(self):
    _RunGdb(self.devices[0], self.args.package_name,
            self.args.debug_process_name, self.args.pid,
            self.args.output_directory, self.args.target_cpu, self.args.port,
            self.args.ide, bool(self.args.verbose_count))

  def _RegisterExtraArgs(self, group):
    pid_group = group.add_mutually_exclusive_group()
    pid_group.add_argument('--debug-process-name',
                           help='Name of the process to attach to. '
                                'E.g. "privileged_process0", or "foo.bar:baz"')
    pid_group.add_argument('--pid',
                           help='The process ID to attach to. Defaults to '
                                'the main process for the package.')
    group.add_argument('--ide', action='store_true',
                       help='Rather than enter a gdb prompt, set up the '
                            'gdb connection and wait for an IDE to '
                            'connect.')
    # Same default port that ndk-gdb.py uses.
    group.add_argument('--port', type=int, default=5039,
                       help='Use the given port for the GDB connection')


class _LogcatCommand(_Command):
  name = 'logcat'
  description = 'Runs "adb logcat" with filters relevant the current APK.'
  long_description = description + """

"Relevant filters" means:
  * Log messages from processes belonging to the apk,
  * Plus log messages from log tags: ActivityManager|DEBUG,
  * Plus fatal logs from any process,
  * Minus spamy dalvikvm logs (for pre-L devices).

Colors:
  * Primary process is white
  * Other processes (gpu, renderer) are yellow
  * Non-apk processes are grey
  * UI thread has a bolded Thread-ID

Java stack traces are detected and deobfuscated (for release builds).

To disable filtering, (but keep coloring), use --verbose.
"""
  needs_package_name = True
  supports_multiple_devices = False

  def Run(self):
    mapping = self.args.proguard_mapping_path
    if self.args.no_deobfuscate:
      mapping = None
    _RunLogcat(self.devices[0], self.args.package_name, mapping,
               bool(self.args.verbose_count))

  def _RegisterExtraArgs(self, group):
    if self._from_wrapper_script:
      group.add_argument('--no-deobfuscate', action='store_true',
          help='Disables ProGuard deobfuscation of logcat.')
    else:
      group.set_defaults(no_deobfuscate=False)
      group.add_argument('--proguard-mapping-path',
          help='Path to ProGuard map (enables deobfuscation)')


class _PsCommand(_Command):
  name = 'ps'
  description = 'Show PIDs of any APK processes currently running.'
  needs_package_name = True
  all_devices_by_default = True

  def Run(self):
    _RunPs(self.devices, self.args.package_name)


class _DiskUsageCommand(_Command):
  name = 'disk-usage'
  description = 'Show how much device storage is being consumed by the app.'
  needs_package_name = True
  all_devices_by_default = True

  def Run(self):
    _RunDiskUsage(self.devices, self.args.package_name)


class _MemUsageCommand(_Command):
  name = 'mem-usage'
  description = 'Show memory usage of currently running APK processes.'
  needs_package_name = True
  all_devices_by_default = True

  def _RegisterExtraArgs(self, group):
    group.add_argument('--query-app', action='store_true',
        help='Do not add --local to "dumpsys meminfo". This will output '
             'additional metrics (e.g. Context count), but also cause memory '
             'to be used in order to gather the metrics.')

  def Run(self):
    _RunMemUsage(self.devices, self.args.package_name,
                 query_app=self.args.query_app)


class _ShellCommand(_Command):
  name = 'shell'
  description = ('Same as "adb shell <command>", but runs as the apk\'s uid '
                 '(via run-as). Useful for inspecting the app\'s data '
                 'directory.')
  needs_package_name = True

  @property
  def calls_exec(self):
    return not self.args.cmd

  @property
  def supports_multiple_devices(self):
    return not self.args.cmd

  def _RegisterExtraArgs(self, group):
    group.add_argument(
        'cmd', nargs=argparse.REMAINDER, help='Command to run.')

  def Run(self):
    _RunShell(self.devices, self.args.package_name, self.args.cmd)


class _CompileDexCommand(_Command):
  name = 'compile-dex'
  description = ('Applicable only for Android N+. Forces .odex files to be '
                 'compiled with the given compilation filter. To see existing '
                 'filter, use "disk-usage" command.')
  needs_package_name = True
  all_devices_by_default = True

  def _RegisterExtraArgs(self, group):
    group.add_argument(
        'compilation_filter',
        choices=['verify', 'quicken', 'space-profile', 'space',
                 'speed-profile', 'speed'],
        help='For WebView/Monochrome, use "speed". For other apks, use '
             '"speed-profile".')

  def Run(self):
    _RunCompileDex(self.devices, self.args.package_name,
                   self.args.compilation_filter)


class _ProfileCommand(_Command):
  name = 'profile'
  description = ('Run the simpleperf sampling CPU profiler on the currently-'
                 'running APK. If --args is used, the extra arguments will be '
                 'passed on to simpleperf; otherwise, the following default '
                 'arguments are used: -g -f 1000 -o /data/local/tmp/perf.data')
  needs_package_name = True
  needs_output_directory = True
  supports_multiple_devices = False
  accepts_args = True

  def _RegisterExtraArgs(self, group):
    group.add_argument(
        '--profile-process', default='browser',
        help=('Which process to profile. This may be a process name or pid '
              'such as you would get from running `%s ps`; or '
              'it can be one of (browser, renderer, gpu).' % sys.argv[0]))
    group.add_argument(
        '--profile-thread', default=None,
        help=('(Optional) Profile only a single thread. This may be either a '
              'thread ID such as you would get by running `adb shell ps -t` '
              '(pre-Oreo) or `adb shell ps -e -T` (Oreo and later); or it may '
              'be one of (io, compositor, main, render), in which case '
              '--profile-process is also required. (Note that "render" thread '
              'refers to a thread in the browser process that manages a '
              'renderer; to profile the main thread of the renderer process, '
              'use --profile-thread=main).'))
    group.add_argument('--profile-output', default='profile.pb',
                       help='Output file for profiling data')

  def Run(self):
    extra_args = shlex.split(self.args.args or '')
    _RunProfile(self.devices[0], self.args.package_name,
                self.args.output_directory, self.args.profile_output,
                self.args.profile_process, self.args.profile_thread,
                extra_args)


class _RunCommand(_InstallCommand, _LaunchCommand, _LogcatCommand):
  name = 'run'
  description = 'Install, launch, and show logcat (when targeting one device).'
  all_devices_by_default = False
  supports_multiple_devices = True

  def _RegisterExtraArgs(self, group):
    _InstallCommand._RegisterExtraArgs(self, group)
    _LaunchCommand._RegisterExtraArgs(self, group)
    _LogcatCommand._RegisterExtraArgs(self, group)
    group.add_argument('--no-logcat', action='store_true',
                       help='Install and launch, but do not enter logcat.')

  def Run(self):
    logging.warning('Installing...')
    _InstallCommand.Run(self)
    logging.warning('Sending launch intent...')
    _LaunchCommand.Run(self)
    if len(self.devices) == 1 and not self.args.no_logcat:
      logging.warning('Entering logcat...')
      _LogcatCommand.Run(self)


class _BuildBundleApks(_Command):
  name = 'build-bundle-apks'
  description = ('Build the .apks archive from an Android app bundle, and '
                 'optionally copy it to a specific destination.')
  need_device_args = False

  def _RegisterExtraArgs(self, group):
    group.add_argument(
        '--output-apks', required=True, help='Destination path for .apks file.')
    group.add_argument(
        '--minimal',
        action='store_true',
        help='Build .apks archive that targets the bundle\'s minSdkVersion and '
        'contains only english splits. It still contains optional splits.')
    group.add_argument(
        '--sdk-version', help='The sdkVersion to build the .apks for.')
    group.add_argument(
        '--build-mode',
        choices=app_bundle_utils.BUILD_APKS_MODES,
        help='Specify which type of APKs archive to build. "default" '
        'generates regular splits, "universal" generates an archive with a '
        'single universal APK, "system" generates an archive with a system '
        'image APK, while "system_compressed" generates a compressed system '
        'APK, with an additional stub APK for the system image.')

  def Run(self):
    _GenerateBundleApks(
        self.bundle_generation_info,
        self.args.output_apks,
        minimal=self.args.minimal,
        minimal_sdk_version=self.args.sdk_version,
        mode=self.args.build_mode)


class _ManifestCommand(_Command):
  name = 'dump-manifest'
  description = 'Dump the android manifest from this bundle, as XML, to stdout.'
  need_device_args = False

  def Run(self):
    bundletool.RunBundleTool([
        'dump', 'manifest', '--bundle', self.bundle_generation_info.bundle_path
    ])


# Shared commands for regular APKs and app bundles.
_COMMANDS = [
    _DevicesCommand,
    _PackageInfoCommand,
    _InstallCommand,
    _UninstallCommand,
    _SetWebViewProviderCommand,
    _LaunchCommand,
    _StopCommand,
    _ClearDataCommand,
    _ArgvCommand,
    _GdbCommand,
    _LogcatCommand,
    _PsCommand,
    _DiskUsageCommand,
    _MemUsageCommand,
    _ShellCommand,
    _CompileDexCommand,
    _ProfileCommand,
    _RunCommand,
]

# Commands specific to app bundles.
_BUNDLE_COMMANDS = [
    _BuildBundleApks,
    _ManifestCommand,
]


def _ParseArgs(parser, from_wrapper_script, is_bundle):
  subparsers = parser.add_subparsers()
  command_list = _COMMANDS + (_BUNDLE_COMMANDS if is_bundle else [])
  commands = [clazz(from_wrapper_script, is_bundle) for clazz in command_list]

  for command in commands:
    if from_wrapper_script or not command.needs_output_directory:
      command.RegisterArgs(subparsers)

  # Show extended help when no command is passed.
  argv = sys.argv[1:]
  if not argv:
    argv = ['--help']

  return parser.parse_args(argv)


def _RunInternal(parser, output_directory=None, bundle_generation_info=None):
  colorama.init()
  parser.set_defaults(output_directory=output_directory)
  from_wrapper_script = bool(output_directory)
  args = _ParseArgs(parser, from_wrapper_script, bool(bundle_generation_info))
  run_tests_helper.SetLogLevel(args.verbose_count)
  args.command.ProcessArgs(args)
  if bundle_generation_info:
    args.command.RegisterBundleGenerationInfo(bundle_generation_info)
  args.command.Run()
  # Incremental install depends on the cache being cleared when uninstalling.
  if args.command.name != 'uninstall':
    _SaveDeviceCaches(args.command.devices, output_directory)


def Run(output_directory, apk_path, incremental_json, command_line_flags_file,
        target_cpu, proguard_mapping_path):
  """Entry point for generated wrapper scripts."""
  constants.SetOutputDirectory(output_directory)
  devil_chromium.Initialize(output_directory=output_directory)
  parser = argparse.ArgumentParser()
  exists_or_none = lambda p: p if p and os.path.exists(p) else None
  parser.set_defaults(
      command_line_flags_file=command_line_flags_file,
      target_cpu=target_cpu,
      apk_path=exists_or_none(apk_path),
      incremental_json=exists_or_none(incremental_json),
      proguard_mapping_path=proguard_mapping_path)
  _RunInternal(parser, output_directory=output_directory)


def RunForBundle(output_directory, bundle_path, bundle_apks_path, aapt2_path,
                 keystore_path, keystore_password, keystore_alias, package_name,
                 command_line_flags_file, proguard_mapping_path, target_cpu,
                 system_image_locales):
  """Entry point for generated app bundle wrapper scripts.

  Args:
    output_dir: Chromium output directory path.
    bundle_path: Input bundle path.
    bundle_apks_path: Output bundle .apks archive path.
    aapt2_path: Aapt2 tool path.
    keystore_path: Keystore file path.
    keystore_password: Keystore password.
    keystore_alias: Signing key name alias in keystore file.
    package_name: Application's package name.
    command_line_flags_file: Optional. Name of an on-device file that will be
      used to store command-line flags for this bundle.
    proguard_mapping_path: Input path to the Proguard mapping file, used to
      deobfuscate Java stack traces.
    target_cpu: Chromium target CPU name, used by the 'gdb' command.
    system_image_locales: List of Chromium locales that should be included in
      system image APKs.
  """
  constants.SetOutputDirectory(output_directory)
  devil_chromium.Initialize(output_directory=output_directory)
  bundle_generation_info = BundleGenerationInfo(
      bundle_path=bundle_path,
      bundle_apks_path=bundle_apks_path,
      aapt2_path=aapt2_path,
      keystore_path=keystore_path,
      keystore_password=keystore_password,
      keystore_alias=keystore_alias,
      system_image_locales=system_image_locales)

  parser = argparse.ArgumentParser()
  parser.set_defaults(
      package_name=package_name,
      command_line_flags_file=command_line_flags_file,
      proguard_mapping_path=proguard_mapping_path,
      target_cpu=target_cpu)
  _RunInternal(parser, output_directory=output_directory,
               bundle_generation_info=bundle_generation_info)


def main():
  devil_chromium.Initialize()
  _RunInternal(argparse.ArgumentParser(), output_directory=None)


if __name__ == '__main__':
  main()
