| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 a variety of device interactions based on adb. | 5 """Provides a variety of device interactions based on adb. |
| 6 | 6 |
| 7 Eventually, this will be based on adb_wrapper. | 7 Eventually, this will be based on adb_wrapper. |
| 8 """ | 8 """ |
| 9 # pylint: disable=W0613 | 9 # pylint: disable=W0613 |
| 10 | 10 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES) | 65 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES) |
| 66 def RestartServer(): | 66 def RestartServer(): |
| 67 """Restarts the adb server. | 67 """Restarts the adb server. |
| 68 | 68 |
| 69 Raises: | 69 Raises: |
| 70 CommandFailedError if we fail to kill or restart the server. | 70 CommandFailedError if we fail to kill or restart the server. |
| 71 """ | 71 """ |
| 72 pylib.android_commands.AndroidCommands().RestartAdbServer() | 72 pylib.android_commands.AndroidCommands().RestartAdbServer() |
| 73 | 73 |
| 74 | 74 |
| 75 def _GetTimeStamp(): |
| 76 """Return a basic ISO 8601 time stamp with the current local time.""" |
| 77 return time.strftime('%Y%m%dT%H%M%S', time.localtime()) |
| 78 |
| 79 |
| 75 class DeviceUtils(object): | 80 class DeviceUtils(object): |
| 76 | 81 |
| 77 _VALID_SHELL_VARIABLE = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') | 82 _VALID_SHELL_VARIABLE = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') |
| 78 | 83 |
| 79 def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT, | 84 def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT, |
| 80 default_retries=_DEFAULT_RETRIES): | 85 default_retries=_DEFAULT_RETRIES): |
| 81 """DeviceUtils constructor. | 86 """DeviceUtils constructor. |
| 82 | 87 |
| 83 Args: | 88 Args: |
| 84 device: Either a device serial, an existing AdbWrapper instance, or an | 89 device: Either a device serial, an existing AdbWrapper instance, or an |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 self.RunShellCommand(cmd, as_root=as_root, check_return=True) | 503 self.RunShellCommand(cmd, as_root=as_root, check_return=True) |
| 499 | 504 |
| 500 if blocking: | 505 if blocking: |
| 501 wait_period = 0.1 | 506 wait_period = 0.1 |
| 502 while self._GetPidsImpl(process_name): | 507 while self._GetPidsImpl(process_name): |
| 503 time.sleep(wait_period) | 508 time.sleep(wait_period) |
| 504 | 509 |
| 505 return len(pids) | 510 return len(pids) |
| 506 | 511 |
| 507 @decorators.WithTimeoutAndRetriesFromInstance() | 512 @decorators.WithTimeoutAndRetriesFromInstance() |
| 508 def StartActivity(self, intent, blocking=False, trace_file_name=None, | 513 def StartActivity(self, intent_obj, blocking=False, trace_file_name=None, |
| 509 force_stop=False, timeout=None, retries=None): | 514 force_stop=False, timeout=None, retries=None): |
| 510 """Start package's activity on the device. | 515 """Start package's activity on the device. |
| 511 | 516 |
| 512 Args: | 517 Args: |
| 513 intent: An Intent to send. | 518 intent_obj: An Intent object to send. |
| 514 blocking: A boolean indicating whether we should wait for the activity to | 519 blocking: A boolean indicating whether we should wait for the activity to |
| 515 finish launching. | 520 finish launching. |
| 516 trace_file_name: If present, a string that both indicates that we want to | 521 trace_file_name: If present, a string that both indicates that we want to |
| 517 profile the activity and contains the path to which the | 522 profile the activity and contains the path to which the |
| 518 trace should be saved. | 523 trace should be saved. |
| 519 force_stop: A boolean indicating whether we should stop the activity | 524 force_stop: A boolean indicating whether we should stop the activity |
| 520 before starting it. | 525 before starting it. |
| 521 timeout: timeout in seconds | 526 timeout: timeout in seconds |
| 522 retries: number of retries | 527 retries: number of retries |
| 523 | 528 |
| 524 Raises: | 529 Raises: |
| 525 CommandFailedError if the activity could not be started. | 530 CommandFailedError if the activity could not be started. |
| 526 CommandTimeoutError on timeout. | 531 CommandTimeoutError on timeout. |
| 527 DeviceUnreachableError on missing device. | 532 DeviceUnreachableError on missing device. |
| 528 """ | 533 """ |
| 529 single_category = (intent.category[0] if isinstance(intent.category, list) | 534 cmd = ['am', 'start'] |
| 530 else intent.category) | 535 if blocking: |
| 531 output = self.old_interface.StartActivity( | 536 cmd.append('-W') |
| 532 intent.package, intent.activity, wait_for_completion=blocking, | 537 if trace_file_name: |
| 533 action=intent.action, category=single_category, data=intent.data, | 538 cmd.extend(['--start-profiler', trace_file_name]) |
| 534 extras=intent.extras, trace_file_name=trace_file_name, | 539 if force_stop: |
| 535 force_stop=force_stop, flags=intent.flags) | 540 cmd.append('-S') |
| 536 for l in output: | 541 cmd.extend(intent_obj.am_args) |
| 537 if l.startswith('Error:'): | 542 for line in self.RunShellCommand(cmd, check_return=True): |
| 538 raise device_errors.CommandFailedError(l, str(self)) | 543 if line.startswith('Error:'): |
| 544 raise device_errors.CommandFailedError(line, str(self)) |
| 539 | 545 |
| 540 @decorators.WithTimeoutAndRetriesFromInstance() | 546 @decorators.WithTimeoutAndRetriesFromInstance() |
| 541 def StartInstrumentation(self, component, finish=True, raw=False, | 547 def StartInstrumentation(self, component, finish=True, raw=False, |
| 542 extras=None, timeout=None, retries=None): | 548 extras=None, timeout=None, retries=None): |
| 543 if extras is None: | 549 if extras is None: |
| 544 extras = {} | 550 extras = {} |
| 545 | 551 |
| 546 cmd = ['am', 'instrument'] | 552 cmd = ['am', 'instrument'] |
| 547 if finish: | 553 if finish: |
| 548 cmd.append('-w') | 554 cmd.append('-w') |
| 549 if raw: | 555 if raw: |
| 550 cmd.append('-r') | 556 cmd.append('-r') |
| 551 for k, v in extras.iteritems(): | 557 for k, v in extras.iteritems(): |
| 552 cmd.extend(['-e', k, v]) | 558 cmd.extend(['-e', k, v]) |
| 553 cmd.append(component) | 559 cmd.append(component) |
| 554 return self.RunShellCommand(cmd, check_return=True) | 560 return self.RunShellCommand(cmd, check_return=True) |
| 555 | 561 |
| 556 @decorators.WithTimeoutAndRetriesFromInstance() | 562 @decorators.WithTimeoutAndRetriesFromInstance() |
| 557 def BroadcastIntent(self, intent, timeout=None, retries=None): | 563 def BroadcastIntent(self, intent_obj, timeout=None, retries=None): |
| 558 """Send a broadcast intent. | 564 """Send a broadcast intent. |
| 559 | 565 |
| 560 Args: | 566 Args: |
| 561 intent: An Intent to broadcast. | 567 intent: An Intent to broadcast. |
| 562 timeout: timeout in seconds | 568 timeout: timeout in seconds |
| 563 retries: number of retries | 569 retries: number of retries |
| 564 | 570 |
| 565 Raises: | 571 Raises: |
| 566 CommandTimeoutError on timeout. | 572 CommandTimeoutError on timeout. |
| 567 DeviceUnreachableError on missing device. | 573 DeviceUnreachableError on missing device. |
| 568 """ | 574 """ |
| 569 cmd = ['am', 'broadcast', '-a', intent.action] | 575 cmd = ['am', 'broadcast'] + intent_obj.am_args |
| 570 if intent.extras: | |
| 571 for key, value in intent.extras.iteritems(): | |
| 572 if key: | |
| 573 cmd.extend(['-e', key]) | |
| 574 if value: | |
| 575 cmd.append(str(value)) | |
| 576 self.RunShellCommand(cmd, check_return=True) | 576 self.RunShellCommand(cmd, check_return=True) |
| 577 | 577 |
| 578 @decorators.WithTimeoutAndRetriesFromInstance() | 578 @decorators.WithTimeoutAndRetriesFromInstance() |
| 579 def GoHome(self, timeout=None, retries=None): | 579 def GoHome(self, timeout=None, retries=None): |
| 580 """Return to the home screen. | 580 """Return to the home screen. |
| 581 | 581 |
| 582 Args: | 582 Args: |
| 583 timeout: timeout in seconds | 583 timeout: timeout in seconds |
| 584 retries: number of retries | 584 retries: number of retries |
| 585 | 585 |
| (...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1191 except IndexError: | 1191 except IndexError: |
| 1192 pass | 1192 pass |
| 1193 return procs_pids | 1193 return procs_pids |
| 1194 | 1194 |
| 1195 @decorators.WithTimeoutAndRetriesFromInstance() | 1195 @decorators.WithTimeoutAndRetriesFromInstance() |
| 1196 def TakeScreenshot(self, host_path=None, timeout=None, retries=None): | 1196 def TakeScreenshot(self, host_path=None, timeout=None, retries=None): |
| 1197 """Takes a screenshot of the device. | 1197 """Takes a screenshot of the device. |
| 1198 | 1198 |
| 1199 Args: | 1199 Args: |
| 1200 host_path: A string containing the path on the host to save the | 1200 host_path: A string containing the path on the host to save the |
| 1201 screenshot to. If None, a file name will be generated. | 1201 screenshot to. If None, a file name in the current |
| 1202 directory will be generated. |
| 1202 timeout: timeout in seconds | 1203 timeout: timeout in seconds |
| 1203 retries: number of retries | 1204 retries: number of retries |
| 1204 | 1205 |
| 1205 Returns: | 1206 Returns: |
| 1206 The name of the file on the host to which the screenshot was saved. | 1207 The name of the file on the host to which the screenshot was saved. |
| 1207 | 1208 |
| 1208 Raises: | 1209 Raises: |
| 1209 CommandFailedError on failure. | 1210 CommandFailedError on failure. |
| 1210 CommandTimeoutError on timeout. | 1211 CommandTimeoutError on timeout. |
| 1211 DeviceUnreachableError on missing device. | 1212 DeviceUnreachableError on missing device. |
| 1212 """ | 1213 """ |
| 1213 return self.old_interface.TakeScreenshot(host_path) | 1214 if not host_path: |
| 1215 host_path = os.path.abspath('screenshot-%s.png' % _GetTimeStamp()) |
| 1216 with device_temp_file.DeviceTempFile(self.adb, suffix='.png') as device_tmp: |
| 1217 self.RunShellCommand(['/system/bin/screencap', '-p', device_tmp.name], |
| 1218 check_return=True) |
| 1219 self.PullFile(device_tmp.name, host_path) |
| 1220 return host_path |
| 1214 | 1221 |
| 1215 @decorators.WithTimeoutAndRetriesFromInstance() | 1222 @decorators.WithTimeoutAndRetriesFromInstance() |
| 1216 def GetIOStats(self, timeout=None, retries=None): | 1223 def GetIOStats(self, timeout=None, retries=None): |
| 1217 """Gets cumulative disk IO stats since boot for all processes. | 1224 """Gets cumulative disk IO stats since boot for all processes. |
| 1218 | 1225 |
| 1219 Args: | 1226 Args: |
| 1220 timeout: timeout in seconds | 1227 timeout: timeout in seconds |
| 1221 retries: number of retries | 1228 retries: number of retries |
| 1222 | 1229 |
| 1223 Returns: | 1230 Returns: |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1269 Returns: | 1276 Returns: |
| 1270 A Parallelizer operating over |devices|. | 1277 A Parallelizer operating over |devices|. |
| 1271 """ | 1278 """ |
| 1272 if not devices: | 1279 if not devices: |
| 1273 devices = adb_wrapper.AdbWrapper.GetDevices() | 1280 devices = adb_wrapper.AdbWrapper.GetDevices() |
| 1274 devices = [d if isinstance(d, cls) else cls(d) for d in devices] | 1281 devices = [d if isinstance(d, cls) else cls(d) for d in devices] |
| 1275 if async: | 1282 if async: |
| 1276 return parallelizer.Parallelizer(devices) | 1283 return parallelizer.Parallelizer(devices) |
| 1277 else: | 1284 else: |
| 1278 return parallelizer.SyncParallelizer(devices) | 1285 return parallelizer.SyncParallelizer(devices) |
| OLD | NEW |