Skip to content

[Android] Keep HasChildPressedStateDelay in minified builds - #4654

Merged
m-bert merged 1 commit into
mainfrom
@mbert/add-proguard
Nov 2, 2026
Merged

m-bert merged 1 commit into
mainfrom
@mbert/add-proguard

Conversation

@m-bert

@m-bert m-bert commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator

Description

On Android, delaysChildPressedState={false} has no effect in a release build that R8 minifies. A Touchable inside such a ScrollView still enters its pressed state only after the tap timeout, exactly like one in a ScrollView that keeps the delay.

NativeViewGestureHandler looks up HasChildPressedStateDelay.setHasChildPressedStateDelay by reflection, since the interface only exists since React Native 0.87. Nothing else references it, so R8 renames the interface and drops its methods. getMethod then throws, the setter stays null and the option becomes a no-op.

This adds a consumer ProGuard rule that keeps the interface and its setter, and lists it in the package files so it is published.

Fixes #4652

Test plan

Tested on an API 34 emulator with basic-example (RN 0.88.0) in release builds, with a ScrollView of each kind holding a Touchable. I logged the time from the raw touch-down to onPressIn after a 400 ms hold (adb shell input swipe x y x y 400):

minified, before minified, after not minified
delaysChildPressedState={false} +102 ms +0 ms +0 ms
delaysChildPressedState={true} +101 ms +101 ms +100 ms

In the minified mapping.txt, HasChildPressedStateDelay is no longer renamed.

Not tested on React Native versions older than 0.87, where the interface does not exist and the rule matches nothing.

Copilot AI balanced review requested due to automatic review settings October 28, 2026 16:43

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@m-bert
m-bert requested a lite review from Copilot October 28, 2026 16:43
@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5e774a84-de67-4734-aabc-bbc3bf0b3349
Commits

Reviewing files that changed from the base of the PR and between b19e233 and 9cc2423.

Files selected for processing: 3
  • packages/react-native-gesture-handler/android/build.gradle
  • packages/react-native-gesture-handler/android/consumer-rules.pro
  • packages/react-native-gesture-handler/package.json

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Improved Android build reliability when code shrinking is enabled. A gesture-related behavior accessed indirectly at runtime is now preserved, helping prevent it from being removed during optimization and ensuring it remains available in the published library.

The Android library adds a consumer ProGuard rule that retains HasChildPressedStateDelay and its setter. The Android build registers the rule, and the package includes it in its published files.

Changes: Android consumer rule

Layer / File(s) Summary
Add and distribute the consumer rule
packages/react-native-gesture-handler/android/consumer-rules.pro, packages/react-native-gesture-handler/android/build.gradle, packages/react-native-gesture-handler/package.json
The rule retains HasChildPressedStateDelay and its setHasChildPressedStateDelay(Boolean) method. The Android build registers the rule, and the package includes it in its published files.

Suggested reviewers: j-piasecki, coado

Priority: Normal

Severity of issue fixed: Medium

Merge Risk: Minimal · up to 9cc24

The ProGuard protection is correctly distributed, so this change is ready to merge.

Pre-merge checks: Passed 3
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: preserving HasChildPressedStateDelay in Android minified builds.
Linked Issues check Passed Issue #4652 requires that Android delaysChildPressedState={false} take effect in minified release builds. The reflective lookup in NativeViewGestureHandler.kt uses Class.forName("com.facebook.react.ui…
Out of Scope Changes check Passed The PR changes three files. android/consumer-rules.pro adds the keep rule for the reflectively accessed interface and setter, which implements #4652. android/build.gradle registers the rule as a consu…
Full details: Linked Issues check

Explanation

Issue #4652 requires that Android delaysChildPressedState={false} take effect in minified release builds. The reflective lookup in NativeViewGestureHandler.kt uses Class.forName("com.facebook.react.uimanager.HasChildPressedStateDelay").getMethod("setHasChildPressedStateDelay", Boolean::class.javaObjectType), which is java.lang.Boolean. The new android/consumer-rules.pro contains -keep interface com.facebook.react.uimanager.HasChildPressedStateDelay { void setHasChildPressedStateDelay(java.lang.Boolean); }. The interface name and the parameter type both match the reflective lookup, so R8 keeps the interface name and the setter. android/build.gradle adds consumerProguardFiles 'consumer-rules.pro' to defaultConfig, so the rule reaches consumer builds. The PR test plan reports that the minified delay drops from +102 ms to +0 ms for delaysChildPressedState={false}, and that mapping.txt no longer renames the interface. The keep rule addresses the requirement. The #4653 consequence is a separate issue and is not a requirement of this PR. The rule is a consumer rule, so it does not change the library's own build output. No coding requirement remains unmet.

Full details: Out of Scope Changes check

Explanation

The PR changes three files. android/consumer-rules.pro adds the keep rule for the reflectively accessed interface and setter, which implements #4652. android/build.gradle registers the rule as a consumer ProGuard file, which makes the rule effective for consumers. package.json adds android/consumer-rules.pro to the published files list, so the rule ships with the package. Each change connects directly to the fix. No unrelated change was found. The packaging change was assessed from the change summary and the diff of build.gradle; the package.json diff was not read directly, but the summary states a one-line addition to files.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI 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.

🟢 Approval recommended

The reviewed changes consistently preserve the reflection-accessed interface and setter by registering the consumer R8 rule and including it in the published package.

No open issues 🎉

Review effort: Lite

@m-bert
m-bert requested a review from j-piasecki October 28, 2026 16:55
@m-bert
m-bert merged commit bf44087 into main Nov 2, 2026
14 checks passed
@m-bert
m-bert deleted the @mbert/add-proguard branch November 2, 2026 07:40
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.

[Android] delaysChildPressedState={false} does nothing in a minified release build

3 participants