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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: build/android/pylib/device/device_utils.py
diff --git a/build/android/pylib/device/device_utils.py b/build/android/pylib/device/device_utils.py
index b2fa1ff3953a702f6cd3676f495db89144dcf0d7..14ee6623da49e1d770051a8ea23c6420c0b03548 100644
--- a/build/android/pylib/device/device_utils.py
+++ b/build/android/pylib/device/device_utils.py
@@ -14,6 +14,7 @@ import os
import re
import sys
import tempfile
+import threading
import time
import zipfile
@@ -220,18 +221,50 @@ class DeviceUtils(object):
CommandTimeoutError if one of the component waits times out.
DeviceUnreachableError if the device becomes unresponsive.
"""
- self._WaitUntilFullyBootedImpl(wifi=wifi, timeout=timeout)
+ def sd_card_ready():
+ return self.RunShellCommand(['ls', self.GetExternalStoragePath()])
- def _WaitUntilFullyBootedImpl(self, wifi=False, timeout=None):
- if timeout is None:
- timeout = self._default_timeout
- self.old_interface.WaitForSystemBootCompleted(timeout)
- self.old_interface.WaitForDevicePm()
- self.old_interface.WaitForSdCardReady(timeout)
+ def pm_ready():
+ return self.GetApplicationPath('android')
+
+ def boot_completed():
+ return self.GetProp('sys.boot_completed') == '1'
+
+ def wifi_enabled():
+ return 'Wi-Fi is enabled' in self.RunShellCommand(['dumpsys', 'wifi'])
+
+ self.adb.WaitForDevice()
+ self._WaitFor(sd_card_ready)
+ self._WaitFor(pm_ready)
+ self._WaitFor(boot_completed)
if wifi:
- while not 'Wi-Fi is enabled' in (
- self.old_interface.RunShellCommand('dumpsys wifi')):
- time.sleep(1)
+ self._WaitFor(wifi_enabled)
+
+ def _WaitFor(self, condition, wait_period=5):
+ start = time.time()
+ while not threading.current_thread().Stopped():
+ try:
+ r = condition()
+ except device_errors.CommandFailedError as e:
+ r = False
jbudorick 2014/10/24 17:30:51 nit: similarly here w.r.t False v None
+ logging.warning('%s at %s', str(e), threading.current_thread().name)
+ elapsed = time.time() - start
+ if r:
+ 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
+ condition.__name__, elapsed, threading.current_thread().name)
+ return r
+ time.sleep(wait_period)
+ logging.warning('%s: condition %r not yet met (%1.2f) at %s', str(self),
+ condition.__name__, elapsed, threading.current_thread().name)
+ 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.
+
+ @decorators.WithTimeoutAndRetriesFromInstance()
+ def GetApplicationPath(self, package, timeout=None, retries=None):
+ output = self.RunShellCommand(['pm', 'path', package], single_line=True)
+ if not output.startswith('package:'):
+ raise device_errors.CommandFailedError('pm path returned: %r' % output, str(self))
+ return output[len('package:'):]
+
REBOOT_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT
REBOOT_DEFAULT_RETRIES = _DEFAULT_RETRIES
@@ -394,7 +427,7 @@ class DeviceUtils(object):
if single_line:
if len(output) != 1:
msg = 'exactly one line of output expected, but got: %s'
- raise device_errors.CommandFailedError(msg % output)
+ raise device_errors.CommandFailedError(msg % output, str(self))
return output[0]
else:
return output
@@ -894,13 +927,13 @@ class DeviceUtils(object):
"""
return self.old_interface.SetJavaAssertsEnabled(enabled)
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetProp(self, property_name, timeout=None, retries=None):
+ 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.
"""Gets a property from the device.
Args:
property_name: A string containing the name of the property to get from
- the device.
+ the device.
+ cache: A boolean indicating whether to cache the value of this property.
timeout: timeout in seconds
retries: number of retries
@@ -910,13 +943,21 @@ class DeviceUtils(object):
Raises:
CommandTimeoutError on timeout.
"""
- return self._GetPropImpl(property_name)
-
- def _GetPropImpl(self, property_name):
- return self.old_interface.system_properties[property_name]
+ cache_name = '_prop:' + property_name
+ 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
+ return self._cache[cache_name]
+ else:
+ # timeout and retries are handled down at run shell, because we don't
+ # want to apply them in the other branch when reading from the cache
+ value = self.RunShellCommand(['getprop', property_name], single_line=True,
+ timeout=timeout, retries=retries)
+ if cache or cache_name in self._cache:
+ self._cache[cache_name] = value
+ return value
@decorators.WithTimeoutAndRetriesFromInstance()
- def SetProp(self, property_name, value, timeout=None, retries=None):
+ 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
+ retries=None):
"""Sets a property on the device.
Args:
@@ -930,7 +971,11 @@ class DeviceUtils(object):
Raises:
CommandTimeoutError on timeout.
"""
- self.old_interface.system_properties[property_name] = value
+ 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
+ if check and value != self.GetProp(property_name):
+ raise device_errors.CommandFailedError(
+ 'Unable to set property %r on the device to %r'
+ % (property_name, value), str(self))
@decorators.WithTimeoutAndRetriesFromInstance()
def GetABI(self, timeout=None, retries=None):
« 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