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 posted main-thread runnable vs the firstonActivityCreated. On API 34+ the OS can drain the runnable 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 first capture viaActivityManager.getMyMemoryState.IMPORTANCE_FOREGROUNDindicates an activity-driven start; anything else maps toUNKNOWN. Pre-API-34 returnsUNKNOWNand the legacy logic owns the decision.Captured once in
AppStartTrace.registerActivityLifecycleCallbacksand consumed by the decision only. No new custom attributes are emitted on the_experiment_app_start_ttidtrace.FirebasePerfEarlystops schedulingStartFromBackgroundRunnableon API 34+ since its 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 the pre-API-34 path; FOREGROUND / UNKNOWN / null-cause cases for API 34+.ProcessStartCauseTest: 6/6 — null-context, pre-API-34, API 34 importance branches (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.