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 sys 8 9from devil.android.constants import chrome 10from devil.android import device_utils, device_errors 11 12class OptionParserIgnoreErrors(optparse.OptionParser): 13 """Wrapper for OptionParser that ignores errors and produces no output.""" 14 15 def error(self, msg): 16 pass 17 18 def exit(self, status=0, msg=None): 19 pass 20 21 def print_usage(self, out_file=None): 22 pass 23 24 def print_help(self, out_file=None): 25 pass 26 27 def print_version(self, out_file=None): 28 pass 29 30 31def run_adb_shell(shell_args, device_serial): 32 """Runs "adb shell" with the given arguments. 33 34 Args: 35 shell_args: array of arguments to pass to adb shell. 36 device_serial: if not empty, will add the appropriate command-line 37 parameters so that adb targets the given device. 38 Returns: 39 A tuple containing the adb output (stdout & stderr) and the return code 40 from adb. Will exit if adb fails to start. 41 """ 42 adb_output = [] 43 adb_return_code = 0 44 device = device_utils.DeviceUtils.HealthyDevices(device_arg=device_serial)[0] 45 try: 46 adb_output = device.RunShellCommand(shell_args, shell=False, 47 check_return=True, raw_output=True) 48 except device_errors.AdbShellCommandFailedError as error: 49 adb_return_code = error.status 50 adb_output = error.output 51 52 return (adb_output, adb_return_code) 53 54 55def get_tracing_path(device_serial=None): 56 """Uses adb to attempt to determine tracing path. The newest kernel doesn't 57 support mounting debugfs, so the Android master uses tracefs to replace it. 58 59 Returns: 60 /sys/kernel/debug/tracing for device with debugfs mount support; 61 /sys/kernel/tracing for device with tracefs support; 62 /sys/kernel/debug/tracing if support can't be determined. 63 """ 64 mount_info_args = ['mount'] 65 66 if device_serial is None: 67 parser = OptionParserIgnoreErrors() 68 parser.add_option('-e', '--serial', dest='device_serial', type='string') 69 options, _ = parser.parse_args() 70 device_serial = options.device_serial 71 72 adb_output, adb_return_code = run_adb_shell(mount_info_args, device_serial, ) 73 if adb_return_code == 0 and 'tracefs on /sys/kernel/tracing' in adb_output: 74 return '/sys/kernel/tracing' 75 return '/sys/kernel/debug/tracing' 76 77 78def get_device_sdk_version(): 79 """Uses adb to attempt to determine the SDK version of a running device.""" 80 81 getprop_args = ['getprop', 'ro.build.version.sdk'] 82 83 # get_device_sdk_version() is called before we even parse our command-line 84 # args. Therefore, parse just the device serial number part of the 85 # command-line so we can send the adb command to the correct device. 86 parser = OptionParserIgnoreErrors() 87 parser.add_option('-e', '--serial', dest='device_serial', type='string') 88 options, unused_args = parser.parse_args() # pylint: disable=unused-variable 89 90 success = False 91 92 adb_output, adb_return_code = run_adb_shell(getprop_args, 93 options.device_serial) 94 95 if adb_return_code == 0: 96 # ADB may print output other than the version number (e.g. it chould 97 # print a message about starting the ADB server). 98 # Break the ADB output into white-space delimited segments. 99 parsed_output = str.split(adb_output) 100 if parsed_output: 101 # Assume that the version number is the last thing printed by ADB. 102 version_string = parsed_output[-1] 103 if version_string: 104 try: 105 # Try to convert the text into an integer. 106 version = int(version_string) 107 except ValueError: 108 version = -1 109 else: 110 success = True 111 112 if not success: 113 print >> sys.stderr, adb_output 114 raise Exception("Failed to get device sdk version") 115 116 return version 117 118 119def get_supported_browsers(): 120 """Returns the package names of all supported browsers.""" 121 # Add aliases for backwards compatibility. 122 supported_browsers = { 123 'stable': chrome.PACKAGE_INFO['chrome_stable'], 124 'beta': chrome.PACKAGE_INFO['chrome_beta'], 125 'dev': chrome.PACKAGE_INFO['chrome_dev'], 126 'build': chrome.PACKAGE_INFO['chrome'], 127 } 128 supported_browsers.update(chrome.PACKAGE_INFO) 129 return supported_browsers 130 131 132def get_default_serial(): 133 if 'ANDROID_SERIAL' in os.environ: 134 return os.environ['ANDROID_SERIAL'] 135 return None 136 137 138def get_main_options(parser): 139 parser.add_option('-o', dest='output_file', help='write trace output to FILE', 140 default=None, metavar='FILE') 141 parser.add_option('-t', '--time', dest='trace_time', type='int', 142 help='trace for N seconds', metavar='N') 143 parser.add_option('-j', '--json', dest='write_json', 144 default=False, action='store_true', 145 help='write a JSON file') 146 parser.add_option('--link-assets', dest='link_assets', default=False, 147 action='store_true', 148 help='(deprecated)') 149 parser.add_option('--from-file', dest='from_file', action='store', 150 help='read the trace from a file (compressed) rather than' 151 'running a live trace') 152 parser.add_option('--asset-dir', dest='asset_dir', default='trace-viewer', 153 type='string', help='(deprecated)') 154 parser.add_option('-e', '--serial', dest='device_serial_number', 155 default=get_default_serial(), 156 type='string', help='adb device serial number') 157 parser.add_option('--target', dest='target', default='android', type='string', 158 help='choose tracing target (android or linux)') 159 parser.add_option('--timeout', dest='timeout', type='int', 160 help='timeout for start and stop tracing (seconds)') 161 parser.add_option('--collection-timeout', dest='collection_timeout', 162 type='int', help='timeout for data collection (seconds)') 163 parser.add_option('-a', '--app', dest='app_name', default=None, 164 type='string', action='store', 165 help='enable application-level tracing for ' 166 'comma-separated list of app cmdlines') 167 parser.add_option('-t', '--time', dest='trace_time', type='int', 168 help='trace for N seconds', metavar='N') 169 parser.add_option('-b', '--buf-size', dest='trace_buf_size', 170 type='int', help='use a trace buffer size ' 171 ' of N KB', metavar='N') 172 return parser 173