diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 8a66868d3cdc..7bea96b405c1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<8af0aea8bbf4cffaad7d312032bef0e4>> + * @generated SignedSource<<4f9777b3b50f714214f9f0f86d5176f1>> */ /** @@ -384,6 +384,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean = accessor.shouldPressibilityUseW3CPointerEventsForHover() + /** + * Do not emit touchcancel from Android ScrollView, instead native topScroll event will trigger responder transfer and terminate in RN renderer. + */ + @JvmStatic + public fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean = accessor.shouldTriggerResponderTransferOnScrollAndroid() + /** * Skip activity identity assertion in ReactHostImpl::onHostPause() */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index 23157792b63a..b8ae3755b2da 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5c2aa1e15e7fbe129b8f774d2dc7be70>> + * @generated SignedSource<<7e45b713bab183402e93ee058ea7cb36>> */ /** @@ -79,6 +79,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var preparedTextCacheSizeCache: Double? = null private var preventShadowTreeCommitExhaustionCache: Boolean? = null private var shouldPressibilityUseW3CPointerEventsForHoverCache: Boolean? = null + private var shouldTriggerResponderTransferOnScrollAndroidCache: Boolean? = null private var skipActivityIdentityAssertionOnHostPauseCache: Boolean? = null private var sweepActiveTouchOnChildNativeGesturesAndroidCache: Boolean? = null private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null @@ -629,6 +630,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean { + var cached = shouldTriggerResponderTransferOnScrollAndroidCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.shouldTriggerResponderTransferOnScrollAndroid() + shouldTriggerResponderTransferOnScrollAndroidCache = cached + } + return cached + } + override fun skipActivityIdentityAssertionOnHostPause(): Boolean { var cached = skipActivityIdentityAssertionOnHostPauseCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index fd1f649b21d1..522a4fbde714 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<0bd8796f4580322a78690ec4469c07ce>> + * @generated SignedSource<> */ /** @@ -146,6 +146,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean + @DoNotStrip @JvmStatic public external fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun skipActivityIdentityAssertionOnHostPause(): Boolean @DoNotStrip @JvmStatic public external fun sweepActiveTouchOnChildNativeGesturesAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index ebbea25b2532..9e96152c19bf 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7c7796cbe2722f0f6e5b2cc4ed43a0d5>> + * @generated SignedSource<> */ /** @@ -141,6 +141,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean = false + override fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean = false + override fun skipActivityIdentityAssertionOnHostPause(): Boolean = false override fun sweepActiveTouchOnChildNativeGesturesAndroid(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 6e6e769a87a2..666593cc03cc 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -83,6 +83,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var preparedTextCacheSizeCache: Double? = null private var preventShadowTreeCommitExhaustionCache: Boolean? = null private var shouldPressibilityUseW3CPointerEventsForHoverCache: Boolean? = null + private var shouldTriggerResponderTransferOnScrollAndroidCache: Boolean? = null private var skipActivityIdentityAssertionOnHostPauseCache: Boolean? = null private var sweepActiveTouchOnChildNativeGesturesAndroidCache: Boolean? = null private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null @@ -692,6 +693,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean { + var cached = shouldTriggerResponderTransferOnScrollAndroidCache + if (cached == null) { + cached = currentProvider.shouldTriggerResponderTransferOnScrollAndroid() + accessedFeatureFlags.add("shouldTriggerResponderTransferOnScrollAndroid") + shouldTriggerResponderTransferOnScrollAndroidCache = cached + } + return cached + } + override fun skipActivityIdentityAssertionOnHostPause(): Boolean { var cached = skipActivityIdentityAssertionOnHostPauseCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 6ec722164981..eebf799b69b4 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -141,6 +141,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean + @DoNotStrip public fun shouldTriggerResponderTransferOnScrollAndroid(): Boolean + @DoNotStrip public fun skipActivityIdentityAssertionOnHostPause(): Boolean @DoNotStrip public fun sweepActiveTouchOnChildNativeGesturesAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index e2f073b58216..a9f529b240a7 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<740fec2589997816f17778f57b1d4abf>> + * @generated SignedSource<<5cf0077264f7ceca6617dbe20bcc122f>> */ /** @@ -393,6 +393,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool shouldTriggerResponderTransferOnScrollAndroid() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("shouldTriggerResponderTransferOnScrollAndroid"); + return method(javaProvider_); + } + bool skipActivityIdentityAssertionOnHostPause() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("skipActivityIdentityAssertionOnHostPause"); @@ -800,6 +806,11 @@ bool JReactNativeFeatureFlagsCxxInterop::shouldPressibilityUseW3CPointerEventsFo return ReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover(); } +bool JReactNativeFeatureFlagsCxxInterop::shouldTriggerResponderTransferOnScrollAndroid( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::shouldTriggerResponderTransferOnScrollAndroid(); +} + bool JReactNativeFeatureFlagsCxxInterop::skipActivityIdentityAssertionOnHostPause( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::skipActivityIdentityAssertionOnHostPause(); @@ -1098,6 +1109,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "shouldPressibilityUseW3CPointerEventsForHover", JReactNativeFeatureFlagsCxxInterop::shouldPressibilityUseW3CPointerEventsForHover), + makeNativeMethod( + "shouldTriggerResponderTransferOnScrollAndroid", + JReactNativeFeatureFlagsCxxInterop::shouldTriggerResponderTransferOnScrollAndroid), makeNativeMethod( "skipActivityIdentityAssertionOnHostPause", JReactNativeFeatureFlagsCxxInterop::skipActivityIdentityAssertionOnHostPause), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index e332f8ded9ee..a098ac47934e 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2d4ccbeed5ffafd40715357ff98d83b1>> + * @generated SignedSource<<04929fb70beb00c1f690bdb11703b322>> */ /** @@ -207,6 +207,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool shouldPressibilityUseW3CPointerEventsForHover( facebook::jni::alias_ref); + static bool shouldTriggerResponderTransferOnScrollAndroid( + facebook::jni::alias_ref); + static bool skipActivityIdentityAssertionOnHostPause( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 4d2cb8d691c1..52e449fb25bb 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<287689f62d05f2d27c146856b7857010>> + * @generated SignedSource<> */ /** @@ -262,6 +262,10 @@ bool ReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover() { return getAccessor().shouldPressibilityUseW3CPointerEventsForHover(); } +bool ReactNativeFeatureFlags::shouldTriggerResponderTransferOnScrollAndroid() { + return getAccessor().shouldTriggerResponderTransferOnScrollAndroid(); +} + bool ReactNativeFeatureFlags::skipActivityIdentityAssertionOnHostPause() { return getAccessor().skipActivityIdentityAssertionOnHostPause(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index d0ca64781ae7..bf628ab7109b 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<72899a3f546792dd4c868c561f55c10f>> */ /** @@ -334,6 +334,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool shouldPressibilityUseW3CPointerEventsForHover(); + /** + * Do not emit touchcancel from Android ScrollView, instead native topScroll event will trigger responder transfer and terminate in RN renderer. + */ + RN_EXPORT static bool shouldTriggerResponderTransferOnScrollAndroid(); + /** * Skip activity identity assertion in ReactHostImpl::onHostPause() */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index cf500ea5de8e..49e55c2c3fbd 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<57620c5eb3ba6b9fa70f21908c4ea71c>> + * @generated SignedSource<<0e252b46c1225d8c1c99d996d660a91d>> */ /** @@ -1091,6 +1091,24 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::shouldTriggerResponderTransferOnScrollAndroid() { + auto flagValue = shouldTriggerResponderTransferOnScrollAndroid_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(59, "shouldTriggerResponderTransferOnScrollAndroid"); + + flagValue = currentProvider_->shouldTriggerResponderTransferOnScrollAndroid(); + shouldTriggerResponderTransferOnScrollAndroid_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() { auto flagValue = skipActivityIdentityAssertionOnHostPause_.load(); @@ -1100,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(59, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(60, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1118,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::sweepActiveTouchOnChildNativeGesturesAndro // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "sweepActiveTouchOnChildNativeGesturesAndroid"); + markFlagAsAccessed(61, "sweepActiveTouchOnChildNativeGesturesAndroid"); flagValue = currentProvider_->sweepActiveTouchOnChildNativeGesturesAndroid(); sweepActiveTouchOnChildNativeGesturesAndroid_ = flagValue; @@ -1136,7 +1154,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(61, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(62, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1154,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(62, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(63, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1172,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(64, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1190,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "useFabricInterop"); + markFlagAsAccessed(65, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1208,7 +1226,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeEqualsInNativeReadableArrayAndroi // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(65, "useNativeEqualsInNativeReadableArrayAndroid"); + markFlagAsAccessed(66, "useNativeEqualsInNativeReadableArrayAndroid"); flagValue = currentProvider_->useNativeEqualsInNativeReadableArrayAndroid(); useNativeEqualsInNativeReadableArrayAndroid_ = flagValue; @@ -1226,7 +1244,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeTransformHelperAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(66, "useNativeTransformHelperAndroid"); + markFlagAsAccessed(67, "useNativeTransformHelperAndroid"); flagValue = currentProvider_->useNativeTransformHelperAndroid(); useNativeTransformHelperAndroid_ = flagValue; @@ -1244,7 +1262,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(67, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(68, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1262,7 +1280,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(68, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(69, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -1280,7 +1298,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(69, "useRawPropsJsiValue"); + markFlagAsAccessed(70, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -1298,7 +1316,7 @@ bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(70, "useShadowNodeStateOnClone"); + markFlagAsAccessed(71, "useShadowNodeStateOnClone"); flagValue = currentProvider_->useShadowNodeStateOnClone(); useShadowNodeStateOnClone_ = flagValue; @@ -1316,7 +1334,7 @@ bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "useSharedAnimatedBackend"); + markFlagAsAccessed(72, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1334,7 +1352,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "useTurboModuleInterop"); + markFlagAsAccessed(73, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1352,7 +1370,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(73, "useTurboModules"); + markFlagAsAccessed(74, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -1370,7 +1388,7 @@ double ReactNativeFeatureFlagsAccessor::viewCullingOutsetRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(74, "viewCullingOutsetRatio"); + markFlagAsAccessed(75, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1388,7 +1406,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewHysteresisRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(75, "virtualViewHysteresisRatio"); + markFlagAsAccessed(76, "virtualViewHysteresisRatio"); flagValue = currentProvider_->virtualViewHysteresisRatio(); virtualViewHysteresisRatio_ = flagValue; @@ -1406,7 +1424,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(76, "virtualViewPrerenderRatio"); + markFlagAsAccessed(77, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 844c198f1d91..2d504842bace 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<6c6458278652bc91570db82b2be6c7f1>> + * @generated SignedSource<> */ /** @@ -91,6 +91,7 @@ class ReactNativeFeatureFlagsAccessor { double preparedTextCacheSize(); bool preventShadowTreeCommitExhaustion(); bool shouldPressibilityUseW3CPointerEventsForHover(); + bool shouldTriggerResponderTransferOnScrollAndroid(); bool skipActivityIdentityAssertionOnHostPause(); bool sweepActiveTouchOnChildNativeGesturesAndroid(); bool traceTurboModulePromiseRejectionsOnAndroid(); @@ -120,7 +121,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 77> accessedFeatureFlags_; + std::array, 78> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -181,6 +182,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> preparedTextCacheSize_; std::atomic> preventShadowTreeCommitExhaustion_; std::atomic> shouldPressibilityUseW3CPointerEventsForHover_; + std::atomic> shouldTriggerResponderTransferOnScrollAndroid_; std::atomic> skipActivityIdentityAssertionOnHostPause_; std::atomic> sweepActiveTouchOnChildNativeGesturesAndroid_; std::atomic> traceTurboModulePromiseRejectionsOnAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 49b781d21f73..e84e08b63a0e 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7879aa079d5dc8603faac4dbf40f70c5>> + * @generated SignedSource<> */ /** @@ -263,6 +263,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool shouldTriggerResponderTransferOnScrollAndroid() override { + return false; + } + bool skipActivityIdentityAssertionOnHostPause() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index cb769766a6de..5a030b48986c 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<5759dee54e04c91401a3ece5b899a7f1>> */ /** @@ -576,6 +576,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::shouldPressibilityUseW3CPointerEventsForHover(); } + bool shouldTriggerResponderTransferOnScrollAndroid() override { + auto value = values_["shouldTriggerResponderTransferOnScrollAndroid"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::shouldTriggerResponderTransferOnScrollAndroid(); + } + bool skipActivityIdentityAssertionOnHostPause() override { auto value = values_["skipActivityIdentityAssertionOnHostPause"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 5648b81f4c4f..c38aa19aa6db 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -84,6 +84,7 @@ class ReactNativeFeatureFlagsProvider { virtual double preparedTextCacheSize() = 0; virtual bool preventShadowTreeCommitExhaustion() = 0; virtual bool shouldPressibilityUseW3CPointerEventsForHover() = 0; + virtual bool shouldTriggerResponderTransferOnScrollAndroid() = 0; virtual bool skipActivityIdentityAssertionOnHostPause() = 0; virtual bool sweepActiveTouchOnChildNativeGesturesAndroid() = 0; virtual bool traceTurboModulePromiseRejectionsOnAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index fa79d14c6459..875891b93fd4 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<9ab0fd663424984d5b389aea261f2d3f>> */ /** @@ -339,6 +339,11 @@ bool NativeReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHove return ReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover(); } +bool NativeReactNativeFeatureFlags::shouldTriggerResponderTransferOnScrollAndroid( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::shouldTriggerResponderTransferOnScrollAndroid(); +} + bool NativeReactNativeFeatureFlags::skipActivityIdentityAssertionOnHostPause( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::skipActivityIdentityAssertionOnHostPause(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 00ca1a309364..82cec939bd5d 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<990b6518e7b1d196deb0965e9ada6605>> + * @generated SignedSource<<3c0d98fc75ad480d43c32c6a1c3dfb16>> */ /** @@ -154,6 +154,8 @@ class NativeReactNativeFeatureFlags bool shouldPressibilityUseW3CPointerEventsForHover(jsi::Runtime& runtime); + bool shouldTriggerResponderTransferOnScrollAndroid(jsi::Runtime& runtime); + bool skipActivityIdentityAssertionOnHostPause(jsi::Runtime& runtime); bool sweepActiveTouchOnChildNativeGesturesAndroid(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 1c95b97baf7e..483122215e7c 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -677,6 +677,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + shouldTriggerResponderTransferOnScrollAndroid: { + defaultValue: false, + metadata: { + dateAdded: '2025-09-30', + description: + 'Do not emit touchcancel from Android ScrollView, instead native topScroll event will trigger responder transfer and terminate in RN renderer.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, skipActivityIdentityAssertionOnHostPause: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 92a5fdf8cd86..1f446c8e1e5a 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<3507d3aa8ee32332308a94bf932e01c2>> + * @generated SignedSource<<3078b8488e9905153bfbf2dc26b7a2c5>> * @flow strict * @noformat */ @@ -109,6 +109,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ preparedTextCacheSize: Getter, preventShadowTreeCommitExhaustion: Getter, shouldPressibilityUseW3CPointerEventsForHover: Getter, + shouldTriggerResponderTransferOnScrollAndroid: Getter, skipActivityIdentityAssertionOnHostPause: Getter, sweepActiveTouchOnChildNativeGesturesAndroid: Getter, traceTurboModulePromiseRejectionsOnAndroid: Getter, @@ -444,6 +445,10 @@ export const preventShadowTreeCommitExhaustion: Getter = createNativeFl * Function used to enable / disable Pressibility from using W3C Pointer Events for its hover callbacks */ export const shouldPressibilityUseW3CPointerEventsForHover: Getter = createNativeFlagGetter('shouldPressibilityUseW3CPointerEventsForHover', false); +/** + * Do not emit touchcancel from Android ScrollView, instead native topScroll event will trigger responder transfer and terminate in RN renderer. + */ +export const shouldTriggerResponderTransferOnScrollAndroid: Getter = createNativeFlagGetter('shouldTriggerResponderTransferOnScrollAndroid', false); /** * Skip activity identity assertion in ReactHostImpl::onHostPause() */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 66050af5cbcf..c160bf70cfe2 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -84,6 +84,7 @@ export interface Spec extends TurboModule { +preparedTextCacheSize?: () => number; +preventShadowTreeCommitExhaustion?: () => boolean; +shouldPressibilityUseW3CPointerEventsForHover?: () => boolean; + +shouldTriggerResponderTransferOnScrollAndroid?: () => boolean; +skipActivityIdentityAssertionOnHostPause?: () => boolean; +sweepActiveTouchOnChildNativeGesturesAndroid?: () => boolean; +traceTurboModulePromiseRejectionsOnAndroid?: () => boolean;