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

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 RunShellCommand call in instrumentation runner 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
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
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
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
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
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
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
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
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
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
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
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])
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698