diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactPackageTurboModuleManagerDelegate.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactPackageTurboModuleManagerDelegate.java index a7a23911199..c0d7e7cfdc5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactPackageTurboModuleManagerDelegate.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactPackageTurboModuleManagerDelegate.java @@ -44,6 +44,12 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule && ReactFeatureFlags.unstable_useTurboModuleInterop; } + private static boolean shouldRouteTurboModulesThroughInteropLayer() { + return ReactFeatureFlags.enableBridgelessArchitecture + && ReactFeatureFlags.unstable_useTurboModuleInterop + && ReactFeatureFlags.unstable_useTurboModuleInteropForAllTurboModules; + } + protected ReactPackageTurboModuleManagerDelegate( ReactApplicationContext reactApplicationContext, List packages) { super(); @@ -146,22 +152,25 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule @Nullable @Override public TurboModule getModule(String moduleName) { + if (shouldRouteTurboModulesThroughInteropLayer()) { + return null; + } + NativeModule resolvedModule = null; for (final ModuleProvider moduleProvider : mModuleProviders) { try { final ReactModuleInfo moduleInfo = mPackageModuleInfos.get(moduleProvider).get(moduleName); - if (moduleInfo == null - // Skip TurboModule-incompatible modules - || !moduleInfo.isTurboModule() - || resolvedModule != null && !moduleInfo.canOverrideExistingModule()) { - continue; + if (moduleInfo != null + && moduleInfo.isTurboModule() + && (resolvedModule == null || moduleInfo.canOverrideExistingModule())) { + + final NativeModule module = moduleProvider.getModule(moduleName); + if (module != null) { + resolvedModule = module; + } } - final NativeModule module = moduleProvider.getModule(moduleName); - if (module != null) { - resolvedModule = module; - } } catch (IllegalArgumentException ex) { /** * TurboReactPackages can throw an IllegalArgumentException when a module isn't found. If @@ -191,17 +200,16 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule for (final ModuleProvider moduleProvider : mModuleProviders) { try { final ReactModuleInfo moduleInfo = mPackageModuleInfos.get(moduleProvider).get(moduleName); - if (moduleInfo == null - // Skip TurboModule-compatible modules - || moduleInfo.isTurboModule() - || resolvedModule != null && !moduleInfo.canOverrideExistingModule()) { - continue; + if (moduleInfo != null + && (!moduleInfo.isTurboModule() || shouldRouteTurboModulesThroughInteropLayer()) + && (resolvedModule == null || moduleInfo.canOverrideExistingModule())) { + + final NativeModule module = moduleProvider.getModule(moduleName); + if (module != null) { + resolvedModule = module; + } } - final NativeModule module = moduleProvider.getModule(moduleName); - if (module != null) { - resolvedModule = module; - } } catch (IllegalArgumentException ex) { /** * TurboReactPackages can throw an IllegalArgumentException when a module isn't found. If @@ -212,7 +220,8 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule } // Skip TurboModule-compatible modules - if (resolvedModule instanceof TurboModule) { + boolean isLegacyModule = !(resolvedModule instanceof TurboModule); + if (!(isLegacyModule || shouldRouteTurboModulesThroughInteropLayer())) { return null; } 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 40d777c5b23..a4dfdbca6f5 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 @@ -28,6 +28,14 @@ public class ReactFeatureFlags { /** In Bridgeless mode, should legacy NativeModules use the TurboModule system? */ public static volatile boolean unstable_useTurboModuleInterop = false; + /** + * Temporary flag that will be used to validate the staibility of the TurboModule interop layer. + * Force all Java NativeModules that are TurboModule-compatible (that would have otherwise gone + * through the C++ codegen method dispatch path) instead through the TurboModule interop layer + * (i.e: the JavaInteropTurboModule method dispatch path). + */ + public static volatile boolean unstable_useTurboModuleInteropForAllTurboModules = false; + /** * Should this application use the new (Fabric) Renderer? If yes, all rendering in this app will * use Fabric instead of the legacy renderer. diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java index b98d9ed6879..abfb6c82ebd 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java @@ -74,7 +74,7 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { new ModuleProvider() { @Nullable public TurboModule getModule(String moduleName) { - if (delegate == null) { + if (delegate == null || shouldRouteTurboModulesThroughInteropLayer()) { return null; } @@ -104,10 +104,12 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { NativeModule nativeModule = delegate.getLegacyModule(moduleName); if (nativeModule != null) { - // TurboModuleManagerDelegate.getLegacyModule must never return a TurboModule - Assertions.assertCondition( - !(nativeModule instanceof TurboModule), - "NativeModule \"" + moduleName + "\" is a TurboModule"); + if (!shouldRouteTurboModulesThroughInteropLayer()) { + // TurboModuleManagerDelegate.getLegacyModule must never return a TurboModule + Assertions.assertCondition( + !(nativeModule instanceof TurboModule), + "NativeModule \"" + moduleName + "\" is a TurboModule"); + } return nativeModule; } return nativeModule; @@ -120,6 +122,12 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { && ReactFeatureFlags.unstable_useTurboModuleInterop; } + private static boolean shouldRouteTurboModulesThroughInteropLayer() { + return ReactFeatureFlags.enableBridgelessArchitecture + && ReactFeatureFlags.unstable_useTurboModuleInterop + && ReactFeatureFlags.unstable_useTurboModuleInteropForAllTurboModules; + } + public List getEagerInitModuleNames() { return mEagerInitModuleNames; } @@ -134,7 +142,8 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { @Nullable private NativeModule getLegacyJavaModule(String moduleName) { final NativeModule module = getNativeModule(moduleName); - return !(module instanceof CxxModuleWrapper) && !(module instanceof TurboModule) + return !(module instanceof CxxModuleWrapper) + && (shouldRouteTurboModulesThroughInteropLayer() || !(module instanceof TurboModule)) ? module : null; } @@ -143,7 +152,8 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { @Nullable private CxxModuleWrapper getLegacyCxxModule(String moduleName) { final NativeModule module = getNativeModule(moduleName); - return module instanceof CxxModuleWrapper && !(module instanceof TurboModule) + return module instanceof CxxModuleWrapper + && (shouldRouteTurboModulesThroughInteropLayer() || !(module instanceof TurboModule)) ? (CxxModuleWrapper) module : null; } @@ -151,6 +161,9 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { @DoNotStrip @Nullable private CxxModuleWrapper getTurboLegacyCxxModule(String moduleName) { + if (shouldRouteTurboModulesThroughInteropLayer()) { + return null; + } final NativeModule module = getNativeModule(moduleName); return module instanceof CxxModuleWrapper && module instanceof TurboModule ? (CxxModuleWrapper) module @@ -160,6 +173,9 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { @DoNotStrip @Nullable private TurboModule getTurboJavaModule(String moduleName) { + if (shouldRouteTurboModulesThroughInteropLayer()) { + return null; + } final NativeModule module = getNativeModule(moduleName); return !(module instanceof CxxModuleWrapper) && module instanceof TurboModule ? (TurboModule) module