Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: build/android/pylib/device/device_utils.py

Issue 669573003: Reland of 'New run shell implementation for DeviceUtils' (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: pass timeout option to adb.Shell Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
(...skipping 16 matching lines...) Expand all
47 """Restarts the adb server. 48 """Restarts the adb server.
48 49
49 Raises: 50 Raises:
50 CommandFailedError if we fail to kill or restart the server. 51 CommandFailedError if we fail to kill or restart the server.
51 """ 52 """
52 pylib.android_commands.AndroidCommands().RestartAdbServer() 53 pylib.android_commands.AndroidCommands().RestartAdbServer()
53 54
54 55
55 class DeviceUtils(object): 56 class DeviceUtils(object):
56 57
58 _VALID_SHELL_VARIABLE = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$')
59
57 def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT, 60 def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT,
58 default_retries=_DEFAULT_RETRIES): 61 default_retries=_DEFAULT_RETRIES):
59 """DeviceUtils constructor. 62 """DeviceUtils constructor.
60 63
61 Args: 64 Args:
62 device: Either a device serial, an existing AdbWrapper instance, an 65 device: Either a device serial, an existing AdbWrapper instance, an
63 an existing AndroidCommands instance, or nothing. 66 an existing AndroidCommands instance, or nothing.
64 default_timeout: An integer containing the default number of seconds to 67 default_timeout: An integer containing the default number of seconds to
65 wait for an operation to complete if no explicit value 68 wait for an operation to complete if no explicit value
66 is provided. 69 is provided.
(...skipping 13 matching lines...) Expand all
80 self.adb = adb_wrapper.AdbWrapper(device.GetDevice()) 83 self.adb = adb_wrapper.AdbWrapper(device.GetDevice())
81 self.old_interface = device 84 self.old_interface = device
82 elif not device: 85 elif not device:
83 self.adb = adb_wrapper.AdbWrapper('') 86 self.adb = adb_wrapper.AdbWrapper('')
84 self.old_interface = pylib.android_commands.AndroidCommands() 87 self.old_interface = pylib.android_commands.AndroidCommands()
85 else: 88 else:
86 raise ValueError('Unsupported type passed for argument "device"') 89 raise ValueError('Unsupported type passed for argument "device"')
87 self._commands_installed = None 90 self._commands_installed = None
88 self._default_timeout = default_timeout 91 self._default_timeout = default_timeout
89 self._default_retries = default_retries 92 self._default_retries = default_retries
93 self._cache = {}
90 assert(hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR)) 94 assert(hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR))
91 assert(hasattr(self, decorators.DEFAULT_RETRIES_ATTR)) 95 assert(hasattr(self, decorators.DEFAULT_RETRIES_ATTR))
92 96
93 @decorators.WithTimeoutAndRetriesFromInstance() 97 @decorators.WithTimeoutAndRetriesFromInstance()
94 def IsOnline(self, timeout=None, retries=None): 98 def IsOnline(self, timeout=None, retries=None):
95 """Checks whether the device is online. 99 """Checks whether the device is online.
96 100
97 Args: 101 Args:
98 timeout: timeout in seconds 102 timeout: timeout in seconds
99 retries: number of retries 103 retries: number of retries
(...skipping 20 matching lines...) Expand all
120 Returns: 124 Returns:
121 True if adbd has root privileges, False otherwise. 125 True if adbd has root privileges, False otherwise.
122 126
123 Raises: 127 Raises:
124 CommandTimeoutError on timeout. 128 CommandTimeoutError on timeout.
125 DeviceUnreachableError on missing device. 129 DeviceUnreachableError on missing device.
126 """ 130 """
127 return self._HasRootImpl() 131 return self._HasRootImpl()
128 132
129 def _HasRootImpl(self): 133 def _HasRootImpl(self):
130 return self.old_interface.IsRootEnabled() 134 try:
135 self._RunShellCommandImpl('ls /root', check_return=True)
136 return True
137 except device_errors.AdbShellCommandFailedError:
138 return False
131 139
132 @decorators.WithTimeoutAndRetriesFromInstance() 140 @decorators.WithTimeoutAndRetriesFromInstance()
133 def EnableRoot(self, timeout=None, retries=None): 141 def EnableRoot(self, timeout=None, retries=None):
134 """Restarts adbd with root privileges. 142 """Restarts adbd with root privileges.
135 143
136 Args: 144 Args:
137 timeout: timeout in seconds 145 timeout: timeout in seconds
138 retries: number of retries 146 retries: number of retries
139 147
140 Raises: 148 Raises:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 The device's path to its SD card. 183 The device's path to its SD card.
176 184
177 Raises: 185 Raises:
178 CommandFailedError if the external storage path could not be determined. 186 CommandFailedError if the external storage path could not be determined.
179 CommandTimeoutError on timeout. 187 CommandTimeoutError on timeout.
180 DeviceUnreachableError on missing device. 188 DeviceUnreachableError on missing device.
181 """ 189 """
182 return self._GetExternalStoragePathImpl() 190 return self._GetExternalStoragePathImpl()
183 191
184 def _GetExternalStoragePathImpl(self): 192 def _GetExternalStoragePathImpl(self):
185 try: 193 if 'external_storage' in self._cache:
186 return self.old_interface.GetExternalStorage() 194 return self._cache['external_storage']
187 except AssertionError as e: 195
188 raise device_errors.CommandFailedError( 196 value = self._RunShellCommandImpl('echo $EXTERNAL_STORAGE',
189 str(e), device=str(self)), None, sys.exc_info()[2] 197 single_line=True,
198 check_return=True)
199 if not value:
200 raise device_errors.CommandFailedError('$EXTERNAL_STORAGE is not set',
201 str(self))
202 self._cache['external_storage'] = value
203 return value
190 204
191 @decorators.WithTimeoutAndRetriesFromInstance() 205 @decorators.WithTimeoutAndRetriesFromInstance()
192 def WaitUntilFullyBooted(self, wifi=False, timeout=None, retries=None): 206 def WaitUntilFullyBooted(self, wifi=False, timeout=None, retries=None):
193 """Wait for the device to fully boot. 207 """Wait for the device to fully boot.
194 208
195 This means waiting for the device to boot, the package manager to be 209 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 210 available, and the SD card to be ready. It can optionally mean waiting
197 for wifi to come up, too. 211 for wifi to come up, too.
198 212
199 Args: 213 Args:
200 wifi: A boolean indicating if we should wait for wifi to come up or not. 214 wifi: A boolean indicating if we should wait for wifi to come up or not.
201 timeout: timeout in seconds 215 timeout: timeout in seconds
202 retries: number of retries 216 retries: number of retries
203 217
204 Raises: 218 Raises:
205 CommandFailedError on failure. 219 CommandFailedError on failure.
206 CommandTimeoutError if one of the component waits times out. 220 CommandTimeoutError if one of the component waits times out.
207 DeviceUnreachableError if the device becomes unresponsive. 221 DeviceUnreachableError if the device becomes unresponsive.
208 """ 222 """
209 self._WaitUntilFullyBootedImpl(wifi=wifi, timeout=timeout) 223 self._WaitUntilFullyBootedImpl(wifi=wifi, timeout=timeout)
210 224
211 def _WaitUntilFullyBootedImpl(self, wifi=False, timeout=None): 225 def _WaitUntilFullyBootedImpl(self, wifi=False, timeout=None):
212 if timeout is None: 226 if timeout is None:
213 timeout = self._default_timeout 227 timeout = self._default_timeout
214 self.old_interface.WaitForSystemBootCompleted(timeout) 228 self.old_interface.WaitForSystemBootCompleted(timeout)
215 self.old_interface.WaitForDevicePm() 229 self.old_interface.WaitForDevicePm()
216 self.old_interface.WaitForSdCardReady(timeout) 230 self.old_interface.WaitForSdCardReady(timeout)
217 if wifi: 231 if wifi:
218 while not 'Wi-Fi is enabled' in ( 232 while not 'Wi-Fi is enabled' in (
219 self._RunShellCommandImpl('dumpsys wifi')): 233 self.old_interface.RunShellCommand('dumpsys wifi')):
220 time.sleep(1) 234 time.sleep(1)
221 235
222 REBOOT_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT 236 REBOOT_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT
223 REBOOT_DEFAULT_RETRIES = _DEFAULT_RETRIES 237 REBOOT_DEFAULT_RETRIES = _DEFAULT_RETRIES
224 238
225 @decorators.WithTimeoutAndRetriesDefaults( 239 @decorators.WithTimeoutAndRetriesDefaults(
226 REBOOT_DEFAULT_TIMEOUT, 240 REBOOT_DEFAULT_TIMEOUT,
227 REBOOT_DEFAULT_RETRIES) 241 REBOOT_DEFAULT_RETRIES)
228 def Reboot(self, block=True, timeout=None, retries=None): 242 def Reboot(self, block=True, timeout=None, retries=None):
229 """Reboot the device. 243 """Reboot the device.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 out = self.old_interface.Install(apk_path, reinstall=reinstall) 299 out = self.old_interface.Install(apk_path, reinstall=reinstall)
286 for line in out.splitlines(): 300 for line in out.splitlines():
287 if 'Failure' in line: 301 if 'Failure' in line:
288 raise device_errors.CommandFailedError( 302 raise device_errors.CommandFailedError(
289 line.strip(), device=str(self)) 303 line.strip(), device=str(self))
290 except AssertionError as e: 304 except AssertionError as e:
291 raise device_errors.CommandFailedError( 305 raise device_errors.CommandFailedError(
292 str(e), device=str(self)), None, sys.exc_info()[2] 306 str(e), device=str(self)), None, sys.exc_info()[2]
293 307
294 @decorators.WithTimeoutAndRetriesFromInstance() 308 @decorators.WithTimeoutAndRetriesFromInstance()
295 def RunShellCommand(self, cmd, check_return=False, as_root=False, cwd=None, 309 def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None,
296 env=None, timeout=None, retries=None): 310 as_root=False, single_line=False,
311 timeout=None, retries=None):
297 """Run an ADB shell command. 312 """Run an ADB shell command.
298 313
299 TODO(jbudorick) Switch the default value of check_return to True after 314 The command to run |cmd| should be a sequence of program arguments or else
300 AndroidCommands is gone. 315 a single string.
316
317 When |cmd| is a sequence, it is assumed to contain the name of the command
318 to run followed by its arguments. In this case, arguments are passed to the
319 command exactly as given, without any further processing by the shell. This
320 allows to easily pass arguments containing spaces or special characters
321 without having to worry about getting quoting right. Whenever possible, it
322 is recomended to pass |cmd| as a sequence.
323
324 When |cmd| is given as a string, it will be interpreted and run by the
325 shell on the device.
326
327 This behaviour is consistent with that of command runners in cmd_helper as
328 well as Python's own subprocess.Popen.
329
330 TODO(perezju) Change the default of |check_return| to True when callers
331 have switched to the new behaviour.
301 332
302 Args: 333 Args:
303 cmd: A list containing the command to run on the device and any arguments. 334 cmd: A string with the full command to run on the device, or a sequence
335 containing the command and its arguments.
304 check_return: A boolean indicating whether or not the return code should 336 check_return: A boolean indicating whether or not the return code should
305 be checked. 337 be checked.
306 as_root: A boolean indicating whether the shell command should be run
307 with root privileges.
308 cwd: The device directory in which the command should be run. 338 cwd: The device directory in which the command should be run.
309 env: The environment variables with which the command should be run. 339 env: The environment variables with which the command should be run.
340 as_root: A boolean indicating whether the shell command should be run
341 with root privileges.
342 single_line: A boolean indicating if a single line of output is expected,
343 and the caller wants to retrieve the value of that line. The default
344 behaviour is to return a list of output lines.
310 timeout: timeout in seconds 345 timeout: timeout in seconds
311 retries: number of retries 346 retries: number of retries
312 347
313 Returns: 348 Returns:
314 The output of the command. 349 The output of the command either as list of lines or, when single_line is
350 True, the value contained in the single expected line of output.
315 351
316 Raises: 352 Raises:
317 CommandFailedError if check_return is True and the return code is nozero. 353 AdbShellCommandFailedError if check_return is True and the exit code of
354 the command run on the device is non-zero.
355 CommandFailedError if single_line is True but the output consists of
356 either zero or more than one lines.
318 CommandTimeoutError on timeout. 357 CommandTimeoutError on timeout.
319 DeviceUnreachableError on missing device. 358 DeviceUnreachableError on missing device.
320 """ 359 """
321 return self._RunShellCommandImpl( 360 return self._RunShellCommandImpl(cmd, check_return=check_return, cwd=cwd,
322 cmd, check_return=check_return, as_root=as_root, cwd=cwd, env=env, 361 env=env, as_root=as_root, single_line=single_line, timeout=timeout)
323 timeout=timeout)
324 362
325 def _RunShellCommandImpl(self, cmd, check_return=False, as_root=False, 363 def _RunShellCommandImpl(self, cmd, check_return=False, cwd=None, env=None,
326 cwd=None, env=None, timeout=None): 364 as_root=False, single_line=False, timeout=None):
327 # TODO(jbudorick): Remove the timeout parameter once this is no longer 365 def env_quote(key, value):
328 # backed by AndroidCommands. 366 if not DeviceUtils._VALID_SHELL_VARIABLE.match(key):
329 if isinstance(cmd, list): 367 raise KeyError('Invalid shell variable name %r' % key)
330 cmd = ' '.join(cmd) 368 # using double quotes here to allow interpolation of shell variables
369 return '%s=%s' % (key, cmd_helper.DoubleQuote(value))
370
371 if not isinstance(cmd, basestring):
372 cmd = ' '.join(cmd_helper.SingleQuote(s) for s in cmd)
331 if as_root and not self._HasRootImpl(): 373 if as_root and not self._HasRootImpl():
332 cmd = 'su -c %s' % cmd 374 cmd = 'su -c %s' % cmd
333 if env: 375 if env:
334 cmd = '%s %s' % ( 376 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) 377 cmd = '%s %s' % (env, cmd)
336 if cwd: 378 if cwd:
337 cmd = 'cd %s && %s' % (cwd, cmd) 379 cmd = 'cd %s && %s' % (cmd_helper.SingleQuote(cwd), cmd)
338 if check_return: 380 if timeout is None:
339 code, output = self.old_interface.GetShellCommandStatusAndOutput( 381 timeout = self._default_timeout
340 cmd, timeout_time=timeout) 382
341 if int(code) != 0: 383 try:
342 raise device_errors.AdbCommandFailedError( 384 # TODO(perezju) still need to make sure that we call a version of
343 cmd.split(), 'Nonzero exit code (%d)' % code, device=str(self)) 385 # adb.Shell without a timeout-and-retries wrapper.
386 output = self.adb.Shell(cmd, expect_rc=0, timeout=timeout, retries=0)
387 except device_errors.AdbShellCommandFailedError as e:
388 if check_return:
389 raise
390 else:
391 output = e.output
392
393 output = output.splitlines()
394 if single_line:
395 if len(output) != 1:
396 msg = 'exactly one line of output expected, but got: %s'
397 raise device_errors.CommandFailedError(msg % output)
398 return output[0]
344 else: 399 else:
345 output = self.old_interface.RunShellCommand(cmd, timeout_time=timeout) 400 return output
346 return output
347 401
348 @decorators.WithTimeoutAndRetriesFromInstance() 402 @decorators.WithTimeoutAndRetriesFromInstance()
349 def KillAll(self, process_name, signum=9, as_root=False, blocking=False, 403 def KillAll(self, process_name, signum=9, as_root=False, blocking=False,
350 timeout=None, retries=None): 404 timeout=None, retries=None):
351 """Kill all processes with the given name on the device. 405 """Kill all processes with the given name on the device.
352 406
353 Args: 407 Args:
354 process_name: A string containing the name of the process to kill. 408 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 409 signum: An integer containing the signal number to send to kill. Defaults
356 to 9 (SIGKILL). 410 to 9 (SIGKILL).
357 as_root: A boolean indicating whether the kill should be executed with 411 as_root: A boolean indicating whether the kill should be executed with
358 root privileges. 412 root privileges.
359 blocking: A boolean indicating whether we should wait until all processes 413 blocking: A boolean indicating whether we should wait until all processes
360 with the given |process_name| are dead. 414 with the given |process_name| are dead.
361 timeout: timeout in seconds 415 timeout: timeout in seconds
362 retries: number of retries 416 retries: number of retries
363 417
364 Raises: 418 Raises:
365 CommandFailedError if no process was killed. 419 CommandFailedError if no process was killed.
366 CommandTimeoutError on timeout. 420 CommandTimeoutError on timeout.
367 DeviceUnreachableError on missing device. 421 DeviceUnreachableError on missing device.
368 """ 422 """
369 pids = self._GetPidsImpl(process_name) 423 pids = self._GetPidsImpl(process_name)
370 if not pids: 424 if not pids:
371 raise device_errors.CommandFailedError( 425 raise device_errors.CommandFailedError(
372 'No process "%s"' % process_name, device=str(self)) 426 'No process "%s"' % process_name, device=str(self))
373 427
374 cmd = 'kill -%d %s' % (signum, ' '.join(pids.values())) 428 cmd = ['kill', '-%d' % signum] + pids.values()
375 self._RunShellCommandImpl(cmd, as_root=as_root) 429 self._RunShellCommandImpl(cmd, as_root=as_root, check_return=True)
376 430
377 if blocking: 431 if blocking:
378 wait_period = 0.1 432 wait_period = 0.1
379 while self._GetPidsImpl(process_name): 433 while self._GetPidsImpl(process_name):
380 time.sleep(wait_period) 434 time.sleep(wait_period)
381 435
382 return len(pids) 436 return len(pids)
383 437
384 @decorators.WithTimeoutAndRetriesFromInstance() 438 @decorators.WithTimeoutAndRetriesFromInstance()
385 def StartActivity(self, intent, blocking=False, trace_file_name=None, 439 def StartActivity(self, intent, blocking=False, trace_file_name=None,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 570
517 Raises: 571 Raises:
518 CommandFailedError on failure. 572 CommandFailedError on failure.
519 CommandTimeoutError on timeout. 573 CommandTimeoutError on timeout.
520 DeviceUnreachableError on missing device. 574 DeviceUnreachableError on missing device.
521 """ 575 """
522 576
523 files = [] 577 files = []
524 for h, d in host_device_tuples: 578 for h, d in host_device_tuples:
525 if os.path.isdir(h): 579 if os.path.isdir(h):
526 self._RunShellCommandImpl(['mkdir', '-p', '"%s"' % d], 580 self._RunShellCommandImpl(['mkdir', '-p', d], check_return=True)
527 check_return=True)
528 files += self._GetChangedFilesImpl(h, d) 581 files += self._GetChangedFilesImpl(h, d)
529 582
530 if not files: 583 if not files:
531 return 584 return
532 585
533 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files) 586 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files)
534 file_count = len(files) 587 file_count = len(files)
535 dir_size = sum(host_utils.GetRecursiveDiskUsage(h) 588 dir_size = sum(host_utils.GetRecursiveDiskUsage(h)
536 for h, _ in host_device_tuples) 589 for h, _ in host_device_tuples)
537 dir_file_count = 0 590 dir_file_count = 0
(...skipping 13 matching lines...) Expand all
551 604
552 if dir_push_duration < push_duration and ( 605 if dir_push_duration < push_duration and (
553 dir_push_duration < zip_duration or not self._commands_installed): 606 dir_push_duration < zip_duration or not self._commands_installed):
554 self._PushChangedFilesIndividually(host_device_tuples) 607 self._PushChangedFilesIndividually(host_device_tuples)
555 elif push_duration < zip_duration or not self._commands_installed: 608 elif push_duration < zip_duration or not self._commands_installed:
556 self._PushChangedFilesIndividually(files) 609 self._PushChangedFilesIndividually(files)
557 else: 610 else:
558 self._PushChangedFilesZipped(files) 611 self._PushChangedFilesZipped(files)
559 self._RunShellCommandImpl( 612 self._RunShellCommandImpl(
560 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples], 613 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples],
561 as_root=True) 614 as_root=True, check_return=True)
562 615
563 def _GetChangedFilesImpl(self, host_path, device_path): 616 def _GetChangedFilesImpl(self, host_path, device_path):
564 real_host_path = os.path.realpath(host_path) 617 real_host_path = os.path.realpath(host_path)
565 try: 618 try:
566 real_device_path = self._RunShellCommandImpl( 619 real_device_path = self._RunShellCommandImpl(
567 ['realpath', device_path], check_return=True) 620 ['realpath', device_path], single_line=True, check_return=True)
568 real_device_path = real_device_path[0]
569 except device_errors.CommandFailedError: 621 except device_errors.CommandFailedError:
570 return [(host_path, device_path)] 622 return [(host_path, device_path)]
571 623
572 # TODO(jbudorick): Move the md5 logic up into DeviceUtils or base 624 # TODO(jbudorick): Move the md5 logic up into DeviceUtils or base
573 # this function on mtime. 625 # this function on mtime.
574 # pylint: disable=W0212 626 # pylint: disable=W0212
575 host_hash_tuples, device_hash_tuples = self.old_interface._RunMd5Sum( 627 host_hash_tuples, device_hash_tuples = self.old_interface._RunMd5Sum(
576 real_host_path, real_device_path) 628 real_host_path, real_device_path)
577 # pylint: enable=W0212 629 # pylint: enable=W0212
578 630
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 target=DeviceUtils._CreateDeviceZip, 702 target=DeviceUtils._CreateDeviceZip,
651 args=(zip_file.name, files)) 703 args=(zip_file.name, files))
652 zip_proc.start() 704 zip_proc.start()
653 zip_proc.join() 705 zip_proc.join()
654 706
655 zip_on_device = '%s/tmp.zip' % self._GetExternalStoragePathImpl() 707 zip_on_device = '%s/tmp.zip' % self._GetExternalStoragePathImpl()
656 try: 708 try:
657 self.adb.Push(zip_file.name, zip_on_device) 709 self.adb.Push(zip_file.name, zip_on_device)
658 self._RunShellCommandImpl( 710 self._RunShellCommandImpl(
659 ['unzip', zip_on_device], 711 ['unzip', zip_on_device],
660 as_root=True, check_return=True, 712 as_root=True,
661 env={'PATH': '$PATH:%s' % install_commands.BIN_DIR}) 713 env={'PATH': '$PATH:%s' % install_commands.BIN_DIR},
714 check_return=True)
662 finally: 715 finally:
663 if zip_proc.is_alive(): 716 if zip_proc.is_alive():
664 zip_proc.terminate() 717 zip_proc.terminate()
665 if self._IsOnlineImpl(): 718 if self._IsOnlineImpl():
666 self._RunShellCommandImpl(['rm', zip_on_device]) 719 self._RunShellCommandImpl(['rm', zip_on_device], check_return=True)
667 720
668 @staticmethod 721 @staticmethod
669 def _CreateDeviceZip(zip_path, host_device_tuples): 722 def _CreateDeviceZip(zip_path, host_device_tuples):
670 with zipfile.ZipFile(zip_path, 'w') as zip_file: 723 with zipfile.ZipFile(zip_path, 'w') as zip_file:
671 for host_path, device_path in host_device_tuples: 724 for host_path, device_path in host_device_tuples:
672 if os.path.isfile(host_path): 725 if os.path.isfile(host_path):
673 zip_file.write(host_path, device_path, zipfile.ZIP_DEFLATED) 726 zip_file.write(host_path, device_path, zipfile.ZIP_DEFLATED)
674 else: 727 else:
675 for hd, _, files in os.walk(host_path): 728 for hd, _, files in os.walk(host_path):
676 dd = '%s/%s' % (device_path, os.path.relpath(host_path, hd)) 729 dd = '%s/%s' % (device_path, os.path.relpath(host_path, hd))
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 as_root: A boolean indicating whether the write should be executed with 845 as_root: A boolean indicating whether the write should be executed with
793 root privileges. 846 root privileges.
794 timeout: timeout in seconds 847 timeout: timeout in seconds
795 retries: number of retries 848 retries: number of retries
796 849
797 Raises: 850 Raises:
798 CommandFailedError if the file could not be written on the device. 851 CommandFailedError if the file could not be written on the device.
799 CommandTimeoutError on timeout. 852 CommandTimeoutError on timeout.
800 DeviceUnreachableError on missing device. 853 DeviceUnreachableError on missing device.
801 """ 854 """
802 self._RunShellCommandImpl('echo {1} > {0}'.format(device_path, 855 cmd = 'echo %s > %s' % (cmd_helper.SingleQuote(text),
803 pipes.quote(text)), check_return=True, as_root=as_root) 856 cmd_helper.SingleQuote(device_path))
857 self._RunShellCommandImpl(cmd, as_root=as_root, check_return=True)
804 858
805 @decorators.WithTimeoutAndRetriesFromInstance() 859 @decorators.WithTimeoutAndRetriesFromInstance()
806 def Ls(self, device_path, timeout=None, retries=None): 860 def Ls(self, device_path, timeout=None, retries=None):
807 """Lists the contents of a directory on the device. 861 """Lists the contents of a directory on the device.
808 862
809 Args: 863 Args:
810 device_path: A string containing the path of the directory on the device 864 device_path: A string containing the path of the directory on the device
811 to list. 865 to list.
812 timeout: timeout in seconds 866 timeout: timeout in seconds
813 retries: number of retries 867 retries: number of retries
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 provided |process_name|. 964 provided |process_name|.
911 965
912 Raises: 966 Raises:
913 CommandTimeoutError on timeout. 967 CommandTimeoutError on timeout.
914 DeviceUnreachableError on missing device. 968 DeviceUnreachableError on missing device.
915 """ 969 """
916 return self._GetPidsImpl(process_name) 970 return self._GetPidsImpl(process_name)
917 971
918 def _GetPidsImpl(self, process_name): 972 def _GetPidsImpl(self, process_name):
919 procs_pids = {} 973 procs_pids = {}
920 for line in self._RunShellCommandImpl('ps'): 974 for line in self._RunShellCommandImpl('ps', check_return=True):
921 try: 975 try:
922 ps_data = line.split() 976 ps_data = line.split()
923 if process_name in ps_data[-1]: 977 if process_name in ps_data[-1]:
924 procs_pids[ps_data[-1]] = ps_data[1] 978 procs_pids[ps_data[-1]] = ps_data[1]
925 except IndexError: 979 except IndexError:
926 pass 980 pass
927 return procs_pids 981 return procs_pids
928 982
929 @decorators.WithTimeoutAndRetriesFromInstance() 983 @decorators.WithTimeoutAndRetriesFromInstance()
930 def TakeScreenshot(self, host_path=None, timeout=None, retries=None): 984 def TakeScreenshot(self, host_path=None, timeout=None, retries=None):
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 Returns: 1062 Returns:
1009 A Parallelizer operating over |devices|. 1063 A Parallelizer operating over |devices|.
1010 """ 1064 """
1011 if not devices or len(devices) == 0: 1065 if not devices or len(devices) == 0:
1012 devices = pylib.android_commands.GetAttachedDevices() 1066 devices = pylib.android_commands.GetAttachedDevices()
1013 parallelizer_type = (parallelizer.Parallelizer if async 1067 parallelizer_type = (parallelizer.Parallelizer if async
1014 else parallelizer.SyncParallelizer) 1068 else parallelizer.SyncParallelizer)
1015 return parallelizer_type([ 1069 return parallelizer_type([
1016 d if isinstance(d, DeviceUtils) else DeviceUtils(d) 1070 d if isinstance(d, DeviceUtils) else DeviceUtils(d)
1017 for d in devices]) 1071 for d in devices])
OLDNEW
« no previous file with comments | « build/android/pylib/device/device_errors.py ('k') | build/android/pylib/device/device_utils_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698