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 |