| 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 2c507204e424c34a0424d710e7f6cb7adfed2b5b..f4bce41f2d660d5d1b843fe9b69d126436ebfc60 100644
|
| --- a/build/android/pylib/device/device_utils.py
|
| +++ b/build/android/pylib/device/device_utils.py
|
| @@ -109,7 +109,11 @@ class DeviceUtils(object):
|
| Raises:
|
| CommandTimeoutError on timeout.
|
| """
|
| - return self.adb.GetState() == 'device'
|
| + try:
|
| + return self.adb.GetState() == 'device'
|
| + except device_errors.BaseError as exc:
|
| + logging.info('Failed to get state: %s', exc)
|
| + return False
|
|
|
| @decorators.WithTimeoutAndRetriesFromInstance()
|
| def HasRoot(self, timeout=None, retries=None):
|
| @@ -126,15 +130,39 @@ class DeviceUtils(object):
|
| CommandTimeoutError on timeout.
|
| DeviceUnreachableError on missing device.
|
| """
|
| - return self._HasRootImpl()
|
| -
|
| - def _HasRootImpl(self):
|
| try:
|
| - self._RunShellCommandImpl('ls /root', check_return=True)
|
| + self.RunShellCommand('ls /root', check_return=True)
|
| return True
|
| except device_errors.AdbShellCommandFailedError:
|
| return False
|
|
|
| + def NeedsSU(self, timeout=None, retries=None):
|
| + """Checks whether 'su' is needed to access protected resources.
|
| +
|
| + Args:
|
| + timeout: timeout in seconds
|
| + retries: number of retries
|
| +
|
| + Returns:
|
| + True if 'su' is available on the device and is needed to to access
|
| + protected resources; False otherwise if either 'su' is not available
|
| + (e.g. because the device has a user build), or not needed (because adbd
|
| + already has root privileges).
|
| +
|
| + Raises:
|
| + CommandTimeoutError on timeout.
|
| + DeviceUnreachableError on missing device.
|
| + """
|
| + if 'needs_su' not in self._cache:
|
| + try:
|
| + self.RunShellCommand('su -c ls /root && ! ls /root', check_return=True,
|
| + timeout=timeout, retries=retries)
|
| + self._cache['needs_su'] = True
|
| + except device_errors.AdbShellCommandFailedError:
|
| + self._cache['needs_su'] = False
|
| + return self._cache['needs_su']
|
| +
|
| +
|
| @decorators.WithTimeoutAndRetriesFromInstance()
|
| def EnableRoot(self, timeout=None, retries=None):
|
| """Restarts adbd with root privileges.
|
| @@ -147,6 +175,8 @@ class DeviceUtils(object):
|
| CommandFailedError if root could not be enabled.
|
| CommandTimeoutError on timeout.
|
| """
|
| + if 'needs_su' in self._cache:
|
| + del self._cache['needs_su']
|
| if not self.old_interface.EnableAdbRoot():
|
| raise device_errors.CommandFailedError(
|
| 'Could not enable root.', device=str(self))
|
| @@ -191,9 +221,9 @@ class DeviceUtils(object):
|
| if 'external_storage' in self._cache:
|
| return self._cache['external_storage']
|
|
|
| - value = self._RunShellCommandImpl('echo $EXTERNAL_STORAGE',
|
| - single_line=True,
|
| - check_return=True)
|
| + value = self.RunShellCommand('echo $EXTERNAL_STORAGE',
|
| + single_line=True,
|
| + check_return=True)
|
| if not value:
|
| raise device_errors.CommandFailedError('$EXTERNAL_STORAGE is not set',
|
| str(self))
|
| @@ -238,8 +268,12 @@ class DeviceUtils(object):
|
| DeviceUnreachableError if the device becomes unresponsive.
|
| """
|
| def sd_card_ready():
|
| - return self.RunShellCommand(['ls', self.GetExternalStoragePath()],
|
| - single_line=True, check_return=True)
|
| + try:
|
| + self.RunShellCommand(['test', '-d', self.GetExternalStoragePath()],
|
| + check_return=True)
|
| + return True
|
| + except device_errors.AdbShellCommandFailedError:
|
| + return False
|
|
|
| def pm_ready():
|
| try:
|
| @@ -389,11 +423,6 @@ class DeviceUtils(object):
|
| CommandTimeoutError on timeout.
|
| DeviceUnreachableError on missing device.
|
| """
|
| - return self._RunShellCommandImpl(cmd, check_return=check_return, cwd=cwd,
|
| - env=env, as_root=as_root, single_line=single_line, timeout=timeout)
|
| -
|
| - def _RunShellCommandImpl(self, cmd, check_return=False, cwd=None, env=None,
|
| - as_root=False, single_line=False, timeout=None):
|
| def env_quote(key, value):
|
| if not DeviceUtils._VALID_SHELL_VARIABLE.match(key):
|
| raise KeyError('Invalid shell variable name %r' % key)
|
| @@ -402,7 +431,7 @@ class DeviceUtils(object):
|
|
|
| if not isinstance(cmd, basestring):
|
| cmd = ' '.join(cmd_helper.SingleQuote(s) for s in cmd)
|
| - if as_root and not self._HasRootImpl():
|
| + if as_root and self.NeedsSU():
|
| cmd = 'su -c %s' % cmd
|
| if env:
|
| env = ' '.join(env_quote(k, v) for k, v in env.iteritems())
|
| @@ -413,9 +442,7 @@ class DeviceUtils(object):
|
| timeout = self._default_timeout
|
|
|
| try:
|
| - # TODO(perezju) still need to make sure that we call a version of
|
| - # adb.Shell without a timeout-and-retries wrapper.
|
| - output = self.adb.Shell(cmd, expect_rc=0, timeout=timeout, retries=0)
|
| + output = self.adb.Shell(cmd, expect_rc=0)
|
| except device_errors.AdbShellCommandFailedError as e:
|
| if check_return:
|
| raise
|
| @@ -461,7 +488,7 @@ class DeviceUtils(object):
|
| 'No process "%s"' % process_name, device=str(self))
|
|
|
| cmd = ['kill', '-%d' % signum] + pids.values()
|
| - self._RunShellCommandImpl(cmd, as_root=as_root, check_return=True)
|
| + self.RunShellCommand(cmd, as_root=as_root, check_return=True)
|
|
|
| if blocking:
|
| wait_period = 0.1
|
| @@ -612,7 +639,7 @@ class DeviceUtils(object):
|
| files = []
|
| for h, d in host_device_tuples:
|
| if os.path.isdir(h):
|
| - self._RunShellCommandImpl(['mkdir', '-p', d], check_return=True)
|
| + self.RunShellCommand(['mkdir', '-p', d], check_return=True)
|
| files += self._GetChangedFilesImpl(h, d)
|
|
|
| if not files:
|
| @@ -644,14 +671,14 @@ class DeviceUtils(object):
|
| self._PushChangedFilesIndividually(files)
|
| else:
|
| self._PushChangedFilesZipped(files)
|
| - self._RunShellCommandImpl(
|
| + self.RunShellCommand(
|
| ['chmod', '-R', '777'] + [d for _, d in host_device_tuples],
|
| as_root=True, check_return=True)
|
|
|
| def _GetChangedFilesImpl(self, host_path, device_path):
|
| real_host_path = os.path.realpath(host_path)
|
| try:
|
| - real_device_path = self._RunShellCommandImpl(
|
| + real_device_path = self.RunShellCommand(
|
| ['realpath', device_path], single_line=True, check_return=True)
|
| except device_errors.CommandFailedError:
|
| real_device_path = None
|
| @@ -744,7 +771,7 @@ class DeviceUtils(object):
|
| zip_on_device = '%s/tmp.zip' % self._GetExternalStoragePathImpl()
|
| try:
|
| self.adb.Push(zip_file.name, zip_on_device)
|
| - self._RunShellCommandImpl(
|
| + self.RunShellCommand(
|
| ['unzip', zip_on_device],
|
| as_root=True,
|
| env={'PATH': '$PATH:%s' % install_commands.BIN_DIR},
|
| @@ -753,7 +780,7 @@ class DeviceUtils(object):
|
| if zip_proc.is_alive():
|
| zip_proc.terminate()
|
| if self.IsOnline():
|
| - self._RunShellCommandImpl(['rm', zip_on_device], check_return=True)
|
| + self.RunShellCommand(['rm', zip_on_device], check_return=True)
|
|
|
| @staticmethod
|
| def _CreateDeviceZip(zip_path, host_device_tuples):
|
| @@ -891,7 +918,7 @@ class DeviceUtils(object):
|
| """
|
| cmd = 'echo %s > %s' % (cmd_helper.SingleQuote(text),
|
| cmd_helper.SingleQuote(device_path))
|
| - self._RunShellCommandImpl(cmd, as_root=as_root, check_return=True)
|
| + self.RunShellCommand(cmd, as_root=as_root, check_return=True)
|
|
|
| @decorators.WithTimeoutAndRetriesFromInstance()
|
| def Ls(self, device_path, timeout=None, retries=None):
|
| @@ -1034,7 +1061,7 @@ class DeviceUtils(object):
|
|
|
| def _GetPidsImpl(self, process_name):
|
| procs_pids = {}
|
| - for line in self._RunShellCommandImpl('ps', check_return=True):
|
| + for line in self.RunShellCommand('ps', check_return=True):
|
| try:
|
| ps_data = line.split()
|
| if process_name in ps_data[-1]:
|
|
|