1# Copyright 2014 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 6 7from telemetry.internal.backends.chrome import android_browser_finder 8from telemetry.internal.platform import profiler 9 10import py_utils 11 12try: 13 from devil.android import device_errors # pylint: disable=import-error 14except ImportError: 15 device_errors = None 16 17 18class AndroidTraceviewProfiler(profiler.Profiler): 19 """Collects a Traceview on Android.""" 20 21 _DEFAULT_DEVICE_DIR = '/data/local/tmp/traceview' 22 23 def __init__(self, browser_backend, platform_backend, output_path, state): 24 super(AndroidTraceviewProfiler, self).__init__( 25 browser_backend, platform_backend, output_path, state) 26 27 if self._browser_backend.device.FileExists(self._DEFAULT_DEVICE_DIR): 28 # Note: command must be passed as a string to expand wildcards. 29 self._browser_backend.device.RunShellCommand( 30 'rm ' + os.path.join(self._DEFAULT_DEVICE_DIR, '*'), 31 check_return=True, shell=True) 32 else: 33 self._browser_backend.device.RunShellCommand( 34 ['mkdir', '-p', self._DEFAULT_DEVICE_DIR], check_return=True) 35 self._browser_backend.device.RunShellCommand( 36 ['chmod', '777', self._DEFAULT_DEVICE_DIR], check_return=True) 37 38 self._trace_files = [] 39 for pid in self._GetProcessOutputFileMap().iterkeys(): 40 device_dump_file = '%s/%s.trace' % (self._DEFAULT_DEVICE_DIR, pid) 41 self._trace_files.append((pid, device_dump_file)) 42 self._browser_backend.device.RunShellCommand( 43 ['am', 'profile', str(pid), 'start', device_dump_file], 44 check_return=True) 45 46 @classmethod 47 def name(cls): 48 return 'android-traceview' 49 50 @classmethod 51 def is_supported(cls, browser_type): 52 if browser_type == 'any': 53 return android_browser_finder.CanFindAvailableBrowsers() 54 return browser_type.startswith('android') 55 56 def CollectProfile(self): 57 output_files = [] 58 for pid, trace_file in self._trace_files: 59 self._browser_backend.device.RunShellCommand( 60 ['am', 'profile', str(pid), 'stop'], check_return=True) 61 # pylint: disable=cell-var-from-loop 62 py_utils.WaitFor(lambda: self._FileSize(trace_file) > 0, timeout=10) 63 output_files.append(trace_file) 64 self._browser_backend.device.PullFile( 65 self._DEFAULT_DEVICE_DIR, self._output_path) 66 # Note: command must be passed as a string to expand wildcards. 67 self._browser_backend.device.RunShellCommand( 68 'rm ' + os.path.join(self._DEFAULT_DEVICE_DIR, '*'), 69 check_return=True, shell=True) 70 print 'Traceview profiles available in ', self._output_path 71 print 'Use third_party/android_tools/sdk/tools/monitor ' 72 print 'then use "File->Open File" to visualize them.' 73 return output_files 74 75 def _FileSize(self, file_name): 76 try: 77 return self._browser_backend.device.FileSize(file_name) 78 except device_errors.CommandFailedError: 79 return 0 80