Bug 1485852 - [mozdevice] adb*.py should use require_root parameter to control root detection, r=jmaher.
authorBob Clary <bclary@bclary.com>
Mon, 27 Aug 2018 06:59:21 -0700
changeset 481781 240acefd371b7b6d1e27c30cc1da6ab4ffb26182
parent 481780 409efae1c7f25ea10da7c55a7d1e0fbba1b43c6f
child 481782 2ed22b84466f2edc8eb565e749889af1d8f1e901
push id232
push userfmarier@mozilla.com
push dateWed, 05 Sep 2018 20:45:54 +0000
reviewersjmaher
bugs1485852
milestone63.0a1
Bug 1485852 - [mozdevice] adb*.py should use require_root parameter to control root detection, r=jmaher.
testing/mozbase/mozdevice/mozdevice/adb.py
testing/mozbase/mozdevice/mozdevice/adb_android.py
--- a/testing/mozbase/mozdevice/mozdevice/adb.py
+++ b/testing/mozbase/mozdevice/mozdevice/adb.py
@@ -355,17 +355,17 @@ class ADBHost(ADBCommand):
         :type timeout: integer or None
         :param bool verbose: provide verbose output
 
         :raises: * ADBError
                  * ADBTimeoutError
         """
         ADBCommand.__init__(self, adb=adb, adb_host=adb_host,
                             adb_port=adb_port, logger_name=logger_name,
-                            timeout=timeout, verbose=verbose)
+                            timeout=timeout, verbose=verbose, require_root=False)
 
     def command(self, cmds, timeout=None):
         """Executes an adb command on the host.
 
         :param list cmds: The command and its arguments to be
             executed.
         :param timeout: The maximum time in
             seconds for any spawned adb process to complete before
@@ -534,17 +534,18 @@ class ADBDevice(ADBCommand):
                  adb='adb',
                  adb_host=None,
                  adb_port=None,
                  test_root='',
                  logger_name='adb',
                  timeout=300,
                  verbose=False,
                  device_ready_retry_wait=20,
-                 device_ready_retry_attempts=3):
+                 device_ready_retry_attempts=3,
+                 require_root=True):
         """Initializes the ADBDevice object.
 
         :param device: When a string is passed, it is interpreted as the
             device serial number. This form is not compatible with
             devices containing a ":" in the serial; in this case
             ValueError will be raised.
             When a dictionary is passed it must have one or both of
             the keys "device_serial" and "usb". This is compatible
@@ -571,24 +572,26 @@ class ADBDevice(ADBCommand):
             specified, the value defaults to 300.
         :type timeout: integer or None
         :param bool verbose: provide verbose output
         :param integer device_ready_retry_wait: number of seconds to wait
             between attempts to check if the device is ready after a
             reboot.
         :param integer device_ready_retry_attempts: number of attempts when
             checking if a device is ready.
+        :param bool require_root: check that we have root permissions on device
 
         :raises: * ADBError
                  * ADBTimeoutError
                  * ValueError
         """
         ADBCommand.__init__(self, adb=adb, adb_host=adb_host,
                             adb_port=adb_port, logger_name=logger_name,
-                            timeout=timeout, verbose=verbose)
+                            timeout=timeout, verbose=verbose,
+                            require_root=require_root)
         self._logger.info('Using adb %s' % self._adb_version)
         self._device_serial = self._get_device_serial(device)
         self._initial_test_root = test_root
         self._test_root = None
         self._device_ready_retry_wait = device_ready_retry_wait
         self._device_ready_retry_attempts = device_ready_retry_attempts
         self._have_root_shell = False
         self._have_su = False
@@ -608,28 +611,30 @@ class ADBDevice(ADBCommand):
         # rebooted again. Therefore this check will need to be
         # performed again after a reboot.
 
         self._check_adb_root(timeout=timeout)
 
         uid = 'uid=0'
         # Do we have a 'Superuser' sh like su?
         try:
-            if self.shell_output("su -c id", timeout=timeout).find(uid) != -1:
+            if (self._require_root and
+                self.shell_output("su -c id", timeout=timeout).find(uid) != -1):
                 self._have_su = True
                 self._logger.info("su -c supported")
         except ADBError:
             self._logger.debug("Check for su -c failed")
 
         # Check if Android's su 0 command works.
         # su 0 id will hang on Pixel 2 8.1.0/OPM2.171019.029.B1/4720900
         # rooted via magisk. If we already have detected su -c support,
         # we can skip this check.
         try:
-            if (not self._have_su and
+            if (self._require_root and
+                not self._have_su and
                 self.shell_output("su 0 id", timeout=timeout).find(uid) != -1):
                 self._have_android_su = True
                 self._logger.info("su 0 supported")
         except ADBError:
             self._logger.debug("Check for su 0 failed")
 
         self._mkdir_p = None
         # Force the use of /system/bin/ls or /system/xbin/ls in case
--- a/testing/mozbase/mozdevice/mozdevice/adb_android.py
+++ b/testing/mozbase/mozdevice/mozdevice/adb_android.py
@@ -36,17 +36,18 @@ class ADBAndroid(ADBDevice):
                  adb='adb',
                  adb_host=None,
                  adb_port=None,
                  test_root='',
                  logger_name='adb',
                  timeout=300,
                  verbose=False,
                  device_ready_retry_wait=20,
-                 device_ready_retry_attempts=3):
+                 device_ready_retry_attempts=3,
+                 require_root=True):
         """Initializes the ADBAndroid object.
 
         :param device: When a string is passed, it is interpreted as the
             device serial number. This form is not compatible with
             devices containing a ":" in the serial; in this case
             ValueError will be raised.
             When a dictionary is passed it must have one or both of
             the keys "device_serial" and "usb". This is compatible
@@ -73,41 +74,45 @@ class ADBAndroid(ADBDevice):
             specified, the value defaults to 300.
         :type timeout: integer or None
         :param bool verbose: provide verbose output
         :param integer device_ready_retry_wait: number of seconds to wait
             between attempts to check if the device is ready after a
             reboot.
         :param integer device_ready_retry_attempts: number of attempts when
             checking if a device is ready.
+        :param bool require_root: check that we have root permissions on device
 
         :raises: * ADBError
                  * ADBTimeoutError
                  * ValueError
         """
         ADBDevice.__init__(self, device=device, adb=adb,
                            adb_host=adb_host, adb_port=adb_port,
                            test_root=test_root,
                            logger_name=logger_name, timeout=timeout,
                            verbose=verbose,
                            device_ready_retry_wait=device_ready_retry_wait,
-                           device_ready_retry_attempts=device_ready_retry_attempts)
+                           device_ready_retry_attempts=device_ready_retry_attempts,
+                           require_root=require_root)
         # https://source.android.com/devices/tech/security/selinux/index.html
         # setenforce
         # usage:  setenforce [ Enforcing | Permissive | 1 | 0 ]
         # getenforce returns either Enforcing or Permissive
 
+        self.selinux = False
         try:
-            self.selinux = True
-            if self.shell_output('getenforce', timeout=timeout) != 'Permissive':
+            enforce = self.shell_output('getenforce', timeout=timeout)
+            self.selinux = (enforce == 'enforcing' or enforce == '1')
+            if self._require_root and enforce:
                 self._logger.info('Setting SELinux Permissive Mode')
                 self.shell_output("setenforce Permissive", timeout=timeout, root=True)
+                self.selinux = True
         except (ADBError, ADBRootError) as e:
             self._logger.warning('Unable to set SELinux Permissive due to %s.' % e)
-            self.selinux = False
 
         self.version = int(self.shell_output("getprop ro.build.version.sdk",
                                              timeout=timeout))
         # Beginning in Android 8.1 /data/anr/traces.txt no longer contains
         # a single file traces.txt but instead will contain individual files
         # for each stack.
         # See https://github.com/aosp-mirror/platform_build/commit/
         # fbba7fe06312241c7eb8c592ec2ac630e4316d55
@@ -255,18 +260,19 @@ class ADBAndroid(ADBDevice):
             failure = 'Unknown failure'
             success = True
             try:
                 state = self.get_state(timeout=timeout)
                 if state != 'device':
                     failure = "Device state: %s" % state
                     success = False
                 else:
-                    if (self.selinux and self.shell_output('getenforce',
-                                                           timeout=timeout) != 'Permissive'):
+                    if (self._require_root and
+                        self.selinux and
+                        self.shell_output('getenforce', timeout=timeout) != 'Permissive'):
                         self._logger.info('Setting SELinux Permissive Mode')
                         self.shell_output("setenforce Permissive", timeout=timeout, root=True)
                     if self.is_dir(ready_path, timeout=timeout):
                         self.rmdir(ready_path, timeout=timeout)
                     self.mkdir(ready_path, timeout=timeout)
                     self.rmdir(ready_path, timeout=timeout)
                     # Invoke the pm list commands to see if it is up and
                     # running.