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