mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Backed out 6 changesets (bug 1214812) for kk emulator test bustage
Backed out changeset b36710809f0c (bug 1214812) Backed out changeset a3b5c66f34e4 (bug 1214812) Backed out changeset df6d3dc3fca9 (bug 1214812) Backed out changeset 9f94be2a3c1d (bug 1214812) Backed out changeset 1eaf9f30b00d (bug 1214812) Backed out changeset 902b985b3273 (bug 1214812) --HG-- extra : commitid : LNisZGOtv0q
This commit is contained in:
parent
f9e576a222
commit
f619310a07
@ -2,6 +2,7 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from abc import ABCMeta, abstractmethod
|
||||
import os
|
||||
import posixpath
|
||||
import re
|
||||
@ -10,8 +11,6 @@ import tempfile
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
|
||||
class ADBProcess(object):
|
||||
"""ADBProcess encapsulates the data related to executing the adb process."""
|
||||
@ -536,58 +535,50 @@ class ADBDevice(ADBCommand):
|
||||
self._have_su = False
|
||||
self._have_android_su = False
|
||||
|
||||
uid = 'uid=0'
|
||||
cmd_id = 'LD_LIBRARY_PATH=/vendor/lib:/system/lib id'
|
||||
# Is shell already running as root?
|
||||
# Catch exceptions due to the potential for segfaults
|
||||
# calling su when using an improperly rooted device.
|
||||
try:
|
||||
if self.shell_output("id").find(uid) != -1:
|
||||
self._have_root_shell = True
|
||||
except ADBError:
|
||||
self._logger.debug("Check for root shell failed")
|
||||
|
||||
# Note this check to see if adbd is running is performed on
|
||||
# the device in the state it exists in when the ADBDevice is
|
||||
# initialized. It may be the case that it has been manipulated
|
||||
# since its last boot and that its current state does not
|
||||
# match the state the device will have immediately after a
|
||||
# reboot. For example, if adb root was called manually prior
|
||||
# to ADBDevice being initialized, then self._have_root_shell
|
||||
# will not reflect the state of the device after it has been
|
||||
# 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.shell_output("su -c '%s'" % cmd_id).find(uid) != -1:
|
||||
self._have_su = True
|
||||
self._logger.info("su -c supported")
|
||||
except ADBError:
|
||||
self._logger.debug("Check for su -c failed")
|
||||
self._logger.debug("Check for su failed")
|
||||
|
||||
# Do we have Android's su?
|
||||
try:
|
||||
if self.shell_output("su 0 id", timeout=timeout).find(uid) != -1:
|
||||
if self.shell_output("su 0 id").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._logger.debug("Check for Android su failed")
|
||||
|
||||
self._mkdir_p = None
|
||||
# Force the use of /system/bin/ls or /system/xbin/ls in case
|
||||
# there is /sbin/ls which embeds ansi escape codes to colorize
|
||||
# the output. Detect if we are using busybox ls. We want each
|
||||
# entry on a single line and we don't want . or ..
|
||||
if self.shell_bool("/system/bin/ls /", timeout=timeout):
|
||||
if self.shell_bool("/system/bin/ls /"):
|
||||
self._ls = "/system/bin/ls"
|
||||
elif self.shell_bool("/system/xbin/ls /", timeout=timeout):
|
||||
elif self.shell_bool("/system/xbin/ls /"):
|
||||
self._ls = "/system/xbin/ls"
|
||||
else:
|
||||
raise ADBError("ADBDevice.__init__: ls not found")
|
||||
try:
|
||||
self.shell_output("%s -1A /" % self._ls, timeout=timeout)
|
||||
self.shell_output("%s -1A /" % self._ls)
|
||||
self._ls += " -1A"
|
||||
except ADBError:
|
||||
self._ls += " -a"
|
||||
|
||||
# Do we have cp?
|
||||
self._have_cp = self.shell_bool("type cp", timeout=timeout)
|
||||
self._have_cp = self.shell_bool("type cp")
|
||||
|
||||
self._logger.debug("ADBDevice: %s" % self.__dict__)
|
||||
|
||||
@ -624,28 +615,6 @@ class ADBDevice(ADBCommand):
|
||||
|
||||
raise ValueError("Unable to get device serial")
|
||||
|
||||
def _check_adb_root(self, timeout=None):
|
||||
self._have_root_shell = False
|
||||
uid = 'uid=0'
|
||||
# Is shell already running as root?
|
||||
try:
|
||||
if self.shell_output("id", timeout=timeout).find(uid) != -1:
|
||||
self._have_root_shell = True
|
||||
self._logger.info("adbd running as root")
|
||||
except ADBError:
|
||||
self._logger.debug("Check for root shell failed")
|
||||
|
||||
# Do we need to run adb root to get a root shell?
|
||||
try:
|
||||
if (not self._have_root_shell and
|
||||
self.command_output(
|
||||
["root"],
|
||||
timeout=timeout).find("cannot run as root") == -1):
|
||||
self._have_root_shell = True
|
||||
self._logger.info("adbd restarted as root")
|
||||
except ADBError:
|
||||
self._logger.debug("Check for root adbd failed")
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _escape_command_line(cmd):
|
||||
@ -984,15 +953,15 @@ class ADBDevice(ADBCommand):
|
||||
It is the caller's responsibilty to clean up by closing
|
||||
the stdout and stderr temporary files.
|
||||
"""
|
||||
if root and not self._have_root_shell:
|
||||
# If root was requested and we do not already have a root
|
||||
# shell, then use the appropriate version of su to invoke
|
||||
# the shell cmd. Prefer Android's su version since it may
|
||||
# falsely report support for su -c.
|
||||
if self._have_android_su:
|
||||
cmd = "su 0 %s" % cmd
|
||||
if root:
|
||||
ld_library_path='LD_LIBRARY_PATH=/vendor/lib:/system/lib'
|
||||
cmd = '%s %s' % (ld_library_path, cmd)
|
||||
if self._have_root_shell:
|
||||
pass
|
||||
elif self._have_su:
|
||||
cmd = "su -c \"%s\"" % cmd
|
||||
elif self._have_android_su:
|
||||
cmd = "su 0 \"%s\"" % cmd
|
||||
else:
|
||||
raise ADBRootError('Can not run command %s as root!' % cmd)
|
||||
|
||||
@ -1891,7 +1860,6 @@ class ADBDevice(ADBCommand):
|
||||
# 'wait-for-device' arguments which is an error in newer
|
||||
# versions of adb.
|
||||
self.command_output([], timeout=timeout)
|
||||
self._check_adb_root(timeout=timeout)
|
||||
return self.is_device_ready(timeout=timeout)
|
||||
|
||||
@abstractmethod
|
||||
|
@ -6,8 +6,6 @@ import os
|
||||
import re
|
||||
import time
|
||||
|
||||
from abc import ABCMeta
|
||||
|
||||
import version_codes
|
||||
|
||||
from adb import ADBDevice, ADBError
|
||||
@ -26,100 +24,6 @@ class ADBAndroid(ADBDevice):
|
||||
if adbdevice.process_exist("org.mozilla.fennec"):
|
||||
print "Fennec is running"
|
||||
"""
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
def __init__(self,
|
||||
device=None,
|
||||
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):
|
||||
"""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
|
||||
with the dictionaries in the list returned by
|
||||
ADBHost.devices(). If the value of device_serial is a
|
||||
valid serial not containing a ":" it will be used to
|
||||
identify the device, otherwise the value of the usb key,
|
||||
prefixed with "usb:" is used.
|
||||
If None is passed and there is exactly one device attached
|
||||
to the host, that device is used. If there is more than one
|
||||
device attached, ValueError is raised. If no device is
|
||||
attached the constructor will block until a device is
|
||||
attached or the timeout is reached.
|
||||
:type device: dict, str or None
|
||||
:param adb_host: host of the adb server to connect to.
|
||||
:type adb_host: str or None
|
||||
:param adb_port: port of the adb server to connect to.
|
||||
:type adb_port: integer or None
|
||||
:param str logger_name: logging logger name. Defaults to 'adb'.
|
||||
: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.
|
||||
|
||||
: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)
|
||||
# https://source.android.com/devices/tech/security/selinux/index.html
|
||||
# setenforce
|
||||
# usage: setenforce [ Enforcing | Permissive | 1 | 0 ]
|
||||
# getenforce returns either Enforcing or Permissive
|
||||
|
||||
try:
|
||||
self.selinux = True
|
||||
if self.shell_output('getenforce', timeout=timeout) != 'Permissive':
|
||||
self._logger.info('Setting SELinux Permissive Mode')
|
||||
self.shell_output("setenforce Permissive", timeout=timeout, root=True)
|
||||
except ADBError:
|
||||
self.selinux = False
|
||||
|
||||
def reboot(self, timeout=None):
|
||||
"""Reboots the device.
|
||||
|
||||
:param timeout: optional integer specifying the maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADB constructor is used.
|
||||
:raises: * ADBTimeoutError
|
||||
* ADBError
|
||||
|
||||
reboot() reboots the device, issues an adb wait-for-device in order to
|
||||
wait for the device to complete rebooting, then calls is_device_ready()
|
||||
to determine if the device has completed booting.
|
||||
|
||||
If the device supports running adbd as root, adbd will be
|
||||
restarted running as root. Then, if the device supports
|
||||
SELinux, setenforce Permissive will be called to change
|
||||
SELinux to permissive. This must be done after adbd is
|
||||
restarted in order for the SELinux Permissive setting to
|
||||
persist.
|
||||
|
||||
"""
|
||||
ready = ADBDevice.reboot(self, timeout=timeout)
|
||||
self._check_adb_root(timeout=timeout)
|
||||
return ready
|
||||
|
||||
# Informational methods
|
||||
|
||||
@ -195,15 +99,10 @@ class ADBAndroid(ADBDevice):
|
||||
failure = "Device state: %s" % state
|
||||
success = False
|
||||
else:
|
||||
if (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, root=True):
|
||||
self.rmdir(ready_path, timeout=timeout, root=True)
|
||||
self.mkdir(ready_path, timeout=timeout, root=True)
|
||||
self.rmdir(ready_path, 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.
|
||||
for pm_list_cmd in pm_list_commands:
|
||||
|
@ -23,10 +23,8 @@ class DeviceManagerADB(DeviceManager):
|
||||
port.
|
||||
"""
|
||||
|
||||
_haveRootShell = None
|
||||
_haveSu = None
|
||||
_suModifier = None
|
||||
_lsModifier = None
|
||||
_haveRootShell = False
|
||||
_haveSu = False
|
||||
_useZip = False
|
||||
_logcatNeedsRoot = False
|
||||
_pollingInterval = 0.01
|
||||
@ -72,8 +70,6 @@ class DeviceManagerADB(DeviceManager):
|
||||
if autoconnect:
|
||||
self.connect()
|
||||
|
||||
self._detectLsModifier()
|
||||
|
||||
def connect(self):
|
||||
if not self.connected:
|
||||
# try to connect to the device over tcp/ip if we have a hostname
|
||||
@ -105,22 +101,17 @@ class DeviceManagerADB(DeviceManager):
|
||||
# always. :(
|
||||
|
||||
# If requested to run as root, check that we can actually do that
|
||||
if root:
|
||||
if self._haveRootShell is None and self._haveSu is None:
|
||||
self._checkForRoot()
|
||||
if not self._haveRootShell and not self._haveSu:
|
||||
raise DMError(
|
||||
"Shell command '%s' requested to run as root but root "
|
||||
"is not available on this device. Root your device or "
|
||||
"refactor the test/harness to not require root." %
|
||||
self._escapedCommandLine(cmd))
|
||||
if root and not self._haveRootShell and not self._haveSu:
|
||||
raise DMError("Shell command '%s' requested to run as root but root "
|
||||
"is not available on this device. Root your device or "
|
||||
"refactor the test/harness to not require root." %
|
||||
self._escapedCommandLine(cmd))
|
||||
|
||||
# Getting the return code is more complex than you'd think because adb
|
||||
# doesn't actually return the return code from a process, so we have to
|
||||
# capture the output to get it
|
||||
if root and self._haveSu:
|
||||
cmdline = "su %s \"%s\"" % (self._suModifier,
|
||||
self._escapedCommandLine(cmd))
|
||||
if root and not self._haveRootShell:
|
||||
cmdline = "su -c \"%s\"" % self._escapedCommandLine(cmd)
|
||||
else:
|
||||
cmdline = self._escapedCommandLine(cmd)
|
||||
cmdline += "; echo $?"
|
||||
@ -268,8 +259,7 @@ class DeviceManagerADB(DeviceManager):
|
||||
mozfile.remove(tmpDir)
|
||||
|
||||
def dirExists(self, remotePath):
|
||||
data = self._runCmd(["shell", "ls", self._lsModifier, remotePath + '/'],
|
||||
timeout=self.short_timeout).output
|
||||
data = self._runCmd(["shell", "ls", "-a", remotePath + '/'], timeout=self.short_timeout).output
|
||||
|
||||
if len(data) == 1:
|
||||
res = data[0]
|
||||
@ -278,8 +268,7 @@ class DeviceManagerADB(DeviceManager):
|
||||
return True
|
||||
|
||||
def fileExists(self, filepath):
|
||||
data = self._runCmd(["shell", "ls", self._lsModifier, filepath],
|
||||
timeout=self.short_timeout).output
|
||||
data = self._runCmd(["shell", "ls", "-a", filepath], timeout=self.short_timeout).output
|
||||
if len(data) == 1:
|
||||
foundpath = data[0].decode('utf-8').rstrip()
|
||||
if foundpath == filepath:
|
||||
@ -303,8 +292,7 @@ class DeviceManagerADB(DeviceManager):
|
||||
self._checkCmd(["shell", "dd", "if=%s" % source, "of=%s" % destination])
|
||||
|
||||
def listFiles(self, rootdir):
|
||||
data = self._runCmd(["shell", "ls", self._lsModifier, rootdir],
|
||||
timeout=self.short_timeout).output
|
||||
data = self._runCmd(["shell", "ls", "-a", rootdir], timeout=self.short_timeout).output
|
||||
data[:] = [item.rstrip('\r\n') for item in data]
|
||||
if (len(data) == 1):
|
||||
if (data[0] == rootdir):
|
||||
@ -317,8 +305,6 @@ class DeviceManagerADB(DeviceManager):
|
||||
return []
|
||||
if (data[0].find("opendir failed") != -1):
|
||||
return []
|
||||
if (data[0].find("Device or resource busy") != -1):
|
||||
return []
|
||||
return data
|
||||
|
||||
def getProcessList(self):
|
||||
@ -676,13 +662,6 @@ class DeviceManagerADB(DeviceManager):
|
||||
raise DMError("unable to connect to device")
|
||||
|
||||
def _checkForRoot(self):
|
||||
self._haveRootShell = False
|
||||
self._haveSu = False
|
||||
# If requested to attempt to run adbd as root, do so before
|
||||
# checking whether adbs is running as root.
|
||||
if self._runAdbAsRoot:
|
||||
self._adb_root()
|
||||
|
||||
# Check whether we _are_ root by default (some development boards work
|
||||
# this way, this is also the result of some relatively rare rooting
|
||||
# techniques)
|
||||
@ -694,30 +673,22 @@ class DeviceManagerADB(DeviceManager):
|
||||
|
||||
# if root shell is not available, check if 'su' can be used to gain
|
||||
# root
|
||||
def su_id(su_modifier, timeout):
|
||||
proc = self._runCmd(["shell", "su", su_modifier, "id"],
|
||||
timeout=timeout)
|
||||
proc = self._runCmd(["shell", "su", "-c", "id"], timeout=self.short_timeout)
|
||||
|
||||
# wait for response for maximum of 15 seconds, in case su
|
||||
# prompts for a password or triggers the Android SuperUser
|
||||
# prompt
|
||||
start_time = time.time()
|
||||
retcode = None
|
||||
while (time.time() - start_time) <= 15 and retcode is None:
|
||||
retcode = proc.poll()
|
||||
if retcode is None: # still not terminated, kill
|
||||
proc.kill()
|
||||
# wait for response for maximum of 15 seconds, in case su prompts for a
|
||||
# password or triggers the Android SuperUser prompt
|
||||
start_time = time.time()
|
||||
retcode = None
|
||||
while (time.time() - start_time) <= 15 and retcode is None:
|
||||
retcode = proc.poll()
|
||||
if retcode is None: # still not terminated, kill
|
||||
proc.kill()
|
||||
|
||||
if proc.output and 'uid=0(root)' in proc.output[0]:
|
||||
return True
|
||||
return False
|
||||
|
||||
if su_id('0', self.short_timeout):
|
||||
if proc.output and 'uid=0(root)' in proc.output[0]:
|
||||
self._haveSu = True
|
||||
self._suModifier = '0'
|
||||
elif su_id('-c', self.short_timeout):
|
||||
self._haveSu = True
|
||||
self._suModifier = '-c'
|
||||
|
||||
if self._runAdbAsRoot:
|
||||
self._adb_root()
|
||||
|
||||
def _isUnzipAvailable(self):
|
||||
data = self._runCmd(["shell", "unzip"]).output
|
||||
@ -758,18 +729,3 @@ class DeviceManagerADB(DeviceManager):
|
||||
self._checkCmd(["wait-for-device"])
|
||||
if self.processInfo("adbd")[2] != "root":
|
||||
raise DMError("We tried rebooting adbd as root, however, it failed.")
|
||||
|
||||
def _detectLsModifier(self):
|
||||
if self._lsModifier is None:
|
||||
# Check if busybox -1A is required in order to get one
|
||||
# file per line.
|
||||
output = self._runCmd(["shell", "ls", "-1A" "/"],
|
||||
timeout=self.short_timeout).output
|
||||
output = ' '.join(output)
|
||||
if "Unknown option '-1'. Aborting." in output:
|
||||
self._lsModifier = "-a"
|
||||
elif "-1A/: No such file or directory" in output:
|
||||
self._lsModifier = "-a"
|
||||
else:
|
||||
self._lsModifier = "-1A"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user