Skip to content

fix(replay): Keep replay recording during animations#5489

Open
romtsn wants to merge 5 commits into
mainfrom
rz/fix/replay-continuous-animations
Open

fix(replay): Keep replay recording during animations#5489
romtsn wants to merge 5 commits into
mainfrom
rz/fix/replay-continuous-animations

Conversation

@romtsn
Copy link
Copy Markdown
Member

@romtsn romtsn commented Jun 1, 2026

📜 Description

Update Session Replay's PixelCopy strategy so continuously invalidating screens do not freeze after the first unstable capture. The strategy now skips only the first unstable PixelCopy/view-hierarchy pair, then resumes emitting frames while the screen keeps drawing.

Add Android sample screens for Lottie, Compose canvas, and classic View animations so the behavior can be tested manually in the sample app. The sample app remains configured to use the Canvas replay screenshot strategy.

💡 Motivation and Context

Continuous animations can cause PixelCopy output and the view hierarchy snapshot to be taken from slightly different moments. The previous debounce treated this as persistent instability and stopped emitting updated frames, which made replay visuals freeze on animated screens.

Fixes #5404

💚 How did you test it?

./gradlew :sentry-android-replay:testDebugUnitTest --tests io.sentry.android.replay.screenshot.PixelCopyStrategyTest
./gradlew spotlessApply apiDump
./gradlew :sentry-samples:sentry-samples-android:installDebug

Example replay: https://sentry-sdks.sentry.io/explore/replays/e6d4d1d93cff44cead71d10ba9d54c59/?t=9

📝 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

romtsn and others added 3 commits June 1, 2026 23:32
Skip only the first unstable PixelCopy capture, then continue emitting frames while the screen keeps invalidating. This prevents animated screens from freezing Session Replay visuals while preserving the existing debounce for one-off redraws.

Fixes GH-5404

Co-Authored-By: Codex <noreply@openai.com>
Add separate Android sample screens for Lottie, Compose canvas, and classic View animations so replay capture behavior can be tested manually.

Keep the sample app on the Canvas replay screenshot strategy while exercising these animations.

Refs GH-5404

Co-Authored-By: Codex <noreply@openai.com>
@romtsn romtsn force-pushed the rz/fix/replay-continuous-animations branch from e5fa288 to 05247b6 Compare June 1, 2026 21:33
@sentry
Copy link
Copy Markdown

sentry Bot commented Jun 1, 2026

📲 Install Builds

Android

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

⚙️ sentry-android Build Distribution Settings

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 322.27 ms 406.35 ms 84.08 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
62b579c 318.48 ms 367.71 ms 49.24 ms
b6702b0 395.86 ms 409.98 ms 14.12 ms
f064536 327.04 ms 405.35 ms 78.31 ms
6b019b7 403.90 ms 546.09 ms 142.19 ms
2195398 344.65 ms 403.96 ms 59.30 ms
ce0a49e 532.00 ms 609.96 ms 77.96 ms
27d7cf8 306.76 ms 366.66 ms 59.90 ms
22f4345 307.87 ms 354.51 ms 46.64 ms
ad8da22 314.52 ms 352.47 ms 37.95 ms
e59e22a 374.68 ms 442.14 ms 67.46 ms

App size

Revision Plain With Sentry Diff
62b579c 0 B 0 B 0 B
b6702b0 1.58 MiB 2.12 MiB 551.79 KiB
f064536 1.58 MiB 2.20 MiB 633.90 KiB
6b019b7 0 B 0 B 0 B
2195398 0 B 0 B 0 B
ce0a49e 1.58 MiB 2.10 MiB 532.94 KiB
27d7cf8 1.58 MiB 2.12 MiB 549.42 KiB
22f4345 1.58 MiB 2.29 MiB 719.83 KiB
ad8da22 1.58 MiB 2.29 MiB 719.83 KiB
e59e22a 1.58 MiB 2.20 MiB 635.34 KiB

Previous results on branch: rz/fix/replay-continuous-animations

Startup times

Revision Plain With Sentry Diff
afd2573 317.70 ms 348.36 ms 30.66 ms
1f03091 314.69 ms 369.52 ms 54.83 ms

App size

Revision Plain With Sentry Diff
afd2573 0 B 0 B 0 B
1f03091 0 B 0 B 0 B

Use ContextCompat.getColor in ReplayAnimationsActivity so release lint passes with the sample app minSdk.

Refs GH-5489

Co-Authored-By: Codex <noreply@openai.com>
@romtsn romtsn changed the title fix(android): Keep replay capturing during animations fix(replay): Keep recording capturing during animations Jun 2, 2026
@romtsn romtsn changed the title fix(replay): Keep recording capturing during animations fix(replay): Keep replay recording during animations Jun 2, 2026
) : ScreenshotStrategy {

private companion object {
const val MAX_UNSTABLE_CAPTURES_TO_SKIP = 1
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

could've been a boolean, but I decided that a counter is more natural and we may want to increase it in the future if we see problems with this

@romtsn romtsn marked this pull request as ready for review June 2, 2026 08:23
Copy link
Copy Markdown
Member

@0xadam-brown 0xadam-brown left a comment

Choose a reason for hiding this comment

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

Implementation looks good.

Any concerns about masking slips during animation?

Nicely, I see our docs flag the possibility:

This strategy has slightly lower performance overhead but may result in masking misalignments due to the asynchronous nature of the PixelCopy API. We recommend using this strategy for apps that do not have strict PII requirements or do not require masking functionality.

Not sure if we want the extra security, but we could also consider:

  1. increasing the mask size when recording unstable captures, or
  2. covering the view's entire range of possible positions during the unstable window, ie, the union of where it was (in the pixels, time T) and where the hierarchy thinks it is (T+delta).

Up to you.

Document why PixelCopyStrategy caps skipped unstable captures so continuous animations keep producing replay frames.

Refs GH-5489

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Session Replay: Continuous animations prevent screenshot capture

2 participants