| Index: build/android/adb_profile_chrome.py
|
| diff --git a/build/android/adb_profile_chrome.py b/build/android/adb_profile_chrome.py
|
| index ead674148870902bc8af363d18aebc768fe49f96..bb3e9d038805e652ad1ff2f5b1da6e54fbad9011 100755
|
| --- a/build/android/adb_profile_chrome.py
|
| +++ b/build/android/adb_profile_chrome.py
|
| @@ -4,6 +4,7 @@
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
|
|
| +import base64
|
| import gzip
|
| import logging
|
| import optparse
|
| @@ -13,6 +14,7 @@ import shutil
|
| import sys
|
| import threading
|
| import time
|
| +import webbrowser
|
| import zipfile
|
| import zlib
|
|
|
| @@ -22,6 +24,43 @@ from pylib import constants
|
| from pylib import pexpect
|
|
|
|
|
| +_TRACE_VIEWER_TEMPLATE = """<!DOCTYPE html>
|
| +<html>
|
| + <head>
|
| + <title>%(title)s</title>
|
| + <style>
|
| + %(timeline_css)s
|
| + </style>
|
| + <style>
|
| + .view {
|
| + overflow: hidden;
|
| + position: absolute;
|
| + top: 0;
|
| + bottom: 0;
|
| + left: 0;
|
| + right: 0;
|
| + }
|
| + </style>
|
| + <script>
|
| + %(timeline_js)s
|
| + </script>
|
| + <script>
|
| + document.addEventListener('DOMContentLoaded', function() {
|
| + var trace_data = window.atob('%(trace_data_base64)s');
|
| + var m = new tracing.TraceModel(trace_data);
|
| + var timelineViewEl = document.querySelector('.view');
|
| + ui.decorate(timelineViewEl, tracing.TimelineView);
|
| + timelineViewEl.model = m;
|
| + timelineViewEl.tabIndex = 1;
|
| + timelineViewEl.timeline.focusElement = timelineViewEl;
|
| + });
|
| + </script>
|
| + </head>
|
| + <body>
|
| + <div class="view"></view>
|
| + </body>
|
| +</html>"""
|
| +
|
| _DEFAULT_CHROME_CATEGORIES = '_DEFAULT_CHROME_CATEGORIES'
|
|
|
|
|
| @@ -29,6 +68,32 @@ def _GetTraceTimestamp():
|
| return time.strftime('%Y-%m-%d-%H%M%S', time.localtime())
|
|
|
|
|
| +def _PackageTraceAsHtml(trace_file_name, html_file_name):
|
| + trace_viewer_root = os.path.join(constants.DIR_SOURCE_ROOT,
|
| + 'third_party', 'trace-viewer')
|
| + build_dir = os.path.join(trace_viewer_root, 'build')
|
| + src_dir = os.path.join(trace_viewer_root, 'src')
|
| + if not build_dir in sys.path:
|
| + sys.path.append(build_dir)
|
| + generate = __import__('generate', {}, {})
|
| + parse_deps = __import__('parse_deps', {}, {})
|
| +
|
| + basename = os.path.splitext(trace_file_name)[0]
|
| + load_sequence = parse_deps.calc_load_sequence(
|
| + ['tracing/standalone_timeline_view.js'], [src_dir])
|
| +
|
| + with open(trace_file_name) as trace_file:
|
| + trace_data = base64.b64encode(trace_file.read())
|
| + with open(html_file_name, 'w') as html_file:
|
| + html = _TRACE_VIEWER_TEMPLATE % {
|
| + 'title': os.path.basename(os.path.splitext(trace_file_name)[0]),
|
| + 'timeline_js': generate.generate_js(load_sequence),
|
| + 'timeline_css': generate.generate_css(load_sequence),
|
| + 'trace_data_base64': trace_data
|
| + }
|
| + html_file.write(html)
|
| +
|
| +
|
| class ChromeTracingController(object):
|
| def __init__(self, adb, package_info, categories, ring_buffer):
|
| self._adb = adb
|
| @@ -208,7 +273,7 @@ def _StopTracing(controllers):
|
| controller.StopTracing()
|
|
|
|
|
| -def _PullTraces(controllers, output, compress):
|
| +def _PullTraces(controllers, output, compress, write_html):
|
| _PrintMessage('Downloading...', eol='')
|
| trace_files = []
|
| for controller in controllers:
|
| @@ -226,11 +291,18 @@ def _PullTraces(controllers, output, compress):
|
| else:
|
| result = trace_files[0]
|
|
|
| + if write_html:
|
| + result, trace_file = os.path.splitext(result)[0] + '.html', result
|
| + _PackageTraceAsHtml(trace_file, result)
|
| + if trace_file != result:
|
| + os.unlink(trace_file)
|
| +
|
| _PrintMessage('done')
|
| _PrintMessage('Trace written to %s' % os.path.abspath(result))
|
| + return result
|
|
|
|
|
| -def _CaptureAndPullTrace(controllers, interval, output, compress):
|
| +def _CaptureAndPullTrace(controllers, interval, output, compress, write_html):
|
| trace_type = ' + '.join(map(str, controllers))
|
| try:
|
| _StartTracing(controllers, interval)
|
| @@ -248,7 +320,7 @@ def _CaptureAndPullTrace(controllers, interval, output, compress):
|
| if interval:
|
| _PrintMessage('done')
|
|
|
| - _PullTraces(controllers, output, compress)
|
| + return _PullTraces(controllers, output, compress, write_html)
|
|
|
|
|
| def _ComputeChromeCategories(options):
|
| @@ -311,7 +383,14 @@ def main():
|
| 'GPU data.', action='store_true')
|
| parser.add_option_group(categories)
|
|
|
| - parser.add_option('-o', '--output', help='Save profile output to file.')
|
| + output_options = optparse.OptionGroup(parser, 'Output options')
|
| + output_options.add_option('-o', '--output', help='Save trace output to file.')
|
| + output_options.add_option('--html', help='Package trace into a standalone '
|
| + 'html file.', 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(_GetSupportedBrowsers().keys())
|
| parser.add_option('-b', '--browser', help='Select among installed browsers. '
|
| 'One of ' + ', '.join(browsers) + ', "stable" is used by '
|
| @@ -358,10 +437,13 @@ def main():
|
| _PrintMessage('No trace categories enabled.')
|
| return 1
|
|
|
| - _CaptureAndPullTrace(controllers,
|
| - options.time if not options.continuous else 0,
|
| - options.output,
|
| - options.compress)
|
| + result = _CaptureAndPullTrace(controllers,
|
| + options.time if not options.continuous else 0,
|
| + options.output,
|
| + options.compress,
|
| + options.html)
|
| + if options.view:
|
| + webbrowser.open(result)
|
|
|
|
|
| if __name__ == '__main__':
|
|
|