Skip to content

feat(android): Report app start reason on standalone app start transaction#5552

Open
buenaflor wants to merge 2 commits into
mainfrom
feat/android-app-start-reason
Open

feat(android): Report app start reason on standalone app start transaction#5552
buenaflor wants to merge 2 commits into
mainfrom
feat/android-app-start-reason

Conversation

@buenaflor

@buenaflor buenaflor commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

📜 Description

Reports why the OS started the process on the standalone app start transaction, using ApplicationStartInfo.getReason() (Android 15 / API 35+).

  • Adds AppStartMetrics.getAppStartReason(), which maps the already-cached ApplicationStartInfo reason to a stable lowercase string (launcher, launcher_recents, start_activity, broadcast, service, content_provider, job, alarm, push, backup, boot_complete, other). Returns null on API < 35, when no start info was resolved, or for an unmapped value.
  • Attaches it as app.vitals.start.reason trace data on the standalone app.start transaction in both paths: foreground/activity (onActivityCreated) and headless/non-activity (onHeadlessAppStart).
  • Also registers a StandaloneAppStart marker in the SDK metadata integrations when the feature is enabled (internal only, no changelog) so we can tell from events that standalone app start tracing was active.

Only standalone app start transactions are affected; this rides the existing enableStandaloneAppStartTracing opt-in and adds no new option.

💡 Motivation and Context

Builds on standalone app start tracing (#5342). The reason is a high-value dimension for standalone starts: it distinguishes a real user launch (launcher / start_activity) from headless starts (broadcast, service, content_provider, job, …) — exactly the disambiguation the headless app start path was built for. The reason (why the process started) is orthogonal to cold/warm (getStartType()), so both are reported.

ApplicationStartInfo is already cached in AppStartMetrics from the standalone work, so this only reads one additional field (getReason()) off the same object — no extra system calls.

💚 How did you test it?

Unit tests in sentry-android-core:

  • AppStartMetricsTestApi35: reason → string mapping (API 35), null when no start info, null for an unmapped reason value.
  • ActivityLifecycleIntegrationTest: app.vitals.start.reason present on the foreground standalone transaction (API 35), absent when unavailable, and present on the headless standalone transaction.

Note: the headless-vs-foreground detection in PerformanceAndroidEventProcessor keys off the absence of app.vitals.start.screen; the new distinct app.vitals.start.reason key does not affect it (existing tests still 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.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

  • Confirm with the product/spec side whether the reason should also be exposed as a queryable tag (in addition to span data), and lock in the exact string values dashboards/alerts will rely on.

@buenaflor buenaflor force-pushed the feat/android-app-start-reason branch from d39e93a to 73d05fc Compare June 16, 2026 16:51
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 0b0dd48

@sentry

sentry Bot commented Jun 16, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

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

⚙️ sentry-android Build Distribution Settings

@buenaflor buenaflor marked this pull request as ready for review June 16, 2026 17:07
Copilot AI review requested due to automatic review settings June 16, 2026 17:07
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 343.87 ms 460.46 ms 116.59 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
a416a65 295.53 ms 373.74 ms 78.21 ms
d15471f 307.28 ms 381.85 ms 74.57 ms
4c04bb8 350.71 ms 413.63 ms 62.92 ms
9e60aca 316.18 ms 345.04 ms 28.86 ms
2124a46 319.19 ms 415.04 ms 95.85 ms
46b442b 321.41 ms 339.30 ms 17.89 ms
b193867 331.08 ms 397.06 ms 65.98 ms
b6702b0 395.86 ms 409.98 ms 14.12 ms
ed33deb 312.34 ms 369.71 ms 57.37 ms
cf708bd 434.73 ms 502.96 ms 68.22 ms

App size

Revision Plain With Sentry Diff
a416a65 1.58 MiB 2.12 MiB 555.26 KiB
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
4c04bb8 0 B 0 B 0 B
9e60aca 0 B 0 B 0 B
2124a46 1.58 MiB 2.12 MiB 551.51 KiB
46b442b 0 B 0 B 0 B
b193867 1.58 MiB 2.19 MiB 620.00 KiB
b6702b0 1.58 MiB 2.12 MiB 551.79 KiB
ed33deb 1.58 MiB 2.13 MiB 559.52 KiB
cf708bd 1.58 MiB 2.11 MiB 539.71 KiB

Previous results on branch: feat/android-app-start-reason

Startup times

Revision Plain With Sentry Diff
1b43bc2 317.36 ms 346.88 ms 29.52 ms

App size

Revision Plain With Sentry Diff
1b43bc2 0 B 0 B 0 B

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Android 15+ (API 35) enrichment to standalone app start tracing by attaching a stable, low-cardinality process start “reason” derived from ApplicationStartInfo.getReason() as trace data on the standalone app.start transaction.

Changes:

  • Add AppStartMetrics.getAppStartReason() to map ApplicationStartInfo start reasons to stable lowercase strings (or null when unavailable/unmapped).
  • Attach app.start.reason to the standalone app.start transaction for both foreground (onActivityCreated) and headless (onHeadlessAppStart) standalone paths.
  • Add/extend unit tests to cover mapping behavior and verify trace data presence/absence on standalone transactions.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
sentry-android-core/src/main/java/io/sentry/android/core/performance/AppStartMetrics.java Adds getAppStartReason() mapping logic and a test-only setter for cached ApplicationStartInfo.
sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java Writes app.start.reason trace data onto standalone app.start transactions in both foreground and headless flows.
sentry-android-core/src/test/java/io/sentry/android/core/performance/AppStartMetricsTestApi35.kt Adds API 35 tests for reason→string mapping and null cases.
sentry-android-core/src/test/java/io/sentry/android/core/ActivityLifecycleIntegrationTest.kt Adds tests asserting app.start.reason is present/absent on standalone transactions (foreground and headless).
sentry-android-core/api/sentry-android-core.api Updates API dump for the new AppStartMetrics methods.
CHANGELOG.md Documents the new app.start.reason data on API 35+ for standalone app start transactions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…ction

Read ApplicationStartInfo.getReason() (API 35+) and attach it as
app.start.reason trace data on the standalone app.start transaction
in both the foreground and headless paths.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@buenaflor buenaflor force-pushed the feat/android-app-start-reason branch from 73d05fc to 2823497 Compare June 16, 2026 17:54
Advertise that standalone app start tracing is active by adding a
StandaloneAppStart marker to the SDK metadata integrations when the
feature is enabled. Internal SDK metadata only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@buenaflor buenaflor force-pushed the feat/android-app-start-reason branch from 990e4c6 to 0b0dd48 Compare June 16, 2026 18:17

if (performanceEnabled && this.options.isEnableStandaloneAppStartTracing()) {
AppStartMetrics.getInstance().setHeadlessAppStartListener(this::onHeadlessAppStart);
addIntegrationToSdkVersion("StandaloneAppStart");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needed for tracking in looker

@runningcode runningcode left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! I feel a bit mixed about the added ActivityLifecycleIntegrationTest.kt since we're just setting the value and then getting it.

Comment thread CHANGELOG.md
- Emits a transaction named `App Start` with op `app.start`, carrying the existing app start measurements and phase spans (`process.load`, `contentprovider.load`, `application.load`, activity lifecycle spans) as direct children of the root
- The standalone transaction shares the same `traceId` as the first `ui.load` activity transaction so they remain linked in the trace view
- Also covers non-activity starts (broadcast receivers, services, content providers)
- On Android 15+ (API 35), the standalone transaction reports why the OS started the process via `app.vitals.start.reason` trace data (e.g. `launcher`, `broadcast`, `service`, `content_provider`), derived from `ApplicationStartInfo.getReason()` ([#5552](https://github.com/getsentry/sentry-java/pull/5552))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe worth mentioning that customers can search/group by this property in trace viewer? (they can, right?)

@romtsn romtsn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dope!

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.

4 participants