[DNM] Thought experiment: Encapsulate standalone app start logic in AppStartIntegration#5488
Draft
0xadam-brown wants to merge 2 commits into
Draft
[DNM] Thought experiment: Encapsulate standalone app start logic in AppStartIntegration#54880xadam-brown wants to merge 2 commits into
0xadam-brown wants to merge 2 commits into
Conversation
Squashed representation of PR #5342. Adds standalone Android app-start transaction support behind the opt-in enableStandaloneAppStartTracing option and the io.sentry.standalone-app-start-tracing.enable manifest key, including the non-activity (headless) startup path. Legacy flag-off behavior is preserved: activity app-start data remains nested under the ui.load transaction. Refs #5342
…tReporter The standalone app-start feature was spread across ActivityLifecycleIntegration, AppStartMetrics, and PerformanceAndroidEventProcessor: ALI held the transaction field, creation branches, and the headless listener callback; AppStartMetrics acted as a trace-id mailbox; and the event processor re-derived "is this a headless standalone app start" by sniffing the presence of a span-data key. No single place owned the feature. Introduce StandaloneAppStartReporter, which owns the feature end-to-end on the post-init side of the SDK (it holds an IScopes and can start transactions): emitting the activity-launch sibling and the headless transaction, keeping the shared trace id, and classifying transactions for the event processor via isStandaloneAppStart/isHeadlessAppStart. AppStartMetrics stays a pre-init, scope-less recorder that only emits the headless signal; ALI delegates to the reporter instead of carrying the logic; the event processor asks the reporter how to classify a transaction rather than poking at its data map. Only data crosses the pre-/post-init seam, not logic. No behavior change. Net -76 lines and two fewer public methods on AppStartMetrics. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> ref(android): Consolidate headless app start scheduling to one site Scheduling of the main-thread idle check lived in two places: registerLifecycleCallbacks (gated on appStartType == UNKNOWN || listener != null) and setHeadlessAppStartListener (a side-effect gated on isCallbackRegistered && no activities yet && first draw not done). The setter's side-effect was load-bearing because the listener is installed during SDK init, after the early SentryPerformanceProvider registration, so on API 35+ with a known start type registerLifecycleCallbacks would skip scheduling and the setter had to cover it. Schedule the idle check unconditionally from the single registration site and make the setter a plain assignment. The idle handler already no-ops once an Activity exists and reads the listener when it fires (after init has installed it), so it can serve both consumers — the pre-API-35 cold/warm heuristic and standalone headless emission — without the setter needing to know about timing. The only behavior change: on API 35+ with a known type and standalone disabled, the idle check is now scheduled (previously skipped). It no-ops for foreground launches and, for a truly headless launch, correctly marks the start as background and stops app-start profilers. ref(android): Add AppStartIntegration for standalone app start Move headless standalone app-start emission out of AppStartMetrics into StandaloneAppStartReporter behind a new AppStartIntegration. Metrics keeps idle scheduling and shared boot bookkeeping; ActivityLifecycleIntegration coordinates via StandaloneAppStartCoordinator only when the feature is enabled. Refs #5342 Co-Authored-By: Cursor <cursoragent@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com> ref(android): Decouple app start from ActivityLifecycleIntegration ActivityLifecycleIntegration dispatches AppStartLifecycle callbacks instead of taking a StandaloneAppStartCoordinator. AppStartIntegration registers StandaloneAppStartReporter as the listener at init time. Refs #5342 Co-Authored-By: Cursor <cursoragent@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com> ref(android): Plan first ui.load via standalone app start listener Use UiLoadStartPlan so ActivityLifecycleIntegration starts ui.load without headless branching while StandaloneAppStartReporter owns trace reuse and sibling App Start emission. Co-Authored-By: Cursor <cursoragent@cursor.com> ref(android): Use single ui.load startTransaction path for standalone planFirstUiLoad now takes isFirstProcessStart so ActivityLifecycleIntegration always builds one TransactionContext while headless reuse stays in the reporter. Co-Authored-By: Cursor <cursoragent@cursor.com> ref(android): Rename FirstUiLoad types and narrow standalone API Rename AppStartLifecycle and AppStartLifecycleListener to FirstUiLoad and FirstUiLoadListener. Make standalone app start wiring package-private and drop those types from the public api dump. Co-Authored-By: Cursor <cursoragent@cursor.com> ref(android): Replace static FirstUiLoad with init-scoped coordinator Wire the standalone app-start listener through a FirstUiLoadCoordinator created in AndroidOptionsInitializer and shared by AppStartIntegration and ActivityLifecycleIntegration instead of a static global holder. Co-Authored-By: Auto <noreply@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📜 Description
PR's latest commit represents a halfway house between the current standalone app implementation from #5342 (== the PR's first commit) and our possible ideal of using
AppStartMetricsas a relay point for transaction-related info that must be shared betweenActivityLifecycleIntegrationand (the newly-proposed)AppStartIntegration(trace ID, start timestamp, end timestamp).See related Excalidraw: link for a comparison between #5342, this branch, and the proposed ideal. (Don't interpret its proposals as being fully baked – they're just initial sketches we'll want to fill in.)
"Draft" status is meant in earnest: I asked Codex for an implementation that treated
AppStartMetricsas an inert data holder + sequestered standalone app start logic into a newAppStartIntegration, and I got one; I haven't reviewed the details.🔮 Next steps
Decide whether we want to merge #5432 as-is, go for the halfway house, or implement the ideal.