From 3d2acf28e0f9eeb9b238a2007f358000093d589e Mon Sep 17 00:00:00 2001 From: LucaCappelletti94 Date: Sat, 10 Oct 2026 17:57:40 +0200 Subject: [PATCH] Wait for the app to leave the foreground before the single-top push --- ci/android/run.sh | 6 +++--- .../androidTest/kotlin/rs/pushups/ci/SingleTopTapTest.kt | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ci/android/run.sh b/ci/android/run.sh index 170ea0f..3d62e3d 100755 --- a/ci/android/run.sh +++ b/ci/android/run.sh @@ -98,9 +98,9 @@ run_variant() { timeout 900 adb shell am instrument -w -e class "rs.pushups.ci.$class" "${arguments[@]}" \ -e coverage true -e coverageFile "$files/jacoco.ec" "$package/androidx.test.runner.AndroidJUnitRunner" \ | tee "$out/$variant.txt" || true - # The device's side of a failure, which the runner's report does not show. - grep -q '^OK (' "$out/$variant.txt" || adb logcat -d -v time \ - | grep -E 'pushups|FirebaseMessaging|FirebaseApp|NotificationService|ActivityTaskManager|AndroidRuntime' | tail -300 + # The device's side of a failure, which the runner's report does not show, by tag, since system lines naming the package and UiDevice's polls for a title would fill the tail. + grep -q '^OK (' "$out/$variant.txt" || adb logcat -d -v time -s pushups:V FirebaseMessaging:V FirebaseApp:V \ + NotificationService:V ActivityManager:V ActivityTaskManager:V AndroidRuntime:V TestRunner:V | tail -300 adb exec-out run-as "$package" cat files/pushups.profraw > "$out/$variant.profraw" adb exec-out run-as "$package" cat files/jacoco.ec > "$out/$variant.ec" } diff --git a/ci/android/src/androidTest/kotlin/rs/pushups/ci/SingleTopTapTest.kt b/ci/android/src/androidTest/kotlin/rs/pushups/ci/SingleTopTapTest.kt index ec1dfb4..7d24e29 100644 --- a/ci/android/src/androidTest/kotlin/rs/pushups/ci/SingleTopTapTest.kt +++ b/ci/android/src/androidTest/kotlin/rs/pushups/ci/SingleTopTapTest.kt @@ -1,6 +1,7 @@ package rs.pushups.ci import android.app.Activity +import android.app.ActivityManager import android.content.Intent import androidx.test.core.app.ActivityScenario import androidx.test.ext.junit.runners.AndroidJUnit4 @@ -77,8 +78,10 @@ class SingleTopTapTest { Probe.setHandler() val id = "single-top-${UUID.randomUUID()}" val title = "pushups tap $id" - // FCM shows a notification only while the app is in the background, and the Activity stays alive there. + // FCM shows a notification only while the process's importance is below foreground, which lags the home press, and the Activity stays alive there. device.pressHome() + waitFor(UI_MS) { if (importance() != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) Unit else null } + ?: error("the app was still in the foreground ${UI_MS / 1000} s after going home") Pushes.send( context, id, @@ -107,4 +110,8 @@ class SingleTopTapTest { instrumentation.runOnMainSync { running.finish() } } } + + /** This process's importance, which FCM reads to choose between showing a push and handing it to the app. */ + private fun importance(): Int = + ActivityManager.RunningAppProcessInfo().also { ActivityManager.getMyMemoryState(it) }.importance }