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 cffb38e37ee343..1fb0daae189337 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<<575eeb1e291c1a372eba7aabcdd948e3>> */ /** @@ -52,6 +52,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun disableEventLoopOnBridgeless(): Boolean = accessor.disableEventLoopOnBridgeless() + /** + * Prevent FabricMountingManager from reordering mountitems, which may lead to invalid state on the UI thread + */ + @JvmStatic + public fun disableMountItemReorderingAndroid(): Boolean = accessor.disableMountItemReorderingAndroid() + /** * Kill-switch to turn off support for aling-items:baseline on Fabric iOS. */ 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 6951d052b2f2ff..9ee03db25ef923 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<<6b3d3512d88c836dd809204cad636211>> + * @generated SignedSource<> */ /** @@ -24,6 +24,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null private var disableEventLoopOnBridgelessCache: Boolean? = null + private var disableMountItemReorderingAndroidCache: Boolean? = null private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null private var enableAndroidLineHeightCenteringCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null @@ -104,6 +105,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun disableMountItemReorderingAndroid(): Boolean { + var cached = disableMountItemReorderingAndroidCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.disableMountItemReorderingAndroid() + disableMountItemReorderingAndroidCache = cached + } + return cached + } + override fun enableAlignItemsBaselineOnFabricIOS(): Boolean { var cached = enableAlignItemsBaselineOnFabricIOSCache 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 beb07351efe7be..5cfdfe9e060603 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<<0ef9a66ccabeb0357f4b15c3e897f8fb>> + * @generated SignedSource<<44d0fe9a36e5e51816e10b8799d451fe>> */ /** @@ -36,6 +36,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun disableEventLoopOnBridgeless(): Boolean + @DoNotStrip @JvmStatic public external fun disableMountItemReorderingAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun enableAlignItemsBaselineOnFabricIOS(): Boolean @DoNotStrip @JvmStatic public external fun enableAndroidLineHeightCentering(): 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 cd29e014259de9..f230cc33fdcfc5 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<<917a6effbfd0a476cc05d90abee3c80b>> */ /** @@ -31,6 +31,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun disableEventLoopOnBridgeless(): Boolean = false + override fun disableMountItemReorderingAndroid(): Boolean = false + override fun enableAlignItemsBaselineOnFabricIOS(): Boolean = true override fun enableAndroidLineHeightCentering(): 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 c8674af73cf3e3..8dd0f02fb5704c 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<<949f5cdf6d0a4015fbd680ba718dce6d>> + * @generated SignedSource<<2ad36465b1a411cb55d85416bd8ba823>> */ /** @@ -28,6 +28,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null private var disableEventLoopOnBridgelessCache: Boolean? = null + private var disableMountItemReorderingAndroidCache: Boolean? = null private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null private var enableAndroidLineHeightCenteringCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null @@ -112,6 +113,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun disableMountItemReorderingAndroid(): Boolean { + var cached = disableMountItemReorderingAndroidCache + if (cached == null) { + cached = currentProvider.disableMountItemReorderingAndroid() + accessedFeatureFlags.add("disableMountItemReorderingAndroid") + disableMountItemReorderingAndroidCache = cached + } + return cached + } + override fun enableAlignItemsBaselineOnFabricIOS(): Boolean { var cached = enableAlignItemsBaselineOnFabricIOSCache 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 36e8db344f06d1..32af144a3bdbdd 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<<4e42e76c98b7434273e4f11212f0527b>> + * @generated SignedSource<<9770a9f125b8bcb4b1daef9e3458433f>> */ /** @@ -31,6 +31,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun disableEventLoopOnBridgeless(): Boolean + @DoNotStrip public fun disableMountItemReorderingAndroid(): Boolean + @DoNotStrip public fun enableAlignItemsBaselineOnFabricIOS(): Boolean @DoNotStrip public fun enableAndroidLineHeightCentering(): 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 b5eb6c64bd238e..c6ae9d3c4ae328 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 @@ -37,7 +37,8 @@ FabricMountingManager::FabricMountingManager( void FabricMountingManager::onSurfaceStart(SurfaceId surfaceId) { std::lock_guard lock(allocatedViewsMutex_); - allocatedViewRegistry_.emplace(surfaceId, std::unordered_set{}); + allocatedViewRegistry_.emplace( + surfaceId, std::unordered_set({surfaceId})); } void FabricMountingManager::onSurfaceStop(SurfaceId surfaceId) { @@ -465,6 +466,9 @@ void FabricMountingManager::executeMount( auto surfaceId = transaction.getSurfaceId(); auto& mutations = transaction.getMutations(); + bool maintainMutationOrder = + ReactNativeFeatureFlags::disableMountItemReorderingAndroid(); + auto revisionNumber = telemetry.getRevisionNumber(); std::vector cppCommonMountItems; @@ -486,7 +490,7 @@ void FabricMountingManager::executeMount( // operand is a value type, the compiler will decide the expression to be a // value type, an unnecessary (sometimes expensive) copy will happen as a // result. - const auto& allocatedViewTags = + auto& allocatedViewTags = allocatedViewsIterator != allocatedViewRegistry_.end() ? allocatedViewsIterator->second : defaultAllocatedViews; @@ -510,6 +514,7 @@ void FabricMountingManager::executeMount( if (shouldCreateView) { cppCommonMountItems.push_back( CppMountItem::CreateMountItem(newChildShadowView)); + allocatedViewTags.insert(newChildShadowView.tag); } break; } @@ -521,20 +526,32 @@ void FabricMountingManager::executeMount( break; } case ShadowViewMutation::Delete: { - cppDeleteMountItems.push_back( - CppMountItem::DeleteMountItem(oldChildShadowView)); + (maintainMutationOrder ? cppCommonMountItems : cppDeleteMountItems) + .push_back(CppMountItem::DeleteMountItem(oldChildShadowView)); + if (allocatedViewTags.erase(oldChildShadowView.tag) != 1) { + LOG(ERROR) << "Emitting delete for unallocated view. " + << oldChildShadowView.tag; + } break; } case ShadowViewMutation::Update: { if (!isVirtual) { + if (!allocatedViewTags.contains(newChildShadowView.tag)) { + LOG(FATAL) << "Emitting update for unallocated view. " + << newChildShadowView.tag; + } + if (oldChildShadowView.props != newChildShadowView.props) { - cppUpdatePropsMountItems.push_back( - CppMountItem::UpdatePropsMountItem( + (maintainMutationOrder ? cppCommonMountItems + : cppUpdatePropsMountItems) + .push_back(CppMountItem::UpdatePropsMountItem( oldChildShadowView, newChildShadowView)); } if (oldChildShadowView.state != newChildShadowView.state) { - cppUpdateStateMountItems.push_back( - CppMountItem::UpdateStateMountItem(newChildShadowView)); + (maintainMutationOrder ? cppCommonMountItems + : cppUpdateStateMountItems) + .push_back( + CppMountItem::UpdateStateMountItem(newChildShadowView)); } // Padding: padding mountItems must be executed before layout props @@ -543,14 +560,17 @@ void FabricMountingManager::executeMount( // padding information. if (oldChildShadowView.layoutMetrics.contentInsets != newChildShadowView.layoutMetrics.contentInsets) { - cppUpdatePaddingMountItems.push_back( - CppMountItem::UpdatePaddingMountItem(newChildShadowView)); + (maintainMutationOrder ? cppCommonMountItems + : cppUpdatePaddingMountItems) + .push_back( + CppMountItem::UpdatePaddingMountItem(newChildShadowView)); } if (oldChildShadowView.layoutMetrics != newChildShadowView.layoutMetrics) { - cppUpdateLayoutMountItems.push_back( - CppMountItem::UpdateLayoutMountItem( + (maintainMutationOrder ? cppCommonMountItems + : cppUpdateLayoutMountItems) + .push_back(CppMountItem::UpdateLayoutMountItem( mutation.newChildShadowView, parentShadowView)); } @@ -560,16 +580,18 @@ void FabricMountingManager::executeMount( // pack too much data there. if ((oldChildShadowView.layoutMetrics.overflowInset != newChildShadowView.layoutMetrics.overflowInset)) { - cppUpdateOverflowInsetMountItems.push_back( - CppMountItem::UpdateOverflowInsetMountItem( + (maintainMutationOrder ? cppCommonMountItems + : cppUpdateOverflowInsetMountItems) + .push_back(CppMountItem::UpdateOverflowInsetMountItem( newChildShadowView)); } } if (oldChildShadowView.eventEmitter != newChildShadowView.eventEmitter) { - cppUpdateEventEmitterMountItems.push_back( - CppMountItem::UpdateEventEmitterMountItem( + (maintainMutationOrder ? cppCommonMountItems + : cppUpdatePropsMountItems) + .push_back(CppMountItem::UpdateEventEmitterMountItem( mutation.newChildShadowView)); } break; @@ -580,19 +602,23 @@ void FabricMountingManager::executeMount( cppCommonMountItems.push_back(CppMountItem::InsertMountItem( parentShadowView, newChildShadowView, index)); - bool allocationCheck = - allocatedViewTags.find(newChildShadowView.tag) == - allocatedViewTags.end(); - bool shouldCreateView = allocationCheck; + bool shouldCreateView = + !allocatedViewTags.contains(newChildShadowView.tag); if (shouldCreateView) { - cppUpdatePropsMountItems.push_back( - CppMountItem::UpdatePropsMountItem({}, newChildShadowView)); + LOG(ERROR) << "Emitting insert for unallocated view. " + << newChildShadowView.tag; + (maintainMutationOrder ? cppCommonMountItems + : cppUpdatePropsMountItems) + .push_back(CppMountItem::UpdatePropsMountItem( + {}, newChildShadowView)); } // State if (newChildShadowView.state) { - cppUpdateStateMountItems.push_back( - CppMountItem::UpdateStateMountItem(newChildShadowView)); + (maintainMutationOrder ? cppCommonMountItems + : cppUpdateStateMountItems) + .push_back( + CppMountItem::UpdateStateMountItem(newChildShadowView)); } // Padding: padding mountItems must be executed before layout props @@ -601,13 +627,16 @@ void FabricMountingManager::executeMount( // padding information. if (newChildShadowView.layoutMetrics.contentInsets != EdgeInsets::ZERO) { - cppUpdatePaddingMountItems.push_back( - CppMountItem::UpdatePaddingMountItem(newChildShadowView)); + (maintainMutationOrder ? cppCommonMountItems + : cppUpdatePaddingMountItems) + .push_back( + CppMountItem::UpdatePaddingMountItem(newChildShadowView)); } // Layout - cppUpdateLayoutMountItems.push_back( - CppMountItem::UpdateLayoutMountItem( + (maintainMutationOrder ? cppCommonMountItems + : cppUpdateLayoutMountItems) + .push_back(CppMountItem::UpdateLayoutMountItem( newChildShadowView, parentShadowView)); // OverflowInset: This is the values indicating boundaries including @@ -616,15 +645,19 @@ void FabricMountingManager::executeMount( // pack too much data there. if (newChildShadowView.layoutMetrics.overflowInset != EdgeInsets::ZERO) { - cppUpdateOverflowInsetMountItems.push_back( - CppMountItem::UpdateOverflowInsetMountItem( + (maintainMutationOrder ? cppCommonMountItems + : cppUpdateOverflowInsetMountItems) + .push_back(CppMountItem::UpdateOverflowInsetMountItem( newChildShadowView)); } } // EventEmitter - cppUpdateEventEmitterMountItems.push_back( - CppMountItem::UpdateEventEmitterMountItem( + // On insert we always update the event emitter, as we do not pass + // it in when preallocating views + (maintainMutationOrder ? cppCommonMountItems + : cppUpdateEventEmitterMountItems) + .push_back(CppMountItem::UpdateEventEmitterMountItem( mutation.newChildShadowView)); break; @@ -634,22 +667,6 @@ void FabricMountingManager::executeMount( } } } - - if (allocatedViewsIterator != allocatedViewRegistry_.end()) { - auto& views = allocatedViewsIterator->second; - for (const auto& mutation : mutations) { - switch (mutation.type) { - case ShadowViewMutation::Create: - views.insert(mutation.newChildShadowView.tag); - break; - case ShadowViewMutation::Delete: - views.erase(mutation.oldChildShadowView.tag); - break; - default: - break; - } - } - } } // We now have all the information we need, including ordering of mount items, @@ -728,12 +745,33 @@ void FabricMountingManager::executeMount( case CppMountItem::Type::Create: writeCreateMountItem(buffer, mountItem); break; + case CppMountItem::Type::Delete: + writeDeleteMountItem(buffer, mountItem); + break; case CppMountItem::Type::Insert: writeInsertMountItem(buffer, mountItem); break; case CppMountItem::Type::Remove: writeRemoveMountItem(buffer, mountItem); break; + case CppMountItem::Type::UpdateProps: + writeUpdatePropsMountItem(buffer, mountItem); + break; + case CppMountItem::Type::UpdateState: + writeUpdateStateMountItem(buffer, mountItem); + break; + case CppMountItem::Type::UpdateLayout: + writeUpdateLayoutMountItem(buffer, mountItem); + break; + case CppMountItem::Type::UpdateEventEmitter: + writeUpdateEventEmitterMountItem(buffer, mountItem); + break; + case CppMountItem::Type::UpdatePadding: + writeUpdatePaddingMountItem(buffer, mountItem); + break; + case CppMountItem::Type::UpdateOverflowInset: + writeUpdateOverflowInsetMountItem(buffer, mountItem); + break; default: LOG(FATAL) << "Unexpected CppMountItem type: " << mountItemType; } @@ -906,11 +944,11 @@ void FabricMountingManager::preallocateShadowView( if (allocatedViewsIterator == allocatedViewRegistry_.end()) { return; } - auto& allocatedViews = allocatedViewsIterator->second; - if (allocatedViews.find(shadowView.tag) != allocatedViews.end()) { + const auto [_, inserted] = + allocatedViewsIterator->second.insert(shadowView.tag); + if (!inserted) { return; } - allocatedViews.insert(shadowView.tag); } bool isLayoutableShadowNode = shadowView.layoutMetrics != EmptyLayoutMetrics; 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 704015059f6d40..e95510f969b67d 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<<732d1ea726d8a08859bd153dc767ec7a>> + * @generated SignedSource<> */ /** @@ -63,6 +63,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool disableMountItemReorderingAndroid() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("disableMountItemReorderingAndroid"); + return method(javaProvider_); + } + bool enableAlignItemsBaselineOnFabricIOS() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableAlignItemsBaselineOnFabricIOS"); @@ -345,6 +351,11 @@ bool JReactNativeFeatureFlagsCxxInterop::disableEventLoopOnBridgeless( return ReactNativeFeatureFlags::disableEventLoopOnBridgeless(); } +bool JReactNativeFeatureFlagsCxxInterop::disableMountItemReorderingAndroid( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::disableMountItemReorderingAndroid(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS(); @@ -603,6 +614,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "disableEventLoopOnBridgeless", JReactNativeFeatureFlagsCxxInterop::disableEventLoopOnBridgeless), + makeNativeMethod( + "disableMountItemReorderingAndroid", + JReactNativeFeatureFlagsCxxInterop::disableMountItemReorderingAndroid), makeNativeMethod( "enableAlignItemsBaselineOnFabricIOS", JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS), 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 e480193163af18..0832d4b67e6a2a 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<<88fc1d08894dc2f774ed8c64b20bdaeb>> + * @generated SignedSource<> */ /** @@ -42,6 +42,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool disableEventLoopOnBridgeless( facebook::jni::alias_ref); + static bool disableMountItemReorderingAndroid( + facebook::jni::alias_ref); + static bool enableAlignItemsBaselineOnFabricIOS( 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 696d000e77bb8a..8a7e60b3777695 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<> + * @generated SignedSource<> */ /** @@ -42,6 +42,10 @@ bool ReactNativeFeatureFlags::disableEventLoopOnBridgeless() { return getAccessor().disableEventLoopOnBridgeless(); } +bool ReactNativeFeatureFlags::disableMountItemReorderingAndroid() { + return getAccessor().disableMountItemReorderingAndroid(); +} + bool ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS() { return getAccessor().enableAlignItemsBaselineOnFabricIOS(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 795a323ea19e2c..84169504a29a2c 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<<29b98e3d5daf7ad09cdee366ef38753e>> + * @generated SignedSource<> */ /** @@ -59,6 +59,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool disableEventLoopOnBridgeless(); + /** + * Prevent FabricMountingManager from reordering mountitems, which may lead to invalid state on the UI thread + */ + RN_EXPORT static bool disableMountItemReorderingAndroid(); + /** * Kill-switch to turn off support for aling-items:baseline on Fabric iOS. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 691e72052380f0..8bbec0e1742778 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<<59763b4423e81fbb2f99f78d12c9cca7>> + * @generated SignedSource<> */ /** @@ -101,6 +101,24 @@ bool ReactNativeFeatureFlagsAccessor::disableEventLoopOnBridgeless() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::disableMountItemReorderingAndroid() { + auto flagValue = disableMountItemReorderingAndroid_.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(4, "disableMountItemReorderingAndroid"); + + flagValue = currentProvider_->disableMountItemReorderingAndroid(); + disableMountItemReorderingAndroid_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableAlignItemsBaselineOnFabricIOS() { auto flagValue = enableAlignItemsBaselineOnFabricIOS_.load(); @@ -110,7 +128,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAlignItemsBaselineOnFabricIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(4, "enableAlignItemsBaselineOnFabricIOS"); + markFlagAsAccessed(5, "enableAlignItemsBaselineOnFabricIOS"); flagValue = currentProvider_->enableAlignItemsBaselineOnFabricIOS(); enableAlignItemsBaselineOnFabricIOS_ = flagValue; @@ -128,7 +146,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAndroidLineHeightCentering() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(5, "enableAndroidLineHeightCentering"); + markFlagAsAccessed(6, "enableAndroidLineHeightCentering"); flagValue = currentProvider_->enableAndroidLineHeightCentering(); enableAndroidLineHeightCentering_ = flagValue; @@ -146,7 +164,7 @@ bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(6, "enableBridgelessArchitecture"); + markFlagAsAccessed(7, "enableBridgelessArchitecture"); flagValue = currentProvider_->enableBridgelessArchitecture(); enableBridgelessArchitecture_ = flagValue; @@ -164,7 +182,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCleanTextInputYogaNode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(7, "enableCleanTextInputYogaNode"); + markFlagAsAccessed(8, "enableCleanTextInputYogaNode"); flagValue = currentProvider_->enableCleanTextInputYogaNode(); enableCleanTextInputYogaNode_ = flagValue; @@ -182,7 +200,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(8, "enableCppPropsIteratorSetter"); + markFlagAsAccessed(9, "enableCppPropsIteratorSetter"); flagValue = currentProvider_->enableCppPropsIteratorSetter(); enableCppPropsIteratorSetter_ = flagValue; @@ -200,7 +218,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDeletionOfUnmountedViews() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(9, "enableDeletionOfUnmountedViews"); + markFlagAsAccessed(10, "enableDeletionOfUnmountedViews"); flagValue = currentProvider_->enableDeletionOfUnmountedViews(); enableDeletionOfUnmountedViews_ = flagValue; @@ -218,7 +236,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(10, "enableEagerRootViewAttachment"); + markFlagAsAccessed(11, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -236,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEventEmitterRetentionDuringGesturesO // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(11, "enableEventEmitterRetentionDuringGesturesOnAndroid"); + markFlagAsAccessed(12, "enableEventEmitterRetentionDuringGesturesOnAndroid"); flagValue = currentProvider_->enableEventEmitterRetentionDuringGesturesOnAndroid(); enableEventEmitterRetentionDuringGesturesOnAndroid_ = flagValue; @@ -254,7 +272,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(12, "enableFabricLogs"); + markFlagAsAccessed(13, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -272,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(13, "enableFabricRenderer"); + markFlagAsAccessed(14, "enableFabricRenderer"); flagValue = currentProvider_->enableFabricRenderer(); enableFabricRenderer_ = flagValue; @@ -290,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRendererExclusively() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(14, "enableFabricRendererExclusively"); + markFlagAsAccessed(15, "enableFabricRendererExclusively"); flagValue = currentProvider_->enableFabricRendererExclusively(); enableFabricRendererExclusively_ = flagValue; @@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableGranularShadowTreeStateReconciliatio // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "enableGranularShadowTreeStateReconciliation"); + markFlagAsAccessed(16, "enableGranularShadowTreeStateReconciliation"); flagValue = currentProvider_->enableGranularShadowTreeStateReconciliation(); enableGranularShadowTreeStateReconciliation_ = flagValue; @@ -326,7 +344,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(16, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(17, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -344,7 +362,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(17, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(18, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -362,7 +380,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(18, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(19, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "enableLongTaskAPI"); + markFlagAsAccessed(20, "enableLongTaskAPI"); flagValue = currentProvider_->enableLongTaskAPI(); enableLongTaskAPI_ = flagValue; @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNewBackgroundAndBorderDrawables() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enableNewBackgroundAndBorderDrawables"); + markFlagAsAccessed(21, "enableNewBackgroundAndBorderDrawables"); flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables(); enableNewBackgroundAndBorderDrawables_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreciseSchedulingForPremountItemsOnA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "enablePreciseSchedulingForPremountItemsOnAndroid"); + markFlagAsAccessed(22, "enablePreciseSchedulingForPremountItemsOnAndroid"); flagValue = currentProvider_->enablePreciseSchedulingForPremountItemsOnAndroid(); enablePreciseSchedulingForPremountItemsOnAndroid_ = flagValue; @@ -434,7 +452,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(22, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(23, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableReportEventPaintTime() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableReportEventPaintTime"); + markFlagAsAccessed(24, "enableReportEventPaintTime"); flagValue = currentProvider_->enableReportEventPaintTime(); enableReportEventPaintTime_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableSynchronousStateUpdates"); + markFlagAsAccessed(25, "enableSynchronousStateUpdates"); flagValue = currentProvider_->enableSynchronousStateUpdates(); enableSynchronousStateUpdates_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableTextPreallocationOptimisation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableTextPreallocationOptimisation"); + markFlagAsAccessed(26, "enableTextPreallocationOptimisation"); flagValue = currentProvider_->enableTextPreallocationOptimisation(); enableTextPreallocationOptimisation_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "enableUIConsistency"); + markFlagAsAccessed(27, "enableUIConsistency"); flagValue = currentProvider_->enableUIConsistency(); enableUIConsistency_ = flagValue; @@ -524,7 +542,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(27, "enableViewRecycling"); + markFlagAsAccessed(28, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::excludeYogaFromRawProps() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "excludeYogaFromRawProps"); + markFlagAsAccessed(29, "excludeYogaFromRawProps"); flagValue = currentProvider_->excludeYogaFromRawProps(); excludeYogaFromRawProps_ = flagValue; @@ -560,7 +578,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(29, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(30, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMountingCoordinatorReportedPendingTrans // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); + markFlagAsAccessed(31, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); flagValue = currentProvider_->fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); fixMountingCoordinatorReportedPendingTransactionsOnAndroid_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::forceBatchingMountItemsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "forceBatchingMountItemsOnAndroid"); + markFlagAsAccessed(32, "forceBatchingMountItemsOnAndroid"); flagValue = currentProvider_->forceBatchingMountItemsOnAndroid(); forceBatchingMountItemsOnAndroid_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledDebug() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "fuseboxEnabledDebug"); + markFlagAsAccessed(33, "fuseboxEnabledDebug"); flagValue = currentProvider_->fuseboxEnabledDebug(); fuseboxEnabledDebug_ = flagValue; @@ -632,7 +650,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(33, "fuseboxEnabledRelease"); + markFlagAsAccessed(34, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::initEagerTurboModulesOnNativeModulesQueueA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "initEagerTurboModulesOnNativeModulesQueueAndroid"); + markFlagAsAccessed(35, "initEagerTurboModulesOnNativeModulesQueueAndroid"); flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid(); initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "lazyAnimationCallbacks"); + markFlagAsAccessed(36, "lazyAnimationCallbacks"); flagValue = currentProvider_->lazyAnimationCallbacks(); lazyAnimationCallbacks_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::loadVectorDrawablesOnImages() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "loadVectorDrawablesOnImages"); + markFlagAsAccessed(37, "loadVectorDrawablesOnImages"); flagValue = currentProvider_->loadVectorDrawablesOnImages(); loadVectorDrawablesOnImages_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::setAndroidLayoutDirection() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "setAndroidLayoutDirection"); + markFlagAsAccessed(38, "setAndroidLayoutDirection"); flagValue = currentProvider_->setAndroidLayoutDirection(); setAndroidLayoutDirection_ = flagValue; @@ -722,7 +740,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(38, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(39, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -740,7 +758,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(39, "useFabricInterop"); + markFlagAsAccessed(40, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "useImmediateExecutorInAndroidBridgeless"); + markFlagAsAccessed(41, "useImmediateExecutorInAndroidBridgeless"); flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless(); useImmediateExecutorInAndroidBridgeless_ = flagValue; @@ -776,7 +794,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(41, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(42, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimisedViewPreallocationOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "useOptimisedViewPreallocationOnAndroid"); + markFlagAsAccessed(43, "useOptimisedViewPreallocationOnAndroid"); flagValue = currentProvider_->useOptimisedViewPreallocationOnAndroid(); useOptimisedViewPreallocationOnAndroid_ = flagValue; @@ -812,7 +830,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(43, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(44, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "useRuntimeShadowNodeReferenceUpdate"); + markFlagAsAccessed(45, "useRuntimeShadowNodeReferenceUpdate"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate(); useRuntimeShadowNodeReferenceUpdate_ = flagValue; @@ -848,7 +866,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(45, "useTurboModuleInterop"); + markFlagAsAccessed(46, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -866,7 +884,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(46, "useTurboModules"); + markFlagAsAccessed(47, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 82934f3674d7af..d723765b1d4b13 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<> + * @generated SignedSource<> */ /** @@ -36,6 +36,7 @@ class ReactNativeFeatureFlagsAccessor { bool allowRecursiveCommitsWithSynchronousMountOnAndroid(); bool completeReactInstanceCreationOnBgThreadOnAndroid(); bool disableEventLoopOnBridgeless(); + bool disableMountItemReorderingAndroid(); bool enableAlignItemsBaselineOnFabricIOS(); bool enableAndroidLineHeightCentering(); bool enableBridgelessArchitecture(); @@ -90,12 +91,13 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 47> accessedFeatureFlags_; + std::array, 48> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> allowRecursiveCommitsWithSynchronousMountOnAndroid_; std::atomic> completeReactInstanceCreationOnBgThreadOnAndroid_; std::atomic> disableEventLoopOnBridgeless_; + std::atomic> disableMountItemReorderingAndroid_; std::atomic> enableAlignItemsBaselineOnFabricIOS_; std::atomic> enableAndroidLineHeightCentering_; std::atomic> enableBridgelessArchitecture_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 1201da7752f220..199c44d34f845d 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<<116547f17bc1b3d16a8de7c92c5a9d53>> + * @generated SignedSource<<631c825e33e07674e19a084a33637a50>> */ /** @@ -43,6 +43,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool disableMountItemReorderingAndroid() override { + return false; + } + bool enableAlignItemsBaselineOnFabricIOS() override { return true; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 69f8d38a5c5cf7..8c4cf367780cbc 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<<18597e1e2a88be3d80b8747f72576d5f>> */ /** @@ -29,6 +29,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool allowRecursiveCommitsWithSynchronousMountOnAndroid() = 0; virtual bool completeReactInstanceCreationOnBgThreadOnAndroid() = 0; virtual bool disableEventLoopOnBridgeless() = 0; + virtual bool disableMountItemReorderingAndroid() = 0; virtual bool enableAlignItemsBaselineOnFabricIOS() = 0; virtual bool enableAndroidLineHeightCentering() = 0; virtual bool enableBridgelessArchitecture() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index ace962fde67a43..1093afddc8a675 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<<77a440bf8f6221e90d5ab7a1d7ad638e>> + * @generated SignedSource<<43e3b8b18dec356b5121b581ab8ffa02>> */ /** @@ -71,6 +71,11 @@ bool NativeReactNativeFeatureFlags::disableEventLoopOnBridgeless( return ReactNativeFeatureFlags::disableEventLoopOnBridgeless(); } +bool NativeReactNativeFeatureFlags::disableMountItemReorderingAndroid( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::disableMountItemReorderingAndroid(); +} + bool NativeReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index ddb938e89eb82e..e7356d78e46c02 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<<0885affcf6782a59b0f4a3d1370ffc90>> + * @generated SignedSource<> */ /** @@ -47,6 +47,8 @@ class NativeReactNativeFeatureFlags bool disableEventLoopOnBridgeless(jsi::Runtime& runtime); + bool disableMountItemReorderingAndroid(jsi::Runtime& runtime); + bool enableAlignItemsBaselineOnFabricIOS(jsi::Runtime& runtime); bool enableAndroidLineHeightCentering(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index fe6354d088be45..3a927575782d86 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -90,6 +90,15 @@ const definitions: FeatureFlagDefinitions = { purpose: 'release', }, }, + disableMountItemReorderingAndroid: { + defaultValue: false, + metadata: { + dateAdded: '2024-10-26', + description: + 'Prevent FabricMountingManager from reordering mountitems, which may lead to invalid state on the UI thread', + purpose: 'experimentation', + }, + }, enableAlignItemsBaselineOnFabricIOS: { defaultValue: true, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 0f17ec52578f00..106d1232cc584d 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<> + * @generated SignedSource<<096ac17a630f7b29d3a029c704dbd8db>> * @flow strict */ @@ -56,6 +56,7 @@ export type ReactNativeFeatureFlags = { batchRenderingUpdatesInEventLoop: Getter, completeReactInstanceCreationOnBgThreadOnAndroid: Getter, disableEventLoopOnBridgeless: Getter, + disableMountItemReorderingAndroid: Getter, enableAlignItemsBaselineOnFabricIOS: Getter, enableAndroidLineHeightCentering: Getter, enableBridgelessArchitecture: Getter, @@ -212,6 +213,10 @@ export const completeReactInstanceCreationOnBgThreadOnAndroid: Getter = * The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances. */ export const disableEventLoopOnBridgeless: Getter = createNativeFlagGetter('disableEventLoopOnBridgeless', false); +/** + * Prevent FabricMountingManager from reordering mountitems, which may lead to invalid state on the UI thread + */ +export const disableMountItemReorderingAndroid: Getter = createNativeFlagGetter('disableMountItemReorderingAndroid', false); /** * Kill-switch to turn off support for aling-items:baseline on Fabric iOS. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 1632204d2a9d1d..6265ddf78f9a1a 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<<8472e224a5a49da4d706820c89262b6b>> + * @generated SignedSource<> * @flow strict */ @@ -29,6 +29,7 @@ export interface Spec extends TurboModule { +batchRenderingUpdatesInEventLoop?: () => boolean; +completeReactInstanceCreationOnBgThreadOnAndroid?: () => boolean; +disableEventLoopOnBridgeless?: () => boolean; + +disableMountItemReorderingAndroid?: () => boolean; +enableAlignItemsBaselineOnFabricIOS?: () => boolean; +enableAndroidLineHeightCentering?: () => boolean; +enableBridgelessArchitecture?: () => boolean;