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 |