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