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