taler-monitoring/android-test/lib_android_env.sh
2026-07-18 13:56:54 +02:00

158 lines
5.2 KiB
Bash

# shellcheck shell=bash
# Shared Android env for GUI / adb smokes.
# Source: . "$ROOT/lib_android_env.sh"
#
# Defaults favour **servers / CI**: no host window (headless emulator), while the
# guest still runs GLES via SwiftShader so UI layout / uiautomator work.
#
# See GUI-AUTOMATION-NOTES.md → Headless mode
# --- SDK / PATH ---------------------------------------------------------------
export ANDROID_HOME="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-$HOME/Android/Sdk}}"
export ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT:-$ANDROID_HOME}"
for d in \
"$ANDROID_HOME/platform-tools" \
"$ANDROID_HOME/emulator" \
"$ANDROID_HOME/cmdline-tools/latest/bin"
do
[ -d "$d" ] && case ":$PATH:" in *":$d:"*) ;; *) PATH="$d:$PATH" ;; esac
done
export PATH
# AVD path (some hosts keep AVDs under ~/.config/.android)
if [ -z "${ANDROID_AVD_HOME:-}" ]; then
if [ -d "$HOME/.android/avd" ]; then
export ANDROID_AVD_HOME="$HOME/.android/avd"
elif [ -d "$HOME/.config/.android/avd" ]; then
export ANDROID_AVD_HOME="$HOME/.config/.android/avd"
# emulator also looks at ~/.android/avd — soft-link if missing
if [ ! -e "$HOME/.android/avd" ]; then
mkdir -p "$HOME/.android"
ln -sfn "$HOME/.config/.android/avd" "$HOME/.android/avd" 2>/dev/null || true
fi
fi
fi
# --- Platform / feature flags -------------------------------------------------
os=$(uname -s)
case "${AUTO_PLATFORM:-auto}" in
auto)
case "$os" in
Linux) : "${AUTO_ANDROID:=1}"; : "${AUTO_GUI:=1}" ;;
Darwin) : "${AUTO_ANDROID:=1}"; : "${AUTO_GUI:=1}" ;;
*) : "${AUTO_ANDROID:=0}"; : "${AUTO_GUI:=0}" ;;
esac
;;
linux|macos) : "${AUTO_ANDROID:=1}"; : "${AUTO_GUI:=1}" ;;
*) : "${AUTO_ANDROID:=0}"; : "${AUTO_GUI:=0}" ;;
esac
# Headless = default (no X11/Wayland window on host). GUI *logic* still runs in
# the guest via software GPU. Set EMULATOR_HEADLESS=0 or WINDOWED=1 for a window.
: "${EMULATOR_HEADLESS:=1}"
if [ "${WINDOWED:-0}" = "1" ]; then
EMULATOR_HEADLESS=0
fi
export EMULATOR_HEADLESS
# Soft GLES for headless; windowed may override to host/auto if set by user.
if [ "${EMULATOR_HEADLESS}" = "1" ]; then
: "${EMULATOR_GPU:=swiftshader_indirect}"
else
: "${EMULATOR_GPU:=swiftshader_indirect}" # still safe default; host GPU: EMULATOR_GPU=host
fi
export EMULATOR_GPU
: "${EMULATOR_AVD:=TalerWallet34}"
: "${EMULATOR_MEMORY:=1536}"
: "${EMULATOR_CORES:=2}"
# If no adb device: start headless AVD (0 = require phone/manual emulator)
: "${AUTO_START_EMULATOR:=1}"
: "${EMULATOR_BOOT_TIMEOUT:=360}"
: "${EMULATOR_LOG:=/tmp/taler-android-emulator.log}"
: "${EMULATOR_NO_SNAPSHOT:=1}"
android_adb_serial() {
adb devices 2>/dev/null | awk '/\tdevice$/{print $1; exit}'
}
android_has_device() {
[ -n "$(android_adb_serial)" ]
}
# Build emulator argv for current headless/windowed mode.
# Prints args; caller exec/nohup.
android_emulator_args() {
local avd="${1:-$EMULATOR_AVD}"
local args=( -avd "$avd" -gpu "$EMULATOR_GPU" -no-audio -no-boot-anim )
if [ "${EMULATOR_HEADLESS}" = "1" ]; then
args+=( -no-window )
# Avoid Qt trying to open a display on servers
export QT_QPA_PLATFORM="${QT_QPA_PLATFORM:-offscreen}"
fi
# Broken default_boot snapshots leave adb offline forever — cold boot by default.
if [ "${EMULATOR_NO_SNAPSHOT:-1}" = "1" ]; then
args+=( -no-snapshot -no-snapshot-load -no-snapshot-save )
fi
if [ -n "${EMULATOR_MEMORY:-}" ]; then
args+=( -memory "$EMULATOR_MEMORY" )
fi
if [ -n "${EMULATOR_CORES:-}" ]; then
args+=( -cores "$EMULATOR_CORES" )
fi
# extra user flags
# shellcheck disable=SC2206
if [ -n "${EMULATOR_EXTRA_ARGS:-}" ]; then
# intentional word-split for extra flags
args+=( ${EMULATOR_EXTRA_ARGS} )
fi
printf '%s\n' "${args[@]}"
}
# Ensure an adb "device" is online. Optionally start headless emulator.
# Sets SERIAL / ANDROID_SERIAL on success. Returns 0 ok, 3 no device.
android_ensure_device() {
local serial
serial="${SERIAL:-${ANDROID_SERIAL:-}}"
if [ -z "$serial" ]; then
serial=$(android_adb_serial || true)
fi
if [ -n "$serial" ]; then
SERIAL="$serial"
export ANDROID_SERIAL="$serial"
return 0
fi
if [ "${AUTO_START_EMULATOR}" != "1" ]; then
echo "no adb device (AUTO_START_EMULATOR=0 — plug phone or start AVD manually)" >&2
return 3
fi
if ! command -v emulator >/dev/null 2>&1; then
echo "no adb device and emulator binary missing under $ANDROID_HOME" >&2
return 3
fi
echo "no adb device → starting AVD ${EMULATOR_AVD} (headless=${EMULATOR_HEADLESS} gpu=${EMULATOR_GPU})"
local starter
starter="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/start-android-emulator.sh"
if [ ! -x "$starter" ]; then
echo "missing $starter" >&2
return 3
fi
EMULATOR_HEADLESS="$EMULATOR_HEADLESS" EMULATOR_GPU="$EMULATOR_GPU" \
EMULATOR_AVD="$EMULATOR_AVD" EMULATOR_MEMORY="$EMULATOR_MEMORY" \
EMULATOR_CORES="$EMULATOR_CORES" EMULATOR_LOG="$EMULATOR_LOG" \
EMULATOR_BOOT_TIMEOUT="$EMULATOR_BOOT_TIMEOUT" \
"$starter" --wait || return 3
serial=$(android_adb_serial || true)
if [ -z "$serial" ]; then
echo "emulator started but no adb device yet — see $EMULATOR_LOG" >&2
return 3
fi
SERIAL="$serial"
export ANDROID_SERIAL="$serial"
echo "device: $SERIAL (headless=${EMULATOR_HEADLESS})"
return 0
}