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

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

Issue 646523002: [Android] Add zip pushing and refine push mode selection. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix findbugs issues. 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 multiprocessing
12 import os
11 import pipes 13 import pipes
12 import sys 14 import sys
15 import tempfile
13 import time 16 import time
17 import zipfile
14 18
15 import pylib.android_commands 19 import pylib.android_commands
16 from pylib.device import adb_wrapper 20 from pylib.device import adb_wrapper
17 from pylib.device import decorators 21 from pylib.device import decorators
18 from pylib.device import device_errors 22 from pylib.device import device_errors
23 from pylib.device.commands import install_commands
19 from pylib.utils import apk_helper 24 from pylib.utils import apk_helper
25 from pylib.utils import host_utils
20 from pylib.utils import parallelizer 26 from pylib.utils import parallelizer
21 27
22 _DEFAULT_TIMEOUT = 30 28 _DEFAULT_TIMEOUT = 30
23 _DEFAULT_RETRIES = 3 29 _DEFAULT_RETRIES = 3
24 30
25 31
26 @decorators.WithExplicitTimeoutAndRetries( 32 @decorators.WithExplicitTimeoutAndRetries(
27 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES) 33 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
28 def GetAVDs(): 34 def GetAVDs():
29 """Returns a list of Android Virtual Devices. 35 """Returns a list of Android Virtual Devices.
(...skipping 24 matching lines...) Expand all
54 Args: 60 Args:
55 device: Either a device serial, an existing AdbWrapper instance, an 61 device: Either a device serial, an existing AdbWrapper instance, an
56 an existing AndroidCommands instance, or nothing. 62 an existing AndroidCommands instance, or nothing.
57 default_timeout: An integer containing the default number of seconds to 63 default_timeout: An integer containing the default number of seconds to
58 wait for an operation to complete if no explicit value 64 wait for an operation to complete if no explicit value
59 is provided. 65 is provided.
60 default_retries: An integer containing the default number or times an 66 default_retries: An integer containing the default number or times an
61 operation should be retried on failure if no explicit 67 operation should be retried on failure if no explicit
62 value is provided. 68 value is provided.
63 """ 69 """
70 self.adb = None
64 self.old_interface = None 71 self.old_interface = None
65 if isinstance(device, basestring): 72 if isinstance(device, basestring):
73 self.adb = adb_wrapper.AdbWrapper(device)
66 self.old_interface = pylib.android_commands.AndroidCommands(device) 74 self.old_interface = pylib.android_commands.AndroidCommands(device)
67 elif isinstance(device, adb_wrapper.AdbWrapper): 75 elif isinstance(device, adb_wrapper.AdbWrapper):
76 self.adb = device
68 self.old_interface = pylib.android_commands.AndroidCommands(str(device)) 77 self.old_interface = pylib.android_commands.AndroidCommands(str(device))
69 elif isinstance(device, pylib.android_commands.AndroidCommands): 78 elif isinstance(device, pylib.android_commands.AndroidCommands):
79 self.adb = adb_wrapper.AdbWrapper(device.GetDevice())
70 self.old_interface = device 80 self.old_interface = device
71 elif not device: 81 elif not device:
82 self.adb = adb_wrapper.AdbWrapper('')
72 self.old_interface = pylib.android_commands.AndroidCommands() 83 self.old_interface = pylib.android_commands.AndroidCommands()
73 else: 84 else:
74 raise ValueError('Unsupported type passed for argument "device"') 85 raise ValueError('Unsupported type passed for argument "device"')
86 self._commands_installed = False
75 self._default_timeout = default_timeout 87 self._default_timeout = default_timeout
76 self._default_retries = default_retries 88 self._default_retries = default_retries
77 assert(hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR)) 89 assert(hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR))
78 assert(hasattr(self, decorators.DEFAULT_RETRIES_ATTR)) 90 assert(hasattr(self, decorators.DEFAULT_RETRIES_ATTR))
79 91
80 @decorators.WithTimeoutAndRetriesFromInstance() 92 @decorators.WithTimeoutAndRetriesFromInstance()
81 def IsOnline(self, timeout=None, retries=None): 93 def IsOnline(self, timeout=None, retries=None):
82 """Checks whether the device is online. 94 """Checks whether the device is online.
83 95
84 Args: 96 Args:
85 timeout: timeout in seconds 97 timeout: timeout in seconds
86 retries: number of retries 98 retries: number of retries
87 99
88 Returns: 100 Returns:
89 True if the device is online, False otherwise. 101 True if the device is online, False otherwise.
90 102
91 Raises: 103 Raises:
92 CommandTimeoutError on timeout. 104 CommandTimeoutError on timeout.
93 """ 105 """
106 return self._IsOnlineImpl()
107
108 def _IsOnlineImpl(self):
94 return self.old_interface.IsOnline() 109 return self.old_interface.IsOnline()
95 110
96 @decorators.WithTimeoutAndRetriesFromInstance() 111 @decorators.WithTimeoutAndRetriesFromInstance()
97 def HasRoot(self, timeout=None, retries=None): 112 def HasRoot(self, timeout=None, retries=None):
98 """Checks whether or not adbd has root privileges. 113 """Checks whether or not adbd has root privileges.
99 114
100 Args: 115 Args:
101 timeout: timeout in seconds 116 timeout: timeout in seconds
102 retries: number of retries 117 retries: number of retries
103 118
104 Returns: 119 Returns:
105 True if adbd has root privileges, False otherwise. 120 True if adbd has root privileges, False otherwise.
106 121
107 Raises: 122 Raises:
108 CommandTimeoutError on timeout. 123 CommandTimeoutError on timeout.
109 DeviceUnreachableError on missing device. 124 DeviceUnreachableError on missing device.
110 """ 125 """
111 return self._HasRootImpl() 126 return self._HasRootImpl()
112 127
113 def _HasRootImpl(self): 128 def _HasRootImpl(self):
114 """Implementation of HasRoot.
115
116 This is split from HasRoot to allow other DeviceUtils methods to call
117 HasRoot without spawning a new timeout thread.
118
119 Returns:
120 Same as for |HasRoot|.
121
122 Raises:
123 Same as for |HasRoot|.
124 """
125 return self.old_interface.IsRootEnabled() 129 return self.old_interface.IsRootEnabled()
126 130
127 @decorators.WithTimeoutAndRetriesFromInstance() 131 @decorators.WithTimeoutAndRetriesFromInstance()
128 def EnableRoot(self, timeout=None, retries=None): 132 def EnableRoot(self, timeout=None, retries=None):
129 """Restarts adbd with root privileges. 133 """Restarts adbd with root privileges.
130 134
131 Args: 135 Args:
132 timeout: timeout in seconds 136 timeout: timeout in seconds
133 retries: number of retries 137 retries: number of retries
134 138
(...skipping 14 matching lines...) Expand all
149 retries: number of retries 153 retries: number of retries
150 154
151 Returns: 155 Returns:
152 The device's path to its SD card. 156 The device's path to its SD card.
153 157
154 Raises: 158 Raises:
155 CommandFailedError if the external storage path could not be determined. 159 CommandFailedError if the external storage path could not be determined.
156 CommandTimeoutError on timeout. 160 CommandTimeoutError on timeout.
157 DeviceUnreachableError on missing device. 161 DeviceUnreachableError on missing device.
158 """ 162 """
163 return self._GetExternalStoragePathImpl()
164
165 def _GetExternalStoragePathImpl(self):
159 try: 166 try:
160 return self.old_interface.GetExternalStorage() 167 return self.old_interface.GetExternalStorage()
161 except AssertionError as e: 168 except AssertionError as e:
162 raise device_errors.CommandFailedError( 169 raise device_errors.CommandFailedError(
163 str(e), device=str(self)), None, sys.exc_info()[2] 170 str(e), device=str(self)), None, sys.exc_info()[2]
164 171
165 @decorators.WithTimeoutAndRetriesFromInstance() 172 @decorators.WithTimeoutAndRetriesFromInstance()
166 def WaitUntilFullyBooted(self, wifi=False, timeout=None, retries=None): 173 def WaitUntilFullyBooted(self, wifi=False, timeout=None, retries=None):
167 """Wait for the device to fully boot. 174 """Wait for the device to fully boot.
168 175
169 This means waiting for the device to boot, the package manager to be 176 This means waiting for the device to boot, the package manager to be
170 available, and the SD card to be ready. It can optionally mean waiting 177 available, and the SD card to be ready. It can optionally mean waiting
171 for wifi to come up, too. 178 for wifi to come up, too.
172 179
173 Args: 180 Args:
174 wifi: A boolean indicating if we should wait for wifi to come up or not. 181 wifi: A boolean indicating if we should wait for wifi to come up or not.
175 timeout: timeout in seconds 182 timeout: timeout in seconds
176 retries: number of retries 183 retries: number of retries
177 184
178 Raises: 185 Raises:
179 CommandFailedError on failure. 186 CommandFailedError on failure.
180 CommandTimeoutError if one of the component waits times out. 187 CommandTimeoutError if one of the component waits times out.
181 DeviceUnreachableError if the device becomes unresponsive. 188 DeviceUnreachableError if the device becomes unresponsive.
182 """ 189 """
183 self._WaitUntilFullyBootedImpl(wifi=wifi, timeout=timeout) 190 self._WaitUntilFullyBootedImpl(wifi=wifi, timeout=timeout)
184 191
185 def _WaitUntilFullyBootedImpl(self, wifi=False, timeout=None): 192 def _WaitUntilFullyBootedImpl(self, wifi=False, timeout=None):
186 """Implementation of WaitUntilFullyBooted.
187
188 This is split from WaitUntilFullyBooted to allow other DeviceUtils methods
189 to call WaitUntilFullyBooted without spawning a new timeout thread.
190
191 TODO(jbudorick) Remove the timeout parameter once this is no longer
192 implemented via AndroidCommands.
193
194 Args:
195 wifi: Same as for |WaitUntilFullyBooted|.
196 timeout: timeout in seconds
197
198 Raises:
199 Same as for |WaitUntilFullyBooted|.
200 """
201 if timeout is None: 193 if timeout is None:
202 timeout = self._default_timeout 194 timeout = self._default_timeout
203 self.old_interface.WaitForSystemBootCompleted(timeout) 195 self.old_interface.WaitForSystemBootCompleted(timeout)
204 self.old_interface.WaitForDevicePm() 196 self.old_interface.WaitForDevicePm()
205 self.old_interface.WaitForSdCardReady(timeout) 197 self.old_interface.WaitForSdCardReady(timeout)
206 if wifi: 198 if wifi:
207 while not 'Wi-Fi is enabled' in ( 199 while not 'Wi-Fi is enabled' in (
208 self._RunShellCommandImpl('dumpsys wifi')): 200 self._RunShellCommandImpl('dumpsys wifi')):
209 time.sleep(1) 201 time.sleep(1)
210 202
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 out = self.old_interface.Install(apk_path, reinstall=reinstall) 266 out = self.old_interface.Install(apk_path, reinstall=reinstall)
275 for line in out.splitlines(): 267 for line in out.splitlines():
276 if 'Failure' in line: 268 if 'Failure' in line:
277 raise device_errors.CommandFailedError( 269 raise device_errors.CommandFailedError(
278 line.strip(), device=str(self)) 270 line.strip(), device=str(self))
279 except AssertionError as e: 271 except AssertionError as e:
280 raise device_errors.CommandFailedError( 272 raise device_errors.CommandFailedError(
281 str(e), device=str(self)), None, sys.exc_info()[2] 273 str(e), device=str(self)), None, sys.exc_info()[2]
282 274
283 @decorators.WithTimeoutAndRetriesFromInstance() 275 @decorators.WithTimeoutAndRetriesFromInstance()
284 def RunShellCommand(self, cmd, check_return=False, as_root=False, 276 def RunShellCommand(self, cmd, check_return=False, as_root=False, cwd=None,
285 timeout=None, retries=None): 277 env=None, timeout=None, retries=None):
286 """Run an ADB shell command. 278 """Run an ADB shell command.
287 279
288 TODO(jbudorick) Switch the default value of check_return to True after 280 TODO(jbudorick) Switch the default value of check_return to True after
289 AndroidCommands is gone. 281 AndroidCommands is gone.
290 282
291 Args: 283 Args:
292 cmd: A list containing the command to run on the device and any arguments. 284 cmd: A list containing the command to run on the device and any arguments.
293 check_return: A boolean indicating whether or not the return code should 285 check_return: A boolean indicating whether or not the return code should
294 be checked. 286 be checked.
295 as_root: A boolean indicating whether the shell command should be run 287 as_root: A boolean indicating whether the shell command should be run
296 with root privileges. 288 with root privileges.
289 cwd: The device directory in which the command should be run.
290 env: The environment variables with which the command should be run.
297 timeout: timeout in seconds 291 timeout: timeout in seconds
298 retries: number of retries 292 retries: number of retries
299 293
300 Returns: 294 Returns:
301 The output of the command. 295 The output of the command.
302 296
303 Raises: 297 Raises:
304 CommandFailedError if check_return is True and the return code is nozero. 298 CommandFailedError if check_return is True and the return code is nozero.
305 CommandTimeoutError on timeout. 299 CommandTimeoutError on timeout.
306 DeviceUnreachableError on missing device. 300 DeviceUnreachableError on missing device.
307 """ 301 """
308 return self._RunShellCommandImpl(cmd, check_return=check_return, 302 return self._RunShellCommandImpl(
309 as_root=as_root, timeout=timeout) 303 cmd, check_return=check_return, as_root=as_root, cwd=cwd, env=env,
304 timeout=timeout)
310 305
311 def _RunShellCommandImpl(self, cmd, check_return=False, as_root=False, 306 def _RunShellCommandImpl(self, cmd, check_return=False, as_root=False,
312 timeout=None): 307 cwd=None, env=None, timeout=None):
313 """Implementation of RunShellCommand. 308 # TODO(jbudorick): Remove the timeout parameter once this is no longer
314 309 # backed by AndroidCommands.
315 This is split from RunShellCommand to allow other DeviceUtils methods to
316 call RunShellCommand without spawning a new timeout thread.
317
318 TODO(jbudorick) Remove the timeout parameter once this is no longer
319 implemented via AndroidCommands.
320
321 Args:
322 cmd: Same as for |RunShellCommand|.
323 check_return: Same as for |RunShellCommand|.
324 as_root: Same as for |RunShellCommand|.
325 timeout: timeout in seconds
326
327 Raises:
328 Same as for |RunShellCommand|.
329
330 Returns:
331 Same as for |RunShellCommand|.
332 """
333 if isinstance(cmd, list): 310 if isinstance(cmd, list):
334 cmd = ' '.join(cmd) 311 cmd = ' '.join(cmd)
335 if as_root and not self.HasRoot(): 312 if as_root and not self._HasRootImpl():
336 cmd = 'su -c %s' % cmd 313 cmd = 'su -c %s' % cmd
314 if env:
315 cmd = '%s %s' % (
316 ' '.join('%s=%s' % (k, v) for k, v in env.iteritems()), cmd)
317 if cwd:
318 cmd = 'cd %s && %s' % (cwd, cmd)
337 if check_return: 319 if check_return:
338 code, output = self.old_interface.GetShellCommandStatusAndOutput( 320 code, output = self.old_interface.GetShellCommandStatusAndOutput(
339 cmd, timeout_time=timeout) 321 cmd, timeout_time=timeout)
340 if int(code) != 0: 322 if int(code) != 0:
341 raise device_errors.AdbCommandFailedError( 323 raise device_errors.AdbCommandFailedError(
342 cmd.split(), 'Nonzero exit code (%d)' % code, device=str(self)) 324 cmd.split(), 'Nonzero exit code (%d)' % code, device=str(self))
343 else: 325 else:
344 output = self.old_interface.RunShellCommand(cmd, timeout_time=timeout) 326 output = self.old_interface.RunShellCommand(cmd, timeout_time=timeout)
345 return output 327 return output
346 328
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 DeviceUnreachableError on missing device. 476 DeviceUnreachableError on missing device.
495 """ 477 """
496 self.old_interface.SendKeyEvent(keycode) 478 self.old_interface.SendKeyEvent(keycode)
497 479
498 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT 480 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT
499 PUSH_CHANGED_FILES_DEFAULT_RETRIES = _DEFAULT_RETRIES 481 PUSH_CHANGED_FILES_DEFAULT_RETRIES = _DEFAULT_RETRIES
500 482
501 @decorators.WithTimeoutAndRetriesDefaults( 483 @decorators.WithTimeoutAndRetriesDefaults(
502 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT, 484 PUSH_CHANGED_FILES_DEFAULT_TIMEOUT,
503 PUSH_CHANGED_FILES_DEFAULT_RETRIES) 485 PUSH_CHANGED_FILES_DEFAULT_RETRIES)
504 def PushChangedFiles(self, host_path, device_path, timeout=None, 486 def PushChangedFiles(self, host_device_tuples, timeout=None,
505 retries=None): 487 retries=None):
506 """Push files to the device, skipping files that don't need updating. 488 """Push files to the device, skipping files that don't need updating.
507 489
508 Args: 490 Args:
509 host_path: A string containing the absolute path to the file or directory 491 host_device_tuples: A list of (host_path, device_path) tuples, where
510 on the host that should be minimally pushed to the device. 492 |host_path| is an absolute path of a file or directory on the host
511 device_path: A string containing the absolute path of the destination on 493 that should be minimially pushed to the device, and |device_path| is
512 the device. 494 an absolute path of the destination on the device.
513 timeout: timeout in seconds 495 timeout: timeout in seconds
514 retries: number of retries 496 retries: number of retries
515 497
516 Raises: 498 Raises:
517 CommandFailedError on failure. 499 CommandFailedError on failure.
518 CommandTimeoutError on timeout. 500 CommandTimeoutError on timeout.
519 DeviceUnreachableError on missing device. 501 DeviceUnreachableError on missing device.
520 """ 502 """
521 self.old_interface.PushIfNeeded(host_path, device_path) 503
504 files = []
505 for h, d in host_device_tuples:
506 if os.path.isdir(h):
507 self._RunShellCommandImpl(['mkdir', '-p', '"%s"' % d],
508 check_return=True)
509 files += self.old_interface.GetFilesChanged(h, d)
510
511 if not files:
512 return
513
514 size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files)
515 file_count = len(files)
516 dir_size = sum(host_utils.GetRecursiveDiskUsage(h)
517 for h, _ in host_device_tuples)
518 dir_file_count = 0
519 for h, _ in host_device_tuples:
520 if os.path.isdir(h):
521 dir_file_count += sum(len(f) for _r, _d, f in os.walk(h))
522 else:
523 dir_file_count += 1
524
525 push_duration = self._ApproximateDuration(
526 file_count, file_count, size, False)
527 dir_push_duration = self._ApproximateDuration(
528 len(host_device_tuples), dir_file_count, dir_size, False)
529 zip_duration = self._ApproximateDuration(1, 1, size, True)
530
531 if dir_push_duration < push_duration and dir_push_duration < zip_duration:
532 self._PushChangedFilesIndividually(host_device_tuples)
533 elif push_duration < zip_duration:
534 self._PushChangedFilesIndividually(files)
535 else:
536 self._PushChangedFilesZipped(files)
537 self._RunShellCommandImpl(
538 ['chmod', '-R', '777'] + [d for _, d in host_device_tuples],
539 as_root=True)
540
541 @staticmethod
542 def _ApproximateDuration(adb_calls, file_count, byte_count, is_zipping):
543 # We approximate the time to push a set of files to a device as:
544 # t = c1 * a + c2 * f + c3 + b / c4 + b / (c5 * c6), where
545 # t: total time (sec)
546 # c1: adb call time delay (sec)
547 # a: number of times adb is called (unitless)
548 # c2: push time delay (sec)
549 # f: number of files pushed via adb (unitless)
550 # c3: zip time delay (sec)
551 # c4: zip rate (bytes/sec)
552 # b: total number of bytes (bytes)
553 # c5: transfer rate (bytes/sec)
554 # c6: compression ratio (unitless)
555
556 # All of these are approximations.
557 ADB_CALL_PENALTY = 0.1 # seconds
558 ADB_PUSH_PENALTY = 0.01 # seconds
559 ZIP_PENALTY = 2.0 # seconds
560 ZIP_RATE = 10000000.0 # bytes / second
561 TRANSFER_RATE = 2000000.0 # bytes / second
562 COMPRESSION_RATIO = 2.0 # unitless
563
564 adb_call_time = ADB_CALL_PENALTY * adb_calls
565 adb_push_setup_time = ADB_PUSH_PENALTY * file_count
566 if is_zipping:
567 zip_time = ZIP_PENALTY + byte_count / ZIP_RATE
568 transfer_time = byte_count / (TRANSFER_RATE * COMPRESSION_RATIO)
569 else:
570 zip_time = 0
571 transfer_time = byte_count / TRANSFER_RATE
572 return (adb_call_time + adb_push_setup_time + zip_time + transfer_time)
573
574 def _PushChangedFilesIndividually(self, files):
575 for h, d in files:
576 self.adb.Push(h, d)
577
578 def _PushChangedFilesZipped(self, files):
579 if not files:
580 return
581
582 self._InstallCommands()
583
584 with tempfile.NamedTemporaryFile(suffix='.zip') as zip_file:
585 zip_proc = multiprocessing.Process(
586 target=DeviceUtils._CreateDeviceZip,
587 args=(zip_file.name, files))
588 zip_proc.start()
589 zip_proc.join()
590
591 zip_on_device = '%s/tmp.zip' % self._GetExternalStoragePathImpl()
592 try:
593 self.adb.Push(zip_file.name, zip_on_device)
594 self._RunShellCommandImpl(
595 ['unzip', zip_on_device],
596 as_root=True, check_return=True,
597 env={'PATH': '$PATH:%s' % install_commands.BIN_DIR})
598 finally:
599 if zip_proc.is_alive():
600 zip_proc.terminate()
601 if self._IsOnlineImpl():
602 self._RunShellCommandImpl(['rm', zip_on_device])
603
604 def _InstallCommands(self):
605 if not self._commands_installed and not install_commands.Installed(self):
606 install_commands.InstallCommands(self)
607 self._commands_installed = True
608
609 @staticmethod
610 def _CreateDeviceZip(zip_path, host_device_tuples):
611 with zipfile.ZipFile(zip_path, 'w') as zip_file:
612 for host_path, device_path in host_device_tuples:
613 if os.path.isfile(host_path):
614 zip_file.write(host_path, device_path, zipfile.ZIP_DEFLATED)
615 else:
616 for hd, _, files in os.walk(host_path):
617 dd = '%s/%s' % (device_path, os.path.relpath(host_path, hd))
618 zip_file.write(hd, dd, zipfile.ZIP_STORED)
619 for f in files:
620 zip_file.write(os.path.join(hd, f), '%s/%s' % (dd, f),
621 zipfile.ZIP_DEFLATED)
522 622
523 @decorators.WithTimeoutAndRetriesFromInstance() 623 @decorators.WithTimeoutAndRetriesFromInstance()
524 def FileExists(self, device_path, timeout=None, retries=None): 624 def FileExists(self, device_path, timeout=None, retries=None):
525 """Checks whether the given file exists on the device. 625 """Checks whether the given file exists on the device.
526 626
527 Args: 627 Args:
528 device_path: A string containing the absolute path to the file on the 628 device_path: A string containing the absolute path to the file on the
529 device. 629 device.
530 timeout: timeout in seconds 630 timeout: timeout in seconds
531 retries: number of retries 631 retries: number of retries
532 632
533 Returns: 633 Returns:
534 True if the file exists on the device, False otherwise. 634 True if the file exists on the device, False otherwise.
535 635
536 Raises: 636 Raises:
537 CommandTimeoutError on timeout. 637 CommandTimeoutError on timeout.
538 DeviceUnreachableError on missing device. 638 DeviceUnreachableError on missing device.
539 """ 639 """
540 return self._FileExistsImpl(device_path)
541
542 def _FileExistsImpl(self, device_path):
543 """Implementation of FileExists.
544
545 This is split from FileExists to allow other DeviceUtils methods to call
546 FileExists without spawning a new timeout thread.
547
548 Args:
549 device_path: Same as for |FileExists|.
550
551 Returns:
552 True if the file exists on the device, False otherwise.
553
554 Raises:
555 Same as for |FileExists|.
556 """
557 return self.old_interface.FileExistsOnDevice(device_path) 640 return self.old_interface.FileExistsOnDevice(device_path)
558 641
559 @decorators.WithTimeoutAndRetriesFromInstance() 642 @decorators.WithTimeoutAndRetriesFromInstance()
560 def PullFile(self, device_path, host_path, timeout=None, retries=None): 643 def PullFile(self, device_path, host_path, timeout=None, retries=None):
561 """Pull a file from the device. 644 """Pull a file from the device.
562 645
563 Args: 646 Args:
564 device_path: A string containing the absolute path of the file to pull 647 device_path: A string containing the absolute path of the file to pull
565 from the device. 648 from the device.
566 host_path: A string containing the absolute path of the destination on 649 host_path: A string containing the absolute path of the destination on
(...skipping 24 matching lines...) Expand all
591 retries: number of retries 674 retries: number of retries
592 675
593 Returns: 676 Returns:
594 The contents of the file at |device_path| as a list of lines. 677 The contents of the file at |device_path| as a list of lines.
595 678
596 Raises: 679 Raises:
597 CommandFailedError if the file can't be read. 680 CommandFailedError if the file can't be read.
598 CommandTimeoutError on timeout. 681 CommandTimeoutError on timeout.
599 DeviceUnreachableError on missing device. 682 DeviceUnreachableError on missing device.
600 """ 683 """
601 # TODO(jbudorick) Evaluate whether we awant to return a list of lines after 684 # TODO(jbudorick) Evaluate whether we want to return a list of lines after
602 # the implementation switch, and if file not found should raise exception. 685 # the implementation switch, and if file not found should raise exception.
603 if as_root: 686 if as_root:
604 if not self.old_interface.CanAccessProtectedFileContents(): 687 if not self.old_interface.CanAccessProtectedFileContents():
605 raise device_errors.CommandFailedError( 688 raise device_errors.CommandFailedError(
606 'Cannot read from %s with root privileges.' % device_path) 689 'Cannot read from %s with root privileges.' % device_path)
607 return self.old_interface.GetProtectedFileContents(device_path) 690 return self.old_interface.GetProtectedFileContents(device_path)
608 else: 691 else:
609 return self.old_interface.GetFileContents(device_path) 692 return self.old_interface.GetFileContents(device_path)
610 693
611 @decorators.WithTimeoutAndRetriesFromInstance() 694 @decorators.WithTimeoutAndRetriesFromInstance()
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 A dict mapping process name to PID for each process that contained the 831 A dict mapping process name to PID for each process that contained the
749 provided |process_name|. 832 provided |process_name|.
750 833
751 Raises: 834 Raises:
752 CommandTimeoutError on timeout. 835 CommandTimeoutError on timeout.
753 DeviceUnreachableError on missing device. 836 DeviceUnreachableError on missing device.
754 """ 837 """
755 return self._GetPidsImpl(process_name) 838 return self._GetPidsImpl(process_name)
756 839
757 def _GetPidsImpl(self, process_name): 840 def _GetPidsImpl(self, process_name):
758 """Implementation of GetPids.
759
760 This is split from GetPids to allow other DeviceUtils methods to call
761 GetPids without spawning a new timeout thread.
762
763 Args:
764 process_name: A string containing the process name to get the PIDs for.
765
766 Returns:
767 A dict mapping process name to PID for each process that contained the
768 provided |process_name|.
769
770 Raises:
771 DeviceUnreachableError on missing device.
772 """
773 procs_pids = {} 841 procs_pids = {}
774 for line in self._RunShellCommandImpl('ps'): 842 for line in self._RunShellCommandImpl('ps'):
775 try: 843 try:
776 ps_data = line.split() 844 ps_data = line.split()
777 if process_name in ps_data[-1]: 845 if process_name in ps_data[-1]:
778 procs_pids[ps_data[-1]] = ps_data[1] 846 procs_pids[ps_data[-1]] = ps_data[1]
779 except IndexError: 847 except IndexError:
780 pass 848 pass
781 return procs_pids 849 return procs_pids
782 850
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 A Parallelizer operating over |devices|. 931 A Parallelizer operating over |devices|.
864 """ 932 """
865 if not devices or len(devices) == 0: 933 if not devices or len(devices) == 0:
866 devices = pylib.android_commands.GetAttachedDevices() 934 devices = pylib.android_commands.GetAttachedDevices()
867 parallelizer_type = (parallelizer.Parallelizer if async 935 parallelizer_type = (parallelizer.Parallelizer if async
868 else parallelizer.SyncParallelizer) 936 else parallelizer.SyncParallelizer)
869 return parallelizer_type([ 937 return parallelizer_type([
870 d if isinstance(d, DeviceUtils) else DeviceUtils(d) 938 d if isinstance(d, DeviceUtils) else DeviceUtils(d)
871 for d in devices]) 939 for d in devices])
872 940
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698