blob: ab6847480ee2c7c3f2d32a78cef6873ce2187a8e [file] [log] [blame]
import argparse
import os
import platform
import shutil
import subprocess
import requests
android_device = None
here = os.path.abspath(os.path.dirname(__file__))
wpt_root = os.path.abspath(os.path.join(here, os.pardir, os.pardir))
def do_delayed_imports():
global android_device
from mozrunner.devices import android_device
android_device.TOOLTOOL_PATH = os.path.join(os.path.dirname(__file__),
os.pardir,
"third_party",
"tooltool",
"tooltool.py")
def get_parser_install():
parser = argparse.ArgumentParser()
parser.add_argument("--reinstall", action="store_true", default=False,
help="Force reinstall even if the emulator already exists")
return parser
def get_parser_start():
return get_parser_install()
def get_sdk_path(dest):
if dest is None:
# os.getcwd() doesn't include the venv path
dest = os.path.join(wpt_root, "_venv")
dest = os.path.join(dest, 'android-sdk')
return os.path.abspath(os.environ.get('ANDROID_SDK_PATH', dest))
def uninstall_sdk(dest=None):
path = get_sdk_path(dest)
if os.path.exists(path) and os.path.isdir(path):
shutil.rmtree(path)
def install_sdk(logger, dest=None):
sdk_path = get_sdk_path(dest)
if os.path.isdir(sdk_path):
logger.info("Using SDK installed at %s" % sdk_path)
return sdk_path, False
if not os.path.exists(sdk_path):
os.makedirs(sdk_path)
os_name = platform.system().lower()
if os_name not in ["darwin", "linux", "windows"]:
logger.critical("Unsupported platform %s" % os_name)
raise NotImplementedError
os_name = 'darwin' if os_name == 'macosx' else os_name
# TODO: either always use the latest version or have some way to
# configure a per-product version if there are strong requirements
# to use a specific version.
url = 'https://dl.google.com/android/repository/sdk-tools-%s-4333796.zip' % (os_name,)
logger.info("Getting SDK from %s" % url)
temp_path = os.path.join(sdk_path, url.rsplit("/", 1)[1])
try:
with open(temp_path, "wb") as f:
with requests.get(url, stream=True) as resp:
shutil.copyfileobj(resp.raw, f)
# Python's zipfile module doesn't seem to work here
subprocess.check_call(["unzip", temp_path], cwd=sdk_path)
finally:
os.unlink(temp_path)
return sdk_path, True
def install_android_packages(logger, sdk_path, no_prompt=False):
sdk_manager_path = os.path.join(sdk_path, "tools", "bin", "sdkmanager")
if not os.path.exists(sdk_manager_path):
raise OSError("Can't find sdkmanager at %s" % sdk_manager_path)
packages = ["platform-tools",
"build-tools;30.0.2",
"platforms;android-30",
"emulator"]
# TODO: make this work non-internactively
logger.info("Installing SDK packages")
cmd = [sdk_manager_path] + packages
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE)
if no_prompt:
data = "Y\n" * 100 if no_prompt else None
proc.communicate(data)
else:
proc.wait()
if proc.returncode != 0:
raise subprocess.CalledProcessError(proc.returncode, cmd)
def get_emulator(sdk_path):
if android_device is None:
do_delayed_imports()
if "ANDROID_SDK_ROOT" not in os.environ:
os.environ["ANDROID_SDK_ROOT"] = sdk_path
substs = {"top_srcdir": wpt_root, "TARGET_CPU": "x86"}
emulator = android_device.AndroidEmulator("*", substs=substs)
emulator.emulator_path = os.path.join(sdk_path, "emulator", "emulator")
return emulator
def install(logger, reinstall=False, no_prompt=False):
if reinstall:
uninstall_sdk()
dest, new_install = install_sdk(logger)
if new_install:
install_android_packages(logger, dest, no_prompt)
if "ANDROID_SDK_ROOT" not in os.environ:
os.environ["ANDROID_SDK_ROOT"] = dest
emulator = get_emulator(dest)
return emulator
def start(logger, emulator=None, reinstall=False):
if reinstall:
install(reinstall=True)
sdk_path = get_sdk_path(None)
if emulator is None:
emulator = get_emulator(sdk_path)
if not emulator.check_avd():
logger.critical("Android AVD not found, please run |mach bootstrap|")
raise NotImplementedError
emulator.start()
emulator.wait_for_start()
return emulator
def run_install(venv, **kwargs):
try:
import logging
logging.basicConfig()
logger = logging.getLogger()
install(logger, **kwargs)
except Exception:
import traceback
traceback.print_exc()
import pdb
pdb.post_mortem()
def run_start(venv, **kwargs):
try:
import logging
logging.basicConfig()
logger = logging.getLogger()
start(logger, **kwargs)
except Exception:
import traceback
traceback.print_exc()
import pdb
pdb.post_mortem()