| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Provides an interface to communicate with the device via the adb command. | 5 """Provides an interface to communicate with the device via the adb command. |
| 6 | 6 |
| 7 Assumes adb binary is currently on system path. | 7 Assumes adb binary is currently on system path. |
| 8 """ | 8 """ |
| 9 | 9 |
| 10 import collections | 10 import collections |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 elapsed = 0 | 523 elapsed = 0 |
| 524 wait_period = 0.1 | 524 wait_period = 0.1 |
| 525 # Note that this doesn't take into account the time spent in ExtractPid(). | 525 # Note that this doesn't take into account the time spent in ExtractPid(). |
| 526 while self.ExtractPid(process) and elapsed < timeout_sec: | 526 while self.ExtractPid(process) and elapsed < timeout_sec: |
| 527 time.sleep(wait_period) | 527 time.sleep(wait_period) |
| 528 elapsed += wait_period | 528 elapsed += wait_period |
| 529 if elapsed >= timeout_sec: | 529 if elapsed >= timeout_sec: |
| 530 return 0 | 530 return 0 |
| 531 return processes_killed | 531 return processes_killed |
| 532 | 532 |
| 533 def StartActivity(self, package, activity, wait_for_completion=False, | 533 def _GetActivityCommand(self, package, activity, wait_for_completion, action, |
| 534 action='android.intent.action.VIEW', | 534 category, data, extras, trace_file_name, force_stop): |
| 535 category=None, data=None, | 535 """Creates command to start |package|'s activity on the device. |
| 536 extras=None, trace_file_name=None, | |
| 537 force_stop=False): | |
| 538 """Starts |package|'s activity on the device. | |
| 539 | 536 |
| 540 Args: | 537 Args - as for StartActivity |
| 541 package: Name of package to start (e.g. 'com.google.android.apps.chrome'). | 538 |
| 542 activity: Name of activity (e.g. '.Main' or | 539 Returns: |
| 543 'com.google.android.apps.chrome.Main'). | 540 the command to run on the target to start the activity |
| 544 wait_for_completion: wait for the activity to finish launching (-W flag). | |
| 545 action: string (e.g. "android.intent.action.MAIN"). Default is VIEW. | |
| 546 category: string (e.g. "android.intent.category.HOME") | |
| 547 data: Data string to pass to activity (e.g. 'http://www.example.com/'). | |
| 548 extras: Dict of extras to pass to activity. Values are significant. | |
| 549 trace_file_name: If used, turns on and saves the trace to this file name. | |
| 550 force_stop: force stop the target app before starting the activity (-S | |
| 551 flag). | |
| 552 """ | 541 """ |
| 553 cmd = 'am start -a %s' % action | 542 cmd = 'am start -a %s' % action |
| 554 if force_stop: | 543 if force_stop: |
| 555 cmd += ' -S' | 544 cmd += ' -S' |
| 556 if wait_for_completion: | 545 if wait_for_completion: |
| 557 cmd += ' -W' | 546 cmd += ' -W' |
| 558 if category: | 547 if category: |
| 559 cmd += ' -c %s' % category | 548 cmd += ' -c %s' % category |
| 560 if package and activity: | 549 if package and activity: |
| 561 cmd += ' -n %s/%s' % (package, activity) | 550 cmd += ' -n %s/%s' % (package, activity) |
| 562 if data: | 551 if data: |
| 563 cmd += ' -d "%s"' % data | 552 cmd += ' -d "%s"' % data |
| 564 if extras: | 553 if extras: |
| 565 for key in extras: | 554 for key in extras: |
| 566 value = extras[key] | 555 value = extras[key] |
| 567 if isinstance(value, str): | 556 if isinstance(value, str): |
| 568 cmd += ' --es' | 557 cmd += ' --es' |
| 569 elif isinstance(value, bool): | 558 elif isinstance(value, bool): |
| 570 cmd += ' --ez' | 559 cmd += ' --ez' |
| 571 elif isinstance(value, int): | 560 elif isinstance(value, int): |
| 572 cmd += ' --ei' | 561 cmd += ' --ei' |
| 573 else: | 562 else: |
| 574 raise NotImplementedError( | 563 raise NotImplementedError( |
| 575 'Need to teach StartActivity how to pass %s extras' % type(value)) | 564 'Need to teach StartActivity how to pass %s extras' % type(value)) |
| 576 cmd += ' %s %s' % (key, value) | 565 cmd += ' %s %s' % (key, value) |
| 577 if trace_file_name: | 566 if trace_file_name: |
| 578 cmd += ' --start-profiler ' + trace_file_name | 567 cmd += ' --start-profiler ' + trace_file_name |
| 568 return cmd |
| 569 |
| 570 def StartActivity(self, package, activity, wait_for_completion=False, |
| 571 action='android.intent.action.VIEW', |
| 572 category=None, data=None, |
| 573 extras=None, trace_file_name=None, |
| 574 force_stop=False): |
| 575 """Starts |package|'s activity on the device. |
| 576 |
| 577 Args: |
| 578 package: Name of package to start (e.g. 'com.google.android.apps.chrome'). |
| 579 activity: Name of activity (e.g. '.Main' or |
| 580 'com.google.android.apps.chrome.Main'). |
| 581 wait_for_completion: wait for the activity to finish launching (-W flag). |
| 582 action: string (e.g. "android.intent.action.MAIN"). Default is VIEW. |
| 583 category: string (e.g. "android.intent.category.HOME") |
| 584 data: Data string to pass to activity (e.g. 'http://www.example.com/'). |
| 585 extras: Dict of extras to pass to activity. Values are significant. |
| 586 trace_file_name: If used, turns on and saves the trace to this file name. |
| 587 force_stop: force stop the target app before starting the activity (-S |
| 588 flag). |
| 589 """ |
| 590 cmd = self._GetActivityCommand(package, activity, wait_for_completion, |
| 591 action, category, data, extras, |
| 592 trace_file_name, force_stop) |
| 579 self.RunShellCommand(cmd) | 593 self.RunShellCommand(cmd) |
| 580 | 594 |
| 595 def StartActivityTimed(self, package, activity, wait_for_completion=False, |
| 596 action='android.intent.action.VIEW', |
| 597 category=None, data=None, |
| 598 extras=None, trace_file_name=None, |
| 599 force_stop=False): |
| 600 """Starts |package|'s activity on the device, returning the start time |
| 601 |
| 602 Args - as for StartActivity |
| 603 |
| 604 Returns: |
| 605 a timestamp string for the time at which the activity started |
| 606 """ |
| 607 cmd = self._GetActivityCommand(package, activity, wait_for_completion, |
| 608 action, category, data, extras, |
| 609 trace_file_name, force_stop) |
| 610 self.StartMonitoringLogcat() |
| 611 self.RunShellCommand('log starting activity; ' + cmd) |
| 612 activity_started_re = re.compile('.*starting activity.*') |
| 613 m = self.WaitForLogMatch(activity_started_re, None) |
| 614 assert m |
| 615 start_line = m.group(0) |
| 616 return GetLogTimestamp(start_line, self.GetDeviceYear()) |
| 617 |
| 581 def GoHome(self): | 618 def GoHome(self): |
| 582 """Tell the device to return to the home screen. Blocks until completion.""" | 619 """Tell the device to return to the home screen. Blocks until completion.""" |
| 583 self.RunShellCommand('am start -W ' | 620 self.RunShellCommand('am start -W ' |
| 584 '-a android.intent.action.MAIN -c android.intent.category.HOME') | 621 '-a android.intent.action.MAIN -c android.intent.category.HOME') |
| 585 | 622 |
| 586 def CloseApplication(self, package): | 623 def CloseApplication(self, package): |
| 587 """Attempt to close down the application, using increasing violence. | 624 """Attempt to close down the application, using increasing violence. |
| 588 | 625 |
| 589 Args: | 626 Args: |
| 590 package: Name of the process to kill off, e.g. | 627 package: Name of the process to kill off, e.g. |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 if error_match: | 888 if error_match: |
| 852 return None | 889 return None |
| 853 success_match = success_re.search(line) | 890 success_match = success_re.search(line) |
| 854 if success_match: | 891 if success_match: |
| 855 return success_match | 892 return success_match |
| 856 logging.info('<<< Skipped Logcat Line:' + str(line)) | 893 logging.info('<<< Skipped Logcat Line:' + str(line)) |
| 857 except pexpect.TIMEOUT: | 894 except pexpect.TIMEOUT: |
| 858 raise pexpect.TIMEOUT( | 895 raise pexpect.TIMEOUT( |
| 859 'Timeout (%ds) exceeded waiting for pattern "%s" (tip: use -vv ' | 896 'Timeout (%ds) exceeded waiting for pattern "%s" (tip: use -vv ' |
| 860 'to debug)' % | 897 'to debug)' % |
| 861 (self._logcat.timeout, success_re.pattern)) | 898 (timeout, success_re.pattern)) |
| 862 except pexpect.EOF: | 899 except pexpect.EOF: |
| 863 # It seems that sometimes logcat can end unexpectedly. This seems | 900 # It seems that sometimes logcat can end unexpectedly. This seems |
| 864 # to happen during Chrome startup after a reboot followed by a cache | 901 # to happen during Chrome startup after a reboot followed by a cache |
| 865 # clean. I don't understand why this happens, but this code deals with | 902 # clean. I don't understand why this happens, but this code deals with |
| 866 # getting EOF in logcat. | 903 # getting EOF in logcat. |
| 867 logging.critical('Found EOF in adb logcat. Restarting...') | 904 logging.critical('Found EOF in adb logcat. Restarting...') |
| 868 # Rerun spawn with original arguments. Note that self._logcat.args[0] is | 905 # Rerun spawn with original arguments. Note that self._logcat.args[0] is |
| 869 # the path of adb, so we don't want it in the arguments. | 906 # the path of adb, so we don't want it in the arguments. |
| 870 self._logcat = pexpect.spawn('adb', | 907 self._logcat = pexpect.spawn('adb', |
| 871 self._logcat.args[1:], | 908 self._logcat.args[1:], |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1148 """ | 1185 """ |
| 1149 def __init__(self, output): | 1186 def __init__(self, output): |
| 1150 self._output = output | 1187 self._output = output |
| 1151 | 1188 |
| 1152 def write(self, data): | 1189 def write(self, data): |
| 1153 data = data.replace('\r\r\n', '\n') | 1190 data = data.replace('\r\r\n', '\n') |
| 1154 self._output.write(data) | 1191 self._output.write(data) |
| 1155 | 1192 |
| 1156 def flush(self): | 1193 def flush(self): |
| 1157 self._output.flush() | 1194 self._output.flush() |
| OLD | NEW |