From bf16be56d07e20dc71a2a783c0bb2d5a17692840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Wed, 6 Mar 2024 08:10:17 -0800 Subject: [PATCH 1/3] Improve logic to report mounted surfaces Differential Revision: D54547194 --- .../react/fabric/FabricUIManager.java | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 4b5adcbf972a..e11dd3637030 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -91,7 +91,6 @@ import java.util.Map; import java.util.Queue; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicBoolean; /** * We instruct ProGuard not to strip out any fields or methods, because many of these methods are @@ -173,7 +172,8 @@ public class FabricUIManager implements UIManager, LifecycleEventListener { @NonNull private final CopyOnWriteArrayList mListeners = new CopyOnWriteArrayList<>(); - @NonNull private final AtomicBoolean mMountNotificationScheduled = new AtomicBoolean(false); + private boolean mMountNotificationScheduled = false; + private final List mMountedSurfaceIds = new ArrayList<>(); @ThreadConfined(UI) @NonNull @@ -1203,6 +1203,8 @@ public Map getPerformanceCounters() { } private class MountItemDispatchListener implements MountItemDispatcher.ItemDispatchListener { + @UiThread + @ThreadConfined(UI) @Override public void willMountItems(@Nullable List mountItems) { for (UIManagerListener listener : mListeners) { @@ -1210,18 +1212,26 @@ public void willMountItems(@Nullable List mountItems) { } } + @UiThread + @ThreadConfined(UI) @Override public void didMountItems(@Nullable List mountItems) { for (UIManagerListener listener : mListeners) { listener.didMountItems(FabricUIManager.this); } - if (!ReactFeatureFlags.enableMountHooks) { + if (!ReactFeatureFlags.enableMountHooks || mountItems == null || mountItems.isEmpty()) { return; } - boolean mountNotificationScheduled = mMountNotificationScheduled.getAndSet(true); - if (!mountNotificationScheduled) { + // Collect surface IDs for all the mount items + for (MountItem mountItem : mountItems) { + if (mountItem != null && !mMountedSurfaceIds.contains(mountItem.getSurfaceId())) { + mMountedSurfaceIds.add(mountItem.getSurfaceId()); + } + } + + if (!mMountNotificationScheduled && !mMountedSurfaceIds.isEmpty()) { // Notify mount when the effects are visible and prevent mount hooks to // delay paint. UiThreadUtil.getUiThreadHandler() @@ -1229,28 +1239,19 @@ public void didMountItems(@Nullable List mountItems) { new Runnable() { @Override public void run() { - mMountNotificationScheduled.set(false); - - if (mDestroyed) { - return; - } + mMountNotificationScheduled = false; final @Nullable Binding binding = mBinding; - if (mountItems == null || binding == null) { + if (binding == null || mDestroyed) { + mMountedSurfaceIds.clear(); return; } - // Collect surface IDs for all the mount items - List surfaceIds = new ArrayList<>(); - for (MountItem mountItem : mountItems) { - if (mountItem != null && !surfaceIds.contains(mountItem.getSurfaceId())) { - surfaceIds.add(mountItem.getSurfaceId()); - } - } - - for (int surfaceId : surfaceIds) { + for (int surfaceId : mMountedSurfaceIds) { binding.reportMount(surfaceId); } + + mMountedSurfaceIds.clear(); } }); } From c18cb8094f203dcdfdde758ffa7f8b90d8956733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Wed, 6 Mar 2024 08:10:17 -0800 Subject: [PATCH 2/3] Migrate mount hooks flag to new system Differential Revision: D54587740 --- .../React/Fabric/RCTSurfacePresenter.mm | 4 --- .../ReactAndroid/api/ReactAndroid.api | 1 - .../react/config/ReactFeatureFlags.java | 3 -- .../react/fabric/FabricUIManager.java | 5 +++- .../featureflags/ReactNativeFeatureFlags.kt | 8 +++++- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +++++++- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 ++- .../ReactNativeFeatureFlagsDefaults.kt | 4 ++- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 ++++++++- .../ReactNativeFeatureFlagsProvider.kt | 4 ++- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 ++++++++++- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +++- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +++- .../featureflags/ReactNativeFeatureFlags.h | 7 ++++- .../ReactNativeFeatureFlagsAccessor.cpp | 28 +++++++++++++++---- .../ReactNativeFeatureFlagsAccessor.h | 6 ++-- .../ReactNativeFeatureFlagsDefaults.h | 6 +++- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 ++++- .../NativeReactNativeFeatureFlags.h | 4 ++- .../ReactCommon/react/utils/CoreFeatures.cpp | 1 - .../ReactCommon/react/utils/CoreFeatures.h | 3 -- .../ReactNativeFeatureFlags.config.js | 5 ++++ .../NativeReactNativeFeatureFlags.js | 3 +- .../featureflags/ReactNativeFeatureFlags.js | 7 ++++- 25 files changed, 129 insertions(+), 36 deletions(-) diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm index 4c1e048c4063..712d2cfe5e4d 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm +++ b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm @@ -265,10 +265,6 @@ - (RCTScheduler *)_createScheduler CoreFeatures::enableGranularScrollViewStateUpdatesIOS = true; } - if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_mount_hooks_ios")) { - CoreFeatures::enableMountHooks = true; - } - if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_cloneless_state_progression")) { CoreFeatures::enableClonelessStateProgression = true; } diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index d2437b2c8a25..16be0c4d3d81 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -1910,7 +1910,6 @@ public class com/facebook/react/config/ReactFeatureFlags { public static field enableFabricPendingEventQueue Z public static field enableFabricRenderer Z public static field enableFabricRendererExclusively Z - public static field enableMountHooks Z public static field enableRemoveDeleteTreeInstruction Z public static field enableTextSpannableCache Z public static field enableViewRecycling Z diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index f122d195bbab..ad6e23618140 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -109,9 +109,6 @@ public class ReactFeatureFlags { */ public static boolean enableRemoveDeleteTreeInstruction = false; - /** Report mount operations from the host platform to notify mount hooks. */ - public static boolean enableMountHooks = false; - /** Use native view configs in bridgeless mode. */ public static boolean useNativeViewConfigsInBridgelessMode = false; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index e11dd3637030..476dd2318d3b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -65,6 +65,7 @@ import com.facebook.react.fabric.mounting.mountitems.MountItem; import com.facebook.react.fabric.mounting.mountitems.MountItemFactory; import com.facebook.react.interfaces.fabric.SurfaceHandler; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.internal.interop.InteropEventEmitter; import com.facebook.react.modules.core.ReactChoreographer; import com.facebook.react.modules.i18nmanager.I18nUtil; @@ -1220,7 +1221,9 @@ public void didMountItems(@Nullable List mountItems) { listener.didMountItems(FabricUIManager.this); } - if (!ReactFeatureFlags.enableMountHooks || mountItems == null || mountItems.isEmpty()) { + if (!ReactNativeFeatureFlags.enableMountHooksAndroid() + || mountItems == null + || mountItems.isEmpty()) { return; } 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 dd048b337de8..a14811239d8f 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<<6d6fd79bdd221b3aeed0057ac756ee92>> + * @generated SignedSource<> */ /** @@ -64,6 +64,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableMicrotasks(): Boolean = accessor.enableMicrotasks() + /** + * Enables the notification of mount operations to mount hooks on Android. + */ + @JvmStatic + public fun enableMountHooksAndroid(): Boolean = accessor.enableMountHooksAndroid() + /** * Uses new, deduplicated logic for constructing Android Spannables from text fragments */ 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 a791381d81b5..e65fa7974529 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<<45776de0416f833eed9bb84d6b7d1052>> + * @generated SignedSource<<7ae379135157666d9646f1d8eeec9989>> */ /** @@ -26,6 +26,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var enableCustomDrawOrderFabricCache: Boolean? = null private var enableFixForClippedSubviewsCrashCache: Boolean? = null private var enableMicrotasksCache: Boolean? = null + private var enableMountHooksAndroidCache: Boolean? = null private var enableSpannableBuildingUnificationCache: Boolean? = null private var inspectorEnableCxxInspectorPackagerConnectionCache: Boolean? = null private var inspectorEnableModernCDPRegistryCache: Boolean? = null @@ -85,6 +86,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun enableMountHooksAndroid(): Boolean { + var cached = enableMountHooksAndroidCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableMountHooksAndroid() + enableMountHooksAndroidCache = cached + } + return cached + } + override fun enableSpannableBuildingUnification(): Boolean { var cached = enableSpannableBuildingUnificationCache 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 84daf0216d61..d6093108c73d 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<> + * @generated SignedSource<<244a0656beee8e018585bdd4bb4e5cd1>> */ /** @@ -40,6 +40,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableMicrotasks(): Boolean + @DoNotStrip @JvmStatic public external fun enableMountHooksAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun enableSpannableBuildingUnification(): Boolean @DoNotStrip @JvmStatic public external fun inspectorEnableCxxInspectorPackagerConnection(): 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 9c3cdc1da857..7a2ac9d16016 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<<4f72683fb2a832d5b77ee2cb37343526>> + * @generated SignedSource<> */ /** @@ -35,6 +35,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableMicrotasks(): Boolean = false + override fun enableMountHooksAndroid(): Boolean = false + override fun enableSpannableBuildingUnification(): Boolean = false override fun inspectorEnableCxxInspectorPackagerConnection(): 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 8f318b3a8eae..cae01383bef9 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<<5fd54183222961f5557dbe0ac111a6ec>> + * @generated SignedSource<<919eb0f27540e5dd7a1e028663c23264>> */ /** @@ -30,6 +30,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var enableCustomDrawOrderFabricCache: Boolean? = null private var enableFixForClippedSubviewsCrashCache: Boolean? = null private var enableMicrotasksCache: Boolean? = null + private var enableMountHooksAndroidCache: Boolean? = null private var enableSpannableBuildingUnificationCache: Boolean? = null private var inspectorEnableCxxInspectorPackagerConnectionCache: Boolean? = null private var inspectorEnableModernCDPRegistryCache: Boolean? = null @@ -95,6 +96,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableMountHooksAndroid(): Boolean { + var cached = enableMountHooksAndroidCache + if (cached == null) { + cached = currentProvider.enableMountHooksAndroid() + accessedFeatureFlags.add("enableMountHooksAndroid") + enableMountHooksAndroidCache = cached + } + return cached + } + override fun enableSpannableBuildingUnification(): Boolean { var cached = enableSpannableBuildingUnificationCache 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 30d0298638f4..451f64be6d98 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<> */ /** @@ -35,6 +35,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableMicrotasks(): Boolean + @DoNotStrip public fun enableMountHooksAndroid(): Boolean + @DoNotStrip public fun enableSpannableBuildingUnification(): Boolean @DoNotStrip public fun inspectorEnableCxxInspectorPackagerConnection(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index d8d1c6994186..4add6436bbd4 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<<5b40c18d94331e9ec3fdd1a8814b1292>> + * @generated SignedSource<<393c6cf93399cfe0b0533927877531d5>> */ /** @@ -75,6 +75,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool enableMountHooksAndroid() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableMountHooksAndroid"); + return method(javaProvider_); + } + bool enableSpannableBuildingUnification() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableSpannableBuildingUnification"); @@ -133,6 +139,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableMicrotasks( return ReactNativeFeatureFlags::enableMicrotasks(); } +bool JReactNativeFeatureFlagsCxxInterop::enableMountHooksAndroid( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableMountHooksAndroid(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableSpannableBuildingUnification( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableSpannableBuildingUnification(); @@ -188,6 +199,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableMicrotasks", JReactNativeFeatureFlagsCxxInterop::enableMicrotasks), + makeNativeMethod( + "enableMountHooksAndroid", + JReactNativeFeatureFlagsCxxInterop::enableMountHooksAndroid), makeNativeMethod( "enableSpannableBuildingUnification", JReactNativeFeatureFlagsCxxInterop::enableSpannableBuildingUnification), 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 800e3eb93b93..d710f2c40522 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<<514446a9fd1351df1f7f3b307de54b56>> + * @generated SignedSource<> */ /** @@ -48,6 +48,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableMicrotasks( facebook::jni::alias_ref); + static bool enableMountHooksAndroid( + facebook::jni::alias_ref); + static bool enableSpannableBuildingUnification( 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 a28c548a1126..163c9e238845 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<<59573653a5f37505d9a52ac76a9dbcff>> + * @generated SignedSource<> */ /** @@ -45,6 +45,10 @@ bool ReactNativeFeatureFlags::enableMicrotasks() { return getAccessor().enableMicrotasks(); } +bool ReactNativeFeatureFlags::enableMountHooksAndroid() { + return getAccessor().enableMountHooksAndroid(); +} + bool ReactNativeFeatureFlags::enableSpannableBuildingUnification() { return getAccessor().enableSpannableBuildingUnification(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 8bab08ca93bd..c8d5083c60df 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<<036e7f3ee4def5b955ed61c707bbc8f8>> + * @generated SignedSource<> */ /** @@ -63,6 +63,11 @@ class ReactNativeFeatureFlags { */ static bool enableMicrotasks(); + /** + * Enables the notification of mount operations to mount hooks on Android. + */ + static bool enableMountHooksAndroid(); + /** * Uses new, deduplicated logic for constructing Android Spannables from text fragments */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index c5754efb7607..9adeb8f60d42 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<> + * @generated SignedSource<> */ /** @@ -137,6 +137,24 @@ bool ReactNativeFeatureFlagsAccessor::enableMicrotasks() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableMountHooksAndroid() { + auto flagValue = enableMountHooksAndroid_.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(6, "enableMountHooksAndroid"); + + flagValue = currentProvider_->enableMountHooksAndroid(); + enableMountHooksAndroid_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableSpannableBuildingUnification() { auto flagValue = enableSpannableBuildingUnification_.load(); @@ -146,7 +164,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSpannableBuildingUnification() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(6, "enableSpannableBuildingUnification"); + markFlagAsAccessed(7, "enableSpannableBuildingUnification"); flagValue = currentProvider_->enableSpannableBuildingUnification(); enableSpannableBuildingUnification_ = flagValue; @@ -164,7 +182,7 @@ bool ReactNativeFeatureFlagsAccessor::inspectorEnableCxxInspectorPackagerConnect // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(7, "inspectorEnableCxxInspectorPackagerConnection"); + markFlagAsAccessed(8, "inspectorEnableCxxInspectorPackagerConnection"); flagValue = currentProvider_->inspectorEnableCxxInspectorPackagerConnection(); inspectorEnableCxxInspectorPackagerConnection_ = flagValue; @@ -182,7 +200,7 @@ bool ReactNativeFeatureFlagsAccessor::inspectorEnableModernCDPRegistry() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(8, "inspectorEnableModernCDPRegistry"); + markFlagAsAccessed(9, "inspectorEnableModernCDPRegistry"); flagValue = currentProvider_->inspectorEnableModernCDPRegistry(); inspectorEnableModernCDPRegistry_ = flagValue; @@ -200,7 +218,7 @@ bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(9, "useModernRuntimeScheduler"); + markFlagAsAccessed(10, "useModernRuntimeScheduler"); flagValue = currentProvider_->useModernRuntimeScheduler(); useModernRuntimeScheduler_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 700ff2a6d67b..5199fc1ca593 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<<2fa6a12c1d9b10483d8e2e23125d231e>> + * @generated SignedSource<> */ /** @@ -37,6 +37,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableCustomDrawOrderFabric(); bool enableFixForClippedSubviewsCrash(); bool enableMicrotasks(); + bool enableMountHooksAndroid(); bool enableSpannableBuildingUnification(); bool inspectorEnableCxxInspectorPackagerConnection(); bool inspectorEnableModernCDPRegistry(); @@ -51,7 +52,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 10> accessedFeatureFlags_; + std::array, 11> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> batchRenderingUpdatesInEventLoop_; @@ -59,6 +60,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableCustomDrawOrderFabric_; std::atomic> enableFixForClippedSubviewsCrash_; std::atomic> enableMicrotasks_; + std::atomic> enableMountHooksAndroid_; std::atomic> enableSpannableBuildingUnification_; std::atomic> inspectorEnableCxxInspectorPackagerConnection_; std::atomic> inspectorEnableModernCDPRegistry_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 32d4954b1ce7..85f6d322e89d 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<<927bc1410a5baadf3a4005e50067c4df>> + * @generated SignedSource<<62de1b0e27590ad769296358a4f42c7a>> */ /** @@ -51,6 +51,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableMountHooksAndroid() override { + return false; + } + bool enableSpannableBuildingUnification() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index eb29ae858fe8..48ec9f28697f 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<<74b4ca674d50bda5fb18d74568024399>> + * @generated SignedSource<<3117fc0389416297369a47ee480eb906>> */ /** @@ -31,6 +31,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableCustomDrawOrderFabric() = 0; virtual bool enableFixForClippedSubviewsCrash() = 0; virtual bool enableMicrotasks() = 0; + virtual bool enableMountHooksAndroid() = 0; virtual bool enableSpannableBuildingUnification() = 0; virtual bool inspectorEnableCxxInspectorPackagerConnection() = 0; virtual bool inspectorEnableModernCDPRegistry() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index a12c50f8b7ea..30c6d98f483d 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<<1a785df8b045c1340d3139bd85add42b>> + * @generated SignedSource<<27923a2dbf1dcbad238a4d06ebb54fb5>> */ /** @@ -67,6 +67,11 @@ bool NativeReactNativeFeatureFlags::enableMicrotasks( return ReactNativeFeatureFlags::enableMicrotasks(); } +bool NativeReactNativeFeatureFlags::enableMountHooksAndroid( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableMountHooksAndroid(); +} + bool NativeReactNativeFeatureFlags::enableSpannableBuildingUnification( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableSpannableBuildingUnification(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 840f4a959f20..4fe211cda461 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<> + * @generated SignedSource<> */ /** @@ -48,6 +48,8 @@ class NativeReactNativeFeatureFlags bool enableMicrotasks(jsi::Runtime& runtime); + bool enableMountHooksAndroid(jsi::Runtime& runtime); + bool enableSpannableBuildingUnification(jsi::Runtime& runtime); bool inspectorEnableCxxInspectorPackagerConnection(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp index 1ae6897bfbc1..f29d262bd1fa 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp @@ -12,7 +12,6 @@ namespace facebook::react { bool CoreFeatures::enablePropIteratorSetter = false; bool CoreFeatures::cacheLastTextMeasurement = false; bool CoreFeatures::enableGranularScrollViewStateUpdatesIOS = false; -bool CoreFeatures::enableMountHooks = false; bool CoreFeatures::enableGranularShadowTreeStateReconciliation = false; bool CoreFeatures::enableClonelessStateProgression = false; bool CoreFeatures::excludeYogaFromRawProps = false; diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h index 1cf5dc68d1e2..7b9731917f58 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h @@ -29,9 +29,6 @@ class CoreFeatures { // updates for all changes in scroll position. static bool enableGranularScrollViewStateUpdatesIOS; - // Report mount operations from the host platform to notify mount hooks. - static bool enableMountHooks; - // When enabled, the renderer would only fail commits when they propagate // state and the last commit that updated state changed before committing. static bool enableGranularShadowTreeStateReconciliation; diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 1719eceb11d4..bec7fcf7f234 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -57,6 +57,11 @@ const definitions: FeatureFlagDefinitions = { description: 'Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).', }, + enableMountHooksAndroid: { + defaultValue: false, + description: + 'Enables the notification of mount operations to mount hooks on Android.', + }, enableSpannableBuildingUnification: { defaultValue: false, description: diff --git a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js index 67bfc466894e..9352ed1141c2 100644 --- a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> * @flow strict-local */ @@ -29,6 +29,7 @@ export interface Spec extends TurboModule { +enableCustomDrawOrderFabric?: () => boolean; +enableFixForClippedSubviewsCrash?: () => boolean; +enableMicrotasks?: () => boolean; + +enableMountHooksAndroid?: () => boolean; +enableSpannableBuildingUnification?: () => boolean; +inspectorEnableCxxInspectorPackagerConnection?: () => boolean; +inspectorEnableModernCDPRegistry?: () => boolean; diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 6c5ab2458d1c..3d68cd7572a3 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<> * @flow strict-local */ @@ -46,6 +46,7 @@ export type ReactNativeFeatureFlags = { enableCustomDrawOrderFabric: Getter, enableFixForClippedSubviewsCrash: Getter, enableMicrotasks: Getter, + enableMountHooksAndroid: Getter, enableSpannableBuildingUnification: Getter, inspectorEnableCxxInspectorPackagerConnection: Getter, inspectorEnableModernCDPRegistry: Getter, @@ -116,6 +117,10 @@ export const enableFixForClippedSubviewsCrash: Getter = createNativeFla * Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution). */ export const enableMicrotasks: Getter = createNativeFlagGetter('enableMicrotasks', false); +/** + * Enables the notification of mount operations to mount hooks on Android. + */ +export const enableMountHooksAndroid: Getter = createNativeFlagGetter('enableMountHooksAndroid', false); /** * Uses new, deduplicated logic for constructing Android Spannables from text fragments */ From ce4fc5a2a67c94c2a7aea4c5e4892167f7da63e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Wed, 6 Mar 2024 08:13:29 -0800 Subject: [PATCH 3/3] Create new flag to disable the last part of the notifications for mount hooks on Android (#43349) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/43349 Changelog: [internal] We still haven't found the root cause of some of the crashes we're seeing in the experiments to enable mount hooks on Android. This adds a new feature flag to skip part of the mount hooks pipeline to see if we can scope the investigation to that specific part (where we query the root tree in the base revision from the mounting coordinator). Differential Revision: D54587739 --- .../featureflags/ReactNativeFeatureFlags.kt | 8 ++++++- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +++++++++- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +++- .../ReactNativeFeatureFlagsDefaults.kt | 4 +++- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 ++++++++++- .../ReactNativeFeatureFlagsProvider.kt | 4 +++- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +++++++++++++- .../JReactNativeFeatureFlagsCxxInterop.h | 5 ++++- .../featureflags/ReactNativeFeatureFlags.cpp | 6 ++++- .../featureflags/ReactNativeFeatureFlags.h | 7 +++++- .../ReactNativeFeatureFlagsAccessor.cpp | 22 +++++++++++++++++-- .../ReactNativeFeatureFlagsAccessor.h | 6 +++-- .../ReactNativeFeatureFlagsDefaults.h | 6 ++++- .../ReactNativeFeatureFlagsProvider.h | 3 ++- .../NativeReactNativeFeatureFlags.cpp | 7 +++++- .../NativeReactNativeFeatureFlags.h | 4 +++- .../react/renderer/uimanager/CMakeLists.txt | 1 + .../react/renderer/uimanager/UIManager.cpp | 9 ++++++++ .../ReactNativeFeatureFlags.config.js | 5 +++++ .../NativeReactNativeFeatureFlags.js | 3 ++- .../featureflags/ReactNativeFeatureFlags.js | 7 +++++- 21 files changed, 132 insertions(+), 20 deletions(-) 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 a14811239d8f..975a7182c5be 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<> */ /** @@ -88,6 +88,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun inspectorEnableModernCDPRegistry(): Boolean = accessor.inspectorEnableModernCDPRegistry() + /** + * This is a temporary flag to disable part of the mount hooks pipeline to investigate a crash. + */ + @JvmStatic + public fun skipMountHookNotifications(): Boolean = accessor.skipMountHookNotifications() + /** * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. */ 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 e65fa7974529..fc217774592d 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<<7ae379135157666d9646f1d8eeec9989>> + * @generated SignedSource<<8539cf7ba13ab52ca878efd2c4858d7a>> */ /** @@ -30,6 +30,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var enableSpannableBuildingUnificationCache: Boolean? = null private var inspectorEnableCxxInspectorPackagerConnectionCache: Boolean? = null private var inspectorEnableModernCDPRegistryCache: Boolean? = null + private var skipMountHookNotificationsCache: Boolean? = null private var useModernRuntimeSchedulerCache: Boolean? = null override fun commonTestFlag(): Boolean { @@ -122,6 +123,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun skipMountHookNotifications(): Boolean { + var cached = skipMountHookNotificationsCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.skipMountHookNotifications() + skipMountHookNotificationsCache = cached + } + return cached + } + override fun useModernRuntimeScheduler(): Boolean { var cached = useModernRuntimeSchedulerCache 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 d6093108c73d..d97a2dd6b4ab 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<<244a0656beee8e018585bdd4bb4e5cd1>> + * @generated SignedSource<> */ /** @@ -48,6 +48,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun inspectorEnableModernCDPRegistry(): Boolean + @DoNotStrip @JvmStatic public external fun skipMountHookNotifications(): Boolean + @DoNotStrip @JvmStatic public external fun useModernRuntimeScheduler(): Boolean @DoNotStrip @JvmStatic public external fun override(provider: Any) 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 7a2ac9d16016..006caa1e9505 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<<99263973c4a06fdc91e7c9edf4aa4e19>> */ /** @@ -43,5 +43,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun inspectorEnableModernCDPRegistry(): Boolean = false + override fun skipMountHookNotifications(): Boolean = false + override fun useModernRuntimeScheduler(): 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 cae01383bef9..88558da84c97 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<<919eb0f27540e5dd7a1e028663c23264>> + * @generated SignedSource<> */ /** @@ -34,6 +34,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var enableSpannableBuildingUnificationCache: Boolean? = null private var inspectorEnableCxxInspectorPackagerConnectionCache: Boolean? = null private var inspectorEnableModernCDPRegistryCache: Boolean? = null + private var skipMountHookNotificationsCache: Boolean? = null private var useModernRuntimeSchedulerCache: Boolean? = null override fun commonTestFlag(): Boolean { @@ -136,6 +137,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun skipMountHookNotifications(): Boolean { + var cached = skipMountHookNotificationsCache + if (cached == null) { + cached = currentProvider.skipMountHookNotifications() + accessedFeatureFlags.add("skipMountHookNotifications") + skipMountHookNotificationsCache = cached + } + return cached + } + override fun useModernRuntimeScheduler(): Boolean { var cached = useModernRuntimeSchedulerCache 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 451f64be6d98..905ee909744a 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<<268a87860fea5f281567d2142f90b0d4>> */ /** @@ -43,5 +43,7 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun inspectorEnableModernCDPRegistry(): Boolean + @DoNotStrip public fun skipMountHookNotifications(): Boolean + @DoNotStrip public fun useModernRuntimeScheduler(): Boolean } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 4add6436bbd4..fec585cacd02 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<<393c6cf93399cfe0b0533927877531d5>> + * @generated SignedSource<> */ /** @@ -99,6 +99,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool skipMountHookNotifications() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("skipMountHookNotifications"); + return method(javaProvider_); + } + bool useModernRuntimeScheduler() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useModernRuntimeScheduler"); @@ -159,6 +165,11 @@ bool JReactNativeFeatureFlagsCxxInterop::inspectorEnableModernCDPRegistry( return ReactNativeFeatureFlags::inspectorEnableModernCDPRegistry(); } +bool JReactNativeFeatureFlagsCxxInterop::skipMountHookNotifications( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::skipMountHookNotifications(); +} + bool JReactNativeFeatureFlagsCxxInterop::useModernRuntimeScheduler( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::useModernRuntimeScheduler(); @@ -211,6 +222,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "inspectorEnableModernCDPRegistry", JReactNativeFeatureFlagsCxxInterop::inspectorEnableModernCDPRegistry), + makeNativeMethod( + "skipMountHookNotifications", + JReactNativeFeatureFlagsCxxInterop::skipMountHookNotifications), makeNativeMethod( "useModernRuntimeScheduler", JReactNativeFeatureFlagsCxxInterop::useModernRuntimeScheduler), 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 d710f2c40522..45ccaf577a0b 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<> */ /** @@ -60,6 +60,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool inspectorEnableModernCDPRegistry( facebook::jni::alias_ref); + static bool skipMountHookNotifications( + facebook::jni::alias_ref); + static bool useModernRuntimeScheduler( 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 163c9e238845..5a1a133eceae 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<> */ /** @@ -61,6 +61,10 @@ bool ReactNativeFeatureFlags::inspectorEnableModernCDPRegistry() { return getAccessor().inspectorEnableModernCDPRegistry(); } +bool ReactNativeFeatureFlags::skipMountHookNotifications() { + return getAccessor().skipMountHookNotifications(); +} + bool ReactNativeFeatureFlags::useModernRuntimeScheduler() { return getAccessor().useModernRuntimeScheduler(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index c8d5083c60df..e37101562997 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -83,6 +83,11 @@ class ReactNativeFeatureFlags { */ static bool inspectorEnableModernCDPRegistry(); + /** + * This is a temporary flag to disable part of the mount hooks pipeline to investigate a crash. + */ + static bool skipMountHookNotifications(); + /** * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 9adeb8f60d42..f352ada4f912 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<> + * @generated SignedSource<<6c1e6b6a51cd6fdddae40d3b61ae2b36>> */ /** @@ -209,6 +209,24 @@ bool ReactNativeFeatureFlagsAccessor::inspectorEnableModernCDPRegistry() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::skipMountHookNotifications() { + auto flagValue = skipMountHookNotifications_.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(10, "skipMountHookNotifications"); + + flagValue = currentProvider_->skipMountHookNotifications(); + skipMountHookNotifications_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { auto flagValue = useModernRuntimeScheduler_.load(); @@ -218,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(10, "useModernRuntimeScheduler"); + markFlagAsAccessed(11, "useModernRuntimeScheduler"); flagValue = currentProvider_->useModernRuntimeScheduler(); useModernRuntimeScheduler_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 5199fc1ca593..6e51c8fda832 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<<4c5446d5b72429d090e17523f2d544a7>> */ /** @@ -41,6 +41,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableSpannableBuildingUnification(); bool inspectorEnableCxxInspectorPackagerConnection(); bool inspectorEnableModernCDPRegistry(); + bool skipMountHookNotifications(); bool useModernRuntimeScheduler(); void override(std::unique_ptr provider); @@ -52,7 +53,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 11> accessedFeatureFlags_; + std::array, 12> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> batchRenderingUpdatesInEventLoop_; @@ -64,6 +65,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableSpannableBuildingUnification_; std::atomic> inspectorEnableCxxInspectorPackagerConnection_; std::atomic> inspectorEnableModernCDPRegistry_; + std::atomic> skipMountHookNotifications_; std::atomic> useModernRuntimeScheduler_; }; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 85f6d322e89d..3324b1239a18 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<<62de1b0e27590ad769296358a4f42c7a>> + * @generated SignedSource<<95e3fd7cf662623e3c09b093649d4ff2>> */ /** @@ -67,6 +67,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool skipMountHookNotifications() override { + return false; + } + bool useModernRuntimeScheduler() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 48ec9f28697f..a28f6e1c2ed1 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<<3117fc0389416297369a47ee480eb906>> + * @generated SignedSource<<26990a0a11bb2d7cf8510773b6ece099>> */ /** @@ -35,6 +35,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableSpannableBuildingUnification() = 0; virtual bool inspectorEnableCxxInspectorPackagerConnection() = 0; virtual bool inspectorEnableModernCDPRegistry() = 0; + virtual bool skipMountHookNotifications() = 0; virtual bool useModernRuntimeScheduler() = 0; }; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 30c6d98f483d..f2a21bbc09d5 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<<27923a2dbf1dcbad238a4d06ebb54fb5>> + * @generated SignedSource<<4f7daa629ad90a9ab2fdc99e7c51e355>> */ /** @@ -87,6 +87,11 @@ bool NativeReactNativeFeatureFlags::inspectorEnableModernCDPRegistry( return ReactNativeFeatureFlags::inspectorEnableModernCDPRegistry(); } +bool NativeReactNativeFeatureFlags::skipMountHookNotifications( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::skipMountHookNotifications(); +} + bool NativeReactNativeFeatureFlags::useModernRuntimeScheduler( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::useModernRuntimeScheduler(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 4fe211cda461..47293751c295 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<> + * @generated SignedSource<> */ /** @@ -56,6 +56,8 @@ class NativeReactNativeFeatureFlags bool inspectorEnableModernCDPRegistry(jsi::Runtime& runtime); + bool skipMountHookNotifications(jsi::Runtime& runtime); + bool useModernRuntimeScheduler(jsi::Runtime& runtime); }; diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/uimanager/CMakeLists.txt index a7583450cadf..8f0aafeb8028 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/CMakeLists.txt @@ -24,6 +24,7 @@ target_link_libraries(react_render_uimanager folly_runtime jsi react_debug + react_featureflags react_render_componentregistry react_render_core react_render_debug diff --git a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp index 2f5b64cf0dc7..98dfb2b053a1 100644 --- a/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp +++ b/packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -718,6 +719,14 @@ void UIManager::reportMount(SurfaceId surfaceId) const { auto time = JSExecutor::performanceNow(); + // We are testing the impact of enabling mount hooks on Android and we're + // seeing some crashes that we didn't see on iOS. We'll run a test to enable + // the mount reporting pipeline excluding the logic below, to see if that + // logic is what's causing the issues. See T179749070. + if (ReactNativeFeatureFlags::skipMountHookNotifications()) { + return; + } + auto rootShadowNode = RootShadowNode::Shared{}; shadowTreeRegistry_.visit(surfaceId, [&](const ShadowTree& shadowTree) { rootShadowNode = diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index bec7fcf7f234..1a10c53c020c 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -77,6 +77,11 @@ const definitions: FeatureFlagDefinitions = { description: 'Flag determining if the modern CDP backend should be enabled. This flag is global and should not be changed across React Host lifetimes.', }, + skipMountHookNotifications: { + defaultValue: false, + description: + 'This is a temporary flag to disable part of the mount hooks pipeline to investigate a crash.', + }, useModernRuntimeScheduler: { defaultValue: false, description: diff --git a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js index 9352ed1141c2..2fda50641c86 100644 --- a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> * @flow strict-local */ @@ -33,6 +33,7 @@ export interface Spec extends TurboModule { +enableSpannableBuildingUnification?: () => boolean; +inspectorEnableCxxInspectorPackagerConnection?: () => boolean; +inspectorEnableModernCDPRegistry?: () => boolean; + +skipMountHookNotifications?: () => boolean; +useModernRuntimeScheduler?: () => boolean; } diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 3d68cd7572a3..56d0b91cb340 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<<5d1eca67ace8cccc336a6c6f65b40c99>> * @flow strict-local */ @@ -50,6 +50,7 @@ export type ReactNativeFeatureFlags = { enableSpannableBuildingUnification: Getter, inspectorEnableCxxInspectorPackagerConnection: Getter, inspectorEnableModernCDPRegistry: Getter, + skipMountHookNotifications: Getter, useModernRuntimeScheduler: Getter, } @@ -133,6 +134,10 @@ export const inspectorEnableCxxInspectorPackagerConnection: Getter = cr * Flag determining if the modern CDP backend should be enabled. This flag is global and should not be changed across React Host lifetimes. */ export const inspectorEnableModernCDPRegistry: Getter = createNativeFlagGetter('inspectorEnableModernCDPRegistry', false); +/** + * This is a temporary flag to disable part of the mount hooks pipeline to investigate a crash. + */ +export const skipMountHookNotifications: Getter = createNativeFlagGetter('skipMountHookNotifications', false); /** * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. */