| 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 1624cccb7596f03d990373e894c233b8576674c6..f461b2802529176da22f9017485e3d9e2a5746dc 100644
|
| --- a/build/android/pylib/device/device_utils.py
|
| +++ b/build/android/pylib/device/device_utils.py
|
| @@ -34,6 +34,11 @@ from pylib.utils import timeout_retry
|
| _DEFAULT_TIMEOUT = 30
|
| _DEFAULT_RETRIES = 3
|
|
|
| +# A sentinel object for default values
|
| +# TODO(jbudorick,perezju): revisit how default values are handled by
|
| +# the timeout_retry decorators.
|
| +DEFAULT = object()
|
| +
|
|
|
| @decorators.WithExplicitTimeoutAndRetries(
|
| _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
|
| @@ -146,7 +151,7 @@ class DeviceUtils(object):
|
| except device_errors.AdbCommandFailedError:
|
| return False
|
|
|
| - def NeedsSU(self, timeout=None, retries=None):
|
| + def NeedsSU(self, timeout=DEFAULT, retries=DEFAULT):
|
| """Checks whether 'su' is needed to access protected resources.
|
|
|
| Args:
|
| @@ -165,8 +170,10 @@ class DeviceUtils(object):
|
| """
|
| if 'needs_su' not in self._cache:
|
| try:
|
| - self.RunShellCommand('su -c ls /root && ! ls /root', check_return=True,
|
| - timeout=timeout, retries=retries)
|
| + self.RunShellCommand(
|
| + 'su -c ls /root && ! ls /root', check_return=True,
|
| + timeout=self._default_timeout if timeout is DEFAULT else timeout,
|
| + retries=self._default_retries if retries is DEFAULT else retries)
|
| self._cache['needs_su'] = True
|
| except device_errors.AdbCommandFailedError:
|
| self._cache['needs_su'] = False
|
| @@ -249,8 +256,14 @@ class DeviceUtils(object):
|
| Returns:
|
| Path to the apk on the device if it exists, None otherwise.
|
| """
|
| + # 'pm path' is liable to incorrectly exit with a nonzero number starting
|
| + # in Lollipop.
|
| + # TODO(jbudorick): Check if this is fixed as new Android versions are
|
| + # released to put an upper bound on this.
|
| + should_check_return = (self.build_version_sdk <
|
| + constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP)
|
| output = self.RunShellCommand(['pm', 'path', package], single_line=True,
|
| - check_return=True)
|
| + check_return=should_check_return)
|
| if not output:
|
| return None
|
| if not output.startswith('package:'):
|
| @@ -994,12 +1007,77 @@ class DeviceUtils(object):
|
| """
|
| return self.old_interface.SetJavaAssertsEnabled(enabled)
|
|
|
| +
|
| + @property
|
| + def build_description(self):
|
| + """Returns the build description of the system.
|
| +
|
| + For example:
|
| + nakasi-user 4.4.4 KTU84P 1227136 release-keys
|
| + """
|
| + return self.GetProp('ro.build.description', cache=True)
|
| +
|
| + @property
|
| + def build_fingerprint(self):
|
| + """Returns the build fingerprint of the system.
|
| +
|
| + For example:
|
| + google/nakasi/grouper:4.4.4/KTU84P/1227136:user/release-keys
|
| + """
|
| + return self.GetProp('ro.build.fingerprint', cache=True)
|
| +
|
| + @property
|
| + def build_id(self):
|
| + """Returns the build ID of the system (e.g. 'KTU84P')."""
|
| + return self.GetProp('ro.build.id', cache=True)
|
| +
|
| + @property
|
| + def build_product(self):
|
| + """Returns the build product of the system (e.g. 'grouper')."""
|
| + return self.GetProp('ro.build.product', cache=True)
|
| +
|
| @property
|
| def build_type(self):
|
| - """Returns the build type of the system (e.g. userdebug)."""
|
| + """Returns the build type of the system (e.g. 'user')."""
|
| return self.GetProp('ro.build.type', cache=True)
|
|
|
| - def GetProp(self, property_name, cache=False, timeout=None, retries=None):
|
| + @property
|
| + def build_version_sdk(self):
|
| + """Returns the build version sdk of the system as a number (e.g. 19).
|
| +
|
| + For version code numbers see:
|
| + http://developer.android.com/reference/android/os/Build.VERSION_CODES.html
|
| +
|
| + For named constants see:
|
| + pylib.constants.ANDROID_SDK_VERSION_CODES
|
| +
|
| + Raises:
|
| + CommandFailedError if the build version sdk is not a number.
|
| + """
|
| + value = self.GetProp('ro.build.version.sdk', cache=True)
|
| + try:
|
| + return int(value)
|
| + except ValueError:
|
| + raise device_errors.CommandFailedError(
|
| + 'Invalid build version sdk: %r' % value)
|
| +
|
| + @property
|
| + def product_cpu_abi(self):
|
| + """Returns the product cpu abi of the device (e.g. 'armeabi-v7a')."""
|
| + return self.GetProp('ro.product.cpu.abi', cache=True)
|
| +
|
| + @property
|
| + def product_model(self):
|
| + """Returns the name of the product model (e.g. 'Nexus 7')."""
|
| + return self.GetProp('ro.product.model', cache=True)
|
| +
|
| + @property
|
| + def product_name(self):
|
| + """Returns the product name of the device (e.g. 'nakasi')."""
|
| + return self.GetProp('ro.product.name', cache=True)
|
| +
|
| + def GetProp(self, property_name, cache=False, timeout=DEFAULT,
|
| + retries=DEFAULT):
|
| """Gets a property from the device.
|
|
|
| Args:
|
| @@ -1024,9 +1102,10 @@ class DeviceUtils(object):
|
| 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, check_return=True,
|
| - timeout=timeout, retries=retries)
|
| + value = self.RunShellCommand(
|
| + ['getprop', property_name], single_line=True, check_return=True,
|
| + timeout=self._default_timeout if timeout is DEFAULT else timeout,
|
| + retries=self._default_retries if retries is DEFAULT else retries)
|
| if cache or cache_key in self._cache:
|
| self._cache[cache_key] = value
|
| return value
|
|
|