diff options
author | skyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-13 16:27:27 +0000 |
---|---|---|
committer | skyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-13 16:27:27 +0000 |
commit | c0921404fb62d69359d9b6551acb3567a4c33ba0 (patch) | |
tree | 6d1aebe7426f214fd4479cda0e66b692e77cc6ef /build | |
parent | 908431e63848edfd99d78ec0cec0277bbea6e48a (diff) | |
download | chromium_src-c0921404fb62d69359d9b6551acb3567a4c33ba0.zip chromium_src-c0921404fb62d69359d9b6551acb3567a4c33ba0.tar.gz chromium_src-c0921404fb62d69359d9b6551acb3567a4c33ba0.tar.bz2 |
Move adb_profile_chrome under tools/android/
Move adb_profile_chrome from build/android/ to tools/android/ to make
its purpose clearer.
BUG=375754
TEST=tools/android/adb_profile_chrome/run_tests
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=276779
Review URL: https://codereview.chromium.org/310413003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@277031 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'build')
19 files changed, 1 insertions, 1135 deletions
diff --git a/build/android/adb_profile_chrome b/build/android/adb_profile_chrome index 00b1199..ee6f940 100755 --- a/build/android/adb_profile_chrome +++ b/build/android/adb_profile_chrome @@ -5,4 +5,4 @@ # found in the LICENSE file. # # Start / stop profiling in chrome. -exec $(dirname $0)/adb_profile_chrome.py $@ +exec $(dirname $0)/../../tools/android/adb_profile_chrome.py $@ diff --git a/build/android/adb_profile_chrome.py b/build/android/adb_profile_chrome.py deleted file mode 100755 index 0270a62..0000000 --- a/build/android/adb_profile_chrome.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2013 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. - -import sys - -from chrome_profiler import main - - -if __name__ == '__main__': - sys.exit(main.main()) diff --git a/build/android/chrome_profiler/__init__.py b/build/android/chrome_profiler/__init__.py deleted file mode 100644 index 4d6aabb..0000000 --- a/build/android/chrome_profiler/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright 2014 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. diff --git a/build/android/chrome_profiler/chrome_controller.py b/build/android/chrome_profiler/chrome_controller.py deleted file mode 100644 index 745e5d7..0000000 --- a/build/android/chrome_profiler/chrome_controller.py +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright 2014 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. - -import json -import os -import re -import time - -from chrome_profiler import controllers - -from pylib import pexpect - -_HEAP_PROFILE_MMAP_PROPERTY = 'heapprof.mmap' - -class ChromeTracingController(controllers.BaseController): - def __init__(self, device, package_info, - categories, ring_buffer, trace_memory=False): - controllers.BaseController.__init__(self) - self._device = device - self._package_info = package_info - self._categories = categories - self._ring_buffer = ring_buffer - self._trace_file = None - self._trace_interval = None - self._trace_memory = trace_memory - self._trace_start_re = \ - re.compile(r'Logging performance trace to file') - self._trace_finish_re = \ - re.compile(r'Profiler finished[.] Results are in (.*)[.]') - self._device.old_interface.StartMonitoringLogcat(clear=False) - - def __repr__(self): - return 'chrome trace' - - @staticmethod - def GetCategories(device, package_info): - device.old_interface.BroadcastIntent( - package_info.package, 'GPU_PROFILER_LIST_CATEGORIES') - try: - json_category_list = device.old_interface.WaitForLogMatch( - re.compile(r'{"traceCategoriesList(.*)'), None, timeout=5).group(0) - except pexpect.TIMEOUT: - raise RuntimeError('Performance trace category list marker not found. ' - 'Is the correct version of the browser running?') - - record_categories = [] - disabled_by_default_categories = [] - json_data = json.loads(json_category_list)['traceCategoriesList'] - for item in json_data: - if item.startswith('disabled-by-default'): - disabled_by_default_categories.append(item) - else: - record_categories.append(item) - - return record_categories, disabled_by_default_categories - - def StartTracing(self, interval): - self._trace_interval = interval - self._device.old_interface.SyncLogCat() - self._device.old_interface.BroadcastIntent( - self._package_info.package, 'GPU_PROFILER_START', - '-e categories "%s"' % ','.join(self._categories), - '-e continuous' if self._ring_buffer else '') - - if self._trace_memory: - self._device.old_interface.EnableAdbRoot() - self._device.old_interface.system_properties \ - [_HEAP_PROFILE_MMAP_PROPERTY] = 1 - - # Chrome logs two different messages related to tracing: - # - # 1. "Logging performance trace to file" - # 2. "Profiler finished. Results are in [...]" - # - # The first one is printed when tracing starts and the second one indicates - # that the trace file is ready to be pulled. - try: - self._device.old_interface.WaitForLogMatch( - self._trace_start_re, None, timeout=5) - except pexpect.TIMEOUT: - raise RuntimeError('Trace start marker not found. Is the correct version ' - 'of the browser running?') - - def StopTracing(self): - self._device.old_interface.BroadcastIntent( - self._package_info.package, - 'GPU_PROFILER_STOP') - self._trace_file = self._device.old_interface.WaitForLogMatch( - self._trace_finish_re, None, timeout=120).group(1) - if self._trace_memory: - self._device.old_interface.system_properties \ - [_HEAP_PROFILE_MMAP_PROPERTY] = 0 - - def PullTrace(self): - # Wait a bit for the browser to finish writing the trace file. - time.sleep(self._trace_interval / 4 + 1) - - trace_file = self._trace_file.replace('/storage/emulated/0/', '/sdcard/') - host_file = os.path.join(os.path.curdir, os.path.basename(trace_file)) - self._device.old_interface.PullFileFromDevice(trace_file, host_file) - return host_file diff --git a/build/android/chrome_profiler/chrome_controller_unittest.py b/build/android/chrome_profiler/chrome_controller_unittest.py deleted file mode 100644 index e8c2829..0000000 --- a/build/android/chrome_profiler/chrome_controller_unittest.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright 2014 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. - -import os -import json - -from chrome_profiler import chrome_controller -from chrome_profiler import controllers_unittest - - -class ChromeControllerTest(controllers_unittest.BaseControllerTest): - def testGetCategories(self): - # Not supported on stable yet. - # TODO(skyostil): Remove this once category queries roll into stable. - if self.browser == 'stable': - return - - categories = \ - chrome_controller.ChromeTracingController.GetCategories( - self.device, self.package_info) - - self.assertEquals(len(categories), 2) - self.assertTrue(categories[0]) - self.assertTrue(categories[1]) - - def testTracing(self): - categories = '*' - ring_buffer = False - controller = chrome_controller.ChromeTracingController(self.device, - self.package_info, - categories, - ring_buffer) - - interval = 1 - try: - controller.StartTracing(interval) - finally: - controller.StopTracing() - - result = controller.PullTrace() - try: - with open(result) as f: - json.loads(f.read()) - finally: - os.remove(result) diff --git a/build/android/chrome_profiler/controllers.py b/build/android/chrome_profiler/controllers.py deleted file mode 100644 index a569dbc..0000000 --- a/build/android/chrome_profiler/controllers.py +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2014 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. - -import exceptions - -# pylint: disable=R0201 -class BaseController(object): - def StartTracing(self, _): - raise exceptions.NotImplementError - - def StopTracing(self): - raise exceptions.NotImplementError - - def PullTrace(self): - raise exceptions.NotImplementError diff --git a/build/android/chrome_profiler/controllers_unittest.py b/build/android/chrome_profiler/controllers_unittest.py deleted file mode 100644 index c2b6a41..0000000 --- a/build/android/chrome_profiler/controllers_unittest.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2014 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. - -import unittest - -from chrome_profiler import profiler - -from pylib import android_commands -from pylib.device import device_utils - - -class BaseControllerTest(unittest.TestCase): - def setUp(self): - devices = android_commands.GetAttachedDevices() - self.browser = 'stable' - self.package_info = profiler.GetSupportedBrowsers()[self.browser] - self.device = device_utils.DeviceUtils(devices[0]) - - adb = android_commands.AndroidCommands(devices[0]) - adb.StartActivity(self.package_info.package, - self.package_info.activity, - wait_for_completion=True) diff --git a/build/android/chrome_profiler/main.py b/build/android/chrome_profiler/main.py deleted file mode 100755 index 729163f..0000000 --- a/build/android/chrome_profiler/main.py +++ /dev/null @@ -1,250 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2014 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. - -import logging -import optparse -import os -import sys -import webbrowser - -from chrome_profiler import chrome_controller -from chrome_profiler import perf_controller -from chrome_profiler import profiler -from chrome_profiler import systrace_controller -from chrome_profiler import ui - -from pylib import android_commands -from pylib.device import device_utils - - -_DEFAULT_CHROME_CATEGORIES = '_DEFAULT_CHROME_CATEGORIES' - - -def _ComputeChromeCategories(options): - categories = [] - if options.trace_frame_viewer: - categories.append('disabled-by-default-cc.debug') - if options.trace_ubercompositor: - categories.append('disabled-by-default-cc.debug*') - if options.trace_gpu: - categories.append('disabled-by-default-gpu.debug*') - if options.trace_flow: - categories.append('disabled-by-default-toplevel.flow') - if options.trace_memory: - categories.append('disabled-by-default-memory') - if options.chrome_categories: - categories += options.chrome_categories.split(',') - return categories - - -def _ComputeSystraceCategories(options): - if not options.systrace_categories: - return [] - return options.systrace_categories.split(',') - - -def _ComputePerfCategories(options): - if not options.perf_categories: - return [] - return options.perf_categories.split(',') - - -def _OptionalValueCallback(default_value): - def callback(option, _, __, parser): - value = default_value - if parser.rargs and not parser.rargs[0].startswith('-'): - value = parser.rargs.pop(0) - setattr(parser.values, option.dest, value) - return callback - - -def _CreateOptionParser(): - parser = optparse.OptionParser(description='Record about://tracing profiles ' - 'from Android browsers. See http://dev.' - 'chromium.org/developers/how-tos/trace-event-' - 'profiling-tool for detailed instructions for ' - 'profiling.') - - timed_options = optparse.OptionGroup(parser, 'Timed tracing') - timed_options.add_option('-t', '--time', help='Profile for N seconds and ' - 'download the resulting trace.', metavar='N', - type='float') - parser.add_option_group(timed_options) - - cont_options = optparse.OptionGroup(parser, 'Continuous tracing') - cont_options.add_option('--continuous', help='Profile continuously until ' - 'stopped.', action='store_true') - cont_options.add_option('--ring-buffer', help='Use the trace buffer as a ' - 'ring buffer and save its contents when stopping ' - 'instead of appending events into one long trace.', - action='store_true') - parser.add_option_group(cont_options) - - chrome_opts = optparse.OptionGroup(parser, 'Chrome tracing options') - chrome_opts.add_option('-c', '--categories', help='Select Chrome tracing ' - 'categories with comma-delimited wildcards, ' - 'e.g., "*", "cat1*,-cat1a". Omit this option to trace ' - 'Chrome\'s default categories. Chrome tracing can be ' - 'disabled with "--categories=\'\'". Use "list" to ' - 'see the available categories.', - metavar='CHROME_CATEGORIES', dest='chrome_categories', - default=_DEFAULT_CHROME_CATEGORIES) - chrome_opts.add_option('--trace-cc', - help='Deprecated, use --trace-frame-viewer.', - action='store_true') - chrome_opts.add_option('--trace-frame-viewer', - help='Enable enough trace categories for ' - 'compositor frame viewing.', action='store_true') - chrome_opts.add_option('--trace-ubercompositor', - help='Enable enough trace categories for ' - 'ubercompositor frame data.', action='store_true') - chrome_opts.add_option('--trace-gpu', help='Enable extra trace categories ' - 'for GPU data.', action='store_true') - chrome_opts.add_option('--trace-flow', help='Enable extra trace categories ' - 'for IPC message flows.', action='store_true') - chrome_opts.add_option('--trace-memory', help='Enable extra trace categories ' - 'for memory profile. (tcmalloc required)', - action='store_true') - parser.add_option_group(chrome_opts) - - systrace_opts = optparse.OptionGroup(parser, 'Systrace tracing options') - systrace_opts.add_option('-s', '--systrace', help='Capture a systrace with ' - 'the chosen comma-delimited systrace categories. You ' - 'can also capture a combined Chrome + systrace by ' - 'enable both types of categories. Use "list" to see ' - 'the available categories. Systrace is disabled by ' - 'default.', metavar='SYS_CATEGORIES', - dest='systrace_categories', default='') - parser.add_option_group(systrace_opts) - - if perf_controller.PerfProfilerController.IsSupported(): - perf_opts = optparse.OptionGroup(parser, 'Perf profiling options') - perf_opts.add_option('-p', '--perf', help='Capture a perf profile with ' - 'the chosen comma-delimited event categories. ' - 'Samples CPU cycles by default. Use "list" to see ' - 'the available sample types.', action='callback', - default='', callback=_OptionalValueCallback('cycles'), - metavar='PERF_CATEGORIES', dest='perf_categories') - parser.add_option_group(perf_opts) - - output_options = optparse.OptionGroup(parser, 'Output options') - output_options.add_option('-o', '--output', help='Save trace output to file.') - output_options.add_option('--json', help='Save trace as raw JSON instead of ' - 'HTML.', action='store_true') - output_options.add_option('--view', help='Open resulting trace file in a ' - 'browser.', action='store_true') - parser.add_option_group(output_options) - - browsers = sorted(profiler.GetSupportedBrowsers().keys()) - parser.add_option('-b', '--browser', help='Select among installed browsers. ' - 'One of ' + ', '.join(browsers) + ', "stable" is used by ' - 'default.', type='choice', choices=browsers, - default='stable') - parser.add_option('-v', '--verbose', help='Verbose logging.', - action='store_true') - parser.add_option('-z', '--compress', help='Compress the resulting trace ' - 'with gzip. ', action='store_true') - return parser - - -def main(): - parser = _CreateOptionParser() - options, _args = parser.parse_args() - if options.trace_cc: - parser.parse_error("""--trace-cc is deprecated. - -For basic jank busting uses, use --trace-frame-viewer -For detailed study of ubercompositor, pass --trace-ubercompositor. - -When in doubt, just try out --trace-frame-viewer. -""") - - if options.verbose: - logging.getLogger().setLevel(logging.DEBUG) - - devices = android_commands.GetAttachedDevices() - if len(devices) != 1: - parser.error('Exactly 1 device must be attached.') - device = device_utils.DeviceUtils(devices[0]) - package_info = profiler.GetSupportedBrowsers()[options.browser] - - if options.chrome_categories in ['list', 'help']: - ui.PrintMessage('Collecting record categories list...', eol='') - record_categories = [] - disabled_by_default_categories = [] - record_categories, disabled_by_default_categories = \ - chrome_controller.ChromeTracingController.GetCategories( - device, package_info) - - ui.PrintMessage('done') - ui.PrintMessage('Record Categories:') - ui.PrintMessage('\n'.join('\t%s' % item \ - for item in sorted(record_categories))) - - ui.PrintMessage('\nDisabled by Default Categories:') - ui.PrintMessage('\n'.join('\t%s' % item \ - for item in sorted(disabled_by_default_categories))) - - return 0 - - if options.systrace_categories in ['list', 'help']: - ui.PrintMessage('\n'.join( - systrace_controller.SystraceController.GetCategories(device))) - return 0 - - if options.perf_categories in ['list', 'help']: - ui.PrintMessage('\n'.join( - perf_controller.PerfProfilerController.GetCategories(device))) - return 0 - - if not options.time and not options.continuous: - ui.PrintMessage('Time interval or continuous tracing should be specified.') - return 1 - - chrome_categories = _ComputeChromeCategories(options) - systrace_categories = _ComputeSystraceCategories(options) - perf_categories = _ComputePerfCategories(options) - - if chrome_categories and 'webview' in systrace_categories: - logging.warning('Using the "webview" category in systrace together with ' - 'Chrome tracing results in duplicate trace events.') - - enabled_controllers = [] - if chrome_categories: - enabled_controllers.append( - chrome_controller.ChromeTracingController(device, - package_info, - chrome_categories, - options.ring_buffer, - options.trace_memory)) - if systrace_categories: - enabled_controllers.append( - systrace_controller.SystraceController(device, - systrace_categories, - options.ring_buffer)) - - if perf_categories: - enabled_controllers.append( - perf_controller.PerfProfilerController(device, - perf_categories)) - - if not enabled_controllers: - ui.PrintMessage('No trace categories enabled.') - return 1 - - if options.output: - options.output = os.path.expanduser(options.output) - result = profiler.CaptureProfile( - enabled_controllers, - options.time if not options.continuous else 0, - output=options.output, - compress=options.compress, - write_json=options.json) - if options.view: - if sys.platform == 'darwin': - os.system('/usr/bin/open %s' % os.path.abspath(result)) - else: - webbrowser.open(result) diff --git a/build/android/chrome_profiler/perf_controller.py b/build/android/chrome_profiler/perf_controller.py deleted file mode 100644 index ba4b572..0000000 --- a/build/android/chrome_profiler/perf_controller.py +++ /dev/null @@ -1,186 +0,0 @@ -# Copyright 2014 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. - -import logging -import os -import subprocess -import sys -import tempfile - -from chrome_profiler import controllers -from chrome_profiler import ui - -from pylib import android_commands -from pylib import constants -from pylib.perf import perf_control - -sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT, - 'tools', - 'telemetry')) -try: - # pylint: disable=F0401 - from telemetry.core.platform.profiler import android_profiling_helper - from telemetry.util import support_binaries -except ImportError: - android_profiling_helper = None - support_binaries = None - - -_PERF_OPTIONS = [ - # Sample across all processes and CPUs to so that the current CPU gets - # recorded to each sample. - '--all-cpus', - # In perf 3.13 --call-graph requires an argument, so use the -g short-hand - # which does not. - '-g', - # Increase priority to avoid dropping samples. Requires root. - '--realtime', '80', - # Record raw samples to get CPU information. - '--raw-samples', - # Increase sampling frequency for better coverage. - '--freq', '2000', -] - - -class _PerfProfiler(object): - def __init__(self, device, perf_binary, categories): - self._device = device - self._output_file = android_commands.DeviceTempFile( - self._device.old_interface, prefix='perf_output') - self._log_file = tempfile.TemporaryFile() - - device_param = (['-s', self._device.old_interface.GetDevice()] - if self._device.old_interface.GetDevice() else []) - cmd = ['adb'] + device_param + \ - ['shell', perf_binary, 'record', - '--output', self._output_file.name] + _PERF_OPTIONS - if categories: - cmd += ['--event', ','.join(categories)] - self._perf_control = perf_control.PerfControl(self._device) - self._perf_control.ForceAllCpusOnline(True) - self._perf_process = subprocess.Popen(cmd, - stdout=self._log_file, - stderr=subprocess.STDOUT) - - def SignalAndWait(self): - perf_pids = self._device.old_interface.ExtractPid('perf') - self._device.old_interface.RunShellCommand( - 'kill -SIGINT ' + ' '.join(perf_pids)) - self._perf_process.wait() - self._perf_control.ForceAllCpusOnline(False) - - def _FailWithLog(self, msg): - self._log_file.seek(0) - log = self._log_file.read() - raise RuntimeError('%s. Log output:\n%s' % (msg, log)) - - def PullResult(self, output_path): - if not self._device.old_interface.FileExistsOnDevice( - self._output_file.name): - self._FailWithLog('Perf recorded no data') - - perf_profile = os.path.join(output_path, - os.path.basename(self._output_file.name)) - self._device.old_interface.PullFileFromDevice(self._output_file.name, - perf_profile) - if not os.stat(perf_profile).st_size: - os.remove(perf_profile) - self._FailWithLog('Perf recorded a zero-sized file') - - self._log_file.close() - self._output_file.close() - return perf_profile - - -class PerfProfilerController(controllers.BaseController): - def __init__(self, device, categories): - controllers.BaseController.__init__(self) - self._device = device - self._categories = categories - self._perf_binary = self._PrepareDevice(device) - self._perf_instance = None - - def __repr__(self): - return 'perf profile' - - @staticmethod - def IsSupported(): - return bool(android_profiling_helper) - - @staticmethod - def _PrepareDevice(device): - if not 'BUILDTYPE' in os.environ: - os.environ['BUILDTYPE'] = 'Release' - return android_profiling_helper.PrepareDeviceForPerf(device) - - @classmethod - def GetCategories(cls, device): - perf_binary = cls._PrepareDevice(device) - return device.old_interface.RunShellCommand('%s list' % perf_binary) - - def StartTracing(self, _): - self._perf_instance = _PerfProfiler(self._device, - self._perf_binary, - self._categories) - - def StopTracing(self): - if not self._perf_instance: - return - self._perf_instance.SignalAndWait() - - @staticmethod - def _GetInteractivePerfCommand(perfhost_path, perf_profile, symfs_dir, - required_libs, kallsyms): - cmd = '%s report -n -i %s --symfs %s --kallsyms %s' % ( - os.path.relpath(perfhost_path, '.'), perf_profile, symfs_dir, kallsyms) - for lib in required_libs: - lib = os.path.join(symfs_dir, lib[1:]) - if not os.path.exists(lib): - continue - objdump_path = android_profiling_helper.GetToolchainBinaryPath( - lib, 'objdump') - if objdump_path: - cmd += ' --objdump %s' % os.path.relpath(objdump_path, '.') - break - return cmd - - def PullTrace(self): - symfs_dir = os.path.join(tempfile.gettempdir(), - os.path.expandvars('$USER-perf-symfs')) - if not os.path.exists(symfs_dir): - os.makedirs(symfs_dir) - required_libs = set() - - # Download the recorded perf profile. - perf_profile = self._perf_instance.PullResult(symfs_dir) - required_libs = \ - android_profiling_helper.GetRequiredLibrariesForPerfProfile( - perf_profile) - if not required_libs: - logging.warning('No libraries required by perf trace. Most likely there ' - 'are no samples in the trace.') - - # Build a symfs with all the necessary libraries. - kallsyms = android_profiling_helper.CreateSymFs(self._device, - symfs_dir, - required_libs, - use_symlinks=False) - perfhost_path = os.path.abspath(support_binaries.FindPath( - 'perfhost', 'linux')) - - ui.PrintMessage('\nNote: to view the profile in perf, run:') - ui.PrintMessage(' ' + self._GetInteractivePerfCommand(perfhost_path, - perf_profile, symfs_dir, required_libs, kallsyms)) - - # Convert the perf profile into JSON. - perf_script_path = os.path.join(constants.DIR_SOURCE_ROOT, - 'tools', 'telemetry', 'telemetry', 'core', 'platform', 'profiler', - 'perf_vis', 'perf_to_tracing.py') - json_file_name = os.path.basename(perf_profile) - with open(os.devnull, 'w') as dev_null, \ - open(json_file_name, 'w') as json_file: - cmd = [perfhost_path, 'script', '-s', perf_script_path, '-i', - perf_profile, '--symfs', symfs_dir, '--kallsyms', kallsyms] - subprocess.call(cmd, stdout=json_file, stderr=dev_null) - return json_file_name diff --git a/build/android/chrome_profiler/perf_controller_unittest.py b/build/android/chrome_profiler/perf_controller_unittest.py deleted file mode 100644 index a621a2e..0000000 --- a/build/android/chrome_profiler/perf_controller_unittest.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2014 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. - -import os -import json - -from chrome_profiler import controllers_unittest -from chrome_profiler import perf_controller - - -class PerfProfilerControllerTest(controllers_unittest.BaseControllerTest): - def testGetCategories(self): - if not perf_controller.PerfProfilerController.IsSupported(): - return - categories = \ - perf_controller.PerfProfilerController.GetCategories(self.device) - assert 'cycles' in ' '.join(categories) - - def testTracing(self): - if not perf_controller.PerfProfilerController.IsSupported(): - return - categories = ['cycles'] - controller = perf_controller.PerfProfilerController(self.device, - categories) - - interval = 1 - try: - controller.StartTracing(interval) - finally: - controller.StopTracing() - - result = controller.PullTrace() - try: - with open(result) as f: - json.loads(f.read()) - finally: - os.remove(result) diff --git a/build/android/chrome_profiler/profiler.py b/build/android/chrome_profiler/profiler.py deleted file mode 100644 index 5393ed3..0000000 --- a/build/android/chrome_profiler/profiler.py +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright 2014 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. - -import os - -from chrome_profiler import trace_packager -from chrome_profiler import ui - -from pylib import constants - - -def _StartTracing(controllers, interval): - for controller in controllers: - controller.StartTracing(interval) - - -def _StopTracing(controllers): - for controller in controllers: - controller.StopTracing() - - -def _PullTraces(controllers, output, compress, write_json): - ui.PrintMessage('Downloading...', eol='') - trace_files = [controller.PullTrace() for controller in controllers] - result = trace_packager.PackageTraces(trace_files, - output=output, - compress=compress, - write_json=write_json) - ui.PrintMessage('done') - ui.PrintMessage('Trace written to file://%s' % os.path.abspath(result)) - return result - - -def GetSupportedBrowsers(): - """Returns the package names of all supported browsers.""" - # Add aliases for backwards compatibility. - supported_browsers = { - 'stable': constants.PACKAGE_INFO['chrome_stable'], - 'beta': constants.PACKAGE_INFO['chrome_beta'], - 'dev': constants.PACKAGE_INFO['chrome_dev'], - 'build': constants.PACKAGE_INFO['chrome'], - } - supported_browsers.update(constants.PACKAGE_INFO) - unsupported_browsers = ['content_browsertests', 'gtest', 'legacy_browser'] - for browser in unsupported_browsers: - del supported_browsers[browser] - return supported_browsers - - -def CaptureProfile(controllers, interval, output=None, compress=False, - write_json=False): - """Records a profiling trace saves the result to a file. - - Args: - controllers: List of tracing controllers. - interval: Time interval to capture in seconds. An interval of None (or 0) - continues tracing until stopped by the user. - output: Output file name or None to use an automatically generated name. - compress: If True, the result will be compressed either with gzip or zip - depending on the number of captured subtraces. - write_json: If True, prefer JSON output over HTML. - - Returns: - Path to saved profile. - """ - trace_type = ' + '.join(map(str, controllers)) - try: - _StartTracing(controllers, interval) - if interval: - ui.PrintMessage('Capturing %d-second %s. Press Enter to stop early...' % \ - (interval, trace_type), eol='') - ui.WaitForEnter(interval) - else: - ui.PrintMessage('Capturing %s. Press Enter to stop...' % \ - trace_type, eol='') - raw_input() - finally: - _StopTracing(controllers) - if interval: - ui.PrintMessage('done') - - return _PullTraces(controllers, output, compress, write_json) diff --git a/build/android/chrome_profiler/profiler_unittest.py b/build/android/chrome_profiler/profiler_unittest.py deleted file mode 100644 index dbf8f22..0000000 --- a/build/android/chrome_profiler/profiler_unittest.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2014 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. - -import os -import tempfile -import unittest -import zipfile - -from chrome_profiler import profiler -from chrome_profiler import ui - - -class FakeController(object): - def __init__(self, contents='fake-contents'): - self.contents = contents - self.interval = None - self.stopped = False - self.filename = None - - def StartTracing(self, interval): - self.interval = interval - - def StopTracing(self): - self.stopped = True - - def PullTrace(self): - with tempfile.NamedTemporaryFile(delete=False) as f: - self.filename = f.name - f.write(self.contents) - return f.name - - def __repr__(self): - return 'faketrace' - - -class ProfilerTest(unittest.TestCase): - def setUp(self): - ui.EnableTestMode() - - def testCaptureBasicProfile(self): - controller = FakeController() - interval = 1.5 - result = profiler.CaptureProfile([controller], interval) - - try: - self.assertEquals(controller.interval, interval) - self.assertTrue(controller.stopped) - self.assertTrue(os.path.exists(result)) - self.assertFalse(os.path.exists(controller.filename)) - self.assertTrue(result.endswith('.html')) - finally: - os.remove(result) - - def testCaptureJsonProfile(self): - controller = FakeController() - result = profiler.CaptureProfile([controller], 1, write_json=True) - - try: - self.assertFalse(result.endswith('.html')) - with open(result) as f: - self.assertEquals(f.read(), controller.contents) - finally: - os.remove(result) - - def testCaptureMultipleProfiles(self): - controllers = [FakeController('c1'), FakeController('c2')] - result = profiler.CaptureProfile(controllers, 1, write_json=True) - - try: - self.assertTrue(result.endswith('.zip')) - self.assertTrue(zipfile.is_zipfile(result)) - with zipfile.ZipFile(result) as f: - self.assertEquals( - f.namelist(), - [controllers[0].filename[1:], controllers[1].filename[1:]]) - finally: - os.remove(result) diff --git a/build/android/chrome_profiler/run_tests b/build/android/chrome_profiler/run_tests deleted file mode 100755 index 2cdce5a..0000000 --- a/build/android/chrome_profiler/run_tests +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -cd $(dirname $0)/.. -exec python -m unittest discover chrome_profiler '*_unittest.py' diff --git a/build/android/chrome_profiler/systrace_controller.py b/build/android/chrome_profiler/systrace_controller.py deleted file mode 100644 index 0903101..0000000 --- a/build/android/chrome_profiler/systrace_controller.py +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright 2014 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. - -import threading -import zlib - -from chrome_profiler import controllers -from chrome_profiler import util - -from pylib import cmd_helper - - -_SYSTRACE_OPTIONS = [ - # Compress the trace before sending it over USB. - '-z', - # Use a large trace buffer to increase the polling interval. - '-b', '16384' -] - -# Interval in seconds for sampling systrace data. -_SYSTRACE_INTERVAL = 15 - - -class SystraceController(controllers.BaseController): - def __init__(self, device, categories, ring_buffer): - controllers.BaseController.__init__(self) - self._device = device - self._categories = categories - self._ring_buffer = ring_buffer - self._done = threading.Event() - self._thread = None - self._trace_data = None - - def __repr__(self): - return 'systrace' - - @staticmethod - def GetCategories(device): - return device.old_interface.RunShellCommand('atrace --list_categories') - - def StartTracing(self, _): - self._thread = threading.Thread(target=self._CollectData) - self._thread.start() - - def StopTracing(self): - self._done.set() - - def PullTrace(self): - self._thread.join() - self._thread = None - if self._trace_data: - output_name = 'systrace-%s' % util.GetTraceTimestamp() - with open(output_name, 'w') as out: - out.write(self._trace_data) - return output_name - - def _RunATraceCommand(self, command): - # TODO(jbudorick) can this be made work with DeviceUtils? - # We use a separate interface to adb because the one from AndroidCommands - # isn't re-entrant. - device_param = (['-s', self._device.old_interface.GetDevice()] - if self._device.old_interface.GetDevice() else []) - cmd = ['adb'] + device_param + ['shell', 'atrace', '--%s' % command] + \ - _SYSTRACE_OPTIONS + self._categories - return cmd_helper.GetCmdOutput(cmd) - - def _CollectData(self): - trace_data = [] - self._RunATraceCommand('async_start') - try: - while not self._done.is_set(): - self._done.wait(_SYSTRACE_INTERVAL) - if not self._ring_buffer or self._done.is_set(): - trace_data.append( - self._DecodeTraceData(self._RunATraceCommand('async_dump'))) - finally: - trace_data.append( - self._DecodeTraceData(self._RunATraceCommand('async_stop'))) - self._trace_data = ''.join([zlib.decompress(d) for d in trace_data]) - - @staticmethod - def _DecodeTraceData(trace_data): - try: - trace_start = trace_data.index('TRACE:') - except ValueError: - raise RuntimeError('Systrace start marker not found') - trace_data = trace_data[trace_start + 6:] - - # Collapse CRLFs that are added by adb shell. - if trace_data.startswith('\r\n'): - trace_data = trace_data.replace('\r\n', '\n') - - # Skip the initial newline. - return trace_data[1:] diff --git a/build/android/chrome_profiler/systrace_controller_unittest.py b/build/android/chrome_profiler/systrace_controller_unittest.py deleted file mode 100644 index 448f328..0000000 --- a/build/android/chrome_profiler/systrace_controller_unittest.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2014 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. - -import os - -from chrome_profiler import controllers_unittest -from chrome_profiler import systrace_controller - - -class SystraceControllerTest(controllers_unittest.BaseControllerTest): - def testGetCategories(self): - categories = \ - systrace_controller.SystraceController.GetCategories(self.device) - self.assertTrue(categories) - assert 'gfx' in ' '.join(categories) - - def testTracing(self): - categories = ['gfx', 'input', 'view'] - ring_buffer = False - controller = systrace_controller.SystraceController(self.device, - categories, - ring_buffer) - - interval = 1 - try: - controller.StartTracing(interval) - finally: - controller.StopTracing() - - result = controller.PullTrace() - try: - with open(result) as f: - self.assertTrue('CPU#' in f.read()) - finally: - os.remove(result) diff --git a/build/android/chrome_profiler/trace_packager.py b/build/android/chrome_profiler/trace_packager.py deleted file mode 100644 index e56a7de..0000000 --- a/build/android/chrome_profiler/trace_packager.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2014 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. - -import gzip -import json -import os -import shutil -import sys -import zipfile - -from chrome_profiler import util - -from pylib import constants - -sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT, - 'third_party', - 'trace-viewer')) -# pylint: disable=F0401 -from trace_viewer.build import trace2html - - -def _PackageTracesAsHtml(trace_files, html_file): - with open(html_file, 'w') as f: - trace2html.WriteHTMLForTracesToFile(trace_files, f) - for trace_file in trace_files: - os.unlink(trace_file) - - -def _CompressFile(host_file, output): - with gzip.open(output, 'wb') as out, \ - open(host_file, 'rb') as input_file: - out.write(input_file.read()) - os.unlink(host_file) - - -def _ArchiveFiles(host_files, output): - with zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED) as z: - for host_file in host_files: - z.write(host_file) - os.unlink(host_file) - - -def _MergeTracesIfNeeded(trace_files): - if len(trace_files) <= 1: - return trace_files - merge_candidates = [] - for trace_file in trace_files: - with open(trace_file) as f: - # Try to detect a JSON file cheaply since that's all we can merge. - if f.read(1) != '{': - continue - f.seek(0) - try: - json_data = json.load(f) - except ValueError: - continue - merge_candidates.append((trace_file, json_data)) - if len(merge_candidates) <= 1: - return trace_files - - other_files = [f for f in trace_files - if not f in [c[0] for c in merge_candidates]] - merged_file, merged_data = merge_candidates[0] - for trace_file, json_data in merge_candidates[1:]: - for key, value in json_data.items(): - if not merged_data.get(key) or json_data[key]: - merged_data[key] = value - os.unlink(trace_file) - - with open(merged_file, 'w') as f: - json.dump(merged_data, f) - return [merged_file] + other_files - - -def PackageTraces(trace_files, output=None, compress=False, write_json=False): - trace_files = _MergeTracesIfNeeded(trace_files) - if not write_json: - html_file = os.path.splitext(trace_files[0])[0] + '.html' - _PackageTracesAsHtml(trace_files, html_file) - trace_files = [html_file] - - if compress and len(trace_files) == 1: - result = output or trace_files[0] + '.gz' - _CompressFile(trace_files[0], result) - elif len(trace_files) > 1: - result = output or 'chrome-combined-trace-%s.zip' % util.GetTraceTimestamp() - _ArchiveFiles(trace_files, result) - elif output: - result = output - shutil.move(trace_files[0], result) - else: - result = trace_files[0] - return result diff --git a/build/android/chrome_profiler/trace_packager_unittest.py b/build/android/chrome_profiler/trace_packager_unittest.py deleted file mode 100644 index 8c50d3a..0000000 --- a/build/android/chrome_profiler/trace_packager_unittest.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2014 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. - -from chrome_profiler import trace_packager - -import json -import tempfile -import unittest - - -class TracePackagerTest(unittest.TestCase): - def testJsonTraceMerging(self): - t1 = {'traceEvents': [{'ts': 123, 'ph': 'b'}]} - t2 = {'traceEvents': [], 'stackFrames': ['blah']} - - # Both trace files will be merged to a third file and will get deleted in - # the process, so there's no need for NamedTemporaryFile to do the - # deletion. - with tempfile.NamedTemporaryFile(delete=False) as f1, \ - tempfile.NamedTemporaryFile(delete=False) as f2: - f1.write(json.dumps(t1)) - f2.write(json.dumps(t2)) - f1.flush() - f2.flush() - - with tempfile.NamedTemporaryFile() as output: - trace_packager.PackageTraces([f1.name, f2.name], - output.name, - compress=False, - write_json=True) - with open(output.name) as output: - output = json.load(output) - self.assertEquals(output['traceEvents'], t1['traceEvents']) - self.assertEquals(output['stackFrames'], t2['stackFrames']) diff --git a/build/android/chrome_profiler/ui.py b/build/android/chrome_profiler/ui.py deleted file mode 100644 index 9913a43..0000000 --- a/build/android/chrome_profiler/ui.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2014 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. - -import select -import sys - - -def PrintMessage(heading, eol='\n'): - sys.stdout.write('%s%s' % (heading, eol)) - sys.stdout.flush() - - -def WaitForEnter(timeout): - select.select([sys.stdin], [], [], timeout) - - -def EnableTestMode(): - def NoOp(*_, **__): - pass - # pylint: disable=W0601 - global PrintMessage - global WaitForEnter - PrintMessage = NoOp - WaitForEnter = NoOp diff --git a/build/android/chrome_profiler/util.py b/build/android/chrome_profiler/util.py deleted file mode 100644 index 75ef1b6..0000000 --- a/build/android/chrome_profiler/util.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2014 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. - -import time - -def GetTraceTimestamp(): - return time.strftime('%Y-%m-%d-%H%M%S', time.localtime()) |