| OLD | NEW |
| 1 # Copyright (C) 2012 Google Inc. All rights reserved. | 1 # Copyright (C) 2012 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 return pids | 250 return pids |
| 251 | 251 |
| 252 def run(self, command, ignore_error=False): | 252 def run(self, command, ignore_error=False): |
| 253 self._log_debug('Run adb command: ' + str(command)) | 253 self._log_debug('Run adb command: ' + str(command)) |
| 254 if ignore_error: | 254 if ignore_error: |
| 255 error_handler = self._executive.ignore_error | 255 error_handler = self._executive.ignore_error |
| 256 else: | 256 else: |
| 257 error_handler = None | 257 error_handler = None |
| 258 | 258 |
| 259 result = self._executive.run_command(self.adb_command() + command, | 259 result = self._executive.run_command(self.adb_command() + command, |
| 260 error_handler=error_handler, | 260 error_handler=error_handler, debug_
logging=self._debug_logging) |
| 261 decode_output=False, | |
| 262 debug_logging=self._debug_logging) | |
| 263 | 261 |
| 264 # We limit the length to avoid outputting too verbose commands, such as
"adb logcat". | 262 # We limit the length to avoid outputting too verbose commands, such as
"adb logcat". |
| 265 self._log_debug('Run adb result: ' + result[:80].decode('ascii', errors=
'replace')) | 263 self._log_debug('Run adb result: ' + result[:80]) |
| 266 return result | 264 return result |
| 267 | 265 |
| 268 def get_serial(self): | 266 def get_serial(self): |
| 269 return self._device_serial | 267 return self._device_serial |
| 270 | 268 |
| 271 def adb_command(self): | 269 def adb_command(self): |
| 272 return [AndroidCommands.adb_command_path(self._executive, self._debug_lo
gging), '-s', self._device_serial] | 270 return [AndroidCommands.adb_command_path(self._executive, self._debug_lo
gging), '-s', self._device_serial] |
| 273 | 271 |
| 274 @staticmethod | 272 @staticmethod |
| 275 def set_adb_command_path_options(paths): | 273 def set_adb_command_path_options(paths): |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 _log.info('[%s] %s' % (self._device_serial, message)) | 306 _log.info('[%s] %s' % (self._device_serial, message)) |
| 309 | 307 |
| 310 def _log_debug(self, message): | 308 def _log_debug(self, message): |
| 311 if self._debug_logging: | 309 if self._debug_logging: |
| 312 _log.debug('[%s] %s' % (self._device_serial, message)) | 310 _log.debug('[%s] %s' % (self._device_serial, message)) |
| 313 | 311 |
| 314 @staticmethod | 312 @staticmethod |
| 315 def _determine_adb_version(adb_command_path, executive, debug_logging): | 313 def _determine_adb_version(adb_command_path, executive, debug_logging): |
| 316 re_version = re.compile('^.*version ([\d\.]+)') | 314 re_version = re.compile('^.*version ([\d\.]+)') |
| 317 try: | 315 try: |
| 318 output = executive.run_command([adb_command_path, 'version'], | 316 output = executive.run_command([adb_command_path, 'version'], error_
handler=executive.ignore_error, |
| 319 error_handler=executive.ignore_error, | |
| 320 decode_output=False, | |
| 321 debug_logging=debug_logging) | 317 debug_logging=debug_logging) |
| 322 except OSError: | 318 except OSError: |
| 323 return None | 319 return None |
| 324 | 320 |
| 325 result = re_version.match(output.decode('ascii', errors='replace')) | 321 result = re_version.match(output) |
| 326 if not output or not result: | 322 if not output or not result: |
| 327 return None | 323 return None |
| 328 | 324 |
| 329 return [int(n) for n in result.group(1).split('.')] | 325 return [int(n) for n in result.group(1).split('.')] |
| 330 | 326 |
| 331 | 327 |
| 332 # A class to encapsulate device status and information, such as the AndroidComma
nds | 328 # A class to encapsulate device status and information, such as the AndroidComma
nds |
| 333 # instances and whether the device has been set up. | 329 # instances and whether the device has been set up. |
| 334 class AndroidDevices(object): | 330 class AndroidDevices(object): |
| 335 # Percentage of battery a device needs to have in order for it to be conside
red | 331 # Percentage of battery a device needs to have in order for it to be conside
red |
| (...skipping 16 matching lines...) Expand all Loading... |
| 352 if self._default_device: | 348 if self._default_device: |
| 353 self._usable_devices = [AndroidCommands(executive, self._default_dev
ice, self._debug_logging)] | 349 self._usable_devices = [AndroidCommands(executive, self._default_dev
ice, self._debug_logging)] |
| 354 return self._usable_devices | 350 return self._usable_devices |
| 355 | 351 |
| 356 # Example "adb devices" command output: | 352 # Example "adb devices" command output: |
| 357 # List of devices attached | 353 # List of devices attached |
| 358 # 0123456789ABCDEF device | 354 # 0123456789ABCDEF device |
| 359 re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE) | 355 re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE) |
| 360 | 356 |
| 361 result = executive.run_command([AndroidCommands.adb_command_path(executi
ve, debug_logging=self._debug_logging), 'devices'], | 357 result = executive.run_command([AndroidCommands.adb_command_path(executi
ve, debug_logging=self._debug_logging), 'devices'], |
| 362 error_handler=executive.ignore_error, | 358 error_handler=executive.ignore_error, deb
ug_logging=self._debug_logging) |
| 363 decode_output=False, | 359 devices = re_device.findall(result) |
| 364 debug_logging=self._debug_logging) | |
| 365 devices = re_device.findall(result.decode('ascii', errors='replace')) | |
| 366 if not devices: | 360 if not devices: |
| 367 return [] | 361 return [] |
| 368 | 362 |
| 369 for device_serial in sorted(devices): | 363 for device_serial in sorted(devices): |
| 370 commands = AndroidCommands(executive, device_serial, self._debug_log
ging) | 364 commands = AndroidCommands(executive, device_serial, self._debug_log
ging) |
| 371 if self._battery_level_for_device(commands) < AndroidDevices.MINIMUM
_BATTERY_PERCENTAGE: | 365 if self._battery_level_for_device(commands) < AndroidDevices.MINIMUM
_BATTERY_PERCENTAGE: |
| 372 _log.warning('Device with serial "%s" skipped because it has les
s than %d percent battery.' | 366 _log.warning('Device with serial "%s" skipped because it has les
s than %d percent battery.' |
| 373 % (commands.get_serial(), AndroidDevices.MINIMUM_BA
TTERY_PERCENTAGE)) | 367 % (commands.get_serial(), AndroidDevices.MINIMUM_BA
TTERY_PERCENTAGE)) |
| 374 continue | 368 continue |
| 375 | 369 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 result = self._check_file_exists(self.path_to_forwarder(), 'forwarder ut
ility') and result | 501 result = self._check_file_exists(self.path_to_forwarder(), 'forwarder ut
ility') and result |
| 508 | 502 |
| 509 if not result: | 503 if not result: |
| 510 # There is a race condition in adb at least <= 4.3 on Linux that cau
ses it to go offline periodically | 504 # There is a race condition in adb at least <= 4.3 on Linux that cau
ses it to go offline periodically |
| 511 # We set the processor affinity for any running adb process to attem
pt to work around this. | 505 # We set the processor affinity for any running adb process to attem
pt to work around this. |
| 512 # See crbug.com/268450 | 506 # See crbug.com/268450 |
| 513 if self.host.platform.is_linux(): | 507 if self.host.platform.is_linux(): |
| 514 pids = self._executive.running_pids(lambda name: 'adb' in name) | 508 pids = self._executive.running_pids(lambda name: 'adb' in name) |
| 515 if not pids: | 509 if not pids: |
| 516 # Apparently adb is not running, which is unusual. Running a
ny adb command should start it. | 510 # Apparently adb is not running, which is unusual. Running a
ny adb command should start it. |
| 517 self._executive.run_command(['adb', 'devices'], | 511 self._executive.run_command(['adb', 'devices']) |
| 518 decode_output=False) | |
| 519 pids = self._executive.running_pids(lambda name: 'adb' in na
me) | 512 pids = self._executive.running_pids(lambda name: 'adb' in na
me) |
| 520 if not pids: | 513 if not pids: |
| 521 _log.error("The adb daemon does not appear to be running.") | 514 _log.error("The adb daemon does not appear to be running.") |
| 522 return False | 515 return False |
| 523 | 516 |
| 524 for pid in pids: | 517 for pid in pids: |
| 525 self._executive.run_command(['taskset', '-p', '-c', '0', str
(pid)], | 518 self._executive.run_command(['taskset', '-p', '-c', '0', str
(pid)]) |
| 526 decode_output=False) | |
| 527 | 519 |
| 528 if not result: | 520 if not result: |
| 529 _log.error('For complete Android build requirements, please see:') | 521 _log.error('For complete Android build requirements, please see:') |
| 530 _log.error('') | 522 _log.error('') |
| 531 _log.error(' https://www.chromium.org/developers/how-tos/android-
build-instructions') | 523 _log.error(' https://www.chromium.org/developers/how-tos/android-
build-instructions') |
| 532 return test_run_results.UNEXPECTED_ERROR_EXIT_STATUS | 524 return test_run_results.UNEXPECTED_ERROR_EXIT_STATUS |
| 533 | 525 |
| 534 return self._check_devices(printer) | 526 return self._check_devices(printer) |
| 535 | 527 |
| 536 def _check_devices(self, printer): | 528 def _check_devices(self, printer): |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 | 727 |
| 736 def attach_to_pid(self, pid): | 728 def attach_to_pid(self, pid): |
| 737 assert(pid) | 729 assert(pid) |
| 738 assert(self._perf_process == None) | 730 assert(self._perf_process == None) |
| 739 # FIXME: This can't be a fixed timeout! | 731 # FIXME: This can't be a fixed timeout! |
| 740 cmd = self._android_commands.adb_command() + ['shell', 'perf', 'record',
'-g', '-p', pid, 'sleep', 30] | 732 cmd = self._android_commands.adb_command() + ['shell', 'perf', 'record',
'-g', '-p', pid, 'sleep', 30] |
| 741 self._perf_process = self._host.executive.popen(cmd) | 733 self._perf_process = self._host.executive.popen(cmd) |
| 742 | 734 |
| 743 def _perf_version_string(self, perf_path): | 735 def _perf_version_string(self, perf_path): |
| 744 try: | 736 try: |
| 745 return self._host.executive.run_command([perf_path, '--version'], | 737 return self._host.executive.run_command([perf_path, '--version']) |
| 746 decode_output=False) | |
| 747 except: | 738 except: |
| 748 return None | 739 return None |
| 749 | 740 |
| 750 def _find_perfhost_binary(self): | 741 def _find_perfhost_binary(self): |
| 751 perfhost_version = self._perf_version_string('perfhost_linux') | 742 perfhost_version = self._perf_version_string('perfhost_linux') |
| 752 if perfhost_version: | 743 if perfhost_version: |
| 753 return 'perfhost_linux' | 744 return 'perfhost_linux' |
| 754 perf_version = self._perf_version_string('perf') | 745 perf_version = self._perf_version_string('perf') |
| 755 if perf_version: | 746 if perf_version: |
| 756 return 'perf' | 747 return 'perf' |
| (...skipping 20 matching lines...) Expand all Loading... |
| 777 | 768 |
| 778 perfhost_path = self._perfhost_path() | 769 perfhost_path = self._perfhost_path() |
| 779 perfhost_report_command = [ | 770 perfhost_report_command = [ |
| 780 'report', | 771 'report', |
| 781 '--input', self._output_path, | 772 '--input', self._output_path, |
| 782 '--symfs', self._symfs_path, | 773 '--symfs', self._symfs_path, |
| 783 '--kallsyms', self._kallsyms_path, | 774 '--kallsyms', self._kallsyms_path, |
| 784 ] | 775 ] |
| 785 if perfhost_path: | 776 if perfhost_path: |
| 786 perfhost_args = [perfhost_path] + perfhost_report_command + ['--call
-graph', 'none'] | 777 perfhost_args = [perfhost_path] + perfhost_report_command + ['--call
-graph', 'none'] |
| 787 perf_output = self._host.executive.run_command(perfhost_args, | 778 perf_output = self._host.executive.run_command(perfhost_args) |
| 788 decode_output=False) | |
| 789 # We could save off the full -g report to a file if users found that
useful. | 779 # We could save off the full -g report to a file if users found that
useful. |
| 790 _log.debug(self._first_ten_lines_of_profile(perf_output).decode('asc
ii', errors='replace')) | 780 _log.debug(self._first_ten_lines_of_profile(perf_output)) |
| 791 else: | 781 else: |
| 792 _log.debug(""" | 782 _log.debug(""" |
| 793 Failed to find perfhost_linux binary, can't process samples from the device. | 783 Failed to find perfhost_linux binary, can't process samples from the device. |
| 794 | 784 |
| 795 perfhost_linux can be built from: | 785 perfhost_linux can be built from: |
| 796 https://android.googlesource.com/platform/external/linux-tools-perf/ | 786 https://android.googlesource.com/platform/external/linux-tools-perf/ |
| 797 also, modern versions of perf (available from apt-get install goobuntu-kernel-to
ols-common) | 787 also, modern versions of perf (available from apt-get install goobuntu-kernel-to
ols-common) |
| 798 may also be able to process the perf.data files from the device. | 788 may also be able to process the perf.data files from the device. |
| 799 | 789 |
| 800 Googlers should read: | 790 Googlers should read: |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 return command | 1302 return command |
| 1313 | 1303 |
| 1314 def _read_prompt(self, deadline): | 1304 def _read_prompt(self, deadline): |
| 1315 last_char = '' | 1305 last_char = '' |
| 1316 while True: | 1306 while True: |
| 1317 current_char = self._server_process.read_stdout(deadline, 1) | 1307 current_char = self._server_process.read_stdout(deadline, 1) |
| 1318 if current_char == ' ': | 1308 if current_char == ' ': |
| 1319 if last_char in ('#', '$'): | 1309 if last_char in ('#', '$'): |
| 1320 return | 1310 return |
| 1321 last_char = current_char | 1311 last_char = current_char |
| OLD | NEW |