Skip to content

feat(replay): allow disabling touches without stopping screenshots - #575

Draft
marandaneto wants to merge 2 commits into
mainfrom
fix/570-replay-capture-touches
Draft

feat(replay): allow disabling touches without stopping screenshots#575
marandaneto wants to merge 2 commits into
mainfrom
fix/570-replay-capture-touches

Conversation

@marandaneto

@marandaneto marandaneto commented Sep 11, 2026

Copy link
Copy Markdown
Member

💡 Motivation and Context

Closes #570.

Masking a PIN keypad hides its pixels but not its replay touch coordinates. A known keypad layout can therefore reveal the entered value.

Add sessionReplayConfig.captureTouches, enabled by default, to disable touch recording on Android and iOS while masked screenshots continue. Set it before Posthog().setup(config). Both native bridges forward the setting during initialization. There is no runtime toggle, and changing the Dart field after setup does not update native state.

Release dependencies: Keep this PR draft until PostHog/posthog-ios#823 and PostHog/posthog-android#780 are merged and released. The dependency floors target iOS 3.74.0 and Android 3.64.0. Confirm those releases contain the changes before merging. Validation used local native builds, not published versions. Normal native dependency resolution remains blocked until those releases exist.

💚 How did you test it?

  • All 343 Flutter tests pass, including setup forwarding, the enabled default, and resetting the configuration through close and fresh setup.
  • All 36 Android bridge tests pass with JDK 17.
  • Ran separate Android emulator startups with touch capture enabled and disabled using local native artifacts. Three keypad taps produced six touch events when enabled and zero when disabled. Each run sent four masked screenshots, replay remained active, and the app received all three taps.
  • Built the iOS Flutter bridge for the simulator against updated local native sources. Native regression tests also verify that disabled touch capture leaves screenshots working.
  • Dart analysis, formatting, API snapshot checks, and committed-branch autoreview pass.

📝 Checklist

  • 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

  • Added a minor changeset file.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Pi implemented and tested the Flutter and native changes in separate worktrees using Flutter, Gradle, adb, XcodeBuildMCP, a local test server, and autoreview. The implementation follows the requested initialization-only configuration. The session transcript remains local. Human review is required.

@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

posthog-flutter Compliance Report

Date: 2026-09-11 11:14:47 UTC
Duration: 96837ms

✅ All Tests Passed!

45/45 tests passed


Capture Tests

29/29 tests passed

View Details
Test Status Duration
Format Validation.Event Has Required Fields 142ms
Format Validation.Event Has Uuid 119ms
Format Validation.Event Has Lib Properties 116ms
Format Validation.Distinct Id Is String 114ms
Format Validation.Token Is Present 116ms
Format Validation.Custom Properties Preserved 116ms
Format Validation.Event Has Timestamp 116ms
Retry Behavior.Retries On 503 5328ms
Retry Behavior.Does Not Retry On 400 2118ms
Retry Behavior.Does Not Retry On 401 2117ms
Retry Behavior.Respects Retry After Header 8125ms
Retry Behavior.Implements Backoff 15448ms
Retry Behavior.Retries On 500 5225ms
Retry Behavior.Retries On 502 5225ms
Retry Behavior.Retries On 504 5226ms
Retry Behavior.Max Retries Respected 15444ms
Deduplication.Generates Unique Uuids 125ms
Deduplication.Preserves Uuid On Retry 5225ms
Deduplication.Preserves Uuid And Timestamp On Retry 10335ms
Deduplication.Preserves Uuid And Timestamp On Batch Retry 5232ms
Deduplication.No Duplicate Events In Batch 125ms
Deduplication.Different Events Have Different Uuids 117ms
Compression.Sends Gzip When Enabled 118ms
Batch Format.Uses Proper Batch Structure 115ms
Batch Format.Flush With No Events Sends Nothing 110ms
Batch Format.Multiple Events Batched Together 125ms
Error Handling.Does Not Retry On 403 2117ms
Error Handling.Does Not Retry On 413 2117ms
Error Handling.Retries On 408 5223ms

Feature_Flags Tests

16/16 tests passed

View Details
Test Status Duration
Request Payload.Request With Person Properties Device Id 13ms
Request Payload.Flags Request Uses V2 Query Param 9ms
Request Payload.Flags Request Hits Flags Path Not Decide 10ms
Request Payload.Flags Request Omits Authorization Header 9ms
Request Payload.Token In Flags Body Matches Init 10ms
Request Payload.Groups Round Trip 9ms
Request Payload.Groups Default To Empty Object 10ms
Request Payload.Person Properties Distinct Id Auto Populated When Caller Omits It 10ms
Request Payload.Disable Geoip False Propagates As Geoip Disable False 9ms
Request Payload.Disable Geoip Omitted Defaults To False 9ms
Request Payload.Flag Keys To Evaluate Contains Only Requested Key 10ms
Request Lifecycle.No Flags Request On Init Alone 4ms
Request Lifecycle.No Flags Request On Normal Capture 113ms
Request Lifecycle.Two Flag Calls Produce Two Remote Requests 15ms
Request Lifecycle.Mock Response Value Is Returned To Caller 9ms
Side Effect Events.Get Feature Flag Captures Feature Flag Called Event 116ms

@marandaneto

Copy link
Copy Markdown
Member Author

TODO: Add the same initialization-only captureTouches option to React Native after the native SDK changes are released. Default it to true and forward it during Android/iOS SDK setup so apps can disable replay touch coordinates while keeping screenshots. No runtime toggle.

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: add captureTouches flag — masking cannot protect keypad entry because tap coordinates leak the value

1 participant