Files
MobileGL/android-plugin/run-avd-ci.sh

233 lines
5.9 KiB
Bash

#!/bin/sh
set -eu
usage() {
cat <<'EOF'
Usage:
sh android-plugin/run-avd-ci.sh create \
--api-level N \
--target TARGET \
--arch ARCH \
--profile PROFILE \
--avd-name NAME
sh android-plugin/run-avd-ci.sh start \
--avd-name NAME \
--gpu GPU \
--emulator-log FILE \
--pid-file FILE \
--boot-timeout SECONDS
sh android-plugin/run-avd-ci.sh stop \
--avd-name NAME \
--emulator-log FILE \
--pid-file FILE
EOF
}
die() {
echo "run-avd-ci.sh: $*" >&2
usage >&2
exit 2
}
next_arg() {
if [ "$#" -lt 2 ]; then
die "$1 requires a value"
fi
printf '%s' "$2"
}
require_value() {
value="$1"
name="$2"
if [ -z "${value}" ]; then
die "missing ${name}"
fi
}
find_android_tool() {
tool="$1"
fallback="$2"
if command -v "${tool}" >/dev/null 2>&1; then
command -v "${tool}"
return 0
fi
sdk_root="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-}}"
if [ -n "${sdk_root}" ] && [ -x "${sdk_root}/${fallback}" ]; then
printf '%s\n' "${sdk_root}/${fallback}"
return 0
fi
die "unable to find Android SDK tool: ${tool}"
}
ensure_android_avd_home() {
if [ -z "${ANDROID_AVD_HOME:-}" ]; then
export ANDROID_AVD_HOME="${RUNNER_TEMP:-${PWD}}/mobilegl-avd"
fi
mkdir -p "${ANDROID_AVD_HOME}"
}
print_diagnostics() {
emulator_log="$1"
adb_bin="$(find_android_tool adb platform-tools/adb)"
"${adb_bin}" devices -l >&2 || true
if [ -f "${emulator_log}" ]; then
echo "----- emulator log -----" >&2
cat "${emulator_log}" >&2 || true
echo "----- end emulator log -----" >&2
fi
}
create_avd() {
api_level=""
target=""
arch=""
profile=""
avd_name=""
while [ "$#" -gt 0 ]; do
case "$1" in
--api-level) api_level="$(next_arg "$@")"; shift 2 ;;
--target) target="$(next_arg "$@")"; shift 2 ;;
--arch) arch="$(next_arg "$@")"; shift 2 ;;
--profile) profile="$(next_arg "$@")"; shift 2 ;;
--avd-name) avd_name="$(next_arg "$@")"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) die "unknown create argument: $1" ;;
esac
done
require_value "${api_level}" "--api-level"
require_value "${target}" "--target"
require_value "${arch}" "--arch"
require_value "${profile}" "--profile"
require_value "${avd_name}" "--avd-name"
sdkmanager_bin="$(find_android_tool sdkmanager cmdline-tools/latest/bin/sdkmanager)"
avdmanager_bin="$(find_android_tool avdmanager cmdline-tools/latest/bin/avdmanager)"
ensure_android_avd_home
system_image="system-images;android-${api_level};${target};${arch}"
yes | "${sdkmanager_bin}" --licenses >/dev/null
yes | "${sdkmanager_bin}" "platform-tools" "emulator" "platforms;android-${api_level}" "${system_image}"
echo no | "${avdmanager_bin}" create avd --force --name "${avd_name}" --package "${system_image}" --device "${profile}"
}
start_avd() {
avd_name=""
gpu=""
emulator_log=""
pid_file=""
boot_timeout=""
while [ "$#" -gt 0 ]; do
case "$1" in
--avd-name) avd_name="$(next_arg "$@")"; shift 2 ;;
--gpu) gpu="$(next_arg "$@")"; shift 2 ;;
--emulator-log) emulator_log="$(next_arg "$@")"; shift 2 ;;
--pid-file) pid_file="$(next_arg "$@")"; shift 2 ;;
--boot-timeout) boot_timeout="$(next_arg "$@")"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) die "unknown start argument: $1" ;;
esac
done
require_value "${avd_name}" "--avd-name"
require_value "${gpu}" "--gpu"
require_value "${emulator_log}" "--emulator-log"
require_value "${pid_file}" "--pid-file"
require_value "${boot_timeout}" "--boot-timeout"
adb_bin="$(find_android_tool adb platform-tools/adb)"
emulator_bin="$(find_android_tool emulator emulator/emulator)"
ensure_android_avd_home
mkdir -p "$(dirname "${emulator_log}")" "$(dirname "${pid_file}")"
"${emulator_bin}" -avd "${avd_name}" \
-no-window \
-gpu "${gpu}" \
-no-snapshot \
-noaudio \
-no-boot-anim \
-camera-back none \
-camera-front none \
> "${emulator_log}" 2>&1 &
emulator_pid="$!"
echo "${emulator_pid}" > "${pid_file}"
if ! timeout "${boot_timeout}" "${adb_bin}" wait-for-device; then
print_diagnostics "${emulator_log}"
die "emulator did not connect to adb within ${boot_timeout}s"
fi
booted=""
for _ in $(seq 1 "${boot_timeout}"); do
booted="$("${adb_bin}" shell getprop sys.boot_completed 2>/dev/null | tr -d '\r' || true)"
if [ "${booted}" = "1" ]; then
break
fi
sleep 1
done
if [ "${booted}" != "1" ]; then
print_diagnostics "${emulator_log}"
die "emulator did not boot within ${boot_timeout}s"
fi
"${adb_bin}" shell settings put global window_animation_scale 0
"${adb_bin}" shell settings put global transition_animation_scale 0
"${adb_bin}" shell settings put global animator_duration_scale 0
"${adb_bin}" shell input keyevent 82 || true
}
stop_avd() {
avd_name=""
emulator_log=""
pid_file=""
while [ "$#" -gt 0 ]; do
case "$1" in
--avd-name) avd_name="$(next_arg "$@")"; shift 2 ;;
--emulator-log) emulator_log="$(next_arg "$@")"; shift 2 ;;
--pid-file) pid_file="$(next_arg "$@")"; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) die "unknown stop argument: $1" ;;
esac
done
require_value "${avd_name}" "--avd-name"
require_value "${emulator_log}" "--emulator-log"
require_value "${pid_file}" "--pid-file"
adb_bin="$(find_android_tool adb platform-tools/adb)"
ensure_android_avd_home
"${adb_bin}" emu kill >/dev/null 2>&1 || true
if [ -f "${pid_file}" ]; then
emulator_pid="$(cat "${pid_file}")"
if [ -n "${emulator_pid}" ] && kill -0 "${emulator_pid}" 2>/dev/null; then
kill "${emulator_pid}" >/dev/null 2>&1 || true
fi
fi
}
if [ "$#" -eq 0 ]; then
die "missing command"
fi
command="$1"
shift
case "${command}" in
create) create_avd "$@" ;;
start) start_avd "$@" ;;
stop) stop_avd "$@" ;;
-h|--help) usage; exit 0 ;;
*) die "unknown command: ${command}" ;;
esac