1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#!/usr/bin/env python
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# found in the LICENSE file.
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import logging
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import optparse
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import os
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import sys
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import webbrowser
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from profile_chrome import chrome_controller
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from profile_chrome import perf_controller
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from profile_chrome import profiler
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from profile_chrome import systrace_controller
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from profile_chrome import ui
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)from pylib import android_commands
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)from pylib.device import device_utils
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)_DEFAULT_CHROME_CATEGORIES = '_DEFAULT_CHROME_CATEGORIES'
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)def _ComputeChromeCategories(options):
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  categories = []
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.trace_frame_viewer:
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    categories.append('disabled-by-default-cc.debug')
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.trace_ubercompositor:
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    categories.append('disabled-by-default-cc.debug*')
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.trace_gpu:
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    categories.append('disabled-by-default-gpu.debug*')
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.trace_flow:
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    categories.append('disabled-by-default-toplevel.flow')
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.trace_memory:
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    categories.append('disabled-by-default-memory')
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if options.trace_scheduler:
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    categories.append('disabled-by-default-cc.debug.scheduler')
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    categories.append('disabled-by-default-blink.scheduler')
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.chrome_categories:
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    categories += options.chrome_categories.split(',')
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return categories
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)def _ComputeSystraceCategories(options):
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if not options.systrace_categories:
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return []
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return options.systrace_categories.split(',')
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)def _ComputePerfCategories(options):
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if not perf_controller.PerfProfilerController.IsSupported():
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return []
5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if not options.perf_categories:
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return []
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return options.perf_categories.split(',')
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)def _OptionalValueCallback(default_value):
6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  def callback(option, _, __, parser):
6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    value = default_value
6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if parser.rargs and not parser.rargs[0].startswith('-'):
6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      value = parser.rargs.pop(0)
6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    setattr(parser.values, option.dest, value)
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return callback
6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)def _CreateOptionParser():
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser = optparse.OptionParser(description='Record about://tracing profiles '
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 'from Android browsers. See http://dev.'
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 'chromium.org/developers/how-tos/trace-event-'
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 'profiling-tool for detailed instructions for '
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                 'profiling.')
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  timed_options = optparse.OptionGroup(parser, 'Timed tracing')
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  timed_options.add_option('-t', '--time', help='Profile for N seconds and '
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          'download the resulting trace.', metavar='N',
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           type='float')
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser.add_option_group(timed_options)
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  cont_options = optparse.OptionGroup(parser, 'Continuous tracing')
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  cont_options.add_option('--continuous', help='Profile continuously until '
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          'stopped.', action='store_true')
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  cont_options.add_option('--ring-buffer', help='Use the trace buffer as a '
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          'ring buffer and save its contents when stopping '
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          'instead of appending events into one long trace.',
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          action='store_true')
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser.add_option_group(cont_options)
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome_opts = optparse.OptionGroup(parser, 'Chrome tracing options')
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome_opts.add_option('-c', '--categories', help='Select Chrome tracing '
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         'categories with comma-delimited wildcards, '
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         'e.g., "*", "cat1*,-cat1a". Omit this option to trace '
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         'Chrome\'s default categories. Chrome tracing can be '
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         'disabled with "--categories=\'\'". Use "list" to '
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         'see the available categories.',
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         metavar='CHROME_CATEGORIES', dest='chrome_categories',
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         default=_DEFAULT_CHROME_CATEGORIES)
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome_opts.add_option('--trace-cc',
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         help='Deprecated, use --trace-frame-viewer.',
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         action='store_true')
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome_opts.add_option('--trace-frame-viewer',
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         help='Enable enough trace categories for '
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         'compositor frame viewing.', action='store_true')
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome_opts.add_option('--trace-ubercompositor',
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         help='Enable enough trace categories for '
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         'ubercompositor frame data.', action='store_true')
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome_opts.add_option('--trace-gpu', help='Enable extra trace categories '
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         'for GPU data.', action='store_true')
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome_opts.add_option('--trace-flow', help='Enable extra trace categories '
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         'for IPC message flows.', action='store_true')
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome_opts.add_option('--trace-memory', help='Enable extra trace categories '
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         'for memory profile. (tcmalloc required)',
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         action='store_true')
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  chrome_opts.add_option('--trace-scheduler', help='Enable extra trace '
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         'categories for scheduler state',
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         action='store_true')
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser.add_option_group(chrome_opts)
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  systrace_opts = optparse.OptionGroup(parser, 'Systrace tracing options')
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  systrace_opts.add_option('-s', '--systrace', help='Capture a systrace with '
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        'the chosen comma-delimited systrace categories. You '
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        'can also capture a combined Chrome + systrace by '
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        'enable both types of categories. Use "list" to see '
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        'the available categories. Systrace is disabled by '
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        'default.', metavar='SYS_CATEGORIES',
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        dest='systrace_categories', default='')
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser.add_option_group(systrace_opts)
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if perf_controller.PerfProfilerController.IsSupported():
13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    perf_opts = optparse.OptionGroup(parser, 'Perf profiling options')
13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    perf_opts.add_option('-p', '--perf', help='Capture a perf profile with '
13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         'the chosen comma-delimited event categories. '
13546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         'Samples CPU cycles by default. Use "list" to see '
13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         'the available sample types.', action='callback',
13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         default='', callback=_OptionalValueCallback('cycles'),
13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                         metavar='PERF_CATEGORIES', dest='perf_categories')
13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    parser.add_option_group(perf_opts)
14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  output_options = optparse.OptionGroup(parser, 'Output options')
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  output_options.add_option('-o', '--output', help='Save trace output to file.')
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  output_options.add_option('--json', help='Save trace as raw JSON instead of '
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            'HTML.', action='store_true')
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  output_options.add_option('--view', help='Open resulting trace file in a '
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            'browser.', action='store_true')
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser.add_option_group(output_options)
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  browsers = sorted(profiler.GetSupportedBrowsers().keys())
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser.add_option('-b', '--browser', help='Select among installed browsers. '
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    'One of ' + ', '.join(browsers) + ', "stable" is used by '
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    'default.', type='choice', choices=browsers,
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    default='stable')
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser.add_option('-v', '--verbose', help='Verbose logging.',
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    action='store_true')
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser.add_option('-z', '--compress', help='Compress the resulting trace '
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    'with gzip. ', action='store_true')
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return parser
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)def main():
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser = _CreateOptionParser()
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  options, _args = parser.parse_args()
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.trace_cc:
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    parser.parse_error("""--trace-cc is deprecated.
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)For basic jank busting uses, use  --trace-frame-viewer
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)For detailed study of ubercompositor, pass --trace-ubercompositor.
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)When in doubt, just try out --trace-frame-viewer.
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)""")
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.verbose:
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    logging.getLogger().setLevel(logging.DEBUG)
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  devices = android_commands.GetAttachedDevices()
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if len(devices) != 1:
178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    parser.error('Exactly 1 device must be attached.')
179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  device = device_utils.DeviceUtils(devices[0])
180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  package_info = profiler.GetSupportedBrowsers()[options.browser]
181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.chrome_categories in ['list', 'help']:
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui.PrintMessage('Collecting record categories list...', eol='')
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    record_categories = []
185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    disabled_by_default_categories = []
186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    record_categories, disabled_by_default_categories = \
187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        chrome_controller.ChromeTracingController.GetCategories(
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            device, package_info)
189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui.PrintMessage('done')
191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui.PrintMessage('Record Categories:')
192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui.PrintMessage('\n'.join('\t%s' % item \
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        for item in sorted(record_categories)))
194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui.PrintMessage('\nDisabled by Default Categories:')
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui.PrintMessage('\n'.join('\t%s' % item \
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        for item in sorted(disabled_by_default_categories)))
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return 0
200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.systrace_categories in ['list', 'help']:
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui.PrintMessage('\n'.join(
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        systrace_controller.SystraceController.GetCategories(device)))
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return 0
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (perf_controller.PerfProfilerController.IsSupported() and
2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      options.perf_categories in ['list', 'help']):
20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    ui.PrintMessage('\n'.join(
20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        perf_controller.PerfProfilerController.GetCategories(device)))
21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return 0
21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if not options.time and not options.continuous:
213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui.PrintMessage('Time interval or continuous tracing should be specified.')
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return 1
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  chrome_categories = _ComputeChromeCategories(options)
217cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  systrace_categories = _ComputeSystraceCategories(options)
21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  perf_categories = _ComputePerfCategories(options)
219cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if chrome_categories and 'webview' in systrace_categories:
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    logging.warning('Using the "webview" category in systrace together with '
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                    'Chrome tracing results in duplicate trace events.')
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  enabled_controllers = []
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if chrome_categories:
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    enabled_controllers.append(
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        chrome_controller.ChromeTracingController(device,
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                  package_info,
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                  chrome_categories,
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                  options.ring_buffer,
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                  options.trace_memory))
232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if systrace_categories:
233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    enabled_controllers.append(
234cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        systrace_controller.SystraceController(device,
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                               systrace_categories,
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                               options.ring_buffer))
237cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if perf_categories:
23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    enabled_controllers.append(
24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        perf_controller.PerfProfilerController(device,
24146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                               perf_categories))
24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if not enabled_controllers:
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ui.PrintMessage('No trace categories enabled.')
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return 1
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.output:
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    options.output = os.path.expanduser(options.output)
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  result = profiler.CaptureProfile(
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      enabled_controllers,
251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      options.time if not options.continuous else 0,
252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      output=options.output,
253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      compress=options.compress,
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      write_json=options.json)
255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if options.view:
256cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if sys.platform == 'darwin':
257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      os.system('/usr/bin/open %s' % os.path.abspath(result))
258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    else:
259cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      webbrowser.open(result)
260