From 50f59f702831f0d36cf71bfa373d23492e62aa8e Mon Sep 17 00:00:00 2001 From: Radoslaw Nowacki Date: Fri, 16 Oct 2026 15:59:24 +0200 Subject: [PATCH 1/2] test(e2e): wait for Android emulator to settle and hide ANR dialogs Right after boot the CI emulator is CPU-saturated and system apps (System UI, GMS) hit ANRs. The "System UI isn't responding" dialog then covers the app, UIAutomator only sees the dialog window, and the greeting check times out. Before Detox starts, suppress error dialogs, wait until CPU pressure (/proc/pressure/cpu) stays low, and close any dialog already showing. The wait is best-effort and never fails the job. Refs #499 --- .../prepare-android-emulator-for-detox.sh | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/apps/brownfield-example-shared-tests/scripts/prepare-android-emulator-for-detox.sh b/apps/brownfield-example-shared-tests/scripts/prepare-android-emulator-for-detox.sh index c8e32a591..e6749dbe4 100755 --- a/apps/brownfield-example-shared-tests/scripts/prepare-android-emulator-for-detox.sh +++ b/apps/brownfield-example-shared-tests/scripts/prepare-android-emulator-for-detox.sh @@ -5,6 +5,11 @@ set -euo pipefail BOOT_TIMEOUT_SEC="${ANDROID_EMULATOR_BOOT_TIMEOUT_SEC:-180}" +# After boot, system apps keep the CPU saturated for a minute or more and some of +# them hit ANRs; the resulting "System UI isn't responding" dialog covers the app. +SETTLE_TIMEOUT_SEC="${ANDROID_EMULATOR_SETTLE_TIMEOUT_SEC:-300}" +SETTLE_CPU_PRESSURE_MAX="${ANDROID_EMULATOR_SETTLE_CPU_PRESSURE_MAX:-40}" +SETTLE_STABLE_CHECKS=3 ADB=(adb) if [[ -n "${ANDROID_SERIAL:-}" ]]; then ADB=(adb -s "${ANDROID_SERIAL}") @@ -42,6 +47,38 @@ if (( SECONDS >= deadline )); then exit 1 fi +# Suppress ANR / crash dialogs from system apps for the rest of the run. +"${ADB[@]}" shell settings put global hide_error_dialogs 1 >/dev/null 2>&1 || true + +# Wait until CPU pressure (PSI "some avg10", % of time tasks stalled on CPU) stays +# low for a few consecutive checks. Best-effort: continue on timeout. +echo "==> Waiting for emulator to settle (cpu pressure avg10 < ${SETTLE_CPU_PRESSURE_MAX}, timeout: ${SETTLE_TIMEOUT_SEC}s)" +settle_deadline=$((SECONDS + SETTLE_TIMEOUT_SEC)) +stable=0 +while (( SECONDS < settle_deadline )); do + pressure="$("${ADB[@]}" shell cat /proc/pressure/cpu 2>/dev/null | tr -d '\r' | awk '/^some/ { split($2, a, "="); print int(a[2]) }' || true)" + if [[ -z "${pressure}" ]]; then + echo "warning: /proc/pressure/cpu not readable, skipping settle wait" >&2 + break + fi + if (( pressure < SETTLE_CPU_PRESSURE_MAX )); then + stable=$((stable + 1)) + if (( stable >= SETTLE_STABLE_CHECKS )); then + echo "==> Emulator settled (cpu pressure avg10=${pressure}, ${SECONDS}s into prep)" + break + fi + else + stable=0 + fi + echo " cpu pressure avg10=${pressure}" + sleep 5 +done +if (( SECONDS >= settle_deadline )); then + echo "warning: emulator did not settle within ${SETTLE_TIMEOUT_SEC}s, continuing" >&2 +fi +# Dismiss any error dialog that was already showing before hide_error_dialogs took effect. +"${ADB[@]}" shell am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS >/dev/null 2>&1 || true + "${ADB[@]}" shell input keyevent KEYCODE_WAKEUP >/dev/null 2>&1 || true "${ADB[@]}" shell wm dismiss-keyguard >/dev/null 2>&1 || true "${ADB[@]}" shell cmd statusbar collapse >/dev/null 2>&1 || true From 2cd4d5911992af4870e3a8a903efb9ee9ab97a43 Mon Sep 17 00:00:00 2001 From: Radoslaw Nowacki Date: Mon, 19 Oct 2026 09:26:13 +0200 Subject: [PATCH 2/2] test(e2e): drop emulator settle wait, keep ANR dialog hiding /proc/pressure/cpu is not readable on the CI emulator image, so the wait was always skipped. Hiding the dialogs is what fixes the failures. --- .../prepare-android-emulator-for-detox.sh | 35 ++----------------- 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/apps/brownfield-example-shared-tests/scripts/prepare-android-emulator-for-detox.sh b/apps/brownfield-example-shared-tests/scripts/prepare-android-emulator-for-detox.sh index e6749dbe4..8c909238a 100755 --- a/apps/brownfield-example-shared-tests/scripts/prepare-android-emulator-for-detox.sh +++ b/apps/brownfield-example-shared-tests/scripts/prepare-android-emulator-for-detox.sh @@ -5,11 +5,6 @@ set -euo pipefail BOOT_TIMEOUT_SEC="${ANDROID_EMULATOR_BOOT_TIMEOUT_SEC:-180}" -# After boot, system apps keep the CPU saturated for a minute or more and some of -# them hit ANRs; the resulting "System UI isn't responding" dialog covers the app. -SETTLE_TIMEOUT_SEC="${ANDROID_EMULATOR_SETTLE_TIMEOUT_SEC:-300}" -SETTLE_CPU_PRESSURE_MAX="${ANDROID_EMULATOR_SETTLE_CPU_PRESSURE_MAX:-40}" -SETTLE_STABLE_CHECKS=3 ADB=(adb) if [[ -n "${ANDROID_SERIAL:-}" ]]; then ADB=(adb -s "${ANDROID_SERIAL}") @@ -47,35 +42,11 @@ if (( SECONDS >= deadline )); then exit 1 fi -# Suppress ANR / crash dialogs from system apps for the rest of the run. +# Right after boot system apps (System UI, GMS) often hit ANRs, and the +# "System UI isn't responding" dialog covers the app. Suppress ANR / crash +# dialogs for the rest of the run; Android then closes the hung app instead. "${ADB[@]}" shell settings put global hide_error_dialogs 1 >/dev/null 2>&1 || true -# Wait until CPU pressure (PSI "some avg10", % of time tasks stalled on CPU) stays -# low for a few consecutive checks. Best-effort: continue on timeout. -echo "==> Waiting for emulator to settle (cpu pressure avg10 < ${SETTLE_CPU_PRESSURE_MAX}, timeout: ${SETTLE_TIMEOUT_SEC}s)" -settle_deadline=$((SECONDS + SETTLE_TIMEOUT_SEC)) -stable=0 -while (( SECONDS < settle_deadline )); do - pressure="$("${ADB[@]}" shell cat /proc/pressure/cpu 2>/dev/null | tr -d '\r' | awk '/^some/ { split($2, a, "="); print int(a[2]) }' || true)" - if [[ -z "${pressure}" ]]; then - echo "warning: /proc/pressure/cpu not readable, skipping settle wait" >&2 - break - fi - if (( pressure < SETTLE_CPU_PRESSURE_MAX )); then - stable=$((stable + 1)) - if (( stable >= SETTLE_STABLE_CHECKS )); then - echo "==> Emulator settled (cpu pressure avg10=${pressure}, ${SECONDS}s into prep)" - break - fi - else - stable=0 - fi - echo " cpu pressure avg10=${pressure}" - sleep 5 -done -if (( SECONDS >= settle_deadline )); then - echo "warning: emulator did not settle within ${SETTLE_TIMEOUT_SEC}s, continuing" >&2 -fi # Dismiss any error dialog that was already showing before hide_error_dialogs took effect. "${ADB[@]}" shell am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS >/dev/null 2>&1 || true