Repository navigation
fix(replay): Do not recycle the canvas screenshot during a pixel copy - #6342
Merged
Merged
Conversation
CanvasStrategy.close() recycled the screenshot bitmap and released the surface on the background handler even when a PixelCopy request was still writing into that bitmap on the RenderThread. libhwui then aborted the process with "cannot access an invalid/free'd bitmap". Track the in-flight copy on the background handler, which runs the render task, the copy callback and the cleanup. close() skips the cleanup while a copy is in flight, and the copy callback releases the resources once it sees the strategy is closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
📲 Install BuildsAndroid
|
romtsn
marked this pull request as ready for review
October 21, 2026 11:12
romtsn
requested review from
0xadam-brown,
adinauer,
markushi and
runningcode
as code owners
October 21, 2026 11:12
markushi
approved these changes
Oct 21, 2026
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
Stopping Session Replay with the canvas screenshot strategy no longer crashes the app when a frame copy is still in progress.
CanvasStrategy.close()posted a cleanup to the background handler that recycled the screenshot bitmap and released the surface. APixelCopy.requeststarted just beforeclose()keeps writing into that bitmap on the RenderThread until its callback runs, so the cleanup could recycle the bitmap mid-copy. libhwui then aborts the process:The render task, the
PixelCopycallback and the cleanup all run on the same background handler, so a plain flag tracks the in-flight copy without extra synchronization.close()skips the cleanup while a copy is in flight, and the copy callback releases the bitmap and surface once it sees the strategy is closed. This mirrors the in-flight gatePixelCopyStrategygot in #5808;PixelCopyStrategyneeds a CAS there because its frame work spans several threads.On SDK shutdown,
WindowRecorder.close()still drops pending background work and quits that thread, so the resources may not be released then. That leak behavior is unchanged and cannot crash.💡 Motivation and Context
Found while verifying #6340 on an emulator: stopping a buffering replay with the canvas strategy aborted the RenderThread.
💚 How did you test it?
CanvasStrategyTestholds back thePixelCopyresult and checks thatclose()keeps the screenshot alive until the copy finishes, and that it still recycles right away when no copy is in flight. The first test fails without the fix.On an API 34 emulator with the sample app (canvas strategy), a stress loop ran 100 cycles of
startBuffering(), a 60–160 ms wait, thenstop():mainclose()50 times and the callback did the cleanup📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
🤖 Generated with Claude Code