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 |