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 |
11 import logging | 11 import logging |
12 import multiprocessing | 12 import multiprocessing |
13 import os | 13 import os |
14 import pipes | 14 import re |
15 import sys | 15 import sys |
16 import tempfile | 16 import tempfile |
17 import time | 17 import time |
18 import zipfile | 18 import zipfile |
19 | 19 |
20 import pylib.android_commands | 20 import pylib.android_commands |
21 from pylib import cmd_helper | |
21 from pylib.device import adb_wrapper | 22 from pylib.device import adb_wrapper |
22 from pylib.device import decorators | 23 from pylib.device import decorators |
23 from pylib.device import device_errors | 24 from pylib.device import device_errors |
24 from pylib.device.commands import install_commands | 25 from pylib.device.commands import install_commands |
25 from pylib.utils import apk_helper | 26 from pylib.utils import apk_helper |
26 from pylib.utils import host_utils | 27 from pylib.utils import host_utils |
27 from pylib.utils import parallelizer | 28 from pylib.utils import parallelizer |
28 | 29 |
29 _DEFAULT_TIMEOUT = 30 | 30 _DEFAULT_TIMEOUT = 30 |
30 _DEFAULT_RETRIES = 3 | 31 _DEFAULT_RETRIES = 3 |
32 _VALID_SHELL_VARIABLE = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') | |
jbudorick
2014/10/17 09:04:53
Not sure about having this at this scope; it shoul
perezju
2014/10/17 11:17:09
Done.
| |
31 | 33 |
32 | 34 |
33 @decorators.WithExplicitTimeoutAndRetries( | 35 @decorators.WithExplicitTimeoutAndRetries( |
34 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES) | 36 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES) |
35 def GetAVDs(): | 37 def GetAVDs(): |
36 """Returns a list of Android Virtual Devices. | 38 """Returns a list of Android Virtual Devices. |
37 | 39 |
38 Returns: | 40 Returns: |
39 A list containing the configured AVDs. | 41 A list containing the configured AVDs. |
40 """ | 42 """ |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 self.adb = adb_wrapper.AdbWrapper(device.GetDevice()) | 82 self.adb = adb_wrapper.AdbWrapper(device.GetDevice()) |
81 self.old_interface = device | 83 self.old_interface = device |
82 elif not device: | 84 elif not device: |
83 self.adb = adb_wrapper.AdbWrapper('') | 85 self.adb = adb_wrapper.AdbWrapper('') |
84 self.old_interface = pylib.android_commands.AndroidCommands() | 86 self.old_interface = pylib.android_commands.AndroidCommands() |
85 else: | 87 else: |
86 raise ValueError('Unsupported type passed for argument "device"') | 88 raise ValueError('Unsupported type passed for argument "device"') |
87 self._commands_installed = None | 89 self._commands_installed = None |
88 self._default_timeout = default_timeout | 90 self._default_timeout = default_timeout |
89 self._default_retries = default_retries | 91 self._default_retries = default_retries |
92 self._cache = {} | |
90 assert(hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR)) | 93 assert(hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR)) |
91 assert(hasattr(self, decorators.DEFAULT_RETRIES_ATTR)) | 94 assert(hasattr(self, decorators.DEFAULT_RETRIES_ATTR)) |
92 | 95 |
93 @decorators.WithTimeoutAndRetriesFromInstance() | 96 @decorators.WithTimeoutAndRetriesFromInstance() |
94 def IsOnline(self, timeout=None, retries=None): | 97 def IsOnline(self, timeout=None, retries=None): |
95 """Checks whether the device is online. | 98 """Checks whether the device is online. |
96 | 99 |
97 Args: | 100 Args: |
98 timeout: timeout in seconds | 101 timeout: timeout in seconds |
99 retries: number of retries | 102 retries: number of retries |
(...skipping 20 matching lines...) Expand all Loading... | |
120 Returns: | 123 Returns: |
121 True if adbd has root privileges, False otherwise. | 124 True if adbd has root privileges, False otherwise. |
122 | 125 |
123 Raises: | 126 Raises: |
124 CommandTimeoutError on timeout. | 127 CommandTimeoutError on timeout. |
125 DeviceUnreachableError on missing device. | 128 DeviceUnreachableError on missing device. |
126 """ | 129 """ |
127 return self._HasRootImpl() | 130 return self._HasRootImpl() |
128 | 131 |
129 def _HasRootImpl(self): | 132 def _HasRootImpl(self): |
130 return self.old_interface.IsRootEnabled() | 133 try: |
jbudorick
2014/10/17 09:04:53
Sneaking a conversion in here, I see.
| |
134 self._RunShellCommandImpl('ls /root') | |
135 return True | |
136 except device_errors.AdbShellCommandFailedError: | |
137 return False | |
131 | 138 |
132 @decorators.WithTimeoutAndRetriesFromInstance() | 139 @decorators.WithTimeoutAndRetriesFromInstance() |
133 def EnableRoot(self, timeout=None, retries=None): | 140 def EnableRoot(self, timeout=None, retries=None): |
134 """Restarts adbd with root privileges. | 141 """Restarts adbd with root privileges. |
135 | 142 |
136 Args: | 143 Args: |
137 timeout: timeout in seconds | 144 timeout: timeout in seconds |
138 retries: number of retries | 145 retries: number of retries |
139 | 146 |
140 Raises: | 147 Raises: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
175 The device's path to its SD card. | 182 The device's path to its SD card. |
176 | 183 |
177 Raises: | 184 Raises: |
178 CommandFailedError if the external storage path could not be determined. | 185 CommandFailedError if the external storage path could not be determined. |
179 CommandTimeoutError on timeout. | 186 CommandTimeoutError on timeout. |
180 DeviceUnreachableError on missing device. | 187 DeviceUnreachableError on missing device. |
181 """ | 188 """ |
182 return self._GetExternalStoragePathImpl() | 189 return self._GetExternalStoragePathImpl() |
183 | 190 |
184 def _GetExternalStoragePathImpl(self): | 191 def _GetExternalStoragePathImpl(self): |
185 try: | 192 if 'external_storage' in self._cache: |
jbudorick
2014/10/17 09:04:53
Another sneaky conversion.
| |
186 return self.old_interface.GetExternalStorage() | 193 return self._cache['external_storage'] |
187 except AssertionError as e: | 194 |
188 raise device_errors.CommandFailedError( | 195 value = self._RunShellCommandImpl('echo $EXTERNAL_STORAGE').rstrip() |
189 str(e), device=str(self)), None, sys.exc_info()[2] | 196 if not value: |
197 raise device_errors.CommandFailedError('$EXTERNAL_STORAGE is not set', | |
198 str(self)) | |
199 self._cache['external_storage'] = value | |
200 return value | |
190 | 201 |
191 @decorators.WithTimeoutAndRetriesFromInstance() | 202 @decorators.WithTimeoutAndRetriesFromInstance() |
192 def WaitUntilFullyBooted(self, wifi=False, timeout=None, retries=None): | 203 def WaitUntilFullyBooted(self, wifi=False, timeout=None, retries=None): |
193 """Wait for the device to fully boot. | 204 """Wait for the device to fully boot. |
194 | 205 |
195 This means waiting for the device to boot, the package manager to be | 206 This means waiting for the device to boot, the package manager to be |
196 available, and the SD card to be ready. It can optionally mean waiting | 207 available, and the SD card to be ready. It can optionally mean waiting |
197 for wifi to come up, too. | 208 for wifi to come up, too. |
198 | 209 |
199 Args: | 210 Args: |
200 wifi: A boolean indicating if we should wait for wifi to come up or not. | 211 wifi: A boolean indicating if we should wait for wifi to come up or not. |
201 timeout: timeout in seconds | 212 timeout: timeout in seconds |
202 retries: number of retries | 213 retries: number of retries |
203 | 214 |
204 Raises: | 215 Raises: |
205 CommandFailedError on failure. | 216 CommandFailedError on failure. |
206 CommandTimeoutError if one of the component waits times out. | 217 CommandTimeoutError if one of the component waits times out. |
207 DeviceUnreachableError if the device becomes unresponsive. | 218 DeviceUnreachableError if the device becomes unresponsive. |
208 """ | 219 """ |
209 self._WaitUntilFullyBootedImpl(wifi=wifi, timeout=timeout) | 220 self._WaitUntilFullyBootedImpl(wifi=wifi, timeout=timeout) |
210 | 221 |
211 def _WaitUntilFullyBootedImpl(self, wifi=False, timeout=None): | 222 def _WaitUntilFullyBootedImpl(self, wifi=False, timeout=None): |
212 if timeout is None: | 223 if timeout is None: |
213 timeout = self._default_timeout | 224 timeout = self._default_timeout |
214 self.old_interface.WaitForSystemBootCompleted(timeout) | 225 self.old_interface.WaitForSystemBootCompleted(timeout) |
215 self.old_interface.WaitForDevicePm() | 226 self.old_interface.WaitForDevicePm() |
216 self.old_interface.WaitForSdCardReady(timeout) | 227 self.old_interface.WaitForSdCardReady(timeout) |
217 if wifi: | 228 if wifi: |
218 while not 'Wi-Fi is enabled' in ( | 229 while not 'Wi-Fi is enabled' in ( |
219 self._RunShellCommandImpl('dumpsys wifi')): | 230 self.old_interface.RunShellCommand('dumpsys wifi')): |
jbudorick
2014/10/17 09:04:53
What's up with this? Is this because of the unit t
perezju
2014/10/17 11:17:09
Yes, because all the others are calls to old_inter
jbudorick
2014/10/17 15:48:00
Hmm. I'm not really a fan of either of those optio
| |
220 time.sleep(1) | 231 time.sleep(1) |
221 | 232 |
222 REBOOT_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT | 233 REBOOT_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT |
223 REBOOT_DEFAULT_RETRIES = _DEFAULT_RETRIES | 234 REBOOT_DEFAULT_RETRIES = _DEFAULT_RETRIES |
224 | 235 |
225 @decorators.WithTimeoutAndRetriesDefaults( | 236 @decorators.WithTimeoutAndRetriesDefaults( |
226 REBOOT_DEFAULT_TIMEOUT, | 237 REBOOT_DEFAULT_TIMEOUT, |
227 REBOOT_DEFAULT_RETRIES) | 238 REBOOT_DEFAULT_RETRIES) |
228 def Reboot(self, block=True, timeout=None, retries=None): | 239 def Reboot(self, block=True, timeout=None, retries=None): |
229 """Reboot the device. | 240 """Reboot the device. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
285 out = self.old_interface.Install(apk_path, reinstall=reinstall) | 296 out = self.old_interface.Install(apk_path, reinstall=reinstall) |
286 for line in out.splitlines(): | 297 for line in out.splitlines(): |
287 if 'Failure' in line: | 298 if 'Failure' in line: |
288 raise device_errors.CommandFailedError( | 299 raise device_errors.CommandFailedError( |
289 line.strip(), device=str(self)) | 300 line.strip(), device=str(self)) |
290 except AssertionError as e: | 301 except AssertionError as e: |
291 raise device_errors.CommandFailedError( | 302 raise device_errors.CommandFailedError( |
292 str(e), device=str(self)), None, sys.exc_info()[2] | 303 str(e), device=str(self)), None, sys.exc_info()[2] |
293 | 304 |
294 @decorators.WithTimeoutAndRetriesFromInstance() | 305 @decorators.WithTimeoutAndRetriesFromInstance() |
295 def RunShellCommand(self, cmd, check_return=False, as_root=False, cwd=None, | 306 def RunShellCommand(self, cmd, check_return=False, want_lines=True, |
296 env=None, timeout=None, retries=None): | 307 cwd=None, env=None, as_root=False, |
308 timeout=None, retries=None): | |
297 """Run an ADB shell command. | 309 """Run an ADB shell command. |
298 | 310 |
299 TODO(jbudorick) Switch the default value of check_return to True after | 311 When the command to run |cmd| is given as a string, it will be interpreted |
300 AndroidCommands is gone. | 312 and run by the shell on the device. |
313 | |
314 Alternatively, one can supply |cmd| as a sequence containing the name of | |
315 the command to run followed by its arguments. In this case, arguments are | |
316 passed to the command exactly as given, without any further processing by | |
317 the shell. This allows to easily pass arguments containing spaces or | |
318 special characters without having to worry about getting quoting right. | |
319 | |
320 TODO(perezju) Remove the options |check_return| and |want_lines|, | |
321 or change their default vaules, when callers have switched to the new | |
322 behaviour. | |
301 | 323 |
302 Args: | 324 Args: |
303 cmd: A list containing the command to run on the device and any arguments. | 325 cmd: A string with the full command to run on the device, or a sequence |
326 containing the command and its arguments. | |
304 check_return: A boolean indicating whether or not the return code should | 327 check_return: A boolean indicating whether or not the return code should |
305 be checked. | 328 be checked. |
306 as_root: A boolean indicating whether the shell command should be run | 329 want_lines: A boolean indicating whether to return the output of the |
jbudorick
2014/10/17 09:04:53
After looking at this and thinking about it, I'm n
| |
307 with root privileges. | 330 command as a list of lines or a single string. |
308 cwd: The device directory in which the command should be run. | 331 cwd: The device directory in which the command should be run. |
309 env: The environment variables with which the command should be run. | 332 env: The environment variables with which the command should be run. |
333 as_root: A boolean indicating whether the shell command should be run | |
334 with root privileges. | |
310 timeout: timeout in seconds | 335 timeout: timeout in seconds |
311 retries: number of retries | 336 retries: number of retries |
312 | 337 |
313 Returns: | 338 Returns: |
314 The output of the command. | 339 The output of the command either as list of lines, when want_lines is |
340 True, or a single string, otherwise. | |
315 | 341 |
316 Raises: | 342 Raises: |
317 CommandFailedError if check_return is True and the return code is nozero. | 343 AdbShellCommandFailedError if check_return is True and the exit code of |
344 the command run on the device is non-zero. | |
318 CommandTimeoutError on timeout. | 345 CommandTimeoutError on timeout. |
319 DeviceUnreachableError on missing device. | 346 DeviceUnreachableError on missing device. |
320 """ | 347 """ |
321 return self._RunShellCommandImpl( | 348 try: |
jbudorick
2014/10/17 09:04:53
This implementation all should move into the _Impl
perezju
2014/10/17 11:17:09
Done.
| |
322 cmd, check_return=check_return, as_root=as_root, cwd=cwd, env=env, | 349 output = self._RunShellCommandImpl(cmd, cwd=cwd, env=env, as_root=as_root) |
323 timeout=timeout) | 350 except device_errors.AdbShellCommandFailedError as e: |
351 if check_return: | |
352 raise | |
353 else: | |
354 output = e.output | |
355 if want_lines: | |
356 output = output.splitlines() | |
357 return output | |
324 | 358 |
325 def _RunShellCommandImpl(self, cmd, check_return=False, as_root=False, | 359 def _RunShellCommandImpl(self, cmd, cwd=None, env=None, as_root=False): |
jbudorick
2014/10/17 09:04:53
You'll have to restore the options you split betwe
| |
326 cwd=None, env=None, timeout=None): | 360 '''Implementation of RunShellCommand. |
327 # TODO(jbudorick): Remove the timeout parameter once this is no longer | 361 |
328 # backed by AndroidCommands. | 362 Note that this function already implements the proposed new behaviour of |
329 if isinstance(cmd, list): | 363 RunShellCommand (i.e, check_return=True, want_lines=False) and is available |
330 cmd = ' '.join(cmd) | 364 to be used by other DeviceUtils' methods. |
365 ''' | |
366 def env_quote(key, value): | |
367 if not _VALID_SHELL_VARIABLE.match(key): | |
368 raise KeyError('Invalid shell variable name %r' % key) | |
369 # using cmd_helper.dquote to quote but allow interpolation of shell vars | |
370 return '%s=%s' % (key, cmd_helper.dquote(value)) | |
jbudorick
2014/10/17 09:04:53
Maybe the dquote functionality should just live in
| |
371 | |
372 if not isinstance(cmd, basestring): | |
373 cmd = ' '.join(cmd_helper.quote(s) for s in cmd) | |
jbudorick
2014/10/17 09:04:53
I really don't like the 'quote = pipes.quote' in p
| |
331 if as_root and not self._HasRootImpl(): | 374 if as_root and not self._HasRootImpl(): |
332 cmd = 'su -c %s' % cmd | 375 cmd = 'su -c %s' % cmd |
333 if env: | 376 if env is not None: |
jbudorick
2014/10/17 09:04:53
As below, this change only matters if env is empty
perezju
2014/10/17 11:17:09
Acknowledged.
| |
334 cmd = '%s %s' % ( | 377 env = ' '.join(env_quote(k, v) for k, v in env.iteritems()) |
335 ' '.join('%s=%s' % (k, v) for k, v in env.iteritems()), cmd) | 378 cmd = '%s %s' % (env, cmd) |
336 if cwd: | 379 if cwd is not None: |
jbudorick
2014/10/17 09:04:53
The only time when this change matters is if cwd i
| |
337 cmd = 'cd %s && %s' % (cwd, cmd) | 380 cmd = 'cd %s && %s' % (cmd_helper.quote(cwd), cmd) |
338 if check_return: | 381 # TODO(perezju) still need to make sure that we call a version of adb.Shell |
339 code, output = self.old_interface.GetShellCommandStatusAndOutput( | 382 # without a timeout-and-retries wrapper. |
340 cmd, timeout_time=timeout) | 383 return self.adb.Shell(cmd, expect_rc=0) |
341 if int(code) != 0: | |
342 raise device_errors.AdbCommandFailedError( | |
343 cmd.split(), 'Nonzero exit code (%d)' % code, device=str(self)) | |
344 else: | |
345 output = self.old_interface.RunShellCommand(cmd, timeout_time=timeout) | |
346 return output | |
347 | 384 |
348 @decorators.WithTimeoutAndRetriesFromInstance() | 385 @decorators.WithTimeoutAndRetriesFromInstance() |
349 def KillAll(self, process_name, signum=9, as_root=False, blocking=False, | 386 def KillAll(self, process_name, signum=9, as_root=False, blocking=False, |
350 timeout=None, retries=None): | 387 timeout=None, retries=None): |
351 """Kill all processes with the given name on the device. | 388 """Kill all processes with the given name on the device. |
352 | 389 |
353 Args: | 390 Args: |
354 process_name: A string containing the name of the process to kill. | 391 process_name: A string containing the name of the process to kill. |
355 signum: An integer containing the signal number to send to kill. Defaults | 392 signum: An integer containing the signal number to send to kill. Defaults |
356 to 9 (SIGKILL). | 393 to 9 (SIGKILL). |
357 as_root: A boolean indicating whether the kill should be executed with | 394 as_root: A boolean indicating whether the kill should be executed with |
358 root privileges. | 395 root privileges. |
359 blocking: A boolean indicating whether we should wait until all processes | 396 blocking: A boolean indicating whether we should wait until all processes |
360 with the given |process_name| are dead. | 397 with the given |process_name| are dead. |
361 timeout: timeout in seconds | 398 timeout: timeout in seconds |
362 retries: number of retries | 399 retries: number of retries |
363 | 400 |
364 Raises: | 401 Raises: |
365 CommandFailedError if no process was killed. | 402 CommandFailedError if no process was killed. |
366 CommandTimeoutError on timeout. | 403 CommandTimeoutError on timeout. |
367 DeviceUnreachableError on missing device. | 404 DeviceUnreachableError on missing device. |
368 """ | 405 """ |
369 pids = self._GetPidsImpl(process_name) | 406 pids = self._GetPidsImpl(process_name) |
370 if not pids: | 407 if not pids: |
371 raise device_errors.CommandFailedError( | 408 raise device_errors.CommandFailedError( |
372 'No process "%s"' % process_name, device=str(self)) | 409 'No process "%s"' % process_name, device=str(self)) |
373 | 410 |
374 cmd = 'kill -%d %s' % (signum, ' '.join(pids.values())) | 411 cmd = ['kill', '-%d' % signum] + pids.values() |
375 self._RunShellCommandImpl(cmd, as_root=as_root) | 412 self._RunShellCommandImpl(cmd, as_root=as_root) |
376 | 413 |
377 if blocking: | 414 if blocking: |
378 wait_period = 0.1 | 415 wait_period = 0.1 |
379 while self._GetPidsImpl(process_name): | 416 while self._GetPidsImpl(process_name): |
380 time.sleep(wait_period) | 417 time.sleep(wait_period) |
381 | 418 |
382 return len(pids) | 419 return len(pids) |
383 | 420 |
384 @decorators.WithTimeoutAndRetriesFromInstance() | 421 @decorators.WithTimeoutAndRetriesFromInstance() |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
516 | 553 |
517 Raises: | 554 Raises: |
518 CommandFailedError on failure. | 555 CommandFailedError on failure. |
519 CommandTimeoutError on timeout. | 556 CommandTimeoutError on timeout. |
520 DeviceUnreachableError on missing device. | 557 DeviceUnreachableError on missing device. |
521 """ | 558 """ |
522 | 559 |
523 files = [] | 560 files = [] |
524 for h, d in host_device_tuples: | 561 for h, d in host_device_tuples: |
525 if os.path.isdir(h): | 562 if os.path.isdir(h): |
526 self._RunShellCommandImpl(['mkdir', '-p', '"%s"' % d], | 563 self._RunShellCommandImpl(['mkdir', '-p', d]) |
jbudorick
2014/10/17 09:04:53
following from my comments on the _Impl split, res
perezju
2014/10/17 11:17:09
All Done.
| |
527 check_return=True) | |
528 files += self._GetChangedFilesImpl(h, d) | 564 files += self._GetChangedFilesImpl(h, d) |
529 | 565 |
530 if not files: | 566 if not files: |
531 return | 567 return |
532 | 568 |
533 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files) | 569 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files) |
534 file_count = len(files) | 570 file_count = len(files) |
535 dir_size = sum(host_utils.GetRecursiveDiskUsage(h) | 571 dir_size = sum(host_utils.GetRecursiveDiskUsage(h) |
536 for h, _ in host_device_tuples) | 572 for h, _ in host_device_tuples) |
537 dir_file_count = 0 | 573 dir_file_count = 0 |
(...skipping 19 matching lines...) Expand all Loading... | |
557 else: | 593 else: |
558 self._PushChangedFilesZipped(files) | 594 self._PushChangedFilesZipped(files) |
559 self._RunShellCommandImpl( | 595 self._RunShellCommandImpl( |
560 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples], | 596 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples], |
561 as_root=True) | 597 as_root=True) |
562 | 598 |
563 def _GetChangedFilesImpl(self, host_path, device_path): | 599 def _GetChangedFilesImpl(self, host_path, device_path): |
564 real_host_path = os.path.realpath(host_path) | 600 real_host_path = os.path.realpath(host_path) |
565 try: | 601 try: |
566 real_device_path = self._RunShellCommandImpl( | 602 real_device_path = self._RunShellCommandImpl( |
567 ['realpath', device_path], check_return=True) | 603 ['realpath', device_path]).rstrip() |
jbudorick
2014/10/17 09:04:53
and here.
| |
568 real_device_path = real_device_path[0] | |
569 except device_errors.CommandFailedError: | 604 except device_errors.CommandFailedError: |
570 return [(host_path, device_path)] | 605 return [(host_path, device_path)] |
571 | 606 |
572 # TODO(jbudorick): Move the md5 logic up into DeviceUtils or base | 607 # TODO(jbudorick): Move the md5 logic up into DeviceUtils or base |
573 # this function on mtime. | 608 # this function on mtime. |
574 # pylint: disable=W0212 | 609 # pylint: disable=W0212 |
575 host_hash_tuples, device_hash_tuples = self.old_interface._RunMd5Sum( | 610 host_hash_tuples, device_hash_tuples = self.old_interface._RunMd5Sum( |
576 real_host_path, real_device_path) | 611 real_host_path, real_device_path) |
577 # pylint: enable=W0212 | 612 # pylint: enable=W0212 |
578 | 613 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
650 target=DeviceUtils._CreateDeviceZip, | 685 target=DeviceUtils._CreateDeviceZip, |
651 args=(zip_file.name, files)) | 686 args=(zip_file.name, files)) |
652 zip_proc.start() | 687 zip_proc.start() |
653 zip_proc.join() | 688 zip_proc.join() |
654 | 689 |
655 zip_on_device = '%s/tmp.zip' % self._GetExternalStoragePathImpl() | 690 zip_on_device = '%s/tmp.zip' % self._GetExternalStoragePathImpl() |
656 try: | 691 try: |
657 self.adb.Push(zip_file.name, zip_on_device) | 692 self.adb.Push(zip_file.name, zip_on_device) |
658 self._RunShellCommandImpl( | 693 self._RunShellCommandImpl( |
659 ['unzip', zip_on_device], | 694 ['unzip', zip_on_device], |
660 as_root=True, check_return=True, | 695 as_root=True, |
jbudorick
2014/10/17 09:04:53
and here.
| |
661 env={'PATH': '$PATH:%s' % install_commands.BIN_DIR}) | 696 env={'PATH': '$PATH:%s' % install_commands.BIN_DIR}) |
662 finally: | 697 finally: |
663 if zip_proc.is_alive(): | 698 if zip_proc.is_alive(): |
664 zip_proc.terminate() | 699 zip_proc.terminate() |
665 if self._IsOnlineImpl(): | 700 if self._IsOnlineImpl(): |
666 self._RunShellCommandImpl(['rm', zip_on_device]) | 701 self._RunShellCommandImpl(['rm', zip_on_device]) |
667 | 702 |
668 @staticmethod | 703 @staticmethod |
669 def _CreateDeviceZip(zip_path, host_device_tuples): | 704 def _CreateDeviceZip(zip_path, host_device_tuples): |
670 with zipfile.ZipFile(zip_path, 'w') as zip_file: | 705 with zipfile.ZipFile(zip_path, 'w') as zip_file: |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
792 as_root: A boolean indicating whether the write should be executed with | 827 as_root: A boolean indicating whether the write should be executed with |
793 root privileges. | 828 root privileges. |
794 timeout: timeout in seconds | 829 timeout: timeout in seconds |
795 retries: number of retries | 830 retries: number of retries |
796 | 831 |
797 Raises: | 832 Raises: |
798 CommandFailedError if the file could not be written on the device. | 833 CommandFailedError if the file could not be written on the device. |
799 CommandTimeoutError on timeout. | 834 CommandTimeoutError on timeout. |
800 DeviceUnreachableError on missing device. | 835 DeviceUnreachableError on missing device. |
801 """ | 836 """ |
802 self._RunShellCommandImpl('echo {1} > {0}'.format(device_path, | 837 cmd = 'echo %s > %s' % (cmd_helper.quote(text), |
803 pipes.quote(text)), check_return=True, as_root=as_root) | 838 cmd_helper.quote(device_path)) |
839 self._RunShellCommandImpl(cmd, as_root=as_root) | |
jbudorick
2014/10/17 09:04:53
and here.
| |
804 | 840 |
805 @decorators.WithTimeoutAndRetriesFromInstance() | 841 @decorators.WithTimeoutAndRetriesFromInstance() |
806 def Ls(self, device_path, timeout=None, retries=None): | 842 def Ls(self, device_path, timeout=None, retries=None): |
807 """Lists the contents of a directory on the device. | 843 """Lists the contents of a directory on the device. |
808 | 844 |
809 Args: | 845 Args: |
810 device_path: A string containing the path of the directory on the device | 846 device_path: A string containing the path of the directory on the device |
811 to list. | 847 to list. |
812 timeout: timeout in seconds | 848 timeout: timeout in seconds |
813 retries: number of retries | 849 retries: number of retries |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
910 provided |process_name|. | 946 provided |process_name|. |
911 | 947 |
912 Raises: | 948 Raises: |
913 CommandTimeoutError on timeout. | 949 CommandTimeoutError on timeout. |
914 DeviceUnreachableError on missing device. | 950 DeviceUnreachableError on missing device. |
915 """ | 951 """ |
916 return self._GetPidsImpl(process_name) | 952 return self._GetPidsImpl(process_name) |
917 | 953 |
918 def _GetPidsImpl(self, process_name): | 954 def _GetPidsImpl(self, process_name): |
919 procs_pids = {} | 955 procs_pids = {} |
920 for line in self._RunShellCommandImpl('ps'): | 956 for line in self._RunShellCommandImpl('ps').splitlines(): |
921 try: | 957 try: |
922 ps_data = line.split() | 958 ps_data = line.split() |
923 if process_name in ps_data[-1]: | 959 if process_name in ps_data[-1]: |
924 procs_pids[ps_data[-1]] = ps_data[1] | 960 procs_pids[ps_data[-1]] = ps_data[1] |
925 except IndexError: | 961 except IndexError: |
926 pass | 962 pass |
927 return procs_pids | 963 return procs_pids |
928 | 964 |
929 @decorators.WithTimeoutAndRetriesFromInstance() | 965 @decorators.WithTimeoutAndRetriesFromInstance() |
930 def TakeScreenshot(self, host_path=None, timeout=None, retries=None): | 966 def TakeScreenshot(self, host_path=None, timeout=None, retries=None): |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1008 Returns: | 1044 Returns: |
1009 A Parallelizer operating over |devices|. | 1045 A Parallelizer operating over |devices|. |
1010 """ | 1046 """ |
1011 if not devices or len(devices) == 0: | 1047 if not devices or len(devices) == 0: |
1012 devices = pylib.android_commands.GetAttachedDevices() | 1048 devices = pylib.android_commands.GetAttachedDevices() |
1013 parallelizer_type = (parallelizer.Parallelizer if async | 1049 parallelizer_type = (parallelizer.Parallelizer if async |
1014 else parallelizer.SyncParallelizer) | 1050 else parallelizer.SyncParallelizer) |
1015 return parallelizer_type([ | 1051 return parallelizer_type([ |
1016 d if isinstance(d, DeviceUtils) else DeviceUtils(d) | 1052 d if isinstance(d, DeviceUtils) else DeviceUtils(d) |
1017 for d in devices]) | 1053 for d in devices]) |
OLD | NEW |