Skip to content

feat(replay): Add manual replay control API - #5978

Open
romtsn wants to merge 15 commits into
mainfrom
romtsn/feat/java-325-replay-control-api
Open

feat(replay): Add manual replay control API#5978
romtsn wants to merge 15 commits into
mainfrom
romtsn/feat/java-325-replay-control-api

Conversation

@romtsn

@romtsn romtsn commented Aug 19, 2026

Copy link
Copy Markdown
Member

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?

  • Ran ./gradlew spotlessApply apiDump.
  • Ran all sentry-android-core unit tests: 1,601 tests, 0 failures, 1 skipped.
  • Ran all sentry-android-replay unit tests successfully.
  • Added focused coverage for the public API, manual pause behavior, buffering, flushing, and lifecycle transitions.

📝 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.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

@linear-code

linear-code Bot commented Aug 19, 2026

Copy link
Copy Markdown

JAVA-325

@github-actions

github-actions Bot commented Aug 19, 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 c8c7801

@sentry

sentry Bot commented Aug 19, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

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

⚙️ sentry-android Build Distribution Settings

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 315.47 ms 382.74 ms 67.27 ms
Size 0 B 0 B 0 B

Baseline results on branch: romtsn/feat/java-665-replay-start-stop

Startup times

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

Previous results on branch: romtsn/feat/java-325-replay-control-api

Startup times

Revision Plain With Sentry Diff
a12ad59 311.45 ms 364.02 ms 52.57 ms
dbf03ab 319.24 ms 369.88 ms 50.63 ms

App size

Revision Plain With Sentry Diff
a12ad59 0 B 0 B 0 B
dbf03ab 0 B 0 B 0 B

@romtsn
romtsn marked this pull request as ready for review August 19, 2026 16:24
@romtsn romtsn added the deep-dive PR needs a thorough review of design, behavior, and edge cases label Aug 19, 2026

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

I did a first pass quick review, ping me for a second round.

Comment thread sentry/src/main/java/io/sentry/IReplayApi.java
Comment thread sentry/src/main/java/io/sentry/IReplayApi.java Outdated
Comment thread sentry-android-replay/src/main/java/io/sentry/android/replay/ReplayIntegration.kt Outdated

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

Comment thread sentry/src/main/java/io/sentry/IReplayApi.java

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

lgtm!

Base automatically changed from romtsn/feat/java-665-replay-start-stop to main August 24, 2026 18:55
romtsn and others added 8 commits August 26, 2026 14:14
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
romtsn force-pushed the romtsn/feat/java-325-replay-control-api branch from 20d793b to 716ddfb Compare August 26, 2026 12:24
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>

@cursor cursor Bot 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ 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.

romtsn and others added 4 commits August 26, 2026 19:00
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deep-dive PR needs a thorough review of design, behavior, and edge cases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants