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()
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()
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]
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
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)
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)