Skip to content

Fix RecorderWindowCallback crash on null menu parameter#3221

Closed
nguyexua wants to merge 2 commits into
developfrom
lan.nguyen/fix-recorder-window-callback-null-menu-crash
Closed

Fix RecorderWindowCallback crash on null menu parameter#3221
nguyexua wants to merge 2 commits into
developfrom
lan.nguyen/fix-recorder-window-callback-null-menu-crash

Conversation

@nguyexua

@nguyexua nguyexua commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Introduces a FixedWindowCallback Java wrapper in Session Replay that annotates nullable parameters correctly, preventing Kotlin's non-null assertions from crashing when Android passes null values to Window.Callback methods. RecorderWindowCallback now extends FixedWindowCallback instead of using Kotlin's by delegation.

Also simplifies AppStartupActivityPredicateTest by removing unnecessary synchronization logic.

Motivation

A customer reported a crash (NullPointerException: Parameter specified as non-null is null: method RecorderWindowCallback.onMenuOpened, parameter p1) when opening a custom popup menu.

RecorderWindowCallback previously used Kotlin's by wrappedCallback delegation for Window.Callback. Kotlin generates non-null assertions for all parameters, but Android can call these methods with null values (known Android bug: https://issuetracker.google.com/issues/188568911). The previous fix only handled dispatchTouchEvent with a try-catch, but the same issue affected all menu-related callbacks.

Changes

Fix RecorderWindowCallback crash on null menu parameter

  • New FixedWindowCallback.java: A Java Window.Callback wrapper that annotates parameters as @Nullable where Android may pass null (e.g., Menu, MenuItem, MotionEvent). For null menu/item parameters, methods return safe defaults (false or no-op) instead of forwarding to the delegate.
  • Refactored RecorderWindowCallback: Now extends FixedWindowCallback instead of using by wrappedCallback delegation. This eliminates the need for the try-catch workaround in dispatchTouchEvent and the logOrRethrowWrappedCallbackException helper.
  • Updated WindowCallbackInterceptor: Uses .delegate (from FixedWindowCallback) instead of .wrappedCallback to unwrap callbacks.
  • Updated tests: Added tests for menu callback delegation (onMenuOpened, onMenuItemSelected, onPanelClosed, onPreparePanel, onCreatePanelMenu) and null-parameter handling. Removed obsolete try-catch tests.

Simplify AppStartupActivityPredicateTest synchronization

  • Removed CountDownLatch-based synchronization and lifecycle callback registration, relying on waitForIdleSync() instead.

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests (unit, integration, e2e)
  • Make sure you discussed the feature or bugfix with the maintaining team in an Issue
  • Make sure each commit and the PR mention the Issue number (cf the CONTRIBUTING doc)

@nguyexua
nguyexua force-pushed the lan.nguyen/fix-recorder-window-callback-null-menu-crash branch from 0849c26 to de0f098 Compare March 4, 2026 22:56
@datadog-datadog-prod-us1

This comment has been minimized.

@nguyexua
nguyexua force-pushed the lan.nguyen/fix-recorder-window-callback-null-menu-crash branch from de0f098 to 95dec94 Compare March 4, 2026 23:45
@codecov-commenter

codecov-commenter commented Mar 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 47.72727% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.38%. Comparing base (ba162fa) to head (a2babf3).

Files with missing lines Patch % Lines
...nternal/recorder/callback/FixedWindowCallback.java 30.30% 18 Missing and 5 partials ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3221      +/-   ##
===========================================
- Coverage    71.49%   71.38%   -0.10%     
===========================================
  Files          934      935       +1     
  Lines        34628    34649      +21     
  Branches      5862     5866       +4     
===========================================
- Hits         24755    24734      -21     
- Misses        8231     8257      +26     
- Partials      1642     1658      +16     
Files with missing lines Coverage Δ
...lay/internal/recorder/WindowCallbackInterceptor.kt 100.00% <100.00%> (ø)
...ternal/recorder/callback/RecorderWindowCallback.kt 93.59% <100.00%> (+1.37%) ⬆️
...nternal/recorder/callback/FixedWindowCallback.java 30.30% <30.30%> (ø)

... and 37 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@nguyexua
nguyexua force-pushed the lan.nguyen/fix-recorder-window-callback-null-menu-crash branch 2 times, most recently from 8d79d88 to 51d9c76 Compare March 6, 2026 10:49
nguyexua added 2 commits March 6, 2026 12:03
Introduce a FixedWindowCallback Java wrapper that annotates nullable
parameters correctly, preventing Kotlin's non-null assertions from
crashing when Android passes null values to Window.Callback methods.
RecorderWindowCallback now extends FixedWindowCallback instead of
using Kotlin's `by` delegation.
Remove CountDownLatch-based synchronization and lifecycle callback
registration, relying on waitForIdleSync() instead.
@nguyexua
nguyexua force-pushed the lan.nguyen/fix-recorder-window-callback-null-menu-crash branch from 51d9c76 to a2babf3 Compare March 6, 2026 11:03
@ambushwork

Copy link
Copy Markdown
Member

@nguyexua this can be closed I guess?

@nguyexua nguyexua closed this Mar 11, 2026
@0xnm
0xnm deleted the lan.nguyen/fix-recorder-window-callback-null-menu-crash branch April 2, 2026 10:15
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.

3 participants