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 7fcdaaeec16..c15c65ba467 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<> + * @generated SignedSource<<4004d8650ddb3d1bc9afb9c5c72fa191>> */ /** @@ -144,6 +144,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableBridgelessArchitecture(): Boolean = accessor.enableBridgelessArchitecture() + /** + * When enabled, Android receives prop updates based on props diffing only for core components with hand-written props (View, Text, Image, ScrollView, TextInput). Other components keep receiving raw props unless `enablePropsUpdateReconciliationAndroid` is enabled. + */ + @JvmStatic + public fun enableCoreComponentsPropsUpdateReconciliationAndroid(): Boolean = accessor.enableCoreComponentsPropsUpdateReconciliationAndroid() + /** * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). */ 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 6e0da4d9d0e..508f7ce8f96 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<> + * @generated SignedSource<> */ /** @@ -39,6 +39,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null private var enableAsyncDiskCacheCheckInMultiSourceImageAndroidCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null + private var enableCoreComponentsPropsUpdateReconciliationAndroidCache: Boolean? = null private var enableCppPropsIteratorSetterCache: Boolean? = null private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null @@ -289,6 +290,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableCoreComponentsPropsUpdateReconciliationAndroid(): Boolean { + var cached = enableCoreComponentsPropsUpdateReconciliationAndroidCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableCoreComponentsPropsUpdateReconciliationAndroid() + enableCoreComponentsPropsUpdateReconciliationAndroidCache = cached + } + return cached + } + override fun enableCppPropsIteratorSetter(): Boolean { var cached = enableCppPropsIteratorSetterCache 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 2268d03f367..06ccc040a0e 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<<6d86d4adbc261c9271b5bed72bd12dcf>> + * @generated SignedSource<<8e143d9668e06e97c1a4e04542e35295>> */ /** @@ -66,6 +66,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableBridgelessArchitecture(): Boolean + @DoNotStrip @JvmStatic public external fun enableCoreComponentsPropsUpdateReconciliationAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun enableCppPropsIteratorSetter(): Boolean @DoNotStrip @JvmStatic public external fun enableCustomFocusSearchOnClippedElementsAndroid(): 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 defafe46f6b..7335882be3e 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<> + * @generated SignedSource<<328892d289851df4d865c737199e8ee0>> */ /** @@ -61,6 +61,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableBridgelessArchitecture(): Boolean = true + override fun enableCoreComponentsPropsUpdateReconciliationAndroid(): Boolean = false + override fun enableCppPropsIteratorSetter(): Boolean = false override fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean = true 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 53af4b4edab..83d2302aa94 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<<19c3e5eaeb8f71fff3433783360a2a5f>> */ /** @@ -43,6 +43,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null private var enableAsyncDiskCacheCheckInMultiSourceImageAndroidCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null + private var enableCoreComponentsPropsUpdateReconciliationAndroidCache: Boolean? = null private var enableCppPropsIteratorSetterCache: Boolean? = null private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null @@ -312,6 +313,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun enableCoreComponentsPropsUpdateReconciliationAndroid(): Boolean { + var cached = enableCoreComponentsPropsUpdateReconciliationAndroidCache + if (cached == null) { + cached = currentProvider.enableCoreComponentsPropsUpdateReconciliationAndroid() + accessedFeatureFlags.add("enableCoreComponentsPropsUpdateReconciliationAndroid") + enableCoreComponentsPropsUpdateReconciliationAndroidCache = cached + } + return cached + } + override fun enableCppPropsIteratorSetter(): Boolean { var cached = enableCppPropsIteratorSetterCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt index 850fcaa9ff5..c16af1df175 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.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<> */ /** @@ -27,6 +27,8 @@ public open class ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android : override fun disableIdleMountItemFrameCallbackRearmAndroid(): Boolean = true + override fun enableCoreComponentsPropsUpdateReconciliationAndroid(): Boolean = true + override fun enableFlexboxAutoMinSizeInStrictMode(): Boolean = true override fun preventShadowTreeCommitExhaustion(): Boolean = true 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 8fa2f426946..38e868007db 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<<12a19d59f2a9d8242a0ae3d3d4b1d825>> */ /** @@ -61,6 +61,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableBridgelessArchitecture(): Boolean + @DoNotStrip public fun enableCoreComponentsPropsUpdateReconciliationAndroid(): Boolean + @DoNotStrip public fun enableCppPropsIteratorSetter(): Boolean @DoNotStrip public fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp index b5f1eb569b2..e2b2001a647 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp @@ -329,15 +329,11 @@ jni::local_ref getProps( const ShadowView& oldShadowView, const ShadowView& newShadowView) { // We calculate the diffing between the props of the last mounted ShadowTree - // and the Props of the latest commited ShadowTree). ONLY for - // components when the "enablePropsUpdateReconciliationAndroid" feature flag - // is enabled. + // and the Props of the latest commited ShadowTree), for components selected + // by `isPropsDiffingEnabled`. auto* oldProps = oldShadowView.props.get(); auto* newProps = newShadowView.props.get(); - if ((ReactNativeFeatureFlags::enablePropsUpdateReconciliationAndroid()) && - strcmp( - newShadowView.componentName, - newProps->getDiffPropsImplementationTarget()) == 0) { + if (isPropsDiffingEnabled(newShadowView.componentName, *newProps)) { auto diff = newProps->getDiffProps(oldProps); #ifdef REACT_NATIVE_DEBUG 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 23fd0978a76..d0725c39879 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<<944781e7a547e601f0637869a3a3ec5e>> + * @generated SignedSource<> */ /** @@ -153,6 +153,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool enableCoreComponentsPropsUpdateReconciliationAndroid() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableCoreComponentsPropsUpdateReconciliationAndroid"); + return method(javaProvider_); + } + bool enableCppPropsIteratorSetter() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableCppPropsIteratorSetter"); @@ -720,6 +726,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableBridgelessArchitecture( return ReactNativeFeatureFlags::enableBridgelessArchitecture(); } +bool JReactNativeFeatureFlagsCxxInterop::enableCoreComponentsPropsUpdateReconciliationAndroid( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableCoreComponentsPropsUpdateReconciliationAndroid(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableCppPropsIteratorSetter(); @@ -1198,6 +1209,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableBridgelessArchitecture", JReactNativeFeatureFlagsCxxInterop::enableBridgelessArchitecture), + makeNativeMethod( + "enableCoreComponentsPropsUpdateReconciliationAndroid", + JReactNativeFeatureFlagsCxxInterop::enableCoreComponentsPropsUpdateReconciliationAndroid), makeNativeMethod( "enableCppPropsIteratorSetter", JReactNativeFeatureFlagsCxxInterop::enableCppPropsIteratorSetter), 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 ae774f80c82..799b58768c3 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<> + * @generated SignedSource<<23f91198ea1e19abb3eb7004de696505>> */ /** @@ -87,6 +87,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableBridgelessArchitecture( facebook::jni::alias_ref); + static bool enableCoreComponentsPropsUpdateReconciliationAndroid( + facebook::jni::alias_ref); + static bool enableCppPropsIteratorSetter( 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 ac8ddb96a11..2e4907a5748 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<<56e127471f63e47798ec619e6fa56738>> + * @generated SignedSource<<764aeebfb1e2fc17dae032247e5e69cf>> */ /** @@ -102,6 +102,10 @@ bool ReactNativeFeatureFlags::enableBridgelessArchitecture() { return getAccessor().enableBridgelessArchitecture(); } +bool ReactNativeFeatureFlags::enableCoreComponentsPropsUpdateReconciliationAndroid() { + return getAccessor().enableCoreComponentsPropsUpdateReconciliationAndroid(); +} + bool ReactNativeFeatureFlags::enableCppPropsIteratorSetter() { return getAccessor().enableCppPropsIteratorSetter(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 0e5b3f2013f..652e976c885 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<<6887b671526bc8a3b0678e3e45b4e3b4>> + * @generated SignedSource<<8fc79697c78a91d401a1aec0b5e44d1b>> */ /** @@ -136,6 +136,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableBridgelessArchitecture(); + /** + * When enabled, Android receives prop updates based on props diffing only for core components with hand-written props (View, Text, Image, ScrollView, TextInput). Other components keep receiving raw props unless `enablePropsUpdateReconciliationAndroid` is enabled. + */ + RN_EXPORT static bool enableCoreComponentsPropsUpdateReconciliationAndroid(); + /** * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 7640cea6418..55db7d64ea8 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<<5d9712bd7e62ba3a29b084ba4c60bec5>> + * @generated SignedSource<<4b3db41e42b1dced34353a26a3c266c2>> */ /** @@ -371,6 +371,24 @@ bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableCoreComponentsPropsUpdateReconciliationAndroid() { + auto flagValue = enableCoreComponentsPropsUpdateReconciliationAndroid_.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(19, "enableCoreComponentsPropsUpdateReconciliationAndroid"); + + flagValue = currentProvider_->enableCoreComponentsPropsUpdateReconciliationAndroid(); + enableCoreComponentsPropsUpdateReconciliationAndroid_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() { auto flagValue = enableCppPropsIteratorSetter_.load(); @@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "enableCppPropsIteratorSetter"); + markFlagAsAccessed(20, "enableCppPropsIteratorSetter"); flagValue = currentProvider_->enableCppPropsIteratorSetter(); enableCppPropsIteratorSetter_ = flagValue; @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCustomFocusSearchOnClippedElementsAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enableCustomFocusSearchOnClippedElementsAndroid"); + markFlagAsAccessed(21, "enableCustomFocusSearchOnClippedElementsAndroid"); flagValue = currentProvider_->enableCustomFocusSearchOnClippedElementsAndroid(); enableCustomFocusSearchOnClippedElementsAndroid_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDestroyShadowTreeRevisionAsync() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "enableDestroyShadowTreeRevisionAsync"); + markFlagAsAccessed(22, "enableDestroyShadowTreeRevisionAsync"); flagValue = currentProvider_->enableDestroyShadowTreeRevisionAsync(); enableDestroyShadowTreeRevisionAsync_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDoubleMeasurementFixAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "enableDoubleMeasurementFixAndroid"); + markFlagAsAccessed(23, "enableDoubleMeasurementFixAndroid"); flagValue = currentProvider_->enableDoubleMeasurementFixAndroid(); enableDoubleMeasurementFixAndroid_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableEagerRootViewAttachment"); + markFlagAsAccessed(24, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableExclusivePropsUpdateAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableExclusivePropsUpdateAndroid"); + markFlagAsAccessed(25, "enableExclusivePropsUpdateAndroid"); flagValue = currentProvider_->enableExclusivePropsUpdateAndroid(); enableExclusivePropsUpdateAndroid_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricCommitBranching() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableFabricCommitBranching"); + markFlagAsAccessed(26, "enableFabricCommitBranching"); flagValue = currentProvider_->enableFabricCommitBranching(); enableFabricCommitBranching_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricCommitBranchingMergeOnMainThre // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "enableFabricCommitBranchingMergeOnMainThread"); + markFlagAsAccessed(27, "enableFabricCommitBranchingMergeOnMainThread"); flagValue = currentProvider_->enableFabricCommitBranchingMergeOnMainThread(); enableFabricCommitBranchingMergeOnMainThread_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "enableFabricLogs"); + markFlagAsAccessed(28, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFlexboxAutoMinSizeInStrictMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "enableFlexboxAutoMinSizeInStrictMode"); + markFlagAsAccessed(29, "enableFlexboxAutoMinSizeInStrictMode"); flagValue = currentProvider_->enableFlexboxAutoMinSizeInStrictMode(); enableFlexboxAutoMinSizeInStrictMode_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFollowUpMountItemDispatchAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "enableFollowUpMountItemDispatchAndroid"); + markFlagAsAccessed(30, "enableFollowUpMountItemDispatchAndroid"); flagValue = currentProvider_->enableFollowUpMountItemDispatchAndroid(); enableFollowUpMountItemDispatchAndroid_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSCompressedTextFrameAdjustment() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "enableIOSCompressedTextFrameAdjustment"); + markFlagAsAccessed(31, "enableIOSCompressedTextFrameAdjustment"); flagValue = currentProvider_->enableIOSCompressedTextFrameAdjustment(); enableIOSCompressedTextFrameAdjustment_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSTextBaselineOffsetPerLine() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "enableIOSTextBaselineOffsetPerLine"); + markFlagAsAccessed(32, "enableIOSTextBaselineOffsetPerLine"); flagValue = currentProvider_->enableIOSTextBaselineOffsetPerLine(); enableIOSTextBaselineOffsetPerLine_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(33, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "enableImagePrefetchingAndroid"); + markFlagAsAccessed(34, "enableImagePrefetchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingAndroid(); enableImagePrefetchingAndroid_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImageTransparentTintColor() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "enableImageTransparentTintColor"); + markFlagAsAccessed(35, "enableImageTransparentTintColor"); flagValue = currentProvider_->enableImageTransparentTintColor(); enableImageTransparentTintColor_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetC // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "enableImmediateUpdateModeForContentOffsetChanges"); + markFlagAsAccessed(36, "enableImmediateUpdateModeForContentOffsetChanges"); flagValue = currentProvider_->enableImmediateUpdateModeForContentOffsetChanges(); enableImmediateUpdateModeForContentOffsetChanges_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImperativeEvents() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "enableImperativeEvents"); + markFlagAsAccessed(37, "enableImperativeEvents"); flagValue = currentProvider_->enableImperativeEvents(); enableImperativeEvents_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImperativeFocus() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "enableImperativeFocus"); + markFlagAsAccessed(38, "enableImperativeFocus"); flagValue = currentProvider_->enableImperativeFocus(); enableImperativeFocus_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimiz // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "enableInteropViewManagerClassLookUpOptimizationIOS"); + markFlagAsAccessed(39, "enableInteropViewManagerClassLookUpOptimizationIOS"); flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS(); enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIntersectionObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "enableIntersectionObserverByDefault"); + markFlagAsAccessed(40, "enableIntersectionObserverByDefault"); flagValue = currentProvider_->enableIntersectionObserverByDefault(); enableIntersectionObserverByDefault_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableKeyEvents() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "enableKeyEvents"); + markFlagAsAccessed(41, "enableKeyEvents"); flagValue = currentProvider_->enableKeyEvents(); enableKeyEvents_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(42, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(43, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::enableModuleArgumentNSNullConversionIOS() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(44, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMountingCoordinatorPullModelAndroid( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "enableMountingCoordinatorPullModelAndroid"); + markFlagAsAccessed(45, "enableMountingCoordinatorPullModelAndroid"); flagValue = currentProvider_->enableMountingCoordinatorPullModelAndroid(); enableMountingCoordinatorPullModelAndroid_ = flagValue; @@ -848,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMutationObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(45, "enableMutationObserverByDefault"); + markFlagAsAccessed(46, "enableMutationObserverByDefault"); flagValue = currentProvider_->enableMutationObserverByDefault(); enableMutationObserverByDefault_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "enableNativeCSSParsing"); + markFlagAsAccessed(47, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreallocatedPropsDiffOnInsertAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "enablePreallocatedPropsDiffOnInsertAndroid"); + markFlagAsAccessed(48, "enablePreallocatedPropsDiffOnInsertAndroid"); flagValue = currentProvider_->enablePreallocatedPropsDiffOnInsertAndroid(); enablePreallocatedPropsDiffOnInsertAndroid_ = flagValue; @@ -902,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreparedTextLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(48, "enablePreparedTextLayout"); + markFlagAsAccessed(49, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -920,7 +938,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(49, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(50, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -938,7 +956,7 @@ bool ReactNativeFeatureFlagsAccessor::enableResizeObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(50, "enableResizeObserverByDefault"); + markFlagAsAccessed(51, "enableResizeObserverByDefault"); flagValue = currentProvider_->enableResizeObserverByDefault(); enableResizeObserverByDefault_ = flagValue; @@ -956,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSwiftUIBasedFilters() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(51, "enableSwiftUIBasedFilters"); + markFlagAsAccessed(52, "enableSwiftUIBasedFilters"); flagValue = currentProvider_->enableSwiftUIBasedFilters(); enableSwiftUIBasedFilters_ = flagValue; @@ -974,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(52, "enableViewCulling"); + markFlagAsAccessed(53, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -992,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(53, "enableViewRecycling"); + markFlagAsAccessed(54, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -1010,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForImage() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "enableViewRecyclingForImage"); + markFlagAsAccessed(55, "enableViewRecyclingForImage"); flagValue = currentProvider_->enableViewRecyclingForImage(); enableViewRecyclingForImage_ = flagValue; @@ -1028,7 +1046,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForScrollView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(55, "enableViewRecyclingForScrollView"); + markFlagAsAccessed(56, "enableViewRecyclingForScrollView"); flagValue = currentProvider_->enableViewRecyclingForScrollView(); enableViewRecyclingForScrollView_ = flagValue; @@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(56, "enableViewRecyclingForText"); + markFlagAsAccessed(57, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -1064,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(57, "enableViewRecyclingForView"); + markFlagAsAccessed(58, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -1082,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewContainerStateExperimenta // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(58, "enableVirtualViewContainerStateExperimental"); + markFlagAsAccessed(59, "enableVirtualViewContainerStateExperimental"); flagValue = currentProvider_->enableVirtualViewContainerStateExperimental(); enableVirtualViewContainerStateExperimental_ = flagValue; @@ -1100,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::fixBorderlessRippleAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(59, "fixBorderlessRippleAndroid"); + markFlagAsAccessed(60, "fixBorderlessRippleAndroid"); flagValue = currentProvider_->fixBorderlessRippleAndroid(); fixBorderlessRippleAndroid_ = flagValue; @@ -1118,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(61, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -1136,7 +1154,7 @@ bool ReactNativeFeatureFlagsAccessor::fixTextLayoutOnPixelDensityChange() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(61, "fixTextLayoutOnPixelDensityChange"); + markFlagAsAccessed(62, "fixTextLayoutOnPixelDensityChange"); flagValue = currentProvider_->fixTextLayoutOnPixelDensityChange(); fixTextLayoutOnPixelDensityChange_ = flagValue; @@ -1154,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::fixYogaFlexBasisFitContentInMainAxis() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(62, "fixYogaFlexBasisFitContentInMainAxis"); + markFlagAsAccessed(63, "fixYogaFlexBasisFitContentInMainAxis"); flagValue = currentProvider_->fixYogaFlexBasisFitContentInMainAxis(); fixYogaFlexBasisFitContentInMainAxis_ = flagValue; @@ -1172,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxAssertSingleHostState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "fuseboxAssertSingleHostState"); + markFlagAsAccessed(64, "fuseboxAssertSingleHostState"); flagValue = currentProvider_->fuseboxAssertSingleHostState(); fuseboxAssertSingleHostState_ = flagValue; @@ -1190,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "fuseboxEnabledRelease"); + markFlagAsAccessed(65, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -1208,7 +1226,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxFrameRecordingEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(65, "fuseboxFrameRecordingEnabled"); + markFlagAsAccessed(66, "fuseboxFrameRecordingEnabled"); flagValue = currentProvider_->fuseboxFrameRecordingEnabled(); fuseboxFrameRecordingEnabled_ = flagValue; @@ -1226,7 +1244,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxScreenshotCaptureEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(66, "fuseboxScreenshotCaptureEnabled"); + markFlagAsAccessed(67, "fuseboxScreenshotCaptureEnabled"); flagValue = currentProvider_->fuseboxScreenshotCaptureEnabled(); fuseboxScreenshotCaptureEnabled_ = flagValue; @@ -1244,7 +1262,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxWebSocketEventsEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(67, "fuseboxWebSocketEventsEnabled"); + markFlagAsAccessed(68, "fuseboxWebSocketEventsEnabled"); flagValue = currentProvider_->fuseboxWebSocketEventsEnabled(); fuseboxWebSocketEventsEnabled_ = flagValue; @@ -1262,7 +1280,7 @@ bool ReactNativeFeatureFlagsAccessor::keepTimersRunningWhileHostPausedAndroid() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(68, "keepTimersRunningWhileHostPausedAndroid"); + markFlagAsAccessed(69, "keepTimersRunningWhileHostPausedAndroid"); flagValue = currentProvider_->keepTimersRunningWhileHostPausedAndroid(); keepTimersRunningWhileHostPausedAndroid_ = flagValue; @@ -1280,7 +1298,7 @@ bool ReactNativeFeatureFlagsAccessor::optimizedAnimatedPropUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(69, "optimizedAnimatedPropUpdates"); + markFlagAsAccessed(70, "optimizedAnimatedPropUpdates"); flagValue = currentProvider_->optimizedAnimatedPropUpdates(); optimizedAnimatedPropUpdates_ = flagValue; @@ -1298,7 +1316,7 @@ bool ReactNativeFeatureFlagsAccessor::overrideBySynchronousMountPropsAtMountingA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(70, "overrideBySynchronousMountPropsAtMountingAndroid"); + markFlagAsAccessed(71, "overrideBySynchronousMountPropsAtMountingAndroid"); flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid(); overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue; @@ -1316,7 +1334,7 @@ bool ReactNativeFeatureFlagsAccessor::perfIssuesEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "perfIssuesEnabled"); + markFlagAsAccessed(72, "perfIssuesEnabled"); flagValue = currentProvider_->perfIssuesEnabled(); perfIssuesEnabled_ = flagValue; @@ -1334,7 +1352,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "perfMonitorV2Enabled"); + markFlagAsAccessed(73, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -1352,7 +1370,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(73, "preparedTextCacheSize"); + markFlagAsAccessed(74, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -1370,7 +1388,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(74, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(75, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -1388,7 +1406,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2Android() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(75, "redBoxV2Android"); + markFlagAsAccessed(76, "redBoxV2Android"); flagValue = currentProvider_->redBoxV2Android(); redBoxV2Android_ = flagValue; @@ -1406,7 +1424,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2IOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(76, "redBoxV2IOS"); + markFlagAsAccessed(77, "redBoxV2IOS"); flagValue = currentProvider_->redBoxV2IOS(); redBoxV2IOS_ = flagValue; @@ -1424,7 +1442,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(77, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(78, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -1442,7 +1460,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldTriggerResponderTransferOnScrollAndr // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(78, "shouldTriggerResponderTransferOnScrollAndroid"); + markFlagAsAccessed(79, "shouldTriggerResponderTransferOnScrollAndroid"); flagValue = currentProvider_->shouldTriggerResponderTransferOnScrollAndroid(); shouldTriggerResponderTransferOnScrollAndroid_ = flagValue; @@ -1460,7 +1478,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(79, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(80, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1478,7 +1496,7 @@ bool ReactNativeFeatureFlagsAccessor::skipUnchangedChildrenInDifferentiator() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(80, "skipUnchangedChildrenInDifferentiator"); + markFlagAsAccessed(81, "skipUnchangedChildrenInDifferentiator"); flagValue = currentProvider_->skipUnchangedChildrenInDifferentiator(); skipUnchangedChildrenInDifferentiator_ = flagValue; @@ -1496,7 +1514,7 @@ bool ReactNativeFeatureFlagsAccessor::syncAndroidClipBoundsWithOverflow() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(81, "syncAndroidClipBoundsWithOverflow"); + markFlagAsAccessed(82, "syncAndroidClipBoundsWithOverflow"); flagValue = currentProvider_->syncAndroidClipBoundsWithOverflow(); syncAndroidClipBoundsWithOverflow_ = flagValue; @@ -1514,7 +1532,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(82, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(83, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1532,7 +1550,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(83, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(84, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1550,7 +1568,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommitT // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(84, "updateRuntimeShadowNodeReferencesOnCommitThread"); + markFlagAsAccessed(85, "updateRuntimeShadowNodeReferencesOnCommitThread"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommitThread(); updateRuntimeShadowNodeReferencesOnCommitThread_ = flagValue; @@ -1568,7 +1586,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(85, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(86, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1586,7 +1604,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(86, "useFabricInterop"); + markFlagAsAccessed(87, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1604,7 +1622,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(87, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(88, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1622,7 +1640,7 @@ bool ReactNativeFeatureFlagsAccessor::useNestedScrollViewAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(88, "useNestedScrollViewAndroid"); + markFlagAsAccessed(89, "useNestedScrollViewAndroid"); flagValue = currentProvider_->useNestedScrollViewAndroid(); useNestedScrollViewAndroid_ = flagValue; @@ -1640,7 +1658,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(89, "useSharedAnimatedBackend"); + markFlagAsAccessed(90, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1658,7 +1676,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(90, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(91, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1676,7 +1694,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(91, "useTurboModuleInterop"); + markFlagAsAccessed(92, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1694,7 +1712,7 @@ bool ReactNativeFeatureFlagsAccessor::useWindowDensityForDisplayMetricsAndroid() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(92, "useWindowDensityForDisplayMetricsAndroid"); + markFlagAsAccessed(93, "useWindowDensityForDisplayMetricsAndroid"); flagValue = currentProvider_->useWindowDensityForDisplayMetricsAndroid(); useWindowDensityForDisplayMetricsAndroid_ = flagValue; @@ -1712,7 +1730,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(93, "viewCullingOutsetRatio"); + markFlagAsAccessed(94, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1730,7 +1748,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(94, "viewTransitionEnabled"); + markFlagAsAccessed(95, "viewTransitionEnabled"); flagValue = currentProvider_->viewTransitionEnabled(); viewTransitionEnabled_ = flagValue; @@ -1748,7 +1766,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionUseHardwareBitmapAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(95, "viewTransitionUseHardwareBitmapAndroid"); + markFlagAsAccessed(96, "viewTransitionUseHardwareBitmapAndroid"); flagValue = currentProvider_->viewTransitionUseHardwareBitmapAndroid(); viewTransitionUseHardwareBitmapAndroid_ = flagValue; @@ -1766,7 +1784,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(96, "virtualViewPrerenderRatio"); + markFlagAsAccessed(97, "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 7a9bc59bc57..0ef554bf15e 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<<17f41335dce7e5b45e7af2878c47d69b>> + * @generated SignedSource<<917c49b8668e677e8e85ca97c8cb91db>> */ /** @@ -53,6 +53,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableAndroidTextMeasurementOptimizations(); bool enableAsyncDiskCacheCheckInMultiSourceImageAndroid(); bool enableBridgelessArchitecture(); + bool enableCoreComponentsPropsUpdateReconciliationAndroid(); bool enableCppPropsIteratorSetter(); bool enableCustomFocusSearchOnClippedElementsAndroid(); bool enableDestroyShadowTreeRevisionAsync(); @@ -142,7 +143,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 97> accessedFeatureFlags_; + std::array, 98> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -163,6 +164,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableAndroidTextMeasurementOptimizations_; std::atomic> enableAsyncDiskCacheCheckInMultiSourceImageAndroid_; std::atomic> enableBridgelessArchitecture_; + std::atomic> enableCoreComponentsPropsUpdateReconciliationAndroid_; std::atomic> enableCppPropsIteratorSetter_; std::atomic> enableCustomFocusSearchOnClippedElementsAndroid_; std::atomic> enableDestroyShadowTreeRevisionAsync_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 600aab1882c..8bcd29a4881 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<<35e8175277baa31d135d802ef5a5e6f1>> + * @generated SignedSource<<2eaa9084184e082b495516961dff4c08>> */ /** @@ -105,6 +105,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return true; } + bool enableCoreComponentsPropsUpdateReconciliationAndroid() override { + return false; + } + bool enableCppPropsIteratorSetter() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 88878807cfe..de4693a32c9 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<> */ /** @@ -218,6 +218,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableBridgelessArchitecture(); } + bool enableCoreComponentsPropsUpdateReconciliationAndroid() override { + auto value = values_["enableCoreComponentsPropsUpdateReconciliationAndroid"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::enableCoreComponentsPropsUpdateReconciliationAndroid(); + } + bool enableCppPropsIteratorSetter() override { auto value = values_["enableCppPropsIteratorSetter"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h index 47292fd47cc..33f32de8279 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.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<<02c8f99ea2314241417752f2efbbefa3>> */ /** @@ -37,6 +37,10 @@ class ReactNativeFeatureFlagsOverridesOSSExperimental : public ReactNativeFeatur return true; } + bool enableCoreComponentsPropsUpdateReconciliationAndroid() override { + return true; + } + bool enableFlexboxAutoMinSizeInStrictMode() override { return true; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 66492228700..ca81245c47b 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<<7413e958441d0502dc1266ff87e9da85>> + * @generated SignedSource<<4134897f2b8e7692103f86614f7ad284>> */ /** @@ -46,6 +46,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableAndroidTextMeasurementOptimizations() = 0; virtual bool enableAsyncDiskCacheCheckInMultiSourceImageAndroid() = 0; virtual bool enableBridgelessArchitecture() = 0; + virtual bool enableCoreComponentsPropsUpdateReconciliationAndroid() = 0; virtual bool enableCppPropsIteratorSetter() = 0; virtual bool enableCustomFocusSearchOnClippedElementsAndroid() = 0; virtual bool enableDestroyShadowTreeRevisionAsync() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index ca8a80f1adb..64d965c296d 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<<65e9161ec3769f2c776bd50686c7edad>> */ /** @@ -139,6 +139,11 @@ bool NativeReactNativeFeatureFlags::enableBridgelessArchitecture( return ReactNativeFeatureFlags::enableBridgelessArchitecture(); } +bool NativeReactNativeFeatureFlags::enableCoreComponentsPropsUpdateReconciliationAndroid( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableCoreComponentsPropsUpdateReconciliationAndroid(); +} + bool NativeReactNativeFeatureFlags::enableCppPropsIteratorSetter( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableCppPropsIteratorSetter(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 7413766e285..66b31a57ffd 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<<90f271ea47f91e6a84979209b7b3d816>> + * @generated SignedSource<> */ /** @@ -76,6 +76,8 @@ class NativeReactNativeFeatureFlags bool enableBridgelessArchitecture(jsi::Runtime& runtime); + bool enableCoreComponentsPropsUpdateReconciliationAndroid(jsi::Runtime& runtime); + bool enableCppPropsIteratorSetter(jsi::Runtime& runtime); bool enableCustomFocusSearchOnClippedElementsAndroid(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/tests/PropsDiffingGateTest.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/tests/PropsDiffingGateTest.cpp new file mode 100644 index 00000000000..db48270aea4 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/tests/PropsDiffingGateTest.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +#include + +#include +#include +#include + +#ifdef RN_SERIALIZABLE_STATE + +namespace facebook::react { + +namespace { + +class PropsDiffingFlags : public ReactNativeFeatureFlagsDefaults { + public: + PropsDiffingFlags(bool allComponents, bool coreComponents) + : allComponents_(allComponents), coreComponents_(coreComponents) {} + + bool enablePropsUpdateReconciliationAndroid() override { + return allComponents_; + } + + bool enableCoreComponentsPropsUpdateReconciliationAndroid() override { + return coreComponents_; + } + + private: + bool allComponents_; + bool coreComponents_; +}; + +// Stands in for codegen props, which return their own component name. +class CodegenLikeProps final : public ViewProps { + public: + ComponentName getDiffPropsImplementationTarget() const override { + return "Switch"; + } +}; + +} // namespace + +class PropsDiffingGateTest : public ::testing::Test { + protected: + void TearDown() override { + ReactNativeFeatureFlags::dangerouslyReset(); + } + + static void setFlags(bool allComponents, bool coreComponents) { + ReactNativeFeatureFlags::dangerouslyReset(); + ReactNativeFeatureFlags::override( + std::make_unique(allComponents, coreComponents)); + } + + const ViewProps viewProps_{}; + const CodegenLikeProps codegenProps_{}; +}; + +TEST_F(PropsDiffingGateTest, disabledWhenNoFlagIsOn) { + setFlags(/*allComponents*/ false, /*coreComponents*/ false); + EXPECT_FALSE(isPropsDiffingEnabled("View", viewProps_)); + EXPECT_FALSE(isPropsDiffingEnabled("Switch", codegenProps_)); +} + +TEST_F(PropsDiffingGateTest, allComponentsFlagEnablesCoreAndCodegen) { + setFlags(/*allComponents*/ true, /*coreComponents*/ false); + EXPECT_TRUE(isPropsDiffingEnabled("View", viewProps_)); + EXPECT_TRUE(isPropsDiffingEnabled("Switch", codegenProps_)); +} + +TEST_F(PropsDiffingGateTest, coreComponentsFlagEnablesOnlyCoreComponents) { + setFlags(/*allComponents*/ false, /*coreComponents*/ true); + EXPECT_TRUE(isPropsDiffingEnabled("View", viewProps_)); + EXPECT_FALSE(isPropsDiffingEnabled("Switch", codegenProps_)); +} + +TEST_F(PropsDiffingGateTest, disabledWhenComponentDoesNotImplementDiffing) { + // A component whose props inherit the View implementation without + // overriding the target falls back to raw props. + setFlags(/*allComponents*/ true, /*coreComponents*/ true); + EXPECT_FALSE(isPropsDiffingEnabled("SafeAreaView", viewProps_)); +} + +TEST_F(PropsDiffingGateTest, viewPropsTargetIsACoreComponent) { + setFlags(/*allComponents*/ false, /*coreComponents*/ true); + EXPECT_TRUE(isPropsDiffingEnabled( + viewProps_.getDiffPropsImplementationTarget(), viewProps_)); +} + +} // namespace facebook::react + +#endif diff --git a/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h b/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h index e11bf20fb3a..7248441a536 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h +++ b/packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h @@ -156,13 +156,9 @@ class ConcreteComponentDescriptor : public ComponentDescriptor { ReactNativeFeatureFlags_DO_NOT_USE::enableAccumulatedUpdatesInRawPropsAndroid()) { // When exclusive props update is enabled, we only apply Props 1.5 processing // (raw props merging) when Props 2.0 is not available. - if (ReactNativeFeatureFlags_DO_NOT_USE::enablePropsUpdateReconciliationAndroid()) { - // Cast to base Props reference to safely call virtual method - const auto &baseProps = static_cast(*shadowNodeProps); - if (strcmp(ShadowNodeT::Name(), baseProps.getDiffPropsImplementationTarget()) == 0) { - // Props 2.0 supported for this component, Props 1.5 processing can be skipped - fallbackToDynamicRawPropsAccumulation = false; - } + if (isPropsDiffingEnabled(ShadowNodeT::Name(), static_cast(*shadowNodeProps))) { + // Props 2.0 supported for this component, Props 1.5 processing can be skipped + fallbackToDynamicRawPropsAccumulation = false; } } if (fallbackToDynamicRawPropsAccumulation) { diff --git a/packages/react-native/ReactCommon/react/renderer/core/Props.cpp b/packages/react-native/ReactCommon/react/renderer/core/Props.cpp index 3e8845e9c31..1cbb629e277 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/Props.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/Props.cpp @@ -13,6 +13,11 @@ #include #include +#include +#include +#include +#include + namespace facebook::react { Props::Props( @@ -59,6 +64,42 @@ void Props::initializeDynamicProps( ComponentName Props::getDiffPropsImplementationTarget() const { return ""; } + +namespace { + +// Components whose hand-written props implement `getDiffProps`. Codegen +// components are excluded: their native defaults are not guaranteed to match +// the C++ defaults that props diffing relies on. +bool isCoreComponentWithPropsDiffing(std::string_view componentName) { + static constexpr std::array kCoreComponents = { + "View", + "Paragraph", + "Text", + "RawText", + "TextEffect", + "Image", + "ScrollView", + "TextInput", + }; + return std::find( + kCoreComponents.begin(), kCoreComponents.end(), componentName) != + kCoreComponents.end(); +} + +} // namespace + +bool isPropsDiffingEnabled(ComponentName componentName, const Props& props) { + if (std::strcmp(componentName, props.getDiffPropsImplementationTarget()) != + 0) { + return false; + } + if (ReactNativeFeatureFlags::enablePropsUpdateReconciliationAndroid()) { + return true; + } + return ReactNativeFeatureFlags:: + enableCoreComponentsPropsUpdateReconciliationAndroid() && + isCoreComponentWithPropsDiffing(componentName); +} #endif #pragma mark - DebugStringConvertible diff --git a/packages/react-native/ReactCommon/react/renderer/core/Props.h b/packages/react-native/ReactCommon/react/renderer/core/Props.h index c717e3182a0..c0e354ba60a 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/Props.h +++ b/packages/react-native/ReactCommon/react/renderer/core/Props.h @@ -86,6 +86,14 @@ class Props : public virtual Sealable, public virtual DebugStringConvertible { #endif }; +#ifdef RN_SERIALIZABLE_STATE +/* + * Whether mount instructions for `componentName` are built with + * `Props::getDiffProps` instead of raw props, given the enabled feature flags. + */ +bool isPropsDiffingEnabled(ComponentName componentName, const Props &props); +#endif + namespace detail { /* diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 612c196ff22..e896a8cb0f2 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -256,6 +256,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'stable', }, + enableCoreComponentsPropsUpdateReconciliationAndroid: { + defaultValue: false, + metadata: { + dateAdded: '2026-10-26', + description: + 'When enabled, Android receives prop updates based on props diffing only for core components with hand-written props (View, Text, Image, ScrollView, TextInput). Other components keep receiving raw props unless `enablePropsUpdateReconciliationAndroid` is enabled.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'experimental', + }, enableCppPropsIteratorSetter: { dangerouslyExposeInPublicCppHeaders: true, defaultValue: false, diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index e5a8120cff6..13ca4b62146 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<<674f975884ae746e067e614523f2bfc3>> + * @generated SignedSource<<5a20b81ad6800e3a83cb4e9681e0f903>> * @flow strict * @noformat */ @@ -68,6 +68,7 @@ export type ReactNativeFeatureFlags = Readonly<{ enableAndroidTextMeasurementOptimizations: Getter, enableAsyncDiskCacheCheckInMultiSourceImageAndroid: Getter, enableBridgelessArchitecture: Getter, + enableCoreComponentsPropsUpdateReconciliationAndroid: Getter, enableCppPropsIteratorSetter: Getter, enableCustomFocusSearchOnClippedElementsAndroid: Getter, enableDestroyShadowTreeRevisionAsync: Getter, @@ -298,6 +299,10 @@ export const enableAsyncDiskCacheCheckInMultiSourceImageAndroid: Getter * Feature flag to enable the new bridgeless architecture. */ export const enableBridgelessArchitecture: Getter = createNativeFlagGetter('enableBridgelessArchitecture', true); +/** + * When enabled, Android receives prop updates based on props diffing only for core components with hand-written props (View, Text, Image, ScrollView, TextInput). Other components keep receiving raw props unless `enablePropsUpdateReconciliationAndroid` is enabled. + */ +export const enableCoreComponentsPropsUpdateReconciliationAndroid: Getter = createNativeFlagGetter('enableCoreComponentsPropsUpdateReconciliationAndroid', false); /** * Enable prop iterator setter-style construction of Props in C++ (this flag is not used in Java). */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 6fc752bba2a..07c69a14ab9 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<<2eb3f4a3dca013c51ad2913944855010>> + * @generated SignedSource<<8a6f75a66050ab8cf760cb8b4920cb0d>> * @flow strict * @noformat */ @@ -44,6 +44,7 @@ export interface Spec extends TurboModule { readonly enableAndroidTextMeasurementOptimizations?: () => boolean; readonly enableAsyncDiskCacheCheckInMultiSourceImageAndroid?: () => boolean; readonly enableBridgelessArchitecture?: () => boolean; + readonly enableCoreComponentsPropsUpdateReconciliationAndroid?: () => boolean; readonly enableCppPropsIteratorSetter?: () => boolean; readonly enableCustomFocusSearchOnClippedElementsAndroid?: () => boolean; readonly enableDestroyShadowTreeRevisionAsync?: () => boolean; diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api index 0b8d391a463..c006a8675ff 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api @@ -490,6 +490,7 @@ YGDirection facebook::react::yogaDirectionFromLayoutDirection(facebook::react::L bool facebook::react::areBorderRadiiCircular(const facebook::react::BorderRadii& borderRadii); bool facebook::react::hostPlatformColorIsColorMeaningful(facebook::react::Color color) noexcept; bool facebook::react::isColorMeaningful(const facebook::react::SharedColor& color) noexcept; +bool facebook::react::isPropsDiffingEnabled(facebook::react::ComponentName componentName, const facebook::react::Props& props); bool facebook::react::isZero(facebook::react::Float n); constexpr auto facebook::react::to_underlying(auto e) noexcept; constexpr char facebook::react::toLower(char c); diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api index 063d23740fa..ed59803dd92 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidFrameworksCxx.api @@ -704,6 +704,7 @@ bool facebook::react::areTextAttributesEquivalentLayoutWise(const facebook::reac bool facebook::react::hostPlatformColorIsColorMeaningful(facebook::react::Color color) noexcept; bool facebook::react::isColorMeaningful(const facebook::react::SharedColor& color) noexcept; bool facebook::react::isHermesBytecodeBundle(const facebook::react::BundleHeader& header); +bool facebook::react::isPropsDiffingEnabled(facebook::react::ComponentName componentName, const facebook::react::Props& props); bool facebook::react::isZero(facebook::react::Float n); const char* facebook::react::stringForScriptTag(const facebook::react::ScriptTag& tag); constexpr auto facebook::react::to_underlying(auto e) noexcept; diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api index 636dea874c7..52a35b8b6ab 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidNewarchCxx.api @@ -490,6 +490,7 @@ YGDirection facebook::react::yogaDirectionFromLayoutDirection(facebook::react::L bool facebook::react::areBorderRadiiCircular(const facebook::react::BorderRadii& borderRadii); bool facebook::react::hostPlatformColorIsColorMeaningful(facebook::react::Color color) noexcept; bool facebook::react::isColorMeaningful(const facebook::react::SharedColor& color) noexcept; +bool facebook::react::isPropsDiffingEnabled(facebook::react::ComponentName componentName, const facebook::react::Props& props); bool facebook::react::isZero(facebook::react::Float n); constexpr auto facebook::react::to_underlying(auto e) noexcept; constexpr char facebook::react::toLower(char c); diff --git a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api index 636dea874c7..52a35b8b6ab 100644 --- a/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api +++ b/scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api @@ -490,6 +490,7 @@ YGDirection facebook::react::yogaDirectionFromLayoutDirection(facebook::react::L bool facebook::react::areBorderRadiiCircular(const facebook::react::BorderRadii& borderRadii); bool facebook::react::hostPlatformColorIsColorMeaningful(facebook::react::Color color) noexcept; bool facebook::react::isColorMeaningful(const facebook::react::SharedColor& color) noexcept; +bool facebook::react::isPropsDiffingEnabled(facebook::react::ComponentName componentName, const facebook::react::Props& props); bool facebook::react::isZero(facebook::react::Float n); constexpr auto facebook::react::to_underlying(auto e) noexcept; constexpr char facebook::react::toLower(char c);