Repository navigation
fix(replay): honour FLAG_SECURE in wireframe mode - #912
Conversation
… their touches in all modes
…eframe # Conflicts: # posthog-android/src/main/java/com/posthog/android/replay/PostHogReplayIntegration.kt
There was a problem hiding this comment.
PostHog Review · Standard · reviewed 503c82d: 1 Must fix.
See this review and its findings in PostHog Review. Comment @posthog review --deep for a Deep review. A Deep review takes longer and looks deeper than a Standard review.
| } else if (window.isSecure()) { | ||
| view.toSecureWireframe() ?: return false | ||
| } else { | ||
| view.toWireframe() ?: return false |
There was a problem hiding this comment.
P1 · Recheck FLAG_SECURE after the wireframe traversal
When the UI thread sets FLAG_SECURE and shows sensitive content while toWireframe() walks the tree on the replay executor, this check has already passed. generateSnapshot() then uploads the collected children and text without rechecking the flag, unlike the screenshot path. Recheck after traversal and discard or replace the frame when secure.
marandaneto
left a comment
There was a problem hiding this comment.
The code looks good; no qualifying findings. Verdict: correct.
…able masked views (#910) * fix(replay): discard legacy frames with an unplaceable masked view * fix(replay): record FLAG_SECURE windows as a fully masked screenshot * fix(replay): read FLAG_SECURE null-safely and cover reused bitmaps and nested masked views * test(replay): cover plain masked text in the legacy transient-state discard * fix(replay): drop touches on FLAG_SECURE windows in screenshot mode Also splits the legacy discard log so a transient-state discard says why, documents the FLAG_SECURE behaviour on the screenshot option, and points the duplicated mask rules at each other. * fix(replay): mask the frame when a window turns secure during the copy * fix(replay): guard the touch interceptor map and test secure touches through the window * test(replay): register the secure-touch test's window through mocked Curtains roots * refactor(replay): share one mask classifier between the mask walk and the discard check (#913) * refactor(replay): share one mask classifier between the mask walk and the discard check * test(replay): cover Compose and hidden children in the mask classifier parity test Drops the refactor changeset: an internal refactor has no user-facing changelog entry. --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> * fix(replay): honour FLAG_SECURE in wireframe mode (#912) * fix(replay): record FLAG_SECURE windows as a black wireframe and drop their touches in all modes * fix(replay): mask the wireframe when a window turns secure during the walk * test(replay): cover the wireframe secure check before the walk * fix(replay): treat no-capture descendants as maskable in the discard check Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Note
Stacked on #910. Merges into
fix/replay-flag-secure.💡 Motivation and Context
#910 makes screenshot mode honour
FLAG_SECURE. Wireframe mode, the 3.x default, still recorded secure windows: their full view tree, unmasked text, and taps. This applies the same decision there.FLAG_SECUREwindow is recorded as one black rectangle the size of the window, with no child views, text or images. The flag is checked before the view tree is walked and again before the frame is recorded, so a window that turns secure mid-walk is masked too (same rule as fix(replay): mask FLAG_SECURE windows and discard frames with unplaceable masked views #910's post-copy check).FLAG_SECUREwindows are no longer recorded in any mode. fix(replay): mask FLAG_SECURE windows and discard frames with unplaceable masked views #910 did this for screenshot mode only.Behaviour change (patch): apps using the default wireframe mode now see secure screens as solid black frames in recordings, without taps.
💚 How did you test it?
a secure window is recorded as one black wireframe in wireframe mode: a secure window with a text child produces a single black root wireframe with no children or text.a window that turns secure during the wireframe walk is recorded as one black wireframe.a touch on a secure window is not recorded: now runs in wireframe mode; touches are recorded before the flag is set and dropped after, and the app still receives them../gradlew spotlessCheck apiCheck :posthog-android:testDebugUnitTestpasses.📝 Checklist
If releasing new changes
pnpm changesetto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
🤖 Generated with Claude Code