# 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 }