Skip to content

fix(android): Drop inflated app start for background-spawned processes on API 35+ - #5841

Draft
alwx wants to merge 3 commits into
mainfrom
alwx/fix/appstart-background-spawn
Draft

fix(android): Drop inflated app start for background-spawned processes on API 35+#5841
alwx wants to merge 3 commits into
mainfrom
alwx/fix/appstart-background-spawn

Conversation

@alwx

@alwx alwx commented Jul 27, 2026

Copy link
Copy Markdown

📜 Description

On API 35+, use ApplicationStartInfo.getReason() to detect processes the OS spawned for background work (FCM push, job, service, broadcast, alarm, backup, boot_complete, content_provider) and mark them as not launched in foreground. The first created activity then re-classifies the launch as a warm start re-anchored at activity creation, instead of reporting the whole background idle gap as an inflated cold start.

Change is confined to AppStartMetrics.registerLifecycleCallbacks + a small private isBackgroundStartReason(int) helper. Unknown/future reasons are treated as user-initiated (no regression). Behavior for user launches (launcher/recents/start_activity) and pre-API-35 is unchanged.

💡 Motivation and Context

When a process is spawned in the background (e.g. by an FCM push) and the user opens the app seconds later, appLaunchedInForeground was only evaluated lazily and the app start span stayed anchored at background process creation. On API 35+ the main-looper idle check that would otherwise mark the launch as headless is skipped once the start type is resolved from ApplicationStartInfo, so the inflated cold start (idle gap up to ~1 min) leaked through into app_start_cold.

Reported downstream in React Native:

Related prior work on app start (mis)classification: #3608, #4920, #4999.

💚 How did you test it?

Added Robolectric tests in AppStartMetricsTestApi35:

  • background reason (push) marks the launch as not-in-foreground;
  • all background reasons (alarm/backup/boot_complete/broadcast/content_provider/job/push/service) do the same;
  • a user-initiated reason (launcher) keeps it in foreground;
  • a background-spawned start is re-classified as WARM and re-anchored at activity creation on the first onActivityCreated (even for a sub-1-minute gap).

./gradlew :sentry-android-core:testReleaseUnitTest --tests "*AppStartMetrics*" and spotlessCheck pass.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • No breaking change or entry added to the changelog.

🔮 Next steps

Follow-up: API < 35 has no reliable process start reason, so a narrow race in the main-looper idle check remains there; not addressed here.

…s on API 35+

When the OS spawns the process for background work (FCM push, job, service,
broadcast, etc.) and the user opens the app later, the app start stayed anchored
at background process creation, inflating the reported cold start by the whole
idle gap.

On API 35+ we now use ApplicationStartInfo.getReason() to detect background
process starts and mark them as not launched in foreground, so the first created
activity re-classifies them as a warm start anchored at activity creation.
@linear-code

linear-code Bot commented Jul 27, 2026

Copy link
Copy Markdown

RN-695

@sentry

sentry Bot commented Jul 27, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.50.0 (1) release

⚙️ sentry-android Build Distribution Settings

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.

Android: app_start_cold is inflated when the process is background-spawned (FCM) before the user opens the app

1 participant