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

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

Issue 292313015: [Android] Switch to DeviceUtils versions of Reboot and Install. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 6 years, 6 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
« no previous file with comments | « build/android/provision_devices.py ('k') | build/android/pylib/device/device_utils_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 """ 5 """Provides a variety of device interactions based on adb.
6 Provides a variety of device interactions based on adb.
7 6
8 Eventually, this will be based on adb_wrapper. 7 Eventually, this will be based on adb_wrapper.
9 """ 8 """
10 # pylint: disable=W0613 9 # pylint: disable=W0613
11 10
12 import time 11 import time
13 12
14 import pylib.android_commands 13 import pylib.android_commands
15 from pylib.device import adb_wrapper 14 from pylib.device import adb_wrapper
16 from pylib.device import decorators 15 from pylib.device import decorators
17 from pylib.device import device_errors 16 from pylib.device import device_errors
17 from pylib.utils import apk_helper
18 from pylib.utils import parallelizer 18 from pylib.utils import parallelizer
19 19
20 _DEFAULT_TIMEOUT = 30 20 _DEFAULT_TIMEOUT = 30
21 _DEFAULT_RETRIES = 3 21 _DEFAULT_RETRIES = 3
22 22
23 23
24 @decorators.WithExplicitTimeoutAndRetries( 24 @decorators.WithExplicitTimeoutAndRetries(
25 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES) 25 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
26 def GetAVDs(): 26 def GetAVDs():
27 """ Returns a list of Android Virtual Devices. 27 """Returns a list of Android Virtual Devices.
28 28
29 Returns: 29 Returns:
30 A list containing the configured AVDs. 30 A list containing the configured AVDs.
31 """ 31 """
32 return pylib.android_commands.GetAVDs() 32 return pylib.android_commands.GetAVDs()
33 33
34 34
35 @decorators.WithExplicitTimeoutAndRetries( 35 @decorators.WithExplicitTimeoutAndRetries(
36 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES) 36 _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
37 def RestartServer(): 37 def RestartServer():
38 """ Restarts the adb server. 38 """Restarts the adb server.
39 39
40 Raises: 40 Raises:
41 CommandFailedError if we fail to kill or restart the server. 41 CommandFailedError if we fail to kill or restart the server.
42 """ 42 """
43 pylib.android_commands.AndroidCommands().RestartAdbServer() 43 pylib.android_commands.AndroidCommands().RestartAdbServer()
44 44
45 45
46 class DeviceUtils(object): 46 class DeviceUtils(object):
47 47
48 def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT, 48 def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT,
49 default_retries=_DEFAULT_RETRIES): 49 default_retries=_DEFAULT_RETRIES):
50 """ DeviceUtils constructor. 50 """DeviceUtils constructor.
51 51
52 Args: 52 Args:
53 device: Either a device serial, an existing AdbWrapper instance, an 53 device: Either a device serial, an existing AdbWrapper instance, an
54 an existing AndroidCommands instance, or nothing. 54 an existing AndroidCommands instance, or nothing.
55 default_timeout: An integer containing the default number of seconds to 55 default_timeout: An integer containing the default number of seconds to
56 wait for an operation to complete if no explicit value 56 wait for an operation to complete if no explicit value
57 is provided. 57 is provided.
58 default_retries: An integer containing the default number or times an 58 default_retries: An integer containing the default number or times an
59 operation should be retried on failure if no explicit 59 operation should be retried on failure if no explicit
60 value is provided. 60 value is provided.
61 """ 61 """
62 self.old_interface = None 62 self.old_interface = None
63 if isinstance(device, basestring): 63 if isinstance(device, basestring):
64 self.old_interface = pylib.android_commands.AndroidCommands(device) 64 self.old_interface = pylib.android_commands.AndroidCommands(device)
65 elif isinstance(device, adb_wrapper.AdbWrapper): 65 elif isinstance(device, adb_wrapper.AdbWrapper):
66 self.old_interface = pylib.android_commands.AndroidCommands(str(device)) 66 self.old_interface = pylib.android_commands.AndroidCommands(str(device))
67 elif isinstance(device, pylib.android_commands.AndroidCommands): 67 elif isinstance(device, pylib.android_commands.AndroidCommands):
68 self.old_interface = device 68 self.old_interface = device
69 elif not device: 69 elif not device:
70 self.old_interface = pylib.android_commands.AndroidCommands() 70 self.old_interface = pylib.android_commands.AndroidCommands()
71 else: 71 else:
72 raise ValueError('Unsupported type passed for argument "device"') 72 raise ValueError('Unsupported type passed for argument "device"')
73 self._default_timeout = default_timeout 73 self._default_timeout = default_timeout
74 self._default_retries = default_retries 74 self._default_retries = default_retries
75 assert(hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR)) 75 assert(hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR))
76 assert(hasattr(self, decorators.DEFAULT_RETRIES_ATTR)) 76 assert(hasattr(self, decorators.DEFAULT_RETRIES_ATTR))
77 77
78 @decorators.WithTimeoutAndRetriesFromInstance() 78 @decorators.WithTimeoutAndRetriesFromInstance()
79 def IsOnline(self, timeout=None, retries=None): 79 def IsOnline(self, timeout=None, retries=None):
80 """ Checks whether the device is online. 80 """Checks whether the device is online.
81 81
82 Args: 82 Args:
83 timeout: An integer containing the number of seconds to wait for the 83 timeout: An integer containing the number of seconds to wait for the
84 operation to complete. 84 operation to complete.
85 retries: An integer containing the number of times the operation should 85 retries: An integer containing the number of times the operation should
86 be retried if it fails. 86 be retried if it fails.
87 Returns: 87 Returns:
88 True if the device is online, False otherwise. 88 True if the device is online, False otherwise.
89 """ 89 """
90 return self.old_interface.IsOnline() 90 return self.old_interface.IsOnline()
91 91
92 @decorators.WithTimeoutAndRetriesFromInstance() 92 @decorators.WithTimeoutAndRetriesFromInstance()
93 def HasRoot(self, timeout=None, retries=None): 93 def HasRoot(self, timeout=None, retries=None):
94 """ Checks whether or not adbd has root privileges. 94 """Checks whether or not adbd has root privileges.
95 95
96 Args: 96 Args:
97 timeout: Same as for |IsOnline|. 97 timeout: Same as for |IsOnline|.
98 retries: Same as for |IsOnline|. 98 retries: Same as for |IsOnline|.
99 Returns: 99 Returns:
100 True if adbd has root privileges, False otherwise. 100 True if adbd has root privileges, False otherwise.
101 """ 101 """
102 return self.old_interface.IsRootEnabled() 102 return self.old_interface.IsRootEnabled()
103 103
104 @decorators.WithTimeoutAndRetriesFromInstance() 104 @decorators.WithTimeoutAndRetriesFromInstance()
105 def EnableRoot(self, timeout=None, retries=None): 105 def EnableRoot(self, timeout=None, retries=None):
106 """ Restarts adbd with root privileges. 106 """Restarts adbd with root privileges.
107 107
108 Args: 108 Args:
109 timeout: Same as for |IsOnline|. 109 timeout: Same as for |IsOnline|.
110 retries: Same as for |IsOnline|. 110 retries: Same as for |IsOnline|.
111 Raises: 111 Raises:
112 CommandFailedError if root could not be enabled. 112 CommandFailedError if root could not be enabled.
113 """ 113 """
114 if not self.old_interface.EnableAdbRoot(): 114 if not self.old_interface.EnableAdbRoot():
115 raise device_errors.CommandFailedError( 115 raise device_errors.CommandFailedError(
116 'adb root', 'Could not enable root.') 116 ['adb', 'root'], 'Could not enable root.')
117 117
118 @decorators.WithTimeoutAndRetriesFromInstance() 118 @decorators.WithTimeoutAndRetriesFromInstance()
119 def GetExternalStoragePath(self, timeout=None, retries=None): 119 def GetExternalStoragePath(self, timeout=None, retries=None):
120 """ Get the device's path to its SD card. 120 """Get the device's path to its SD card.
121 121
122 Args: 122 Args:
123 timeout: Same as for |IsOnline|. 123 timeout: Same as for |IsOnline|.
124 retries: Same as for |IsOnline|. 124 retries: Same as for |IsOnline|.
125 Returns: 125 Returns:
126 The device's path to its SD card. 126 The device's path to its SD card.
127 """ 127 """
128 try: 128 try:
129 return self.old_interface.GetExternalStorage() 129 return self.old_interface.GetExternalStorage()
130 except AssertionError as e: 130 except AssertionError as e:
131 raise device_errors.CommandFailedError(str(e)) 131 raise device_errors.CommandFailedError(
132 ['adb', 'shell', 'echo', '$EXTERNAL_STORAGE'], str(e))
132 133
133 @decorators.WithTimeoutAndRetriesFromInstance() 134 @decorators.WithTimeoutAndRetriesFromInstance()
134 def WaitUntilFullyBooted(self, wifi=False, timeout=None, retries=None): 135 def WaitUntilFullyBooted(self, wifi=False, timeout=None, retries=None):
135 """ Wait for the device to fully boot. 136 """Wait for the device to fully boot.
136 137
137 This means waiting for the device to boot, the package manager to be 138 This means waiting for the device to boot, the package manager to be
138 available, and the SD card to be ready. It can optionally mean waiting 139 available, and the SD card to be ready. It can optionally mean waiting
139 for wifi to come up, too. 140 for wifi to come up, too.
140 141
141 Args: 142 Args:
142 wifi: A boolean indicating if we should wait for wifi to come up or not. 143 wifi: A boolean indicating if we should wait for wifi to come up or not.
143 timeout: Same as for |IsOnline|. 144 timeout: Same as for |IsOnline|.
144 retries: Same as for |IsOnline|. 145 retries: Same as for |IsOnline|.
145 Raises: 146 Raises:
146 CommandTimeoutError if one of the component waits times out. 147 CommandTimeoutError if one of the component waits times out.
147 DeviceUnreachableError if the device becomes unresponsive. 148 DeviceUnreachableError if the device becomes unresponsive.
148 """ 149 """
150 self._WaitUntilFullyBootedImpl(wifi=wifi, timeout=timeout)
151
152 def _WaitUntilFullyBootedImpl(self, wifi=False, timeout=None):
153 """ Implementation of WaitUntilFullyBooted.
154
155 This is split from WaitUntilFullyBooted to allow other DeviceUtils methods
156 to call WaitUntilFullyBooted without spawning a new timeout thread.
157
158 TODO(jbudorick) Remove the timeout parameter once this is no longer
159 implemented via AndroidCommands.
160
161 Args:
162 wifi: Same as for |WaitUntilFullyBooted|.
163 timeout: Same as for |IsOnline|.
164 Raises:
165 Same as for |WaitUntilFullyBooted|.
166 """
167 if timeout is None:
168 timeout = self._default_timeout
149 self.old_interface.WaitForSystemBootCompleted(timeout) 169 self.old_interface.WaitForSystemBootCompleted(timeout)
150 self.old_interface.WaitForDevicePm() 170 self.old_interface.WaitForDevicePm()
151 self.old_interface.WaitForSdCardReady(timeout) 171 self.old_interface.WaitForSdCardReady(timeout)
152 if wifi: 172 if wifi:
153 while not 'Wi-Fi is enabled' in ( 173 while not 'Wi-Fi is enabled' in (
154 self.old_interface.RunShellCommand('dumpsys wifi')): 174 self.old_interface.RunShellCommand('dumpsys wifi')):
155 time.sleep(0.1) 175 time.sleep(0.1)
156 176
177 @decorators.WithTimeoutAndRetriesDefaults(
178 10 * _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
179 def Reboot(self, block=True, timeout=None, retries=None):
180 """Reboot the device.
181
182 Args:
183 block: A boolean indicating if we should wait for the reboot to complete.
184 timeout: Same as for |IsOnline|.
185 retries: Same as for |IsOnline|.
186 """
187 self.old_interface.Reboot()
188 if block:
189 self._WaitUntilFullyBootedImpl(timeout=timeout)
190
191 @decorators.WithTimeoutAndRetriesDefaults(
192 4 * _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
193 def Install(self, apk_path, reinstall=False, timeout=None, retries=None):
194 """Install an APK.
195
196 Noop if an identical APK is already installed.
197
198 Args:
199 apk_path: A string containing the path to the APK to install.
200 reinstall: A boolean indicating if we should keep any existing app data.
201 timeout: Same as for |IsOnline|.
202 retries: Same as for |IsOnline|.
203 Raises:
204 CommandFailedError if the installation fails.
205 CommandTimeoutError if the installation times out.
206 """
207 package_name = apk_helper.GetPackageName(apk_path)
208 device_path = self.old_interface.GetApplicationPath(package_name)
209 if device_path is not None:
210 files_changed = self.old_interface.GetFilesChanged(
211 apk_path, device_path, ignore_filenames=True)
212 if len(files_changed) > 0:
213 should_install = True
214 if not reinstall:
215 out = self.old_interface.Uninstall(package_name)
216 for line in out.splitlines():
217 if 'Failure' in line:
218 raise device_errors.CommandFailedError(
219 ['adb', 'uninstall', package_name], line.strip())
220 else:
221 should_install = False
222 else:
223 should_install = True
224 if should_install:
225 try:
226 out = self.old_interface.Install(apk_path, reinstall=reinstall)
227 for line in out.splitlines():
228 if 'Failure' in line:
229 raise device_errors.CommandFailedError(
230 ['adb', 'install', apk_path], line.strip())
231 except AssertionError as e:
232 raise device_errors.CommandFailedError(
233 ['adb', 'install', apk_path], str(e))
234
157 def __str__(self): 235 def __str__(self):
158 """Returns the device serial.""" 236 """Returns the device serial."""
159 return self.old_interface.GetDevice() 237 return self.old_interface.GetDevice()
160 238
161 @staticmethod 239 @staticmethod
162 def parallel(devices=None, async=False): 240 def parallel(devices=None, async=False):
163 """ Creates a Parallelizer to operate over the provided list of devices. 241 """Creates a Parallelizer to operate over the provided list of devices.
164 242
165 If |devices| is either |None| or an empty list, the Parallelizer will 243 If |devices| is either |None| or an empty list, the Parallelizer will
166 operate over all attached devices. 244 operate over all attached devices.
167 245
168 Args: 246 Args:
169 devices: A list of either DeviceUtils instances or objects from 247 devices: A list of either DeviceUtils instances or objects from
170 from which DeviceUtils instances can be constructed. If None, 248 from which DeviceUtils instances can be constructed. If None,
171 all attached devices will be used. 249 all attached devices will be used.
172 async: If true, returns a Parallelizer that runs operations 250 async: If true, returns a Parallelizer that runs operations
173 asynchronously. 251 asynchronously.
174 Returns: 252 Returns:
175 A Parallelizer operating over |devices|. 253 A Parallelizer operating over |devices|.
176 """ 254 """
177 if not devices or len(devices) == 0: 255 if not devices or len(devices) == 0:
178 devices = pylib.android_commands.GetAttachedDevices() 256 devices = pylib.android_commands.GetAttachedDevices()
179 parallelizer_type = (parallelizer.Parallelizer if async 257 parallelizer_type = (parallelizer.Parallelizer if async
180 else parallelizer.SyncParallelizer) 258 else parallelizer.SyncParallelizer)
181 return parallelizer_type([ 259 return parallelizer_type([
182 d if isinstance(d, DeviceUtils) else DeviceUtils(d) 260 d if isinstance(d, DeviceUtils) else DeviceUtils(d)
183 for d in devices]) 261 for d in devices])
184 262
OLDNEW
« no previous file with comments | « build/android/provision_devices.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