feat(replay): Add manual replay control API - #5978
Open
romtsn wants to merge 15 commits into
Open
Conversation
Contributor
|
📲 Install BuildsAndroid
|
Contributor
Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| a21e537 | 319.04 ms | 357.04 ms | 38.00 ms |
| 5cdb0b8 | 311.75 ms | 369.08 ms | 57.33 ms |
| b208705 | 315.54 ms | 354.54 ms | 39.00 ms |
| f158a9a | 352.96 ms | 413.17 ms | 60.21 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| a21e537 | 0 B | 0 B | 0 B |
| 5cdb0b8 | 0 B | 0 B | 0 B |
| b208705 | 0 B | 0 B | 0 B |
| f158a9a | 0 B | 0 B | 0 B |
6 tasks
romtsn
marked this pull request as ready for review
August 19, 2026 16:24
romtsn
requested review from
0xadam-brown,
adinauer,
markushi and
runningcode
as code owners
August 19, 2026 16:24
runningcode
reviewed
Aug 20, 2026
runningcode
left a comment
Contributor
There was a problem hiding this comment.
I did a first pass quick review, ping me for a second round.
runningcode
reviewed
Aug 24, 2026
runningcode
left a comment
Contributor
There was a problem hiding this comment.
looks good. I still think the start and startBuffering methods are confusing. Not sure if better javadocs would be less confusing. I understand that it is that way to align with js.
Base automatically changed from
romtsn/feat/java-665-replay-start-stop
to
main
August 24, 2026 18:55
Expose start, buffering, pause, resume, stop, and flush operations through Sentry.replay(). Keep lifecycle pauses distinct from explicit user pauses. Foregrounding therefore does not resume sensitive-screen recording unexpectedly. Refs JAVA-325 Co-Authored-By: OpenAI Codex <noreply@openai.com>
A foreground callback can run before ReplayIntegration registers and initializes its options. Ignore lifecycle callbacks until the integration is enabled to avoid crashing during SDK initialization. Refs JAVA-325 Co-Authored-By: Codex <noreply@openai.com>
Track whether a buffered replay was started automatically so only automatic buffers apply per-error sampling. Manually started buffers now capture on errors as documented. Refs JAVA-325 Co-Authored-By: Codex <noreply@openai.com>
This reverts commit 8073208. Reason: Match Sentry JavaScript by applying onErrorSampleRate to all buffered replay captures. Refs JAVA-325 Co-Authored-By: Codex <noreply@openai.com>
Drop foreground and background callbacks received before Replay is registered instead of leaving stale work on the main queue. Clarify the manual replay API documentation. Refs JAVA-325 Co-Authored-By: Codex <noreply@openai.com>
Check Replay registration when the foreground callback executes so AppState catch-up can start Replay after registration. Cover both callback orderings with tests. Refs JAVA-325 Co-Authored-By: Codex <noreply@openai.com>
Expose each manual Session Replay operation on the Android sample replay screen for interactive testing and demonstration. Refs JAVA-325 Co-Authored-By: Codex <noreply@openai.com>
romtsn
force-pushed
the
romtsn/feat/java-325-replay-control-api
branch
from
August 26, 2026 12:24
20d793b to
716ddfb
Compare
Make explicit replay flushes send the current segment in both capture modes. Restart automatic replay recording when a new app session begins, and document how flush differs from event-triggered capture. Refs JAVA-325 Co-Authored-By: OpenAI Codex <noreply@openai.com>
Read session timeline state on the replay executor so queued natural segment boundaries cannot make an explicit flush stale. Document and test that a new app session replaces a manually paused replay. Refs JAVA-325 Co-Authored-By: Codex <noreply@openai.com>
Keep the invocation timestamp when queuing segment work so executor delays do not extend replay segments. Continue reading the mutable segment cursor on the replay executor to avoid stale boundaries. Refs JAVA-325 Co-Authored-By: Codex <noreply@openai.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ff3b7ae. Configure here.
Keep an explicit replay pause when automatic app-session rollover replaces the active replay. Require resume before the replacement replay records, and document the process-local lifetime. Refs JAVA-325 Co-Authored-By: Codex <noreply@openai.com>
Serialize resume timeline updates behind queued replay work and use frame capture timestamps for session boundaries and deadlines. This prevents pause/resume races and stops executor backlog from counting as recorded time. Co-Authored-By: OpenAI Codex <noreply@openai.com>
Keep pause state while a replacement replay waits for its first recorder configuration. This prevents a newly created capturer from recording before the user explicitly resumes. Refs JAVA-325 Co-Authored-By: OpenAI Codex <noreply@openai.com>
Route lifecycle-driven replay shutdown through a dedicated internal callback so it keeps an explicit user pause. Public stop still clears the pause state. Replace the recorder-level workaround with a regression test covering timeout, foreground, and explicit resume. Refs JAVA-325 Co-Authored-By: Codex <noreply@openai.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.

Depends on #5965.
📜 Description
Add
Sentry.replay()controls for starting full-session or buffered recording, stopping, pausing, resuming, and flushing.Lifecycle-driven background pauses remain separate from explicit user pauses. Foregrounding resumes only lifecycle-paused recording; an explicit pause remains active across automatic replay restarts in the same process until
resume()is called. Starting an already-running replay is a no-op; flushing a stopped replay starts a full session, matching the JavaScript SDK. Explicit starts bypass replay sample rates, which continue to control automatic startup.💡 Motivation and Context
Give Android applications explicit control over Session Replay for opt-in flows and sensitive screens while preserving automatic lifecycle behavior.
Refs JAVA-325
💚 How did you test it?
./gradlew spotlessApply apiDump.sentry-android-coreunit tests: 1,601 tests, 0 failures, 1 skipped.sentry-android-replayunit tests successfully.📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps