firebase-perf: fix API 34+ background-start heuristic in AppStartTrac…#8202
firebase-perf: fix API 34+ background-start heuristic in AppStartTrac…#8202jrodiz wants to merge 1 commit into
Conversation
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. |
firebase#8103) Replace the timing-window heuristic in resolveIsStartedFromBackground on API 34+ with an OS-reported process start cause. Pre-API-34 keeps the legacy runnable-before-onActivityCreated check. API < 34: mainThreadRunnableTime set first ⇒ suppress (legacy, unchanged). API 34+: ProcessStartCause.cause FOREGROUND ⇒ log. UNKNOWN / null ⇒ suppress. New ProcessStartCause helper reads RunningAppProcessInfo.importance at first capture via ActivityManager.getMyMemoryState. IMPORTANCE_FOREGROUND indicates an activity-driven start; anything else maps to UNKNOWN. Pre-API-34 returns UNKNOWN and the legacy AppStartTrace logic owns the decision. FirebasePerfEarly stops scheduling StartFromBackgroundRunnable on API 34+ since its output is no longer consumed there. :firebase-perf:testReleaseUnitTest — 0 failures / 0 errors. AppStartTraceTest 9/9, ProcessStartCauseTest 6/6.
2a1360d to
3d1d730
Compare
firebase-perf: fix API 34+ background-start heuristic in AppStartTrace
Fixes #8103
(follow-up to b/339891952).
AppStartTrace's background-start detection relied on the ordering of a postedmain-thread runnable vs the first
onActivityCreated. On API 34+ the OS can drain therunnable before delivering the activity-launch Binder transaction even on a genuine
cold foreground launch, and the gap on real Pixel devices is ~200–300 ms — well above
the previous 50 ms tolerance. Every affected user lost their
_app_starttraces.Fix
Replace the timing-window heuristic in
resolveIsStartedFromBackgroundon API 34+with an OS-reported process start cause. Pre-API-34 keeps the legacy
runnable-before-
onActivityCreatedcheck.New
ProcessStartCausehelper readsRunningAppProcessInfo.importanceat firstcapture via
ActivityManager.getMyMemoryState.IMPORTANCE_FOREGROUNDindicates anactivity-driven start; anything else maps to
UNKNOWN. Pre-API-34 returnsUNKNOWNand the legacy logic owns the decision.
Captured once in
AppStartTrace.registerActivityLifecycleCallbacksand consumed bythe decision only. No new custom attributes are emitted on the
_experiment_app_start_ttidtrace.FirebasePerfEarlystops schedulingStartFromBackgroundRunnableon API 34+ sinceits output is no longer consumed there.
Behavior matrix
Tests
./gradlew :firebase-perf:spotlessApply— clean../gradlew :firebase-perf:testReleaseUnitTest— 0 failures / 0 errors.AppStartTraceTest: 9/9 —@Config(sdk = 33)regression tests for thepre-API-34 path; FOREGROUND / UNKNOWN / null-cause cases for API 34+.
ProcessStartCauseTest: 6/6 — null-context, pre-API-34, API 34 importancebranches (FOREGROUND / SERVICE / CACHED), constructor.
Files
firebase-perf/src/main/java/.../FirebasePerfEarly.javaStartFromBackgroundRunnableschedule on API 34+.firebase-perf/src/main/java/.../metrics/AppStartTrace.javaprocessStartCausefield; newresolveIsStartedFromBackgrounddecision split.firebase-perf/src/main/java/.../metrics/ProcessStartCause.javafirebase-perf/src/test/java/.../metrics/AppStartTraceTest.javafirebase-perf/src/test/java/.../metrics/ProcessStartCauseTest.javafirebase-perf/CHANGELOG.md[fixed]entry referencing #8103.Risks
importance-based signal wired in.
_app_startemission rate goes up on thepreviously-broken population, which is the intent.
RunningAppProcessInfo.importanceis a stable public-SDK field and a single BinderIPC; no reflection required.