| 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 | 58 |
| 59 class DeviceUtils(object): | 59 class DeviceUtils(object): |
| 60 | 60 |
| 61 _VALID_SHELL_VARIABLE = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') | 61 _VALID_SHELL_VARIABLE = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') |
| 62 | 62 |
| 63 def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT, | 63 def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT, |
| 64 default_retries=_DEFAULT_RETRIES): | 64 default_retries=_DEFAULT_RETRIES): |
| 65 """DeviceUtils constructor. | 65 """DeviceUtils constructor. |
| 66 | 66 |
| 67 Args: | 67 Args: |
| 68 device: Either a device serial, an existing AdbWrapper instance, an | 68 device: Either a device serial, an existing AdbWrapper instance, or an |
| 69 an existing AndroidCommands instance, or nothing. | 69 an existing AndroidCommands instance. |
| 70 default_timeout: An integer containing the default number of seconds to | 70 default_timeout: An integer containing the default number of seconds to |
| 71 wait for an operation to complete if no explicit value | 71 wait for an operation to complete if no explicit value |
| 72 is provided. | 72 is provided. |
| 73 default_retries: An integer containing the default number or times an | 73 default_retries: An integer containing the default number or times an |
| 74 operation should be retried on failure if no explicit | 74 operation should be retried on failure if no explicit |
| 75 value is provided. | 75 value is provided. |
| 76 """ | 76 """ |
| 77 self.adb = None | 77 self.adb = None |
| 78 self.old_interface = None | 78 self.old_interface = None |
| 79 if isinstance(device, basestring): | 79 if isinstance(device, basestring): |
| 80 self.adb = adb_wrapper.AdbWrapper(device) | 80 self.adb = adb_wrapper.AdbWrapper(device) |
| 81 self.old_interface = pylib.android_commands.AndroidCommands(device) | 81 self.old_interface = pylib.android_commands.AndroidCommands(device) |
| 82 elif isinstance(device, adb_wrapper.AdbWrapper): | 82 elif isinstance(device, adb_wrapper.AdbWrapper): |
| 83 self.adb = device | 83 self.adb = device |
| 84 self.old_interface = pylib.android_commands.AndroidCommands(str(device)) | 84 self.old_interface = pylib.android_commands.AndroidCommands(str(device)) |
| 85 elif isinstance(device, pylib.android_commands.AndroidCommands): | 85 elif isinstance(device, pylib.android_commands.AndroidCommands): |
| 86 self.adb = adb_wrapper.AdbWrapper(device.GetDevice()) | 86 self.adb = adb_wrapper.AdbWrapper(device.GetDevice()) |
| 87 self.old_interface = device | 87 self.old_interface = device |
| 88 elif not device: | |
| 89 self.adb = adb_wrapper.AdbWrapper('') | |
| 90 self.old_interface = pylib.android_commands.AndroidCommands() | |
| 91 else: | 88 else: |
| 92 raise ValueError('Unsupported type passed for argument "device"') | 89 raise ValueError('Unsupported device value: %r' % device) |
| 93 self._commands_installed = None | 90 self._commands_installed = None |
| 94 self._default_timeout = default_timeout | 91 self._default_timeout = default_timeout |
| 95 self._default_retries = default_retries | 92 self._default_retries = default_retries |
| 96 self._cache = {} | 93 self._cache = {} |
| 97 assert hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR) | 94 assert hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR) |
| 98 assert hasattr(self, decorators.DEFAULT_RETRIES_ATTR) | 95 assert hasattr(self, decorators.DEFAULT_RETRIES_ATTR) |
| 99 | 96 |
| 100 @decorators.WithTimeoutAndRetriesFromInstance() | 97 @decorators.WithTimeoutAndRetriesFromInstance() |
| 101 def IsOnline(self, timeout=None, retries=None): | 98 def IsOnline(self, timeout=None, retries=None): |
| 102 """Checks whether the device is online. | 99 """Checks whether the device is online. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 128 Returns: | 125 Returns: |
| 129 True if adbd has root privileges, False otherwise. | 126 True if adbd has root privileges, False otherwise. |
| 130 | 127 |
| 131 Raises: | 128 Raises: |
| 132 CommandTimeoutError on timeout. | 129 CommandTimeoutError on timeout. |
| 133 DeviceUnreachableError on missing device. | 130 DeviceUnreachableError on missing device. |
| 134 """ | 131 """ |
| 135 try: | 132 try: |
| 136 self.RunShellCommand('ls /root', check_return=True) | 133 self.RunShellCommand('ls /root', check_return=True) |
| 137 return True | 134 return True |
| 138 except device_errors.AdbShellCommandFailedError: | 135 except device_errors.AdbCommandFailedError: |
| 139 return False | 136 return False |
| 140 | 137 |
| 141 def NeedsSU(self, timeout=None, retries=None): | 138 def NeedsSU(self, timeout=None, retries=None): |
| 142 """Checks whether 'su' is needed to access protected resources. | 139 """Checks whether 'su' is needed to access protected resources. |
| 143 | 140 |
| 144 Args: | 141 Args: |
| 145 timeout: timeout in seconds | 142 timeout: timeout in seconds |
| 146 retries: number of retries | 143 retries: number of retries |
| 147 | 144 |
| 148 Returns: | 145 Returns: |
| 149 True if 'su' is available on the device and is needed to to access | 146 True if 'su' is available on the device and is needed to to access |
| 150 protected resources; False otherwise if either 'su' is not available | 147 protected resources; False otherwise if either 'su' is not available |
| 151 (e.g. because the device has a user build), or not needed (because adbd | 148 (e.g. because the device has a user build), or not needed (because adbd |
| 152 already has root privileges). | 149 already has root privileges). |
| 153 | 150 |
| 154 Raises: | 151 Raises: |
| 155 CommandTimeoutError on timeout. | 152 CommandTimeoutError on timeout. |
| 156 DeviceUnreachableError on missing device. | 153 DeviceUnreachableError on missing device. |
| 157 """ | 154 """ |
| 158 if 'needs_su' not in self._cache: | 155 if 'needs_su' not in self._cache: |
| 159 try: | 156 try: |
| 160 self.RunShellCommand('su -c ls /root && ! ls /root', check_return=True, | 157 self.RunShellCommand('su -c ls /root && ! ls /root', check_return=True, |
| 161 timeout=timeout, retries=retries) | 158 timeout=timeout, retries=retries) |
| 162 self._cache['needs_su'] = True | 159 self._cache['needs_su'] = True |
| 163 except device_errors.AdbShellCommandFailedError: | 160 except device_errors.AdbCommandFailedError: |
| 164 self._cache['needs_su'] = False | 161 self._cache['needs_su'] = False |
| 165 return self._cache['needs_su'] | 162 return self._cache['needs_su'] |
| 166 | 163 |
| 167 | 164 |
| 168 @decorators.WithTimeoutAndRetriesFromInstance() | 165 @decorators.WithTimeoutAndRetriesFromInstance() |
| 169 def EnableRoot(self, timeout=None, retries=None): | 166 def EnableRoot(self, timeout=None, retries=None): |
| 170 """Restarts adbd with root privileges. | 167 """Restarts adbd with root privileges. |
| 171 | 168 |
| 172 Args: | 169 Args: |
| 173 timeout: timeout in seconds | 170 timeout: timeout in seconds |
| 174 retries: number of retries | 171 retries: number of retries |
| 175 | 172 |
| 176 Raises: | 173 Raises: |
| 177 CommandFailedError if root could not be enabled. | 174 CommandFailedError if root could not be enabled. |
| 178 CommandTimeoutError on timeout. | 175 CommandTimeoutError on timeout. |
| 179 """ | 176 """ |
| 177 if self.IsUserBuild(): |
| 178 raise device_errors.CommandFailedError( |
| 179 'Cannot enable root in user builds.', str(self)) |
| 180 if 'needs_su' in self._cache: | 180 if 'needs_su' in self._cache: |
| 181 del self._cache['needs_su'] | 181 del self._cache['needs_su'] |
| 182 if not self.old_interface.EnableAdbRoot(): | 182 self.adb.Root() |
| 183 raise device_errors.CommandFailedError( | 183 self.adb.WaitForDevice() |
| 184 'Could not enable root.', device=str(self)) | |
| 185 | 184 |
| 186 @decorators.WithTimeoutAndRetriesFromInstance() | 185 @decorators.WithTimeoutAndRetriesFromInstance() |
| 187 def IsUserBuild(self, timeout=None, retries=None): | 186 def IsUserBuild(self, timeout=None, retries=None): |
| 188 """Checks whether or not the device is running a user build. | 187 """Checks whether or not the device is running a user build. |
| 189 | 188 |
| 190 Args: | 189 Args: |
| 191 timeout: timeout in seconds | 190 timeout: timeout in seconds |
| 192 retries: number of retries | 191 retries: number of retries |
| 193 | 192 |
| 194 Returns: | 193 Returns: |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 Raises: | 263 Raises: |
| 265 CommandFailedError on failure. | 264 CommandFailedError on failure. |
| 266 CommandTimeoutError if one of the component waits times out. | 265 CommandTimeoutError if one of the component waits times out. |
| 267 DeviceUnreachableError if the device becomes unresponsive. | 266 DeviceUnreachableError if the device becomes unresponsive. |
| 268 """ | 267 """ |
| 269 def sd_card_ready(): | 268 def sd_card_ready(): |
| 270 try: | 269 try: |
| 271 self.RunShellCommand(['test', '-d', self.GetExternalStoragePath()], | 270 self.RunShellCommand(['test', '-d', self.GetExternalStoragePath()], |
| 272 check_return=True) | 271 check_return=True) |
| 273 return True | 272 return True |
| 274 except device_errors.AdbShellCommandFailedError: | 273 except device_errors.AdbCommandFailedError: |
| 275 return False | 274 return False |
| 276 | 275 |
| 277 def pm_ready(): | 276 def pm_ready(): |
| 278 try: | 277 try: |
| 279 return self.GetApplicationPath('android') | 278 return self.GetApplicationPath('android') |
| 280 except device_errors.CommandFailedError: | 279 except device_errors.CommandFailedError: |
| 281 return False | 280 return False |
| 282 | 281 |
| 283 def boot_completed(): | 282 def boot_completed(): |
| 284 return self.GetProp('sys.boot_completed') == '1' | 283 return self.GetProp('sys.boot_completed') == '1' |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 device_path = self.old_interface.GetApplicationPath(package_name) | 346 device_path = self.old_interface.GetApplicationPath(package_name) |
| 348 if device_path is not None: | 347 if device_path is not None: |
| 349 files_changed = self.old_interface.GetFilesChanged( | 348 files_changed = self.old_interface.GetFilesChanged( |
| 350 apk_path, device_path, ignore_filenames=True) | 349 apk_path, device_path, ignore_filenames=True) |
| 351 if len(files_changed) > 0: | 350 if len(files_changed) > 0: |
| 352 should_install = True | 351 should_install = True |
| 353 if not reinstall: | 352 if not reinstall: |
| 354 out = self.old_interface.Uninstall(package_name) | 353 out = self.old_interface.Uninstall(package_name) |
| 355 for line in out.splitlines(): | 354 for line in out.splitlines(): |
| 356 if 'Failure' in line: | 355 if 'Failure' in line: |
| 357 raise device_errors.CommandFailedError( | 356 raise device_errors.CommandFailedError(line.strip(), str(self)) |
| 358 line.strip(), device=str(self)) | |
| 359 else: | 357 else: |
| 360 should_install = False | 358 should_install = False |
| 361 else: | 359 else: |
| 362 should_install = True | 360 should_install = True |
| 363 if should_install: | 361 if should_install: |
| 364 try: | 362 try: |
| 365 out = self.old_interface.Install(apk_path, reinstall=reinstall) | 363 out = self.old_interface.Install(apk_path, reinstall=reinstall) |
| 366 for line in out.splitlines(): | 364 for line in out.splitlines(): |
| 367 if 'Failure' in line: | 365 if 'Failure' in line: |
| 368 raise device_errors.CommandFailedError( | 366 raise device_errors.CommandFailedError(line.strip(), str(self)) |
| 369 line.strip(), device=str(self)) | |
| 370 except AssertionError as e: | 367 except AssertionError as e: |
| 371 raise device_errors.CommandFailedError( | 368 raise device_errors.CommandFailedError( |
| 372 str(e), device=str(self)), None, sys.exc_info()[2] | 369 str(e), str(self)), None, sys.exc_info()[2] |
| 373 | 370 |
| 374 @decorators.WithTimeoutAndRetriesFromInstance() | 371 @decorators.WithTimeoutAndRetriesFromInstance() |
| 375 def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None, | 372 def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None, |
| 376 as_root=False, single_line=False, | 373 as_root=False, single_line=False, |
| 377 timeout=None, retries=None): | 374 timeout=None, retries=None): |
| 378 """Run an ADB shell command. | 375 """Run an ADB shell command. |
| 379 | 376 |
| 380 The command to run |cmd| should be a sequence of program arguments or else | 377 The command to run |cmd| should be a sequence of program arguments or else |
| 381 a single string. | 378 a single string. |
| 382 | 379 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 409 expected. | 406 expected. |
| 410 timeout: timeout in seconds | 407 timeout: timeout in seconds |
| 411 retries: number of retries | 408 retries: number of retries |
| 412 | 409 |
| 413 Returns: | 410 Returns: |
| 414 If single_line is False, the output of the command as a list of lines, | 411 If single_line is False, the output of the command as a list of lines, |
| 415 otherwise, a string with the unique line of output emmited by the command | 412 otherwise, a string with the unique line of output emmited by the command |
| 416 (with the optional newline at the end stripped). | 413 (with the optional newline at the end stripped). |
| 417 | 414 |
| 418 Raises: | 415 Raises: |
| 419 AdbShellCommandFailedError if check_return is True and the exit code of | 416 AdbCommandFailedError if check_return is True and the exit code of |
| 420 the command run on the device is non-zero. | 417 the command run on the device is non-zero. |
| 421 CommandFailedError if single_line is True but the output contains two or | 418 CommandFailedError if single_line is True but the output contains two or |
| 422 more lines. | 419 more lines. |
| 423 CommandTimeoutError on timeout. | 420 CommandTimeoutError on timeout. |
| 424 DeviceUnreachableError on missing device. | 421 DeviceUnreachableError on missing device. |
| 425 """ | 422 """ |
| 426 def env_quote(key, value): | 423 def env_quote(key, value): |
| 427 if not DeviceUtils._VALID_SHELL_VARIABLE.match(key): | 424 if not DeviceUtils._VALID_SHELL_VARIABLE.match(key): |
| 428 raise KeyError('Invalid shell variable name %r' % key) | 425 raise KeyError('Invalid shell variable name %r' % key) |
| 429 # using double quotes here to allow interpolation of shell variables | 426 # using double quotes here to allow interpolation of shell variables |
| 430 return '%s=%s' % (key, cmd_helper.DoubleQuote(value)) | 427 return '%s=%s' % (key, cmd_helper.DoubleQuote(value)) |
| 431 | 428 |
| 432 if not isinstance(cmd, basestring): | 429 if not isinstance(cmd, basestring): |
| 433 cmd = ' '.join(cmd_helper.SingleQuote(s) for s in cmd) | 430 cmd = ' '.join(cmd_helper.SingleQuote(s) for s in cmd) |
| 434 if env: | 431 if env: |
| 435 env = ' '.join(env_quote(k, v) for k, v in env.iteritems()) | 432 env = ' '.join(env_quote(k, v) for k, v in env.iteritems()) |
| 436 cmd = '%s %s' % (env, cmd) | 433 cmd = '%s %s' % (env, cmd) |
| 437 if cwd: | 434 if cwd: |
| 438 cmd = 'cd %s && %s' % (cmd_helper.SingleQuote(cwd), cmd) | 435 cmd = 'cd %s && %s' % (cmd_helper.SingleQuote(cwd), cmd) |
| 439 if as_root and self.NeedsSU(): | 436 if as_root and self.NeedsSU(): |
| 440 # "su -c sh -c" allows using shell features in |cmd| | 437 # "su -c sh -c" allows using shell features in |cmd| |
| 441 cmd = 'su -c sh -c %s' % cmd_helper.SingleQuote(cmd) | 438 cmd = 'su -c sh -c %s' % cmd_helper.SingleQuote(cmd) |
| 442 if timeout is None: | 439 if timeout is None: |
| 443 timeout = self._default_timeout | 440 timeout = self._default_timeout |
| 444 | 441 |
| 445 try: | 442 try: |
| 446 output = self.adb.Shell(cmd) | 443 output = self.adb.Shell(cmd) |
| 447 except device_errors.AdbShellCommandFailedError as e: | 444 except device_errors.AdbCommandFailedError as e: |
| 448 if check_return: | 445 if check_return: |
| 449 raise | 446 raise |
| 450 else: | 447 else: |
| 451 output = e.output | 448 output = e.output |
| 452 | 449 |
| 453 output = output.splitlines() | 450 output = output.splitlines() |
| 454 if single_line: | 451 if single_line: |
| 455 if not output: | 452 if not output: |
| 456 return '' | 453 return '' |
| 457 elif len(output) == 1: | 454 elif len(output) == 1: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 479 retries: number of retries | 476 retries: number of retries |
| 480 | 477 |
| 481 Raises: | 478 Raises: |
| 482 CommandFailedError if no process was killed. | 479 CommandFailedError if no process was killed. |
| 483 CommandTimeoutError on timeout. | 480 CommandTimeoutError on timeout. |
| 484 DeviceUnreachableError on missing device. | 481 DeviceUnreachableError on missing device. |
| 485 """ | 482 """ |
| 486 pids = self._GetPidsImpl(process_name) | 483 pids = self._GetPidsImpl(process_name) |
| 487 if not pids: | 484 if not pids: |
| 488 raise device_errors.CommandFailedError( | 485 raise device_errors.CommandFailedError( |
| 489 'No process "%s"' % process_name, device=str(self)) | 486 'No process "%s"' % process_name, str(self)) |
| 490 | 487 |
| 491 cmd = ['kill', '-%d' % signum] + pids.values() | 488 cmd = ['kill', '-%d' % signum] + pids.values() |
| 492 self.RunShellCommand(cmd, as_root=as_root, check_return=True) | 489 self.RunShellCommand(cmd, as_root=as_root, check_return=True) |
| 493 | 490 |
| 494 if blocking: | 491 if blocking: |
| 495 wait_period = 0.1 | 492 wait_period = 0.1 |
| 496 while self._GetPidsImpl(process_name): | 493 while self._GetPidsImpl(process_name): |
| 497 time.sleep(wait_period) | 494 time.sleep(wait_period) |
| 498 | 495 |
| 499 return len(pids) | 496 return len(pids) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 522 """ | 519 """ |
| 523 single_category = (intent.category[0] if isinstance(intent.category, list) | 520 single_category = (intent.category[0] if isinstance(intent.category, list) |
| 524 else intent.category) | 521 else intent.category) |
| 525 output = self.old_interface.StartActivity( | 522 output = self.old_interface.StartActivity( |
| 526 intent.package, intent.activity, wait_for_completion=blocking, | 523 intent.package, intent.activity, wait_for_completion=blocking, |
| 527 action=intent.action, category=single_category, data=intent.data, | 524 action=intent.action, category=single_category, data=intent.data, |
| 528 extras=intent.extras, trace_file_name=trace_file_name, | 525 extras=intent.extras, trace_file_name=trace_file_name, |
| 529 force_stop=force_stop, flags=intent.flags) | 526 force_stop=force_stop, flags=intent.flags) |
| 530 for l in output: | 527 for l in output: |
| 531 if l.startswith('Error:'): | 528 if l.startswith('Error:'): |
| 532 raise device_errors.CommandFailedError(l, device=str(self)) | 529 raise device_errors.CommandFailedError(l, str(self)) |
| 533 | 530 |
| 534 @decorators.WithTimeoutAndRetriesFromInstance() | 531 @decorators.WithTimeoutAndRetriesFromInstance() |
| 535 def StartInstrumentation(self, component, finish=True, raw=False, | 532 def StartInstrumentation(self, component, finish=True, raw=False, |
| 536 extras=None, timeout=None, retries=None): | 533 extras=None, timeout=None, retries=None): |
| 537 if extras is None: | 534 if extras is None: |
| 538 extras = {} | 535 extras = {} |
| 539 | 536 |
| 540 cmd = ['am', 'instrument'] | 537 cmd = ['am', 'instrument'] |
| 541 if finish: | 538 if finish: |
| 542 cmd.append('-w') | 539 cmd.append('-w') |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 timeout: timeout in seconds | 821 timeout: timeout in seconds |
| 825 retries: number of retries | 822 retries: number of retries |
| 826 | 823 |
| 827 Returns: | 824 Returns: |
| 828 True if the file exists on the device, False otherwise. | 825 True if the file exists on the device, False otherwise. |
| 829 | 826 |
| 830 Raises: | 827 Raises: |
| 831 CommandTimeoutError on timeout. | 828 CommandTimeoutError on timeout. |
| 832 DeviceUnreachableError on missing device. | 829 DeviceUnreachableError on missing device. |
| 833 """ | 830 """ |
| 834 return self.old_interface.FileExistsOnDevice(device_path) | 831 try: |
| 832 self.RunShellCommand(['test', '-e', device_path], check_return=True) |
| 833 return True |
| 834 except device_errors.AdbCommandFailedError: |
| 835 return False |
| 835 | 836 |
| 836 @decorators.WithTimeoutAndRetriesFromInstance() | 837 @decorators.WithTimeoutAndRetriesFromInstance() |
| 837 def PullFile(self, device_path, host_path, timeout=None, retries=None): | 838 def PullFile(self, device_path, host_path, timeout=None, retries=None): |
| 838 """Pull a file from the device. | 839 """Pull a file from the device. |
| 839 | 840 |
| 840 Args: | 841 Args: |
| 841 device_path: A string containing the absolute path of the file to pull | 842 device_path: A string containing the absolute path of the file to pull |
| 842 from the device. | 843 from the device. |
| 843 host_path: A string containing the absolute path of the destination on | 844 host_path: A string containing the absolute path of the destination on |
| 844 the host. | 845 the host. |
| 845 timeout: timeout in seconds | 846 timeout: timeout in seconds |
| 846 retries: number of retries | 847 retries: number of retries |
| 847 | 848 |
| 848 Raises: | 849 Raises: |
| 849 CommandFailedError on failure. | 850 CommandFailedError on failure. |
| 850 CommandTimeoutError on timeout. | 851 CommandTimeoutError on timeout. |
| 851 """ | 852 """ |
| 852 try: | 853 try: |
| 853 self.old_interface.PullFileFromDevice(device_path, host_path) | 854 self.old_interface.PullFileFromDevice(device_path, host_path) |
| 854 except AssertionError as e: | 855 except AssertionError as e: |
| 855 raise device_errors.CommandFailedError( | 856 raise device_errors.CommandFailedError( |
| 856 str(e), device=str(self)), None, sys.exc_info()[2] | 857 str(e), str(self)), None, sys.exc_info()[2] |
| 857 | 858 |
| 858 @decorators.WithTimeoutAndRetriesFromInstance() | 859 @decorators.WithTimeoutAndRetriesFromInstance() |
| 859 def ReadFile(self, device_path, as_root=False, timeout=None, retries=None): | 860 def ReadFile(self, device_path, as_root=False, timeout=None, retries=None): |
| 860 """Reads the contents of a file from the device. | 861 """Reads the contents of a file from the device. |
| 861 | 862 |
| 862 Args: | 863 Args: |
| 863 device_path: A string containing the absolute path of the file to read | 864 device_path: A string containing the absolute path of the file to read |
| 864 from the device. | 865 from the device. |
| 865 as_root: A boolean indicating whether the read should be executed with | 866 as_root: A boolean indicating whether the read should be executed with |
| 866 root privileges. | 867 root privileges. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 cache: A boolean indicating whether to cache the value of this property. | 979 cache: A boolean indicating whether to cache the value of this property. |
| 979 timeout: timeout in seconds | 980 timeout: timeout in seconds |
| 980 retries: number of retries | 981 retries: number of retries |
| 981 | 982 |
| 982 Returns: | 983 Returns: |
| 983 The value of the device's |property_name| property. | 984 The value of the device's |property_name| property. |
| 984 | 985 |
| 985 Raises: | 986 Raises: |
| 986 CommandTimeoutError on timeout. | 987 CommandTimeoutError on timeout. |
| 987 """ | 988 """ |
| 989 assert isinstance(property_name, basestring), ( |
| 990 "property_name is not a string: %r" % property_name) |
| 991 |
| 988 cache_key = '_prop:' + property_name | 992 cache_key = '_prop:' + property_name |
| 989 if cache and cache_key in self._cache: | 993 if cache and cache_key in self._cache: |
| 990 return self._cache[cache_key] | 994 return self._cache[cache_key] |
| 991 else: | 995 else: |
| 992 # timeout and retries are handled down at run shell, because we don't | 996 # timeout and retries are handled down at run shell, because we don't |
| 993 # want to apply them in the other branch when reading from the cache | 997 # want to apply them in the other branch when reading from the cache |
| 994 value = self.RunShellCommand(['getprop', property_name], | 998 value = self.RunShellCommand(['getprop', property_name], |
| 995 single_line=True, check_return=True, | 999 single_line=True, check_return=True, |
| 996 timeout=timeout, retries=retries) | 1000 timeout=timeout, retries=retries) |
| 997 if cache or cache_key in self._cache: | 1001 if cache or cache_key in self._cache: |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1011 check: A boolean indicating whether to check that the property was | 1015 check: A boolean indicating whether to check that the property was |
| 1012 successfully set on the device. | 1016 successfully set on the device. |
| 1013 timeout: timeout in seconds | 1017 timeout: timeout in seconds |
| 1014 retries: number of retries | 1018 retries: number of retries |
| 1015 | 1019 |
| 1016 Raises: | 1020 Raises: |
| 1017 CommandFailedError if check is true and the property was not correctly | 1021 CommandFailedError if check is true and the property was not correctly |
| 1018 set on the device (e.g. because it is not rooted). | 1022 set on the device (e.g. because it is not rooted). |
| 1019 CommandTimeoutError on timeout. | 1023 CommandTimeoutError on timeout. |
| 1020 """ | 1024 """ |
| 1025 assert isinstance(property_name, basestring), ( |
| 1026 "property_name is not a string: %r" % property_name) |
| 1027 assert isinstance(value, basestring), "value is not a string: %r" % value |
| 1028 |
| 1021 self.RunShellCommand(['setprop', property_name, value], check_return=True) | 1029 self.RunShellCommand(['setprop', property_name, value], check_return=True) |
| 1022 if property_name in self._cache: | 1030 if property_name in self._cache: |
| 1023 del self._cache[property_name] | 1031 del self._cache[property_name] |
| 1024 # TODO(perezju) remove the option and make the check mandatory, but using a | 1032 # TODO(perezju) remove the option and make the check mandatory, but using a |
| 1025 # single shell script to both set- and getprop. | 1033 # single shell script to both set- and getprop. |
| 1026 if check and value != self.GetProp(property_name): | 1034 if check and value != self.GetProp(property_name): |
| 1027 raise device_errors.CommandFailedError( | 1035 raise device_errors.CommandFailedError( |
| 1028 'Unable to set property %r on the device to %r' | 1036 'Unable to set property %r on the device to %r' |
| 1029 % (property_name, value), str(self)) | 1037 % (property_name, value), str(self)) |
| 1030 | 1038 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 - A dict containing the overall memory usage statistics for the PID. | 1135 - A dict containing the overall memory usage statistics for the PID. |
| 1128 - A dict containing memory usage statistics broken down by mapping. | 1136 - A dict containing memory usage statistics broken down by mapping. |
| 1129 | 1137 |
| 1130 Raises: | 1138 Raises: |
| 1131 CommandTimeoutError on timeout. | 1139 CommandTimeoutError on timeout. |
| 1132 """ | 1140 """ |
| 1133 return self.old_interface.GetMemoryUsageForPid(pid) | 1141 return self.old_interface.GetMemoryUsageForPid(pid) |
| 1134 | 1142 |
| 1135 def __str__(self): | 1143 def __str__(self): |
| 1136 """Returns the device serial.""" | 1144 """Returns the device serial.""" |
| 1137 s = self.old_interface.GetDevice() | 1145 return self.adb.GetDeviceSerial() |
| 1138 if not s: | |
| 1139 s = self.old_interface.Adb().GetSerialNumber() | |
| 1140 if s == 'unknown': | |
| 1141 raise device_errors.NoDevicesError() | |
| 1142 return s | |
| 1143 | 1146 |
| 1144 @staticmethod | 1147 @staticmethod |
| 1145 def parallel(devices=None, async=False): | 1148 def parallel(devices=None, async=False): |
| 1146 """Creates a Parallelizer to operate over the provided list of devices. | 1149 """Creates a Parallelizer to operate over the provided list of devices. |
| 1147 | 1150 |
| 1148 If |devices| is either |None| or an empty list, the Parallelizer will | 1151 If |devices| is either |None| or an empty list, the Parallelizer will |
| 1149 operate over all attached devices. | 1152 operate over all attached devices. |
| 1150 | 1153 |
| 1151 Args: | 1154 Args: |
| 1152 devices: A list of either DeviceUtils instances or objects from | 1155 devices: A list of either DeviceUtils instances or objects from |
| 1153 from which DeviceUtils instances can be constructed. If None, | 1156 from which DeviceUtils instances can be constructed. If None, |
| 1154 all attached devices will be used. | 1157 all attached devices will be used. |
| 1155 async: If true, returns a Parallelizer that runs operations | 1158 async: If true, returns a Parallelizer that runs operations |
| 1156 asynchronously. | 1159 asynchronously. |
| 1157 | 1160 |
| 1158 Returns: | 1161 Returns: |
| 1159 A Parallelizer operating over |devices|. | 1162 A Parallelizer operating over |devices|. |
| 1160 """ | 1163 """ |
| 1161 if not devices or len(devices) == 0: | 1164 if not devices or len(devices) == 0: |
| 1162 devices = pylib.android_commands.GetAttachedDevices() | 1165 devices = pylib.android_commands.GetAttachedDevices() |
| 1163 parallelizer_type = (parallelizer.Parallelizer if async | 1166 parallelizer_type = (parallelizer.Parallelizer if async |
| 1164 else parallelizer.SyncParallelizer) | 1167 else parallelizer.SyncParallelizer) |
| 1165 return parallelizer_type([ | 1168 return parallelizer_type([ |
| 1166 d if isinstance(d, DeviceUtils) else DeviceUtils(d) | 1169 d if isinstance(d, DeviceUtils) else DeviceUtils(d) |
| 1167 for d in devices]) | 1170 for d in devices]) |
| OLD | NEW |