Bug 1883086 - Adding a Mach Install Command for different Android Apps. r=firefox-build-system-reviewers,nalexander

Differential Revision: https://phabricator.services.mozilla.com/D218892
This commit is contained in:
Aaditya Dhingra 2024-09-23 18:05:37 +00:00
parent 4a5897c66b
commit 6190431f91
3 changed files with 110 additions and 56 deletions

View File

@ -286,6 +286,28 @@ def android_install_geckoview_example(command_context, args):
return 0
@SubCommand("android", "install-fenix", """Install fenix """)
@CommandArgument("args", nargs=argparse.REMAINDER)
def android_install_fenix(command_context, args):
gradle(
command_context,
["fenix:installFenixDebug"] + args,
verbose=True,
)
return 0
@SubCommand("android", "install-focus", """Install focus """)
@CommandArgument("args", nargs=argparse.REMAINDER)
def android_install_focus(command_context, args):
gradle(
command_context,
["focus-android:installFocusDebug"] + args,
verbose=True,
)
return 0
@SubCommand(
"android", "install-geckoview-test_runner", """Install geckoview.test_runner """
)
@ -534,6 +556,7 @@ def gradle(command_context, args, verbose=False):
gradle_flags += ["--console=plain"]
env = os.environ.copy()
env.update(
{
"GRADLE_OPTS": "-Dfile.encoding=utf-8",

View File

@ -1235,7 +1235,11 @@ def install(command_context, **kwargs):
)
ret = (
verify_android_device(command_context, install=InstallIntent.YES, **kwargs)
verify_android_device(
command_context,
install=InstallIntent.YES,
**kwargs,
)
== 0
)
else:
@ -1551,17 +1555,14 @@ def _run_android(
from mozrunner.devices.android_device import (
InstallIntent,
_get_device,
metadata_for_app,
verify_android_device,
)
from six.moves import shlex_quote
if app == "org.mozilla.geckoview_example":
activity_name = "org.mozilla.geckoview_example.GeckoViewActivity"
elif app == "org.mozilla.geckoview.test_runner":
activity_name = "org.mozilla.geckoview.test_runner.TestRunnerActivity"
elif "fennec" in app or "firefox" in app:
activity_name = "org.mozilla.gecko.BrowserApp"
else:
metadata = metadata_for_app(app)
if not metadata.activity_name:
raise RuntimeError("Application not recognized: {}".format(app))
# If we want to debug an existing process, we implicitly do not want
@ -1572,7 +1573,7 @@ def _run_android(
# `verify_android_device` respects `DEVICE_SERIAL` if it is set and sets it otherwise.
verify_android_device(
command_context,
app=app,
app=metadata.package_name,
aab=aab,
debugger=debug,
install=InstallIntent.NO if no_install else InstallIntent.YES,
@ -1591,10 +1592,10 @@ def _run_android(
command_context.log(
logging.INFO,
"run",
{"app": app},
{"app": metadata.package_name},
"Setting {app} as the device debug app",
)
device.shell("am set-debug-app -w --persistent %s" % app)
device.shell("am set-debug-app -w --persistent %s" % metadata.package_name)
else:
# Make sure that the app doesn't block waiting for jdb
device.shell("am clear-debug-app")
@ -1607,7 +1608,9 @@ def _run_android(
# Always /data/local/tmp, rather than `device.test_root`, because
# GeckoView only takes its configuration file from /data/local/tmp,
# and we want to follow suit.
target_profile = "/data/local/tmp/{}-profile".format(app)
target_profile = "/data/local/tmp/{}-profile".format(
metadata.package_name
)
device.rm(target_profile, recursive=True, force=True)
device.push(host_profile, target_profile)
command_context.log(
@ -1650,23 +1653,26 @@ def _run_android(
command_context.log(
logging.INFO,
"run",
{"app": app},
{"app": metadata.package_name},
"Stopping {app} to ensure clean restart.",
)
device.stop_application(app)
device.stop_application(metadata.package_name)
# We'd prefer to log the actual `am start ...` command, but it's not trivial
# to wire the device's logger to mach's logger.
command_context.log(
logging.INFO,
"run",
{"app": app, "activity_name": activity_name},
{
"app": metadata.package_name,
"activity_name": metadata.activity_name,
},
"Starting {app}/{activity_name}.",
)
device.launch_application(
app_name=app,
activity_name=activity_name,
app_name=metadata.package_name,
activity_name=metadata.activity_name,
intent=intent,
extras=extras,
url=url,
@ -1679,7 +1685,9 @@ def _run_android(
from mozrunner.devices.android_device import run_lldb_server
socket_file = run_lldb_server(app, command_context.substs, device_serial)
socket_file = run_lldb_server(
metadata.package_name, command_context.substs, device_serial
)
if not socket_file:
command_context.log(
logging.ERROR,
@ -1719,14 +1727,14 @@ def _run_android(
proc_list = [
proc[:-1]
for proc in device.get_process_list()
if _is_geckoview_process(proc[1], app)
if _is_geckoview_process(proc[1], metadata.package_name)
]
if not proc_list:
command_context.log(
logging.ERROR,
"run",
{"app": app},
{"app": metadata.package_name},
"No existing {app} processes found",
)
return 1
@ -1752,7 +1760,7 @@ def _run_android(
else:
# We're not using an existing process, so there should only be our
# parent process at this time.
pids = device.pidof(app_name=app)
pids = device.pidof(app_name=metadata.package_name)
if len(pids) != 1:
command_context.log(
logging.ERROR,

View File

@ -13,6 +13,7 @@ import subprocess
import sys
import telnetlib
import time
from collections import namedtuple
from enum import Enum
import six
@ -277,6 +278,42 @@ def _maybe_update_host_utils(build_obj):
_install_host_utils(build_obj)
def metadata_for_app(app, aab=False):
"""Given an app name like "fenix", "focus", or "org.mozilla.geckoview_example",
return Android metadata including launch `activity_name`, `package_name`, 'subcommand'.
to reduce special-casing throughout the code base"""
metadata = namedtuple("metadata", ["activity_name", "package_name", "subcommand"])
package_name = app
activity_name = None
subcommand = None
if "fennec" in app or "firefox" in app:
activity_name = "org.mozilla.gecko.BrowserApp"
elif app == "org.mozilla.geckoview.test":
subcommand = "install-geckoview-test"
elif app == "org.mozilla.geckoview.test_runner":
activity_name = "org.mozilla.geckoview.test_runner.TestRunnerActivity"
subcommand = (
"install-geckoview-test_runner-aab"
if aab
else "install-geckoview-test_runner"
)
elif app == "org.mozilla.geckoview_example":
activity_name = "org.mozilla.geckoview_example.GeckoViewActivity"
subcommand = (
"install-geckoview_example-aab" if aab else "install-geckoview_example"
)
elif "fenix" in app:
package_name = "org.mozilla.fenix.debug"
activity_name = "org.mozilla.fenix.debug.App"
subcommand = "install-fenix"
elif "focus" in app:
package_name = "org.mozilla.focus.debug"
activity_name = "org.mozilla.focus.activity.MainActivity"
subcommand = "install-focus"
return metadata(activity_name, package_name, subcommand)
def verify_android_device(
build_obj,
install=InstallIntent.NO,
@ -368,55 +405,39 @@ def verify_android_device(
app = "org.mozilla.geckoview.test_runner"
device = _get_device(build_obj.substs, device_serial)
response = ""
installed = device.is_app_installed(app)
metadata = metadata_for_app(app, aab)
installed = device.is_app_installed(metadata.package_name)
if not installed:
_log_info("It looks like %s is not installed on this device." % app)
if "fennec" in app or "firefox" in app:
_log_info(
"It looks like %s is not installed on this device."
% metadata.package_name
)
if metadata.subcommand and installed:
device.uninstall_app(metadata.package_name)
if "fennec" in metadata.package_name or "firefox" in metadata.package_name:
if installed:
device.uninstall_app(app)
device.uninstall_app(metadata.package_name)
_log_info("Installing Firefox...")
build_obj._run_make(directory=".", target="install", ensure_exit_code=False)
elif app == "org.mozilla.geckoview.test":
if installed:
device.uninstall_app(app)
_log_info("Installing geckoview AndroidTest...")
elif metadata.subcommand:
_log_info("Installing %s..." % metadata.package_name)
build_obj._mach_context.commands.dispatch(
"android",
build_obj._mach_context,
subcommand="install-geckoview-test",
subcommand=metadata.subcommand,
args=[],
)
elif app == "org.mozilla.geckoview.test_runner":
if installed:
device.uninstall_app(app)
_log_info("Installing geckoview test_runner...")
sub = (
"install-geckoview-test_runner-aab"
if aab
else "install-geckoview-test_runner"
)
build_obj._mach_context.commands.dispatch(
"android", build_obj._mach_context, subcommand=sub, args=[]
)
elif app == "org.mozilla.geckoview_example":
if installed:
device.uninstall_app(app)
_log_info("Installing geckoview_example...")
sub = (
"install-geckoview_example-aab" if aab else "install-geckoview_example"
)
build_obj._mach_context.commands.dispatch(
"android", build_obj._mach_context, subcommand=sub, args=[]
)
elif not installed:
response = input(
"It looks like %s is not installed on this device,\n"
"but I don't know how to install it.\n"
"Install it now, then hit Enter " % app
"Install it now, then hit Enter " % metadata.package_name
)
device.run_as_package = app
device.run_as_package = metadata.package_name
if device_verified and xre:
# Check whether MOZ_HOST_BIN has been set to a valid xre; if not,
@ -455,7 +476,7 @@ def verify_android_device(
serial = device_serial or os.environ.get("DEVICE_SERIAL")
if not serial or ("emulator" not in serial):
device = _get_device(build_obj.substs, serial)
device.run_as_package = app
device.run_as_package = metadata.package_name
try:
addr = device.get_ip_address()
if not addr:
@ -478,7 +499,9 @@ def verify_android_device(
_log_debug("network check skipped on emulator")
if debugger:
_setup_or_run_lldb_server(app, build_obj.substs, device_serial, setup=True)
_setup_or_run_lldb_server(
metadata.package_name, build_obj.substs, device_serial, setup=True
)
return device_verified