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

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

Issue 636273004: Make TimeoutRetryThread's stoppable (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 re 14 import re
15 import sys 15 import sys
16 import tempfile 16 import tempfile
17 import threading
17 import time 18 import time
18 import zipfile 19 import zipfile
19 20
20 import pylib.android_commands 21 import pylib.android_commands
21 from pylib import cmd_helper 22 from pylib import cmd_helper
22 from pylib.device import adb_wrapper 23 from pylib.device import adb_wrapper
23 from pylib.device import decorators 24 from pylib.device import decorators
24 from pylib.device import device_errors 25 from pylib.device import device_errors
25 from pylib.device.commands import install_commands 26 from pylib.device.commands import install_commands
26 from pylib.utils import apk_helper 27 from pylib.utils import apk_helper
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 Args: 214 Args:
214 wifi: A boolean indicating if we should wait for wifi to come up or not. 215 wifi: A boolean indicating if we should wait for wifi to come up or not.
215 timeout: timeout in seconds 216 timeout: timeout in seconds
216 retries: number of retries 217 retries: number of retries
217 218
218 Raises: 219 Raises:
219 CommandFailedError on failure. 220 CommandFailedError on failure.
220 CommandTimeoutError if one of the component waits times out. 221 CommandTimeoutError if one of the component waits times out.
221 DeviceUnreachableError if the device becomes unresponsive. 222 DeviceUnreachableError if the device becomes unresponsive.
222 """ 223 """
223 self._WaitUntilFullyBootedImpl(wifi=wifi, timeout=timeout) 224 def sd_card_ready():
225 return self.RunShellCommand(['ls', self.GetExternalStoragePath()])
224 226
225 def _WaitUntilFullyBootedImpl(self, wifi=False, timeout=None): 227 def pm_ready():
226 if timeout is None: 228 return self.GetApplicationPath('android')
227 timeout = self._default_timeout 229
228 self.old_interface.WaitForSystemBootCompleted(timeout) 230 def boot_completed():
229 self.old_interface.WaitForDevicePm() 231 return self.GetProp('sys.boot_completed') == '1'
230 self.old_interface.WaitForSdCardReady(timeout) 232
233 def wifi_enabled():
234 return 'Wi-Fi is enabled' in self.RunShellCommand(['dumpsys', 'wifi'])
235
236 self.adb.WaitForDevice()
237 self._WaitFor(sd_card_ready)
238 self._WaitFor(pm_ready)
239 self._WaitFor(boot_completed)
231 if wifi: 240 if wifi:
232 while not 'Wi-Fi is enabled' in ( 241 self._WaitFor(wifi_enabled)
233 self.old_interface.RunShellCommand('dumpsys wifi')): 242
234 time.sleep(1) 243 def _WaitFor(self, condition, wait_period=5):
244 start = time.time()
245 while not threading.current_thread().Stopped():
246 try:
247 r = condition()
248 except device_errors.CommandFailedError as e:
249 r = False
jbudorick 2014/10/24 17:30:51 nit: similarly here w.r.t False v None
250 logging.warning('%s at %s', str(e), threading.current_thread().name)
251 elapsed = time.time() - start
252 if r:
253 logging.warning('%s: condition %r met (%1.2f) at %s', str(self),
jbudorick 2014/10/24 17:30:51 nit: should be info or debug, not warning
perezju 2014/10/27 11:07:07 Yes, I agree these should be info. At the moment t
254 condition.__name__, elapsed, threading.current_thread().nam e)
255 return r
256 time.sleep(wait_period)
257 logging.warning('%s: condition %r not yet met (%1.2f) at %s', str(self),
258 condition.__name__, elapsed, threading.current_thread().name)
259 return False
jbudorick 2014/10/24 17:30:51 nit: I think this should return None, as False imp
perezju 2014/10/27 11:07:06 Agree.
260
261 @decorators.WithTimeoutAndRetriesFromInstance()
262 def GetApplicationPath(self, package, timeout=None, retries=None):
263 output = self.RunShellCommand(['pm', 'path', package], single_line=True)
264 if not output.startswith('package:'):
265 raise device_errors.CommandFailedError('pm path returned: %r' % output, st r(self))
266 return output[len('package:'):]
267
235 268
236 REBOOT_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT 269 REBOOT_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT
237 REBOOT_DEFAULT_RETRIES = _DEFAULT_RETRIES 270 REBOOT_DEFAULT_RETRIES = _DEFAULT_RETRIES
238 271
239 @decorators.WithTimeoutAndRetriesDefaults( 272 @decorators.WithTimeoutAndRetriesDefaults(
240 REBOOT_DEFAULT_TIMEOUT, 273 REBOOT_DEFAULT_TIMEOUT,
241 REBOOT_DEFAULT_RETRIES) 274 REBOOT_DEFAULT_RETRIES)
242 def Reboot(self, block=True, timeout=None, retries=None): 275 def Reboot(self, block=True, timeout=None, retries=None):
243 """Reboot the device. 276 """Reboot the device.
244 277
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 except device_errors.AdbShellCommandFailedError as e: 420 except device_errors.AdbShellCommandFailedError as e:
388 if check_return: 421 if check_return:
389 raise 422 raise
390 else: 423 else:
391 output = e.output 424 output = e.output
392 425
393 output = output.splitlines() 426 output = output.splitlines()
394 if single_line: 427 if single_line:
395 if len(output) != 1: 428 if len(output) != 1:
396 msg = 'exactly one line of output expected, but got: %s' 429 msg = 'exactly one line of output expected, but got: %s'
397 raise device_errors.CommandFailedError(msg % output) 430 raise device_errors.CommandFailedError(msg % output, str(self))
398 return output[0] 431 return output[0]
399 else: 432 else:
400 return output 433 return output
401 434
402 @decorators.WithTimeoutAndRetriesFromInstance() 435 @decorators.WithTimeoutAndRetriesFromInstance()
403 def KillAll(self, process_name, signum=9, as_root=False, blocking=False, 436 def KillAll(self, process_name, signum=9, as_root=False, blocking=False,
404 timeout=None, retries=None): 437 timeout=None, retries=None):
405 """Kill all processes with the given name on the device. 438 """Kill all processes with the given name on the device.
406 439
407 Args: 440 Args:
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 920
888 Returns: 921 Returns:
889 True if the device-side property changed and a restart is required as a 922 True if the device-side property changed and a restart is required as a
890 result, False otherwise. 923 result, False otherwise.
891 924
892 Raises: 925 Raises:
893 CommandTimeoutError on timeout. 926 CommandTimeoutError on timeout.
894 """ 927 """
895 return self.old_interface.SetJavaAssertsEnabled(enabled) 928 return self.old_interface.SetJavaAssertsEnabled(enabled)
896 929
897 @decorators.WithTimeoutAndRetriesFromInstance() 930 def GetProp(self, property_name, cache=False, timeout=None, retries=None):
jbudorick 2014/10/24 17:30:51 We should make sure we test the timeout/retries pa
perezju 2014/10/27 11:07:07 Acknowledged.
898 def GetProp(self, property_name, timeout=None, retries=None):
899 """Gets a property from the device. 931 """Gets a property from the device.
900 932
901 Args: 933 Args:
902 property_name: A string containing the name of the property to get from 934 property_name: A string containing the name of the property to get from
903 the device. 935 the device.
936 cache: A boolean indicating whether to cache the value of this property.
904 timeout: timeout in seconds 937 timeout: timeout in seconds
905 retries: number of retries 938 retries: number of retries
906 939
907 Returns: 940 Returns:
908 The value of the device's |property_name| property. 941 The value of the device's |property_name| property.
909 942
910 Raises: 943 Raises:
911 CommandTimeoutError on timeout. 944 CommandTimeoutError on timeout.
912 """ 945 """
913 return self._GetPropImpl(property_name) 946 cache_name = '_prop:' + property_name
914 947 if cache and cache_name in self._cache:
jbudorick 2014/10/24 17:30:51 I think that, for now, we should limit property ca
perezju 2014/10/27 11:07:07 An idea I had was to provide the class with some p
915 def _GetPropImpl(self, property_name): 948 return self._cache[cache_name]
916 return self.old_interface.system_properties[property_name] 949 else:
950 # timeout and retries are handled down at run shell, because we don't
951 # want to apply them in the other branch when reading from the cache
952 value = self.RunShellCommand(['getprop', property_name], single_line=True,
953 timeout=timeout, retries=retries)
954 if cache or cache_name in self._cache:
955 self._cache[cache_name] = value
956 return value
917 957
918 @decorators.WithTimeoutAndRetriesFromInstance() 958 @decorators.WithTimeoutAndRetriesFromInstance()
919 def SetProp(self, property_name, value, timeout=None, retries=None): 959 def SetProp(self, property_name, value, check=False, timeout=None,
jbudorick 2014/10/24 17:30:51 What's the motivation behind check?
perezju 2014/10/27 11:07:07 The TODO here https://cs.corp.google.com/#clankium
jbudorick 2014/10/27 19:15:36 Use the public cs for upstream reviews: https://co
960 retries=None):
920 """Sets a property on the device. 961 """Sets a property on the device.
921 962
922 Args: 963 Args:
923 property_name: A string containing the name of the property to set on 964 property_name: A string containing the name of the property to set on
924 the device. 965 the device.
925 value: A string containing the value to set to the property on the 966 value: A string containing the value to set to the property on the
926 device. 967 device.
927 timeout: timeout in seconds 968 timeout: timeout in seconds
928 retries: number of retries 969 retries: number of retries
929 970
930 Raises: 971 Raises:
931 CommandTimeoutError on timeout. 972 CommandTimeoutError on timeout.
932 """ 973 """
933 self.old_interface.system_properties[property_name] = value 974 self.RunShellCommand(['setprop', property_name, value])
jbudorick 2014/10/24 17:30:51 If we expand caching beyond read-only properties,
perezju 2014/10/27 11:07:06 This happens "auto-magically" when check=True. May
975 if check and value != self.GetProp(property_name):
976 raise device_errors.CommandFailedError(
977 'Unable to set property %r on the device to %r'
978 % (property_name, value), str(self))
934 979
935 @decorators.WithTimeoutAndRetriesFromInstance() 980 @decorators.WithTimeoutAndRetriesFromInstance()
936 def GetABI(self, timeout=None, retries=None): 981 def GetABI(self, timeout=None, retries=None):
937 """Gets the device main ABI. 982 """Gets the device main ABI.
938 983
939 Args: 984 Args:
940 timeout: timeout in seconds 985 timeout: timeout in seconds
941 retries: number of retries 986 retries: number of retries
942 987
943 Returns: 988 Returns:
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 Returns: 1107 Returns:
1063 A Parallelizer operating over |devices|. 1108 A Parallelizer operating over |devices|.
1064 """ 1109 """
1065 if not devices or len(devices) == 0: 1110 if not devices or len(devices) == 0:
1066 devices = pylib.android_commands.GetAttachedDevices() 1111 devices = pylib.android_commands.GetAttachedDevices()
1067 parallelizer_type = (parallelizer.Parallelizer if async 1112 parallelizer_type = (parallelizer.Parallelizer if async
1068 else parallelizer.SyncParallelizer) 1113 else parallelizer.SyncParallelizer)
1069 return parallelizer_type([ 1114 return parallelizer_type([
1070 d if isinstance(d, DeviceUtils) else DeviceUtils(d) 1115 d if isinstance(d, DeviceUtils) else DeviceUtils(d)
1071 for d in devices]) 1116 for d in devices])
OLDNEW
« no previous file with comments | « no previous file | build/android/pylib/utils/reraiser_thread.py » ('j') | build/android/pylib/utils/reraiser_thread.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698