# found in the LICENSE file.
import gzip
+import json
import logging
import optparse
import os
from pylib import cmd_helper
from pylib import constants
from pylib import pexpect
+from pylib.device import device_utils
_TRACE_VIEWER_ROOT = os.path.join(constants.DIR_SOURCE_ROOT,
'third_party', 'trace-viewer')
class ChromeTracingController(object):
- def __init__(self, adb, package_info, categories, ring_buffer):
- self._adb = adb
+ def __init__(self, device, package_info, categories, ring_buffer):
+ 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_start_re = \
- re.compile(r'Logging performance trace to file: (.*)')
+ re.compile(r'Logging performance trace to file')
self._trace_finish_re = \
re.compile(r'Profiler finished[.] Results are in (.*)[.]')
- self._adb.StartMonitoringLogcat(clear=False)
+ self._device.old_interface.StartMonitoringLogcat(clear=False)
def __str__(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._adb.SyncLogCat()
- self._adb.BroadcastIntent(self._package_info.package, 'GPU_PROFILER_START',
- '-e categories "%s"' % ','.join(self._categories),
- '-e continuous' if self._ring_buffer else '')
+ 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 '')
# Chrome logs two different messages related to tracing:
#
- # 1. "Logging performance trace to file [...]"
+ # 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._trace_file = self._adb.WaitForLogMatch(self._trace_start_re,
- None,
- timeout=5).group(1)
+ 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):
- if not self._trace_file:
- return
- self._adb.BroadcastIntent(self._package_info.package, 'GPU_PROFILER_STOP')
- self._adb.WaitForLogMatch(self._trace_finish_re, None, timeout=120)
+ 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)
def PullTrace(self):
# Wait a bit for the browser to finish writing the trace file.
trace_file = self._trace_file.replace('/storage/emulated/0/', '/sdcard/')
host_file = os.path.join(os.path.curdir, os.path.basename(trace_file))
- self._adb.PullFileFromDevice(trace_file, host_file)
+ self._device.old_interface.PullFileFromDevice(trace_file, host_file)
return host_file
class SystraceController(object):
- def __init__(self, adb, categories, ring_buffer):
- self._adb = adb
+ def __init__(self, device, categories, ring_buffer):
+ self._device = device
self._categories = categories
self._ring_buffer = ring_buffer
self._done = threading.Event()
return 'systrace'
@staticmethod
- def GetCategories(adb):
- return adb.RunShellCommand('atrace --list_categories')
+ def GetCategories(device):
+ return device.old_interface.RunShellCommand('atrace --list_categories')
def StartTracing(self, _):
self._thread = threading.Thread(target=self._CollectData)
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 = ['-s', self._adb.GetDevice()] if self._adb.GetDevice() else []
- cmd = ['adb'] + device + ['shell', 'atrace', '--%s' % command] + \
+ 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)
'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=\'\'".',
+ 'disabled with "--categories=\'\'". Use "list" to see '
+ 'the available categories.',
metavar='CHROME_CATEGORIES', dest='chrome_categories',
default=_DEFAULT_CHROME_CATEGORIES)
categories.add_option('-s', '--systrace', help='Capture a systrace with the '
if options.verbose:
logging.getLogger().setLevel(logging.DEBUG)
- adb = android_commands.AndroidCommands()
+ devices = android_commands.GetAttachedDevices()
+ if len(devices) != 1:
+ parser.error('Exactly 1 device much be attached.')
+ device = device_utils.DeviceUtils(devices[0])
+ package_info = _GetSupportedBrowsers()[options.browser]
+
+ if options.chrome_categories in ['list', 'help']:
+ _PrintMessage('Collecting record categories list...', eol='')
+ record_categories = []
+ disabled_by_default_categories = []
+ record_categories, disabled_by_default_categories = \
+ ChromeTracingController.GetCategories(device, package_info)
+
+ _PrintMessage('done')
+ _PrintMessage('Record Categories:')
+ _PrintMessage('\n'.join('\t%s' % item \
+ for item in sorted(record_categories)))
+
+ _PrintMessage('\nDisabled by Default Categories:')
+ _PrintMessage('\n'.join('\t%s' % item \
+ for item in sorted(disabled_by_default_categories)))
+
+ return 0
+
if options.systrace_categories in ['list', 'help']:
- _PrintMessage('\n'.join(SystraceController.GetCategories(adb)))
+ _PrintMessage('\n'.join(SystraceController.GetCategories(device)))
return 0
if not options.time and not options.continuous:
chrome_categories = _ComputeChromeCategories(options)
systrace_categories = _ComputeSystraceCategories(options)
- package_info = _GetSupportedBrowsers()[options.browser]
if chrome_categories and 'webview' in systrace_categories:
logging.warning('Using the "webview" category in systrace together with '
controllers = []
if chrome_categories:
- controllers.append(ChromeTracingController(adb,
+ controllers.append(ChromeTracingController(device,
package_info,
chrome_categories,
options.ring_buffer))
if systrace_categories:
- controllers.append(SystraceController(adb,
+ controllers.append(SystraceController(device,
systrace_categories,
options.ring_buffer))