• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2#
3# Copyright 2015 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7import logging
8import optparse
9import os
10import sys
11import webbrowser
12
13_SYSTRACE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
14sys.path.append(_SYSTRACE_DIR)
15
16from profile_chrome import chrome_startup_controller
17from profile_chrome import controllers
18from profile_chrome import flags
19from profile_chrome import profiler
20from profile_chrome import systrace_controller
21from profile_chrome import ui
22
23_CATAPULT_DIR = os.path.join(
24    os.path.dirname(os.path.abspath(__file__)), '..', '..')
25sys.path.append(os.path.join(_CATAPULT_DIR, 'devil'))
26
27from devil.android import device_utils
28
29
30def _CreateOptionParser():
31  parser = optparse.OptionParser(description='Record about://tracing profiles '
32                                 'from Android browsers startup, combined with '
33                                 'Android systrace. See http://dev.chromium.org'
34                                 '/developers/how-tos/trace-event-profiling-'
35                                 'tool for detailed instructions for '
36                                 'profiling.')
37  parser.add_option('--url', help='URL to visit on startup. Default: '
38                    'https://www.google.com. An empty URL launches Chrome with'
39                    ' a MAIN action instead of VIEW.',
40                    default='https://www.google.com', metavar='URL')
41  parser.add_option('--cold', help='Flush the OS page cache before starting the'
42                    ' browser. Note that this require a device with root '
43                    'access.', default=False, action='store_true')
44  parser.add_option_group(flags.SystraceOptions(parser))
45  parser.add_option_group(flags.OutputOptions(parser))
46
47  browsers = sorted(profiler.GetSupportedBrowsers().keys())
48  parser.add_option('-b', '--browser', help='Select among installed browsers. '
49                    'One of ' + ', '.join(browsers) + ', "stable" is used by '
50                    'default.', type='choice', choices=browsers,
51                    default='stable')
52  parser.add_option('-v', '--verbose', help='Verbose logging.',
53                    action='store_true')
54  parser.add_option('-z', '--compress', help='Compress the resulting trace '
55                    'with gzip. ', action='store_true')
56  parser.add_option('-t', '--time', help='Stops tracing after N seconds, 0 to '
57                    'manually stop (startup trace ends after at most 5s).',
58                    default=5, metavar='N', type='int')
59  return parser
60
61
62def main():
63  parser = _CreateOptionParser()
64  options, _ = parser.parse_args()
65
66  if options.verbose:
67    logging.getLogger().setLevel(logging.DEBUG)
68
69  devices = device_utils.DeviceUtils.HealthyDevices()
70  if len(devices) != 1:
71    logging.error('Exactly 1 device must be attached.')
72    return 1
73  device = devices[0]
74  package_info = profiler.GetSupportedBrowsers()[options.browser]
75
76  if options.systrace_categories in ['list', 'help']:
77    ui.PrintMessage('\n'.join(
78        systrace_controller.SystraceController.GetCategories(device)))
79    return 0
80  systrace_categories = (options.systrace_categories.split(',')
81                         if options.systrace_categories else [])
82  enabled_controllers = []
83  # Enable the systrace and chrome controller. The systrace controller should go
84  # first because otherwise the resulting traces miss early systrace data.
85  if systrace_categories:
86    enabled_controllers.append(systrace_controller.SystraceController(
87        device, systrace_categories, False))
88  enabled_controllers.append(
89      chrome_startup_controller.ChromeStartupTracingController(
90          device, package_info, options.cold, options.url))
91  if options.output:
92    options.output = os.path.expanduser(options.output)
93  result = profiler.CaptureProfile(enabled_controllers,
94                                   options.time,
95                                   output=options.output,
96                                   compress=options.compress,
97                                   write_json=options.json)
98  if options.view:
99    if sys.platform == 'darwin':
100      os.system('/usr/bin/open %s' % os.path.abspath(result))
101    else:
102      webbrowser.open(result)
103
104
105if __name__ == '__main__':
106  sys.exit(main())
107