Bug 1440714 - Convert Android mach commands to adb.py; r=bc

This commit is contained in:
Geoff Brown 2018-04-05 12:50:29 -06:00
parent 88e7b137f4
commit 146ff5998a
5 changed files with 76 additions and 71 deletions

View File

@ -137,7 +137,7 @@ class ReftestRunner(MozbuildObject):
args.printDeviceInfo = False
from mozrunner.devices.android_device import grant_runtime_permissions, get_adb_path
grant_runtime_permissions(self, args.app)
grant_runtime_permissions(self, args.app, device_serial=args.deviceSerial)
if not args.adb_path:
args.adb_path = get_adb_path(self)
@ -231,6 +231,7 @@ class MachCommands(MachCommandBase):
reftest = self._spawn(ReftestRunner)
if conditions.is_android(self):
from mozrunner.devices.android_device import verify_android_device
verify_android_device(self, install=True, xre=True, app=kwargs["app"])
verify_android_device(self, install=True, xre=True, app=kwargs["app"],
device_serial=kwargs["deviceSerial"])
return reftest.run_android_test(**kwargs)
return reftest.run_desktop_test(**kwargs)

View File

@ -403,10 +403,12 @@ class MachCommands(MachCommandBase):
app = kwargs.get('app')
if not app:
app = self.substs["ANDROID_PACKAGE_NAME"]
device_serial = kwargs.get('deviceSerial')
# verify installation
verify_android_device(self, install=True, xre=False, app=app)
grant_runtime_permissions(self, app)
verify_android_device(self, install=True, xre=False, app=app,
device_serial=device_serial)
grant_runtime_permissions(self, app, device_serial=device_serial)
run_mochitest = mochitest.run_android_test
else:
run_mochitest = mochitest.run_desktop_test
@ -481,8 +483,10 @@ class RobocopCommands(MachCommandBase):
app = kwargs.get('app')
if not app:
app = self.substs["ANDROID_PACKAGE_NAME"]
verify_android_device(self, install=True, xre=False, app=app)
grant_runtime_permissions(self, app)
device_serial = kwargs.get('deviceSerial')
verify_android_device(self, install=True, xre=False, app=app,
device_serial=device_serial)
grant_runtime_permissions(self, app, device_serial=device_serial)
if not kwargs['adbPath']:
kwargs['adbPath'] = get_adb_path(self)

View File

@ -19,7 +19,7 @@ import urlparse
import urllib2
from distutils.spawn import find_executable
from mozdevice import DeviceManagerADB, DMError
from mozdevice import ADBHost, ADBAndroid
from mozprocess import ProcessHandler
EMULATOR_HOME_DIR = os.path.join(os.path.expanduser('~'), '.mozbuild', 'android-device')
@ -33,6 +33,7 @@ TRY_URL = 'https://hg.mozilla.org/try/raw-file/default'
MANIFEST_PATH = 'testing/config/tooltool-manifests'
verbose_logging = False
devices = {}
class AvdInfo(object):
@ -106,6 +107,19 @@ AVD_DICT = {
}
def _get_device(substs, device_serial=None):
global devices
if device_serial in devices:
device = devices[device_serial]
else:
adb_path = _find_sdk_exe(substs, 'adb', False)
if not adb_path:
adb_path = 'adb'
device = ADBAndroid(adb=adb_path, verbose=verbose_logging, device=device_serial)
devices[device_serial] = device
return device
def _install_host_utils(build_obj):
_log_info("Installing host utilities. This may take a while...")
installed = False
@ -178,7 +192,7 @@ def _maybe_update_host_utils(build_obj):
def verify_android_device(build_obj, install=False, xre=False, debugger=False,
verbose=False, app=None):
verbose=False, app=None, device_serial=None):
"""
Determine if any Android device is connected via adb.
If no device is found, prompt to start an emulator.
@ -195,8 +209,12 @@ def verify_android_device(build_obj, install=False, xre=False, debugger=False,
"""
device_verified = False
emulator = AndroidEmulator('*', substs=build_obj.substs, verbose=verbose)
devices = emulator.dm.devices()
if (len(devices) > 0) and ('device' in [d[1] for d in devices]):
adb_path = _find_sdk_exe(build_obj.substs, 'adb', False)
if not adb_path:
adb_path = 'adb'
adbhost = ADBHost(adb=adb_path, verbose=verbose, timeout=10)
devices = adbhost.devices(timeout=10)
if 'device' in [d['state'] for d in devices]:
device_verified = True
elif emulator.is_available():
response = raw_input(
@ -224,11 +242,10 @@ def verify_android_device(build_obj, install=False, xre=False, debugger=False,
# Installing every time is problematic because:
# - it prevents testing against other builds (downloaded apk)
# - installation may take a couple of minutes.
installed = emulator.dm.shellCheckOutput(['pm', 'list',
'packages', 'org.mozilla.'])
if not app:
app = build_obj.substs["ANDROID_PACKAGE_NAME"]
if app not in installed:
device = _get_device(build_obj.substs, device_serial)
if not device.is_app_installed(app):
if 'fennec' not in app and 'firefox' not in app:
raw_input(
"It looks like %s is not installed on this device,\n"
@ -334,10 +351,7 @@ def run_firefox_for_android(build_obj, params):
Launch Firefox for Android on the connected device.
Optional 'params' allow parameters to be passed to Firefox.
"""
adb_path = _find_sdk_exe(build_obj.substs, 'adb', False)
if not adb_path:
adb_path = 'adb'
dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
device = _get_device(build_obj.substs)
try:
#
# Construct an adb command similar to:
@ -347,45 +361,37 @@ def run_firefox_for_android(build_obj, params):
# -d <url param> \
# --es args "<params>"
#
app = "%s/org.mozilla.gecko.BrowserApp" % build_obj.substs['ANDROID_PACKAGE_NAME']
cmd = ['am', 'start', '-a', 'android.activity.MAIN', '-n', app]
app = build_obj.substs['ANDROID_PACKAGE_NAME']
url = None
if params:
for p in params:
if urlparse.urlparse(p).scheme != "":
cmd.extend(['-d', p])
url = p
params.remove(p)
break
if params:
cmd.extend(['--es', 'args', '"%s"' % ' '.join(params)])
_log_debug(cmd)
output = dm.shellCheckOutput(cmd, timeout=10)
_log_info(output)
except DMError:
device.launch_fennec(app, extra_args=params, url=url)
except Exception:
_log_warning("unable to launch Firefox for Android")
return 1
return 0
def grant_runtime_permissions(build_obj, app):
def grant_runtime_permissions(build_obj, app, device_serial=None):
"""
Grant required runtime permissions to the specified app
(typically org.mozilla.fennec_$USER).
"""
adb_path = _find_sdk_exe(build_obj.substs, 'adb', False)
if not adb_path:
adb_path = 'adb'
dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
dm.default_timeout = 10
device = _get_device(build_obj.substs, device_serial)
try:
sdk_level = dm.shellCheckOutput(['getprop', 'ro.build.version.sdk'])
if sdk_level and int(sdk_level) >= 23:
sdk_level = device.version
if sdk_level and sdk_level >= 23:
_log_info("Granting important runtime permissions to %s" % app)
dm.shellCheckOutput(['pm', 'grant', app, 'android.permission.WRITE_EXTERNAL_STORAGE'])
dm.shellCheckOutput(['pm', 'grant', app, 'android.permission.READ_EXTERNAL_STORAGE'])
dm.shellCheckOutput(['pm', 'grant', app, 'android.permission.ACCESS_COARSE_LOCATION'])
dm.shellCheckOutput(['pm', 'grant', app, 'android.permission.ACCESS_FINE_LOCATION'])
dm.shellCheckOutput(['pm', 'grant', app, 'android.permission.CAMERA'])
except DMError:
device.shell_output('pm grant %s android.permission.WRITE_EXTERNAL_STORAGE' % app)
device.shell_output('pm grant %s android.permission.READ_EXTERNAL_STORAGE' % app)
device.shell_output('pm grant %s android.permission.ACCESS_COARSE_LOCATION' % app)
device.shell_output('pm grant %s android.permission.ACCESS_FINE_LOCATION' % app)
device.shell_output('pm grant %s android.permission.CAMERA' % app)
except Exception:
_log_warning("Unable to grant runtime permissions to %s" % app)
@ -416,12 +422,7 @@ class AndroidEmulator(object):
self.avd_info = AVD_DICT[self.avd_type]
self.gpu = True
self.restarted = False
adb_path = _find_sdk_exe(substs, 'adb', False)
if not adb_path:
adb_path = 'adb'
self.dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1,
deviceSerial=device_serial)
self.dm.default_timeout = 10
self.device_serial = device_serial
_log_debug("Running on %s" % platform.platform())
_log_debug("Emulator created with type %s" % self.avd_type)
@ -543,20 +544,28 @@ class AndroidEmulator(object):
if self.check_completed():
return False
_log_debug("Waiting for device status...")
while(('emulator-5554', 'device') not in self.dm.devices()):
adb_path = _find_sdk_exe(self.substs, 'adb', False)
if not adb_path:
adb_path = 'adb'
adbhost = ADBHost(adb=adb_path, verbose=verbose_logging, timeout=10)
devs = adbhost.devices(timeout=10)
devs = [(d['device_serial'], d['state']) for d in devs]
while ('emulator-5554', 'device') not in devs:
time.sleep(10)
if self.check_completed():
return False
devs = adbhost.devices(timeout=10)
devs = [(d['device_serial'], d['state']) for d in devs]
_log_debug("Device status verified.")
_log_debug("Checking that Android has booted...")
device = _get_device(self.substs, self.device_serial)
complete = False
while(not complete):
while not complete:
output = ''
try:
output = self.dm.shellCheckOutput(
['getprop', 'sys.boot_completed'], timeout=5)
except DMError:
output = device.get_prop('sys.boot_completed', timeout=5)
except Exception:
# adb not yet responding...keep trying
pass
if output.strip() == '1':
@ -843,19 +852,8 @@ def _get_host_platform():
def _get_device_platform(substs):
# PIE executables are required when SDK level >= 21 - important for gdbserver
adb_path = _find_sdk_exe(substs, 'adb', False)
if not adb_path:
adb_path = 'adb'
dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
sdk_level = None
try:
cmd = ['getprop', 'ro.build.version.sdk']
_log_debug(cmd)
output = dm.shellCheckOutput(cmd, timeout=10)
if output:
sdk_level = int(output)
except Exception:
_log_warning("unable to determine Android sdk level")
device = _get_device(substs)
sdk_level = device.version
pie = ''
if sdk_level and sdk_level >= 21:
pie = '-pie'

View File

@ -19,7 +19,7 @@ import BaseHTTPServer
import SimpleHTTPServer
from mozbuild.virtualenv import VirtualenvManager
from mozdevice import DeviceManagerADB
from mozdevice import ADBHost, ADBAndroid
from mozprocess import ProcessHandler
@ -193,12 +193,13 @@ class AutophoneRunner(object):
"adb not found. Enter path to adb: ").strip()
if self.verbose:
print("Using adb at %s" % adb_path)
dm = DeviceManagerADB(autoconnect=False, adbPath=adb_path, retryLimit=1)
adbhost = ADBHost(adb=adb_path, timeout=10)
device_index = 1
try:
with open(os.path.join(self.config['base-dir'], 'devices.ini'), 'w') as f:
for device in dm.devices():
serial = device[0]
for device in adbhost.devices():
serial = device['device_serial']
if self.verify_device(adb_path, serial):
f.write("[device-%d]\nserialno=%s\n" % (device_index, serial))
device_index += 1
@ -444,8 +445,8 @@ time_out = 300""" % (xre_path, xre_path))
Check that the specified device is available and rooted.
"""
try:
dm = DeviceManagerADB(adbPath=adb_path, retryLimit=1, deviceSerial=device)
if dm._haveSu or dm._haveRootShell:
device = ADBAndroid(adb=adb_path, device=device, timeout=10)
if device._have_su or device._have_android_su or device._have_root_shell:
return True
except Exception:
self.build_obj.log(

View File

@ -247,7 +247,8 @@ class MachCommands(MachCommandBase):
if conditions.is_android(self):
from mozrunner.devices.android_device import verify_android_device, get_adb_path
verify_android_device(self)
device_serial = params.get('deviceSerial')
verify_android_device(self, device_serial=device_serial)
if not params['adbPath']:
params['adbPath'] = get_adb_path(self)
xpcshell = self._spawn(AndroidXPCShellRunner)