Home | History | Annotate | Download | only in bin
      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 
      7 import logging
      8 import optparse
      9 import os
     10 import sys
     11 import webbrowser
     12 
     13 _SYSTRACE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
     14 sys.path.append(_SYSTRACE_DIR)
     15 
     16 from profile_chrome import chrome_startup_tracing_agent
     17 from profile_chrome import flags
     18 from profile_chrome import profiler
     19 from profile_chrome import ui
     20 from systrace import util
     21 from systrace.tracing_agents import atrace_agent
     22 
     23 _CATAPULT_DIR = os.path.join(
     24     os.path.dirname(os.path.abspath(__file__)), '..', '..')
     25 sys.path.append(os.path.join(_CATAPULT_DIR, 'devil'))
     26 
     27 from devil.android import device_utils
     28 from devil.android.sdk import adb_wrapper
     29 
     30 
     31 _CHROME_STARTUP_MODULES = [atrace_agent, chrome_startup_tracing_agent]
     32 _DEFAULT_CHROME_CATEGORIES = '_DEFAULT_CHROME_CATEGORIES'
     33 
     34 
     35 def _CreateOptionParser():
     36   parser = optparse.OptionParser(description='Record about://tracing profiles '
     37                                  'from Android browsers startup, combined with '
     38                                  'Android systrace. See http://dev.chromium.org'
     39                                  '/developers/how-tos/trace-event-profiling-'
     40                                  'tool for detailed instructions for '
     41                                  'profiling.', conflict_handler='resolve')
     42   parser = util.get_main_options(parser)
     43 
     44   browsers = sorted(util.get_supported_browsers().keys())
     45   parser.add_option('-b', '--browser', help='Select among installed browsers. '
     46                     'One of ' + ', '.join(browsers) + ', "stable" is used by '
     47                     'default.', type='choice', choices=browsers,
     48                     default='stable')
     49   parser.add_option('-v', '--verbose', help='Verbose logging.',
     50                     action='store_true')
     51   parser.add_option('-z', '--compress', help='Compress the resulting trace '
     52                     'with gzip. ', action='store_true')
     53   parser.add_option('-t', '--time', help='Stops tracing after N seconds, 0 to '
     54                     'manually stop (startup trace ends after at most 5s).',
     55                     default=5, metavar='N', type='int', dest='trace_time')
     56 
     57   parser.add_option_group(chrome_startup_tracing_agent.add_options(parser))
     58   parser.add_option_group(atrace_agent.add_options(parser))
     59   parser.add_option_group(flags.OutputOptions(parser))
     60 
     61   return parser
     62 
     63 
     64 def main():
     65   parser = _CreateOptionParser()
     66   options, _ = parser.parse_args()
     67 
     68   if not options.device_serial_number:
     69     devices = [a.GetDeviceSerial() for a in adb_wrapper.AdbWrapper.Devices()]
     70     if len(devices) == 0:
     71       raise RuntimeError('No ADB devices connected.')
     72     elif len(devices) >= 2:
     73       raise RuntimeError('Multiple devices connected, serial number required')
     74     options.device_serial_number = devices[0]
     75 
     76   if options.verbose:
     77     logging.getLogger().setLevel(logging.DEBUG)
     78 
     79   devices = device_utils.DeviceUtils.HealthyDevices()
     80   if len(devices) != 1:
     81     logging.error('Exactly 1 device must be attached.')
     82     return 1
     83   device = devices[0]
     84   package_info = util.get_supported_browsers()[options.browser]
     85 
     86   options.device = device
     87   options.package_info = package_info
     88 
     89   # TODO(washingtonp): Once Systrace uses all of the profile_chrome agents,
     90   # manually setting these options will no longer be necessary and should be
     91   # removed.
     92   options.ring_buffer = False
     93   options.trace_memory = False
     94   options.chrome_categories = _DEFAULT_CHROME_CATEGORIES
     95 
     96   if options.atrace_categories in ['list', 'help']:
     97     atrace_agent.list_categories(atrace_agent.get_config(options))
     98     print '\n'
     99     return 0
    100   result = profiler.CaptureProfile(options,
    101                                    options.trace_time,
    102                                    _CHROME_STARTUP_MODULES,
    103                                    output=options.output_file,
    104                                    compress=options.compress,
    105                                    write_json=options.write_json)
    106   if options.view:
    107     if sys.platform == 'darwin':
    108       os.system('/usr/bin/open %s' % os.path.abspath(result))
    109     else:
    110       webbrowser.open(result)
    111 
    112 
    113 if __name__ == '__main__':
    114   sys.exit(main())
    115