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 |