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 py_utils 8import re 9 10from profile_chrome import util 11from systrace import trace_result 12from systrace import tracing_agents 13 14 15_DDMS_SAMPLING_FREQUENCY_US = 100 16 17 18class 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 77class 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 85def try_create_agent(config): 86 if config.ddms: 87 return DdmsAgent(config.device, config.package_info) 88 return None 89 90def 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 96def get_config(options): 97 return DdmsConfig(options.device, options.package_info, options.ddms) 98