• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2015 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import optparse
6import os
7import re
8
9import py_utils
10
11from profile_chrome import util
12from systrace import trace_result
13from systrace import tracing_agents
14
15
16_DDMS_SAMPLING_FREQUENCY_US = 100
17
18
19class DdmsAgent(tracing_agents.TracingAgent):
20  def __init__(self, device, package_info):
21    tracing_agents.TracingAgent.__init__(self)
22    self._device = device
23    self._package = package_info.package
24    self._output_file = None
25    self._supports_sampling = self._SupportsSampling()
26
27  def __repr__(self):
28    return 'ddms profile'
29
30  def _SupportsSampling(self):
31    for line in self._device.RunShellCommand(
32        ['am', '--help'], check_return=True):
33      if re.match(r'.*am profile start.*--sampling', line):
34        return True
35    return False
36
37  @py_utils.Timeout(tracing_agents.START_STOP_TIMEOUT)
38  def StartAgentTracing(self, config, timeout=None):
39    self._output_file = (
40        '/data/local/tmp/ddms-profile-%s' % util.GetTraceTimestamp())
41    cmd = ['am', 'profile', 'start']
42    if self._supports_sampling:
43      cmd.extend(['--sampling', str(_DDMS_SAMPLING_FREQUENCY_US)])
44    cmd.extend([self._package, self._output_file])
45    self._device.RunShellCommand(cmd, check_return=True)
46    return True
47
48  @py_utils.Timeout(tracing_agents.START_STOP_TIMEOUT)
49  def StopAgentTracing(self, timeout=None):
50    self._device.RunShellCommand(
51        ['am', 'profile', 'stop', self._package], check_return=True)
52    return True
53
54  @py_utils.Timeout(tracing_agents.GET_RESULTS_TIMEOUT)
55  def GetResults(self, timeout=None):
56    with open(self._PullTrace(), 'r') as f:
57      trace_data = f.read()
58    return trace_result.TraceResult('ddms', trace_data)
59
60  def _PullTrace(self):
61    if not self._output_file:
62      return None
63
64    host_file = os.path.join(
65        os.path.curdir, os.path.basename(self._output_file))
66    self._device.PullFile(self._output_file, host_file)
67    return host_file
68
69  def SupportsExplicitClockSync(self):
70    return False
71
72  def RecordClockSyncMarker(self, sync_id, did_record_sync_marker_callback):
73    # pylint: disable=unused-argument
74    assert self.SupportsExplicitClockSync(), ('Clock sync marker cannot be '
75        'recorded since explicit clock sync is not supported.')
76
77
78class DdmsConfig(tracing_agents.TracingConfig):
79  def __init__(self, device, package_info, ddms):
80    tracing_agents.TracingConfig.__init__(self)
81    self.device = device
82    self.package_info = package_info
83    self.ddms = ddms
84
85
86def try_create_agent(config):
87  if config.ddms:
88    return DdmsAgent(config.device, config.package_info)
89  return None
90
91def add_options(parser):
92  options = optparse.OptionGroup(parser, 'Java tracing')
93  options.add_option('--ddms', help='Trace Java execution using DDMS '
94                     'sampling.', action='store_true')
95  return options
96
97def get_config(options):
98  return DdmsConfig(options.device, options.package_info, options.ddms)
99