Skip to content

fix(replay): honour FLAG_SECURE in wireframe mode - #912

Merged
turnipdabeets merged 5 commits into
fix/replay-flag-securefrom
fix/replay-flag-secure-wireframe
Oct 30, 2026
Merged

turnipdabeets merged 5 commits into
fix/replay-flag-securefrom
fix/replay-flag-secure-wireframe

Conversation

@turnipdabeets

@turnipdabeets turnipdabeets commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

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.

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.
  • Each fails without its fix and passes here.
  • ./gradlew spotlessCheck apiCheck :posthog-android:testDebugUnitTest passes.
  • Not tested on a device.

📝 Checklist

  • All commits are signed (see Commit signing)
  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Ran pnpm changeset to generate a changeset file

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

  • Claude Code. The maintainer asked for wireframe mode to follow fix(replay): mask FLAG_SECURE windows and discard frames with unplaceable masked views #910's decision (record secure windows fully masked) and for the touch drop to cover all modes.
  • A black root wireframe mirrors the screenshot path's solid black frame and keeps the window's id, so toggling the flag shows up as the root update plus removal of its children.
  • A self-run pre-PR review pass found nothing material; independent review still to run.

🤖 Generated with Claude Code

…eframe

# Conflicts:
#	posthog-android/src/main/java/com/posthog/android/replay/PostHogReplayIntegration.kt

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

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.

Comment on lines 814 to 817
} else if (window.isSecure()) {
view.toSecureWireframe() ?: return false
} else {
view.toWireframe() ?: return false

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.

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 marandaneto left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The code looks good; no qualifying findings. Verdict: correct.

@turnipdabeets
turnipdabeets merged commit fd1d137 into fix/replay-flag-secure Oct 30, 2026
11 checks passed
@turnipdabeets
turnipdabeets deleted the fix/replay-flag-secure-wireframe branch October 30, 2026 15:30
turnipdabeets added a commit that referenced this pull request Oct 30, 2026
…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>
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.

2 participants