diff options
author | skyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-12 19:52:32 +0000 |
---|---|---|
committer | skyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-12 19:52:32 +0000 |
commit | 5d42aee40bbf4edff392a5ea6aa9e5334a35d030 (patch) | |
tree | 26126d388b9baaa3518fa67e357aaf546a0d53f1 /tools/android/adb_profile_chrome/systrace_controller.py | |
parent | a939586048b9a634d05feadb88d68efd98ecdca4 (diff) | |
download | chromium_src-5d42aee40bbf4edff392a5ea6aa9e5334a35d030.zip chromium_src-5d42aee40bbf4edff392a5ea6aa9e5334a35d030.tar.gz chromium_src-5d42aee40bbf4edff392a5ea6aa9e5334a35d030.tar.bz2 |
Move adb_profile_chrome under tools/android/
Move adb_profile_chrome from build/android/ to tools/android/ to make
its purpose clearer.
BUG=375754
TEST=tools/android/adb_profile_chrome/run_tests
Review URL: https://codereview.chromium.org/310413003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276779 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/android/adb_profile_chrome/systrace_controller.py')
-rw-r--r-- | tools/android/adb_profile_chrome/systrace_controller.py | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/tools/android/adb_profile_chrome/systrace_controller.py b/tools/android/adb_profile_chrome/systrace_controller.py new file mode 100644 index 0000000..369bc88 --- /dev/null +++ b/tools/android/adb_profile_chrome/systrace_controller.py @@ -0,0 +1,95 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import threading +import zlib + +from adb_profile_chrome import controllers +from adb_profile_chrome import util + +from pylib import cmd_helper + + +_SYSTRACE_OPTIONS = [ + # Compress the trace before sending it over USB. + '-z', + # Use a large trace buffer to increase the polling interval. + '-b', '16384' +] + +# Interval in seconds for sampling systrace data. +_SYSTRACE_INTERVAL = 15 + + +class SystraceController(controllers.BaseController): + def __init__(self, device, categories, ring_buffer): + controllers.BaseController.__init__(self) + self._device = device + self._categories = categories + self._ring_buffer = ring_buffer + self._done = threading.Event() + self._thread = None + self._trace_data = None + + def __repr__(self): + return 'systrace' + + @staticmethod + def GetCategories(device): + return device.old_interface.RunShellCommand('atrace --list_categories') + + def StartTracing(self, _): + self._thread = threading.Thread(target=self._CollectData) + self._thread.start() + + def StopTracing(self): + self._done.set() + + def PullTrace(self): + self._thread.join() + self._thread = None + if self._trace_data: + output_name = 'systrace-%s' % util.GetTraceTimestamp() + with open(output_name, 'w') as out: + out.write(self._trace_data) + 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_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) + + def _CollectData(self): + trace_data = [] + self._RunATraceCommand('async_start') + try: + while not self._done.is_set(): + self._done.wait(_SYSTRACE_INTERVAL) + if not self._ring_buffer or self._done.is_set(): + trace_data.append( + self._DecodeTraceData(self._RunATraceCommand('async_dump'))) + finally: + trace_data.append( + self._DecodeTraceData(self._RunATraceCommand('async_stop'))) + self._trace_data = ''.join([zlib.decompress(d) for d in trace_data]) + + @staticmethod + def _DecodeTraceData(trace_data): + try: + trace_start = trace_data.index('TRACE:') + except ValueError: + raise RuntimeError('Systrace start marker not found') + trace_data = trace_data[trace_start + 6:] + + # Collapse CRLFs that are added by adb shell. + if trace_data.startswith('\r\n'): + trace_data = trace_data.replace('\r\n', '\n') + + # Skip the initial newline. + return trace_data[1:] |