diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 5a6275d610c8..44b360ca562e 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3840,6 +3840,7 @@ public abstract interface class com/facebook/react/runtime/internal/bolts/Contin } public class com/facebook/react/runtime/internal/bolts/Task : com/facebook/react/interfaces/TaskInterface { + public static final field IMMEDIATE_EXECUTOR Ljava/util/concurrent/Executor; public static final field UI_THREAD_EXECUTOR Ljava/util/concurrent/Executor; public static fun call (Ljava/util/concurrent/Callable;)Lcom/facebook/react/runtime/internal/bolts/Task; public static fun call (Ljava/util/concurrent/Callable;Ljava/util/concurrent/Executor;)Lcom/facebook/react/runtime/internal/bolts/Task; 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 aac75718daf9..1d37426856c4 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<<177f05d7b2fadcfffa32cb5a7a21c76b>> */ /** @@ -136,6 +136,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun setAndroidLayoutDirection(): Boolean = accessor.setAndroidLayoutDirection() + /** + * Invoke callbacks immediately on the ReactInstance rather than going through a background thread for synchronization + */ + @JvmStatic + public fun useImmediateExecutorInAndroidBridgeless(): Boolean = accessor.useImmediateExecutorInAndroidBridgeless() + /** * 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 5292ebefde7a..25b762bd413d 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<<546c981f0b56bb022ad4e96e6a6ddb17>> + * @generated SignedSource<<492902f307361b8f7b7d42973561a3b4>> */ /** @@ -38,6 +38,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var lazyAnimationCallbacksCache: Boolean? = null private var preventDoubleTextMeasureCache: Boolean? = null private var setAndroidLayoutDirectionCache: Boolean? = null + private var useImmediateExecutorInAndroidBridgelessCache: Boolean? = null private var useModernRuntimeSchedulerCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useRuntimeShadowNodeReferenceUpdateCache: Boolean? = null @@ -206,6 +207,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun useImmediateExecutorInAndroidBridgeless(): Boolean { + var cached = useImmediateExecutorInAndroidBridgelessCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.useImmediateExecutorInAndroidBridgeless() + useImmediateExecutorInAndroidBridgelessCache = 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 82c1dd5b9bc0..947512885ac5 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<<05bf91e1b2a64cdc48615137deec627a>> */ /** @@ -64,6 +64,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun setAndroidLayoutDirection(): Boolean + @DoNotStrip @JvmStatic public external fun useImmediateExecutorInAndroidBridgeless(): Boolean + @DoNotStrip @JvmStatic public external fun useModernRuntimeScheduler(): Boolean @DoNotStrip @JvmStatic public external fun useNativeViewConfigsInBridgelessMode(): 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 c3c01abccb8c..27cf09922f0d 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<<8cb9343bf5aa9a7ec1940720ce253c5b>> + * @generated SignedSource<<7c95ebf976344317cd8904d71ea22fe5>> */ /** @@ -59,6 +59,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun setAndroidLayoutDirection(): Boolean = false + override fun useImmediateExecutorInAndroidBridgeless(): Boolean = false + override fun useModernRuntimeScheduler(): Boolean = false override fun useNativeViewConfigsInBridgelessMode(): 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 702a8ebc9483..f73a9f3d2651 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<<3b6ad9b32518e319bb7d11da4eaa262c>> + * @generated SignedSource<> */ /** @@ -42,6 +42,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var lazyAnimationCallbacksCache: Boolean? = null private var preventDoubleTextMeasureCache: Boolean? = null private var setAndroidLayoutDirectionCache: Boolean? = null + private var useImmediateExecutorInAndroidBridgelessCache: Boolean? = null private var useModernRuntimeSchedulerCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useRuntimeShadowNodeReferenceUpdateCache: Boolean? = null @@ -228,6 +229,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun useImmediateExecutorInAndroidBridgeless(): Boolean { + var cached = useImmediateExecutorInAndroidBridgelessCache + if (cached == null) { + cached = currentProvider.useImmediateExecutorInAndroidBridgeless() + accessedFeatureFlags.add("useImmediateExecutorInAndroidBridgeless") + useImmediateExecutorInAndroidBridgelessCache = 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 09b2170629f2..d4a63baf4d20 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<> */ /** @@ -59,6 +59,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun setAndroidLayoutDirection(): Boolean + @DoNotStrip public fun useImmediateExecutorInAndroidBridgeless(): Boolean + @DoNotStrip public fun useModernRuntimeScheduler(): Boolean @DoNotStrip public fun useNativeViewConfigsInBridgelessMode(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java index e58483008be6..437b7d939c56 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java @@ -59,6 +59,7 @@ import com.facebook.react.interfaces.TaskInterface; import com.facebook.react.interfaces.exceptionmanager.ReactJsExceptionHandler; import com.facebook.react.interfaces.fabric.ReactSurface; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.modules.appearance.AppearanceModule; import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; import com.facebook.react.modules.core.DeviceEventManagerModule; @@ -215,7 +216,8 @@ TaskInterface prerenderSurface(final ReactSurfaceImpl surface) { reactInstance -> { log(method, "Execute"); reactInstance.prerenderSurface(surface); - }); + }, + mBGExecutor); } /** @@ -235,7 +237,8 @@ TaskInterface startSurface(final ReactSurfaceImpl surface) { reactInstance -> { log(method, "Execute"); reactInstance.startSurface(surface); - }); + }, + mBGExecutor); } /** @@ -255,7 +258,8 @@ TaskInterface stopSurface(final ReactSurfaceImpl surface) { reactInstance -> { log(method, "Execute"); reactInstance.stopSurface(surface); - }) + }, + mBGExecutor) .makeVoid(); } @@ -756,7 +760,8 @@ DefaultHardwareBackBtnHandler getDefaultBackButtonHandler() { reactInstance -> { log(method, "Execute"); reactInstance.loadJSBundle(bundleLoader); - }); + }, + null); } /* package */ Task registerSegment( @@ -771,7 +776,8 @@ DefaultHardwareBackBtnHandler getDefaultBackButtonHandler() { log(method, "Execute"); reactInstance.registerSegment(segmentId, path); assertNotNull(callback).invoke(); - }); + }, + null); } /* package */ void handleHostException(Exception e) { @@ -800,7 +806,8 @@ DefaultHardwareBackBtnHandler getDefaultBackButtonHandler() { method, reactInstance -> { reactInstance.callFunctionOnModule(moduleName, methodName, args); - }); + }, + null); } /* package */ void attachSurface(ReactSurfaceImpl surface) { @@ -852,8 +859,8 @@ public void removeBeforeDestroyListener(@NonNull Function0 onBeforeDestroy } } - /* package */ interface VeniceThenable { - void then(T t); + private interface ReactInstanceCalback { + void then(ReactInstance reactInstance); } @ThreadConfined("ReactHost") @@ -909,9 +916,18 @@ private void raiseSoftException(String method, String message, @Nullable Throwab /** Schedule work on a ReactInstance that is already created. */ private Task callWithExistingReactInstance( - final String callingMethod, final VeniceThenable continuation) { + final String callingMethod, + final ReactInstanceCalback continuation, + @Nullable Executor executor) { final String method = "callWithExistingReactInstance(" + callingMethod + ")"; + if (executor == null) { + executor = + ReactNativeFeatureFlags.useImmediateExecutorInAndroidBridgeless() + ? Task.IMMEDIATE_EXECUTOR + : mBGExecutor; + } + return mReactInstanceTaskRef .get() .onSuccess( @@ -925,14 +941,23 @@ private Task callWithExistingReactInstance( continuation.then(reactInstance); return TRUE; }, - mBGExecutor); + executor); } /** Create a ReactInstance if it doesn't exist already, and schedule work on it. */ private Task callAfterGetOrCreateReactInstance( - final String callingMethod, final VeniceThenable runnable) { + final String callingMethod, + final ReactInstanceCalback runnable, + @Nullable Executor executor) { final String method = "callAfterGetOrCreateReactInstance(" + callingMethod + ")"; + if (executor == null) { + executor = + ReactNativeFeatureFlags.useImmediateExecutorInAndroidBridgeless() + ? Task.IMMEDIATE_EXECUTOR + : mBGExecutor; + } + return getOrCreateReactInstance() .onSuccess( task -> { @@ -945,15 +970,14 @@ private Task callAfterGetOrCreateReactInstance( runnable.then(reactInstance); return null; }, - mBGExecutor) + executor) .continueWith( task -> { if (task.isFaulted()) { handleHostException(task.getError()); } return null; - }, - mBGExecutor); + }); } private BridgelessReactContext getOrCreateReactContext() { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java index 86902f2ab5fc..107ada4b40ca 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java @@ -369,6 +369,7 @@ public Collection getNativeModules() { } } + @ThreadConfined("ReactHost") /* package */ void prerenderSurface(ReactSurfaceImpl surface) { Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstance.prerenderSurface"); FLog.d(TAG, "call prerenderSurface with surface: " + surface.getModuleName()); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Task.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Task.java index 38cdfb5a80aa..840d582a7b17 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Task.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/internal/bolts/Task.java @@ -27,7 +27,7 @@ public class Task implements TaskInterface { * stack runs too deep, at which point it will delegate to {@link Task#BACKGROUND_EXECUTOR} in * order to trim the stack. */ - private static final Executor IMMEDIATE_EXECUTOR = Executors.IMMEDIATE; + public static final Executor IMMEDIATE_EXECUTOR = Executors.IMMEDIATE; /** An {@link java.util.concurrent.Executor} that executes tasks on the UI thread. */ public static final Executor UI_THREAD_EXECUTOR = Executors.UI_THREAD; 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 1cddc94e2d57..9eeab79065a2 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<<43b256d5f58743df52f579dc69721083>> + * @generated SignedSource<<2af7a8ae4860f81b46e48afb17ee54b6>> */ /** @@ -147,6 +147,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool useImmediateExecutorInAndroidBridgeless() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useImmediateExecutorInAndroidBridgeless"); + return method(javaProvider_); + } + bool useModernRuntimeScheduler() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useModernRuntimeScheduler"); @@ -271,6 +277,11 @@ bool JReactNativeFeatureFlagsCxxInterop::setAndroidLayoutDirection( return ReactNativeFeatureFlags::setAndroidLayoutDirection(); } +bool JReactNativeFeatureFlagsCxxInterop::useImmediateExecutorInAndroidBridgeless( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::useImmediateExecutorInAndroidBridgeless(); +} + bool JReactNativeFeatureFlagsCxxInterop::useModernRuntimeScheduler( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::useModernRuntimeScheduler(); @@ -367,6 +378,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "setAndroidLayoutDirection", JReactNativeFeatureFlagsCxxInterop::setAndroidLayoutDirection), + makeNativeMethod( + "useImmediateExecutorInAndroidBridgeless", + JReactNativeFeatureFlagsCxxInterop::useImmediateExecutorInAndroidBridgeless), 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 0fc1b7eeaab4..1206b2215fb8 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<<19fe3642ec462c23d361e0f036da887a>> + * @generated SignedSource<<1d1422d073ae40ee4bbc788dc222cc28>> */ /** @@ -84,6 +84,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool setAndroidLayoutDirection( facebook::jni::alias_ref); + static bool useImmediateExecutorInAndroidBridgeless( + 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 220b7c9413fc..0d291b1b9ecd 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<> */ /** @@ -93,6 +93,10 @@ bool ReactNativeFeatureFlags::setAndroidLayoutDirection() { return getAccessor().setAndroidLayoutDirection(); } +bool ReactNativeFeatureFlags::useImmediateExecutorInAndroidBridgeless() { + return getAccessor().useImmediateExecutorInAndroidBridgeless(); +} + 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 b73431522d9c..b809f8409f73 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<<5f1ae3edfe01ee0545bd89137c5cb3e9>> */ /** @@ -127,6 +127,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool setAndroidLayoutDirection(); + /** + * Invoke callbacks immediately on the ReactInstance rather than going through a background thread for synchronization + */ + RN_EXPORT static bool useImmediateExecutorInAndroidBridgeless(); + /** * 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 b7c574d3c510..8bca846e683b 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<<5f27dd10824706ea065dc0340d46c409>> + * @generated SignedSource<<6d08fc8ff31f1db50cb4b14edb6b690f>> */ /** @@ -353,6 +353,24 @@ bool ReactNativeFeatureFlagsAccessor::setAndroidLayoutDirection() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless() { + auto flagValue = useImmediateExecutorInAndroidBridgeless_.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(18, "useImmediateExecutorInAndroidBridgeless"); + + flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless(); + useImmediateExecutorInAndroidBridgeless_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { auto flagValue = useModernRuntimeScheduler_.load(); @@ -362,7 +380,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(18, "useModernRuntimeScheduler"); + markFlagAsAccessed(19, "useModernRuntimeScheduler"); flagValue = currentProvider_->useModernRuntimeScheduler(); useModernRuntimeScheduler_ = flagValue; @@ -380,7 +398,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(19, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(20, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -398,7 +416,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(20, "useRuntimeShadowNodeReferenceUpdate"); + markFlagAsAccessed(21, "useRuntimeShadowNodeReferenceUpdate"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate(); useRuntimeShadowNodeReferenceUpdate_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdateOnLayou // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "useRuntimeShadowNodeReferenceUpdateOnLayout"); + markFlagAsAccessed(22, "useRuntimeShadowNodeReferenceUpdateOnLayout"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdateOnLayout(); useRuntimeShadowNodeReferenceUpdateOnLayout_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::useStateAlignmentMechanism() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "useStateAlignmentMechanism"); + markFlagAsAccessed(23, "useStateAlignmentMechanism"); flagValue = currentProvider_->useStateAlignmentMechanism(); useStateAlignmentMechanism_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index e67bfd3bfa11..ac520127127c 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<<8837dd1578561f205e6f682afd98c450>> + * @generated SignedSource<<3be4d7eb8694603de9fb5885562d5a78>> */ /** @@ -49,6 +49,7 @@ class ReactNativeFeatureFlagsAccessor { bool lazyAnimationCallbacks(); bool preventDoubleTextMeasure(); bool setAndroidLayoutDirection(); + bool useImmediateExecutorInAndroidBridgeless(); bool useModernRuntimeScheduler(); bool useNativeViewConfigsInBridgelessMode(); bool useRuntimeShadowNodeReferenceUpdate(); @@ -64,7 +65,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 23> accessedFeatureFlags_; + std::array, 24> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> allowCollapsableChildren_; @@ -84,6 +85,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> lazyAnimationCallbacks_; std::atomic> preventDoubleTextMeasure_; std::atomic> setAndroidLayoutDirection_; + std::atomic> useImmediateExecutorInAndroidBridgeless_; std::atomic> useModernRuntimeScheduler_; std::atomic> useNativeViewConfigsInBridgelessMode_; std::atomic> useRuntimeShadowNodeReferenceUpdate_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 171c8cd8a5f0..916ed06c2aa4 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<<2a0324c7b8009e906b18db11c5d2beb9>> + * @generated SignedSource<<97c824bb63734389fae8eea61b92d440>> */ /** @@ -99,6 +99,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool useImmediateExecutorInAndroidBridgeless() 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 522fc6ae5701..3923d4b9e882 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<<7cd3889fcccc029925651f7ef406ff40>> + * @generated SignedSource<<454a55db4c97f9c28c0a8427d4c0bd57>> */ /** @@ -43,6 +43,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool lazyAnimationCallbacks() = 0; virtual bool preventDoubleTextMeasure() = 0; virtual bool setAndroidLayoutDirection() = 0; + virtual bool useImmediateExecutorInAndroidBridgeless() = 0; virtual bool useModernRuntimeScheduler() = 0; virtual bool useNativeViewConfigsInBridgelessMode() = 0; virtual bool useRuntimeShadowNodeReferenceUpdate() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 158cadd740f5..4d6a71669d17 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<<914fa03d71af61b82f05f005d3f3973d>> + * @generated SignedSource<<81d9543c4231939f31dc5c9bb06c942c>> */ /** @@ -127,6 +127,11 @@ bool NativeReactNativeFeatureFlags::setAndroidLayoutDirection( return ReactNativeFeatureFlags::setAndroidLayoutDirection(); } +bool NativeReactNativeFeatureFlags::useImmediateExecutorInAndroidBridgeless( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::useImmediateExecutorInAndroidBridgeless(); +} + 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 3b12e4f8e167..0b16a9e99a01 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<<1458397650db55d5a985685fa4998e41>> + * @generated SignedSource<> */ /** @@ -71,6 +71,8 @@ class NativeReactNativeFeatureFlags bool setAndroidLayoutDirection(jsi::Runtime& runtime); + bool useImmediateExecutorInAndroidBridgeless(jsi::Runtime& runtime); + bool useModernRuntimeScheduler(jsi::Runtime& runtime); bool useNativeViewConfigsInBridgelessMode(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 45df9f5eea4c..3cd9aeabda89 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -122,6 +122,11 @@ const definitions: FeatureFlagDefinitions = { defaultValue: false, description: 'Propagate layout direction to Android views.', }, + useImmediateExecutorInAndroidBridgeless: { + defaultValue: false, + description: + 'Invoke callbacks immediately on the ReactInstance rather than going through a background thread for synchronization', + }, useModernRuntimeScheduler: { defaultValue: false, description: diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index ba219228c1fc..2554ebcc349c 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<<870e25c844e692bb04ee49fe20cd3baf>> * @flow strict-local */ @@ -58,6 +58,7 @@ export type ReactNativeFeatureFlags = { lazyAnimationCallbacks: Getter, preventDoubleTextMeasure: Getter, setAndroidLayoutDirection: Getter, + useImmediateExecutorInAndroidBridgeless: Getter, useModernRuntimeScheduler: Getter, useNativeViewConfigsInBridgelessMode: Getter, useRuntimeShadowNodeReferenceUpdate: Getter, @@ -177,6 +178,10 @@ export const preventDoubleTextMeasure: Getter = createNativeFlagGetter( * Propagate layout direction to Android views. */ export const setAndroidLayoutDirection: Getter = createNativeFlagGetter('setAndroidLayoutDirection', false); +/** + * Invoke callbacks immediately on the ReactInstance rather than going through a background thread for synchronization + */ +export const useImmediateExecutorInAndroidBridgeless: Getter = createNativeFlagGetter('useImmediateExecutorInAndroidBridgeless', false); /** * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 3fe725e3e1f0..6d879790467c 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<<4a30969e69164b149af42698f94c3b28>> + * @generated SignedSource<<6922b452333fc62a263bd77d42afbbbe>> * @flow strict-local */ @@ -41,6 +41,7 @@ export interface Spec extends TurboModule { +lazyAnimationCallbacks?: () => boolean; +preventDoubleTextMeasure?: () => boolean; +setAndroidLayoutDirection?: () => boolean; + +useImmediateExecutorInAndroidBridgeless?: () => boolean; +useModernRuntimeScheduler?: () => boolean; +useNativeViewConfigsInBridgelessMode?: () => boolean; +useRuntimeShadowNodeReferenceUpdate?: () => boolean;