1# Copyright 2013 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 os 6import StringIO 7import subprocess 8import zipfile 9 10from telemetry.core import util 11from telemetry.core.backends.chrome import android_browser_finder 12from telemetry.core.platform import profiler 13from telemetry.core.platform import tracing_options 14 15_SYSTRACE_CATEGORIES = [ 16 'gfx', 17 'input', 18 'view', 19 'sched', 20 'freq', 21] 22 23class AndroidSystraceProfiler(profiler.Profiler): 24 """Collects a Systrace on Android.""" 25 26 def __init__(self, browser_backend, platform_backend, output_path, state): 27 super(AndroidSystraceProfiler, self).__init__( 28 browser_backend, platform_backend, output_path, state) 29 assert self._browser_backend.supports_tracing 30 self._output_path = output_path + '-trace.zip' 31 self._systrace_output_path = output_path + '.systrace' 32 33 # Use telemetry's own tracing backend instead the combined mode in 34 # adb_profile_chrome because some benchmarks also do tracing of their own 35 # and the two methods conflict. 36 options = tracing_options.TracingOptions() 37 options.enable_chrome_trace = True 38 self._browser_backend.StartTracing(options, timeout=10) 39 self._profiler = subprocess.Popen( 40 ['python', os.path.join(util.GetChromiumSrcDir(), 'tools', 41 'profile_chrome.py'), 42 '--categories', '', '--continuous', '--output', 43 self._systrace_output_path, '--json', '--systrace', 44 ','.join(_SYSTRACE_CATEGORIES)], 45 stdin=subprocess.PIPE, stdout=subprocess.PIPE) 46 47 @classmethod 48 def name(cls): 49 return 'android-systrace' 50 51 @classmethod 52 def is_supported(cls, browser_type): 53 if browser_type == 'any': 54 return android_browser_finder.CanFindAvailableBrowsers() 55 return browser_type.startswith('android') 56 57 def CollectProfile(self): 58 self._profiler.communicate(input='\n') 59 trace_result = self._browser_backend.StopTracing() 60 61 trace_file = StringIO.StringIO() 62 trace_result.Serialize(trace_file) 63 64 # Merge the chrome and systraces into a zip file. 65 with zipfile.ZipFile(self._output_path, 'w', zipfile.ZIP_DEFLATED) as z: 66 z.writestr('trace.json', trace_file.getvalue()) 67 z.write(self._systrace_output_path, 'systrace') 68 os.unlink(self._systrace_output_path) 69 70 print 'Systrace saved as %s' % self._output_path 71 print 'To view, open in chrome://tracing' 72 return [self._output_path] 73