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

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

Issue 659533002: New run shell implementation for DeviceUtils (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixed nit, and TODO to make cmd_helper_test run on bots 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)
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):
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
339 code, output = self.old_interface.GetShellCommandStatusAndOutput( 381 try:
340 cmd, timeout_time=timeout) 382 # TODO(perezju) still need to make sure that we call a version of
341 if int(code) != 0: 383 # adb.Shell without a timeout-and-retries wrapper.
342 raise device_errors.AdbCommandFailedError( 384 output = self.adb.Shell(cmd, expect_rc=0)
343 cmd.split(), 'Nonzero exit code (%d)' % code, device=str(self)) 385 except device_errors.AdbShellCommandFailedError as e:
386 if check_return:
387 raise
388 else:
389 output = e.output
390
391 output = output.splitlines()
392 if single_line:
393 if len(output) != 1:
394 msg = 'exactly one line of output expected, but got: %s'
395 raise device_errors.CommandFailedError(msg % output)
396 return output[0]
344 else: 397 else:
345 output = self.old_interface.RunShellCommand(cmd, timeout_time=timeout) 398 return output
346 return output
347 399
348 @decorators.WithTimeoutAndRetriesFromInstance() 400 @decorators.WithTimeoutAndRetriesFromInstance()
349 def KillAll(self, process_name, signum=9, as_root=False, blocking=False, 401 def KillAll(self, process_name, signum=9, as_root=False, blocking=False,
350 timeout=None, retries=None): 402 timeout=None, retries=None):
351 """Kill all processes with the given name on the device. 403 """Kill all processes with the given name on the device.
352 404
353 Args: 405 Args:
354 process_name: A string containing the name of the process to kill. 406 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 407 signum: An integer containing the signal number to send to kill. Defaults
356 to 9 (SIGKILL). 408 to 9 (SIGKILL).
357 as_root: A boolean indicating whether the kill should be executed with 409 as_root: A boolean indicating whether the kill should be executed with
358 root privileges. 410 root privileges.
359 blocking: A boolean indicating whether we should wait until all processes 411 blocking: A boolean indicating whether we should wait until all processes
360 with the given |process_name| are dead. 412 with the given |process_name| are dead.
361 timeout: timeout in seconds 413 timeout: timeout in seconds
362 retries: number of retries 414 retries: number of retries
363 415
364 Raises: 416 Raises:
365 CommandFailedError if no process was killed. 417 CommandFailedError if no process was killed.
366 CommandTimeoutError on timeout. 418 CommandTimeoutError on timeout.
367 DeviceUnreachableError on missing device. 419 DeviceUnreachableError on missing device.
368 """ 420 """
369 pids = self._GetPidsImpl(process_name) 421 pids = self._GetPidsImpl(process_name)
370 if not pids: 422 if not pids:
371 raise device_errors.CommandFailedError( 423 raise device_errors.CommandFailedError(
372 'No process "%s"' % process_name, device=str(self)) 424 'No process "%s"' % process_name, device=str(self))
373 425
374 cmd = 'kill -%d %s' % (signum, ' '.join(pids.values())) 426 cmd = ['kill', '-%d' % signum] + pids.values()
375 self._RunShellCommandImpl(cmd, as_root=as_root) 427 self._RunShellCommandImpl(cmd, as_root=as_root, check_return=True)
376 428
377 if blocking: 429 if blocking:
378 wait_period = 0.1 430 wait_period = 0.1
379 while self._GetPidsImpl(process_name): 431 while self._GetPidsImpl(process_name):
380 time.sleep(wait_period) 432 time.sleep(wait_period)
381 433
382 return len(pids) 434 return len(pids)
383 435
384 @decorators.WithTimeoutAndRetriesFromInstance() 436 @decorators.WithTimeoutAndRetriesFromInstance()
385 def StartActivity(self, intent, blocking=False, trace_file_name=None, 437 def StartActivity(self, intent, blocking=False, trace_file_name=None,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 568
517 Raises: 569 Raises:
518 CommandFailedError on failure. 570 CommandFailedError on failure.
519 CommandTimeoutError on timeout. 571 CommandTimeoutError on timeout.
520 DeviceUnreachableError on missing device. 572 DeviceUnreachableError on missing device.
521 """ 573 """
522 574
523 files = [] 575 files = []
524 for h, d in host_device_tuples: 576 for h, d in host_device_tuples:
525 if os.path.isdir(h): 577 if os.path.isdir(h):
526 self._RunShellCommandImpl(['mkdir', '-p', '"%s"' % d], 578 self._RunShellCommandImpl(['mkdir', '-p', d], check_return=True)
527 check_return=True)
528 files += self._GetChangedFilesImpl(h, d) 579 files += self._GetChangedFilesImpl(h, d)
529 580
530 if not files: 581 if not files:
531 return 582 return
532 583
533 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files) 584 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files)
534 file_count = len(files) 585 file_count = len(files)
535 dir_size = sum(host_utils.GetRecursiveDiskUsage(h) 586 dir_size = sum(host_utils.GetRecursiveDiskUsage(h)
536 for h, _ in host_device_tuples) 587 for h, _ in host_device_tuples)
537 dir_file_count = 0 588 dir_file_count = 0
(...skipping 13 matching lines...) Expand all
551 602
552 if dir_push_duration < push_duration and ( 603 if dir_push_duration < push_duration and (
553 dir_push_duration < zip_duration or not self._commands_installed): 604 dir_push_duration < zip_duration or not self._commands_installed):
554 self._PushChangedFilesIndividually(host_device_tuples) 605 self._PushChangedFilesIndividually(host_device_tuples)
555 elif push_duration < zip_duration or not self._commands_installed: 606 elif push_duration < zip_duration or not self._commands_installed:
556 self._PushChangedFilesIndividually(files) 607 self._PushChangedFilesIndividually(files)
557 else: 608 else:
558 self._PushChangedFilesZipped(files) 609 self._PushChangedFilesZipped(files)
559 self._RunShellCommandImpl( 610 self._RunShellCommandImpl(
560 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples], 611 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples],
561 as_root=True) 612 as_root=True, check_return=True)
562 613
563 def _GetChangedFilesImpl(self, host_path, device_path): 614 def _GetChangedFilesImpl(self, host_path, device_path):
564 real_host_path = os.path.realpath(host_path) 615 real_host_path = os.path.realpath(host_path)
565 try: 616 try:
566 real_device_path = self._RunShellCommandImpl( 617 real_device_path = self._RunShellCommandImpl(
567 ['realpath', device_path], check_return=True) 618 ['realpath', device_path], single_line=True, check_return=True)
568 real_device_path = real_device_path[0]
569 except device_errors.CommandFailedError: 619 except device_errors.CommandFailedError:
570 return [(host_path, device_path)] 620 return [(host_path, device_path)]
571 621
572 # TODO(jbudorick): Move the md5 logic up into DeviceUtils or base 622 # TODO(jbudorick): Move the md5 logic up into DeviceUtils or base
573 # this function on mtime. 623 # this function on mtime.
574 # pylint: disable=W0212 624 # pylint: disable=W0212
575 host_hash_tuples, device_hash_tuples = self.old_interface._RunMd5Sum( 625 host_hash_tuples, device_hash_tuples = self.old_interface._RunMd5Sum(
576 real_host_path, real_device_path) 626 real_host_path, real_device_path)
577 # pylint: enable=W0212 627 # pylint: enable=W0212
578 628
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 target=DeviceUtils._CreateDeviceZip, 700 target=DeviceUtils._CreateDeviceZip,
651 args=(zip_file.name, files)) 701 args=(zip_file.name, files))
652 zip_proc.start() 702 zip_proc.start()
653 zip_proc.join() 703 zip_proc.join()
654 704
655 zip_on_device = '%s/tmp.zip' % self._GetExternalStoragePathImpl() 705 zip_on_device = '%s/tmp.zip' % self._GetExternalStoragePathImpl()
656 try: 706 try:
657 self.adb.Push(zip_file.name, zip_on_device) 707 self.adb.Push(zip_file.name, zip_on_device)
658 self._RunShellCommandImpl( 708 self._RunShellCommandImpl(
659 ['unzip', zip_on_device], 709 ['unzip', zip_on_device],
660 as_root=True, check_return=True, 710 as_root=True,
661 env={'PATH': '$PATH:%s' % install_commands.BIN_DIR}) 711 env={'PATH': '$PATH:%s' % install_commands.BIN_DIR},
712 check_return=True)
662 finally: 713 finally:
663 if zip_proc.is_alive(): 714 if zip_proc.is_alive():
664 zip_proc.terminate() 715 zip_proc.terminate()
665 if self._IsOnlineImpl(): 716 if self._IsOnlineImpl():
666 self._RunShellCommandImpl(['rm', zip_on_device]) 717 self._RunShellCommandImpl(['rm', zip_on_device], check_return=True)
667 718
668 @staticmethod 719 @staticmethod
669 def _CreateDeviceZip(zip_path, host_device_tuples): 720 def _CreateDeviceZip(zip_path, host_device_tuples):
670 with zipfile.ZipFile(zip_path, 'w') as zip_file: 721 with zipfile.ZipFile(zip_path, 'w') as zip_file:
671 for host_path, device_path in host_device_tuples: 722 for host_path, device_path in host_device_tuples:
672 if os.path.isfile(host_path): 723 if os.path.isfile(host_path):
673 zip_file.write(host_path, device_path, zipfile.ZIP_DEFLATED) 724 zip_file.write(host_path, device_path, zipfile.ZIP_DEFLATED)
674 else: 725 else:
675 for hd, _, files in os.walk(host_path): 726 for hd, _, files in os.walk(host_path):
676 dd = '%s/%s' % (device_path, os.path.relpath(host_path, hd)) 727 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 843 as_root: A boolean indicating whether the write should be executed with
793 root privileges. 844 root privileges.
794 timeout: timeout in seconds 845 timeout: timeout in seconds
795 retries: number of retries 846 retries: number of retries
796 847
797 Raises: 848 Raises:
798 CommandFailedError if the file could not be written on the device. 849 CommandFailedError if the file could not be written on the device.
799 CommandTimeoutError on timeout. 850 CommandTimeoutError on timeout.
800 DeviceUnreachableError on missing device. 851 DeviceUnreachableError on missing device.
801 """ 852 """
802 self._RunShellCommandImpl('echo {1} > {0}'.format(device_path, 853 cmd = 'echo %s > %s' % (cmd_helper.SingleQuote(text),
803 pipes.quote(text)), check_return=True, as_root=as_root) 854 cmd_helper.SingleQuote(device_path))
855 self._RunShellCommandImpl(cmd, as_root=as_root, check_return=True)
804 856
805 @decorators.WithTimeoutAndRetriesFromInstance() 857 @decorators.WithTimeoutAndRetriesFromInstance()
806 def Ls(self, device_path, timeout=None, retries=None): 858 def Ls(self, device_path, timeout=None, retries=None):
807 """Lists the contents of a directory on the device. 859 """Lists the contents of a directory on the device.
808 860
809 Args: 861 Args:
810 device_path: A string containing the path of the directory on the device 862 device_path: A string containing the path of the directory on the device
811 to list. 863 to list.
812 timeout: timeout in seconds 864 timeout: timeout in seconds
813 retries: number of retries 865 retries: number of retries
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 provided |process_name|. 962 provided |process_name|.
911 963
912 Raises: 964 Raises:
913 CommandTimeoutError on timeout. 965 CommandTimeoutError on timeout.
914 DeviceUnreachableError on missing device. 966 DeviceUnreachableError on missing device.
915 """ 967 """
916 return self._GetPidsImpl(process_name) 968 return self._GetPidsImpl(process_name)
917 969
918 def _GetPidsImpl(self, process_name): 970 def _GetPidsImpl(self, process_name):
919 procs_pids = {} 971 procs_pids = {}
920 for line in self._RunShellCommandImpl('ps'): 972 for line in self._RunShellCommandImpl('ps', check_return=True):
921 try: 973 try:
922 ps_data = line.split() 974 ps_data = line.split()
923 if process_name in ps_data[-1]: 975 if process_name in ps_data[-1]:
924 procs_pids[ps_data[-1]] = ps_data[1] 976 procs_pids[ps_data[-1]] = ps_data[1]
925 except IndexError: 977 except IndexError:
926 pass 978 pass
927 return procs_pids 979 return procs_pids
928 980
929 @decorators.WithTimeoutAndRetriesFromInstance() 981 @decorators.WithTimeoutAndRetriesFromInstance()
930 def TakeScreenshot(self, host_path=None, timeout=None, retries=None): 982 def TakeScreenshot(self, host_path=None, timeout=None, retries=None):
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 Returns: 1060 Returns:
1009 A Parallelizer operating over |devices|. 1061 A Parallelizer operating over |devices|.
1010 """ 1062 """
1011 if not devices or len(devices) == 0: 1063 if not devices or len(devices) == 0:
1012 devices = pylib.android_commands.GetAttachedDevices() 1064 devices = pylib.android_commands.GetAttachedDevices()
1013 parallelizer_type = (parallelizer.Parallelizer if async 1065 parallelizer_type = (parallelizer.Parallelizer if async
1014 else parallelizer.SyncParallelizer) 1066 else parallelizer.SyncParallelizer)
1015 return parallelizer_type([ 1067 return parallelizer_type([
1016 d if isinstance(d, DeviceUtils) else DeviceUtils(d) 1068 d if isinstance(d, DeviceUtils) else DeviceUtils(d)
1017 for d in devices]) 1069 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