Skip to content

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

Open
buenaflor wants to merge 3 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 3 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 2af9a1c

@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.44.1 (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 372.30 ms 460.98 ms 88.68 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
a416a65 316.52 ms 359.67 ms 43.15 ms
22ff2c7 306.60 ms 336.65 ms 30.05 ms
d15471f 310.26 ms 377.04 ms 66.78 ms
b750b96 408.98 ms 480.32 ms 71.34 ms
14ff5ee 419.75 ms 495.73 ms 75.98 ms
eb95ded 317.51 ms 369.08 ms 51.57 ms
c8125f3 383.82 ms 441.66 ms 57.84 ms
17a0955 372.53 ms 446.70 ms 74.17 ms
9d2f4e3 311.75 ms 357.80 ms 46.05 ms
ed33deb 343.30 ms 362.41 ms 19.10 ms

App size

Revision Plain With Sentry Diff
a416a65 1.58 MiB 2.12 MiB 555.26 KiB
22ff2c7 0 B 0 B 0 B
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
b750b96 1.58 MiB 2.10 MiB 533.19 KiB
14ff5ee 1.58 MiB 2.10 MiB 535.08 KiB
eb95ded 0 B 0 B 0 B
c8125f3 1.58 MiB 2.10 MiB 532.32 KiB
17a0955 1.58 MiB 2.10 MiB 533.20 KiB
9d2f4e3 0 B 0 B 0 B
ed33deb 1.58 MiB 2.13 MiB 559.52 KiB

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

Startup times

Revision Plain With Sentry Diff
3280187 343.87 ms 460.46 ms 116.59 ms
1b43bc2 317.36 ms 346.88 ms 29.52 ms

App size

Revision Plain With Sentry Diff
3280187 0 B 0 B 0 B
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 Outdated

@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!

@buenaflor

Copy link
Copy Markdown
Contributor Author

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

Ah yeah, the mapping itself is covered in AppStartMetricsTestApi35, so these activity integration tests are really just checking the wiring that the reason ends up on the standalone app.start transaction under the right key, for both the foreground and headless paths

Address review feedback to mention that customers can search and group
by the app.vitals.start.reason attribute.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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