示例#1
0
def main(raw_args):
  parser = argparse.ArgumentParser()
  parser.add_argument('--debug', action='store_true',
                      help='Get additional debugging mode')
  parser.add_argument(
      '--output-directory',
      help='the path to the build output directory, such as out/Debug')
  parser.add_argument('--report-path',
                      default='report.html', help='Report path')
  parser.add_argument('--adb-path',
                      help='Absolute path to the adb binary to use.')

  script_common.AddDeviceArguments(parser)
  logging_common.AddLoggingArguments(parser)

  args = parser.parse_args(raw_args)
  logging_common.InitializeLogging(args)
  devil_chromium.Initialize(adb_path=args.adb_path)

  devices = script_common.GetDevices(args.devices, args.blacklist_file)
  device = devices[0]

  if len(devices) > 1:
    raise device_errors.MultipleDevicesError(devices)

  with tempfile_ext.NamedTemporaryDirectory(
      prefix='tmp_simpleperf') as tmp_dir:
    runner = SimplePerfRunner(
        device, args, tmp_dir,
        StackAddressInterpreter(args, tmp_dir))
    runner.Run()
示例#2
0
def main(raw_args):
    parser = argparse.ArgumentParser()
    parser.add_argument('--debug',
                        action='store_true',
                        help='Get additional debugging mode')
    parser.add_argument(
        '--output-directory',
        help='the path to the build output directory, such as out/Debug')
    parser.add_argument('--report-path',
                        default='report.html',
                        help='Report path')
    parser.add_argument('--adb-path',
                        help='Absolute path to the adb binary to use.')
    parser.add_argument(
        '--record-options',
        help=('Set recording options for app_profiler.py command.'
              ' Example: "-e task-clock:u -f 1000 -g --duration'
              ' 10" where -f means sampling frequency per second.'
              ' Try `app_profiler.py record -h` for more '
              ' information. Note that not setting this defaults'
              ' to the default record options.'))
    parser.add_argument('--show-file-line',
                        action='store_true',
                        help='Show file name and lines in the result.')
    parser.add_argument(
        '--system-wide',
        action='store_true',
        help=('Whether to profile system wide (without launching'
              'an app).'))

    script_common.AddDeviceArguments(parser)
    logging_common.AddLoggingArguments(parser)

    args = parser.parse_args(raw_args)
    logging_common.InitializeLogging(args)
    devil_chromium.Initialize(adb_path=args.adb_path)

    devices = script_common.GetDevices(args.devices, args.denylist_file)
    device = devices[0]

    if len(devices) > 1:
        raise device_errors.MultipleDevicesError(devices)

    with tempfile_ext.NamedTemporaryDirectory(
            prefix='tmp_simpleperf') as tmp_dir:
        runner = SimplePerfRunner(device, args, tmp_dir,
                                  StackAddressInterpreter(args, tmp_dir))
        runner.Run()
示例#3
0
def DetermineDeviceToUse(devices):
  """Like DeviceUtils.HealthyDevices(), but only allow a single device.

  Args:
    devices: A (possibly empty) list of serial numbers, such as from the
        --device flag.
  Returns:
    A single device_utils.DeviceUtils instance.
  Raises:
    device_errors.NoDevicesError: Raised when no non-denylisted devices exist.
    device_errors.MultipleDevicesError: Raise when multiple devices exist, but
        |devices| does not distinguish which to use.
  """
  if not devices:
    # If the user did not specify which device, we let HealthyDevices raise
    # MultipleDevicesError.
    devices = None
  usable_devices = device_utils.DeviceUtils.HealthyDevices(device_arg=devices)
  # If the user specified more than one device, we still only want to support a
  # single device, so we explicitly raise MultipleDevicesError.
  if len(usable_devices) > 1:
    raise device_errors.MultipleDevicesError(usable_devices)
  return usable_devices[0]
示例#4
0
def main():
    parser = argparse.ArgumentParser(description="""
Configures WebView to start recording a netlog. This script chooses a suitable
netlog filename for the application, and will pull the netlog off the device
when the user terminates the script (with ctrl-C). For a more complete usage
guide, open your web browser to:
https://chromium.googlesource.com/chromium/src/+/HEAD/android_webview/docs/net-debugging.md
""")
    parser.add_argument(
        '--package',
        required=True,
        type=str,
        help='Package name of the application you intend to use.')
    parser.add_argument('--force',
                        default=False,
                        action='store_true',
                        help='Suppress user checks.')

    script_common.AddEnvironmentArguments(parser)
    script_common.AddDeviceArguments(parser)
    logging_common.AddLoggingArguments(parser)

    args = parser.parse_args()
    logging_common.InitializeLogging(args)
    devil_chromium.Initialize(adb_path=args.adb_path)

    # Only use a single device, for the sake of simplicity (of implementation and
    # user experience).
    devices = device_utils.DeviceUtils.HealthyDevices(device_arg=args.devices)
    device = devices[0]
    if len(devices) > 1:
        raise device_errors.MultipleDevicesError(devices)

    package_name = args.package
    device_netlog_file_name = 'netlog.json'
    device_netlog_path = os.path.join(
        device.GetApplicationDataDirectory(package_name), 'app_webview',
        device_netlog_file_name)

    CheckAppNotRunning(device, package_name, args.force)

    # Append to the existing flags, to allow users to experiment with other
    # features/flags enabled. The CustomCommandLineFlags will restore the original
    # flag state after the user presses 'ctrl-C'.
    changer = flag_changer.FlagChanger(device, WEBVIEW_COMMAND_LINE)
    new_flags = changer.GetCurrentFlags()
    new_flags.append('--log-net-log={}'.format(device_netlog_path))

    logging.info('Running with flags %r', new_flags)
    with flag_changer.CustomCommandLineFlags(device, WEBVIEW_COMMAND_LINE,
                                             new_flags):
        print(
            'Netlog will start recording as soon as app starts up. Press ctrl-C '
            'to stop recording.')
        _WaitUntilCtrlC()

    host_netlog_path = 'netlog.json'
    print('Pulling netlog to "%s"' % host_netlog_path)
    # The netlog file will be under the app's uid, which the default shell doesn't
    # have permission to read (but root does). Prefer this to EnableRoot(), which
    # restarts the adb daemon.
    device.PullFile(device_netlog_path, host_netlog_path, as_root=True)
    device.RemovePath(device_netlog_path, as_root=True)
  def ProcessArgs(self, args):
    devices = device_utils.DeviceUtils.HealthyDevices(
        device_arg=args.devices,
        enable_device_files_cache=bool(args.output_directory),
        default_retries=0)
    self.args = args
    self.devices = devices
    # TODO(agrieve): Device cache should not depend on output directory.
    #     Maybe put int /tmp?
    _LoadDeviceCaches(devices, args.output_directory)
    # 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)

    try:
      if len(devices) > 1:
        if not self.supports_multiple_devices:
          self._parser.error(device_errors.MultipleDevicesError(devices))
        if not args.all and not args.devices:
          self._parser.error(_GenerateMissingAllFlagMessage(devices))

      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.')
          args.incremental_json = None
        elif args.incremental:
          if not args.incremental_json:
            self._parser.error('Incremental apk has not been built.')
          args.apk_path = None

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

      if self.needs_apk_path or args.apk_path or args.incremental_json:
        if args.incremental_json:
          with open(args.incremental_json) as f:
            install_dict = json.load(f)
          apk_path = os.path.join(args.output_directory,
                                  install_dict['apk_path'])
          if os.path.exists(apk_path):
            self.install_dict = install_dict
            self.apk_helper = apk_helper.ToHelper(
                os.path.join(args.output_directory,
                             self.install_dict['apk_path']))
        if not self.apk_helper and args.apk_path:
          self.apk_helper = apk_helper.ToHelper(args.apk_path)
        if not self.apk_helper:
          self._parser.error(
              'Neither incremental nor non-incremental apk is 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(
              'Neither incremental nor non-incremental apk is built.')
        else:
          self._parser.error('One of --package-name or --apk-path is required.')

      # Save cache now if command will not get a chance to afterwards.
      if self.calls_exec:
        _SaveDeviceCaches(devices, args.output_directory)
    except:
      _SaveDeviceCaches(devices, args.output_directory)
      raise
示例#6
0
def Run(output_directory, apk_path, inc_apk_path, inc_install_script,
         command_line_flags_file):
  constants.SetOutputDirectory(output_directory)

  parser = argparse.ArgumentParser()
  command_parsers = parser.add_subparsers(title='Apk operations',
                                          dest='command')
  subp = command_parsers.add_parser('install', help='Install the apk.')
  _AddCommonOptions(subp)

  subp = command_parsers.add_parser('uninstall', help='Uninstall the apk.')
  _AddCommonOptions(subp)

  subp = command_parsers.add_parser('launch',
                                    help='Launches the apk with the given '
                                    'command-line flags, and optionally the '
                                    'given URL')
  _AddCommonOptions(subp)
  _AddLaunchOptions(subp)
  _AddArgsOptions(subp)

  subp = command_parsers.add_parser('run', help='Install and launch.')
  _AddCommonOptions(subp)
  _AddLaunchOptions(subp)
  _AddArgsOptions(subp)

  subp = command_parsers.add_parser('stop', help='Stop apks on all devices')
  _AddCommonOptions(subp)

  subp = command_parsers.add_parser('clear-data',
                                    help='Clear states for the given package')
  _AddCommonOptions(subp)

  subp = command_parsers.add_parser('argv',
                                    help='Display and update flags on devices.')
  _AddCommonOptions(subp)
  _AddArgsOptions(subp)

  subp = command_parsers.add_parser('gdb',
                                    help='Run build/android/adb_gdb script.')
  _AddCommonOptions(subp)
  _AddArgsOptions(subp)

  subp = command_parsers.add_parser('logcat',
                                    help='Run the shell command "adb logcat".')
  _AddCommonOptions(subp)

  args = parser.parse_args()
  run_tests_helper.SetLogLevel(args.verbose_count)
  command = args.command

  devil_chromium.Initialize()

  devices = device_utils.DeviceUtils.HealthyDevices(device_arg=args.devices,
                                                    default_retries=0)
  devices_obj = device_utils.DeviceUtils.parallel(devices)

  if command in {'gdb', 'logcat'} and len(devices) > 1:
    raise device_errors.MultipleDevicesError(devices)
  if command in {'argv', 'stop', 'clear-data'} or len(args.devices) > 0:
    args.all = True
  if len(devices) > 1 and not args.all:
    raise Exception(_GenerateMissingAllFlagMessage(devices, devices_obj))

  if args.incremental and args.non_incremental:
    raise Exception('--incremental and --non-incremental cannot be set at the '
                    'same time.')
  install_incremental = False
  active_apk = None
  apk_package = None
  apk_name = os.path.basename(apk_path)
  if apk_path and not os.path.exists(apk_path):
    apk_path = None

  if args.non_incremental:
    if apk_path:
      active_apk = apk_path
      logging.info('Use the non-incremental apk.')
    else:
      raise Exception("No regular apk is available.")

  if inc_apk_path and not os.path.exists(inc_apk_path):
    inc_apk_path = None

  if args.incremental:
    if inc_apk_path:
      active_apk = inc_apk_path
      install_incremental = True
      logging.info('Use the incremental apk.')
    else:
      raise Exception("No incremental apk is available.")

  if not args.incremental and not args.non_incremental and command in {
      'install', 'run'}:
    if apk_path and inc_apk_path:
      raise Exception('Both incremental and non-incremental apks exist, please '
                      'use --incremental or --non-incremental to select one.')
    if not apk_path and not inc_apk_path:
      raise Exception('Neither incremental nor non-incremental apk is '
                      'available.')
    if apk_path:
      active_apk = apk_path
      logging.info('Use the non-incremental apk.')
    else:
      active_apk = inc_apk_path
      install_incremental = True
      logging.info('Use the incremental apk.')

  if apk_path is not None:
    apk_package = apk_helper.GetPackageName(apk_path)
  elif inc_apk_path is not None:
    apk_package = apk_helper.GetPackageName(inc_apk_path)

  # Use the cache if possible.
  use_cache = True
  if command in {'gdb', 'logcat'}:
    # Only the current data is needed for these cmds.
    use_cache = False
  if use_cache:
    for d in devices:
      cache_path = _DeviceCachePath(d)
      if os.path.exists(cache_path):
        logging.info('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.info('No cache present for device: %s', d)

  if command == 'install':
    _InstallApk(install_incremental, inc_install_script, devices_obj,
                active_apk)
  elif command == 'uninstall':
    _UninstallApk(install_incremental, devices_obj, apk_package)
  elif command == 'launch':
    _LaunchUrl(devices_obj, args.args, command_line_flags_file,
               args.url, apk_package)
  elif command == 'run':
    _InstallApk(install_incremental, inc_install_script, devices_obj,
                active_apk)
    devices_obj.pFinish(None)
    _LaunchUrl(devices_obj, args.args, command_line_flags_file,
               args.url, apk_package)
  elif command == 'stop':
    devices_obj.ForceStop(apk_package)
  elif command == 'clear-data':
    devices_obj.ClearApplicationState(apk_package)
  elif command == 'argv':
    _ChangeFlags(devices, devices_obj, args.args,
                 command_line_flags_file)
  elif command == 'gdb':
    gdb_script_path = os.path.dirname(__file__) + '/adb_gdb'
    program_name = '--program-name=%s' % os.path.splitext(apk_name)[0]
    package_name = '--package-name=%s' % apk_package
    # The output directory is the one including lib* files.
    output_dir = '--output-directory=%s' % os.path.abspath(
        os.path.join(output_directory, os.pardir))
    adb_path = '--adb=%s' % adb_wrapper.AdbWrapper.GetAdbPath()
    device = '--device=%s' % devices[0].adb.GetDeviceSerial()
    flags = [gdb_script_path, program_name, package_name, output_dir, adb_path,
             device]
    if args.args:
      flags += shlex.split(args.args)
    # Enable verbose output of adb_gdb if it's set for this script.
    if args.verbose_count > 0:
      flags.append('--verbose')
    logging.warning('Running: %s', ' '.join(pipes.quote(f) for f in flags))
    os.execv(gdb_script_path, flags)
  elif command == 'logcat':
    adb_path = adb_wrapper.AdbWrapper.GetAdbPath()
    flags = [adb_path, '-s', devices[0].adb.GetDeviceSerial(), 'logcat']
    os.execv(adb_path, flags)

  # Wait for all threads to finish.
  devices_obj.pFinish(None)

  # Save back to the cache.
  if use_cache:
    for d in devices:
      cache_path = _DeviceCachePath(d)
      with open(cache_path, 'w') as f:
        f.write(d.DumpCacheData())
        logging.info('Wrote device cache: %s', cache_path)
示例#7
0
def Run(output_directory, apk_path, incremental_install_json_path,
        command_line_flags_file):
    constants.SetOutputDirectory(output_directory)

    parser = argparse.ArgumentParser()
    command_parsers = parser.add_subparsers(title='Apk operations',
                                            dest='command')
    subp = command_parsers.add_parser('install', help='Install the apk.')
    _AddCommonOptions(subp)

    subp = command_parsers.add_parser('uninstall', help='Uninstall the apk.')
    _AddCommonOptions(subp)

    subp = command_parsers.add_parser('launch',
                                      help='Launches the apk with the given '
                                      'command-line flags, and optionally the '
                                      'given URL')
    _AddCommonOptions(subp)
    _AddLaunchOptions(subp)
    _AddArgsOptions(subp)

    subp = command_parsers.add_parser('run', help='Install and launch.')
    _AddCommonOptions(subp)
    _AddLaunchOptions(subp)
    _AddArgsOptions(subp)

    subp = command_parsers.add_parser('stop', help='Stop apks on all devices')
    _AddCommonOptions(subp)

    subp = command_parsers.add_parser(
        'clear-data', help='Clear states for the given package')
    _AddCommonOptions(subp)

    subp = command_parsers.add_parser(
        'argv', help='Display and update flags on devices.')
    _AddCommonOptions(subp)
    _AddArgsOptions(subp)

    subp = command_parsers.add_parser('gdb',
                                      help='Run build/android/adb_gdb script.')
    _AddCommonOptions(subp)
    _AddArgsOptions(subp)

    subp = command_parsers.add_parser(
        'logcat', help='Run the shell command "adb logcat".')
    _AddCommonOptions(subp)

    args = parser.parse_args()
    run_tests_helper.SetLogLevel(args.verbose_count)
    command = args.command
    # Enable caching unless executing a helper script (where we won't get a chance
    # to update the cache afterwards).
    use_cache = command not in {'gdb', 'logcat'}

    devil_chromium.Initialize()

    devices = device_utils.DeviceUtils.HealthyDevices(
        device_arg=args.devices,
        enable_device_files_cache=use_cache,
        default_retries=0)
    devices_obj = device_utils.DeviceUtils.parallel(devices)

    if command in {'gdb', 'logcat'} and len(devices) > 1:
        raise device_errors.MultipleDevicesError(devices)
    if command in {'argv', 'stop', 'clear-data'} or len(args.devices) > 0:
        args.all = True
    if len(devices) > 1 and not args.all:
        raise Exception(_GenerateMissingAllFlagMessage(devices, devices_obj))

    apk_name = os.path.basename(apk_path)
    apk_path, incremental_install_json_path = _SelectApk(
        apk_path, incremental_install_json_path, parser, args)
    install_dict = None

    if incremental_install_json_path:
        with open(incremental_install_json_path) as f:
            install_dict = json.load(f)
        apk = apk_helper.ToHelper(
            os.path.join(output_directory, install_dict['apk_path']))
    else:
        apk = apk_helper.ToHelper(apk_path)

    apk_package = apk.GetPackageName()

    if use_cache:
        _LoadDeviceCaches(devices)

    if command == 'install':
        _InstallApk(apk, install_dict, devices_obj)
    elif command == 'uninstall':
        _UninstallApk(install_dict, devices_obj, apk_package)
    elif command == 'launch':
        _LaunchUrl(devices_obj, args.args, command_line_flags_file, args.url,
                   apk)
    elif command == 'run':
        logging.warning('Installing...')
        _InstallApk(apk, install_dict, devices_obj)
        logging.warning('Sending launch intent...')
        _LaunchUrl(devices_obj, args.args, command_line_flags_file, args.url,
                   apk)
    elif command == 'stop':
        devices_obj.ForceStop(apk_package)
    elif command == 'clear-data':
        devices_obj.ClearApplicationState(apk_package)
    elif command == 'argv':
        _ChangeFlags(devices, devices_obj, args.args, command_line_flags_file)
    elif command == 'gdb':
        gdb_script_path = os.path.dirname(__file__) + '/adb_gdb'
        program_name = '--program-name=%s' % os.path.splitext(apk_name)[0]
        package_name = '--package-name=%s' % apk_package
        output_dir = '--output-directory=%s' % output_directory
        adb_path = '--adb=%s' % adb_wrapper.AdbWrapper.GetAdbPath()
        device = '--device=%s' % devices[0].adb.GetDeviceSerial()
        # Use one lib dir per device so that changing between devices does require
        # refetching the device libs.
        libs_dir = '--pull-libs-dir=/tmp/adb-gdb-libs-%s' % (
            devices[0].adb.GetDeviceSerial())
        flags = [
            gdb_script_path, program_name, package_name, output_dir, device,
            adb_path, libs_dir
        ]
        if args.args:
            flags += shlex.split(args.args)
        # Enable verbose output of adb_gdb if it's set for this script.
        if args.verbose_count > 0:
            flags.append('--verbose')
        logging.warning('Running: %s', ' '.join(pipes.quote(f) for f in flags))
        logging.warning('All subsequent output is from adb_gdb script.')
        os.execv(gdb_script_path, flags)
    elif command == 'logcat':
        adb_path = adb_wrapper.AdbWrapper.GetAdbPath()
        flags = [adb_path, '-s', devices[0].adb.GetDeviceSerial(), 'logcat']
        os.execv(adb_path, flags)

    # Save back to the cache.
    if use_cache:
        _SaveDeviceCaches(devices)