Skip to content

firebase-perf: fix API 34+ background-start heuristic in AppStartTrac…#8202

Open
jrodiz wants to merge 1 commit into
firebase:mainfrom
jrodiz:feature/jrc--8103.Fix.API.34.heuristic
Open

firebase-perf: fix API 34+ background-start heuristic in AppStartTrac…#8202
jrodiz wants to merge 1 commit into
firebase:mainfrom
jrodiz:feature/jrc--8103.Fix.API.34.heuristic

Conversation

@jrodiz
Copy link
Copy Markdown
Contributor

@jrodiz jrodiz commented May 22, 2026

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 first onActivityCreated. 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_start traces.

Fix

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: legacy mainThreadRunnableTime check (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 logic owns the decision.

Captured once in AppStartTrace.registerActivityLifecycleCallbacks and consumed by
the decision only. No new custom attributes are emitted on the
_experiment_app_start_ttid trace.

FirebasePerfEarly stops scheduling StartFromBackgroundRunnable on API 34+ since
its output is no longer consumed there.

Behavior matrix

Scenario API <34 API 34+
Foreground launcher tap log (unchanged) log via FOREGROUND cause
Background broadcast (no activity) n/a n/a
Warm start (broadcast → activity) suppress (unchanged) suppress via UNKNOWN cause

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

File Change
firebase-perf/src/main/java/.../FirebasePerfEarly.java Skip StartFromBackgroundRunnable schedule on API 34+.
firebase-perf/src/main/java/.../metrics/AppStartTrace.java New processStartCause field; new resolveIsStartedFromBackground decision split.
firebase-perf/src/main/java/.../metrics/ProcessStartCause.java New file. Importance-only capture, ~100 lines.
firebase-perf/src/test/java/.../metrics/AppStartTraceTest.java New per-API regression and causal-signal tests.
firebase-perf/src/test/java/.../metrics/ProcessStartCauseTest.java New file.
firebase-perf/CHANGELOG.md [fixed] entry referencing #8103.

Risks

  • Behavior change on API 34+ for every app: timing-window heuristic gone,
    importance-based signal wired in. _app_start emission rate goes up on the
    previously-broken population, which is the intent.
  • RunningAppProcessInfo.importance is a stable public-SDK field and a single Binder
    IPC; no reflection required.
  • Pre-API-34 path untouched.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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.
@jrodiz jrodiz force-pushed the feature/jrc--8103.Fix.API.34.heuristic branch from 2a1360d to 3d1d730 Compare May 22, 2026 03:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[firebase-perf] _app_start suppressed on API >=34 for large apps — 50ms MAX_BACKGROUND_RUNNABLE_DELAY threshold insufficient (b/339891952 follow-up)

1 participant