Finish the Java-facing side of the TurboModule interop layer (#36627)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36627

## Changes
Now, when you call TurboModuleManager.getModule(interopModuleName), the TurboModuleManager will create and return that interop module to you.

Changes in this diff:
1. Forward interop NativeModules from app's ReactPackages to the TurboModuleManager
2. Extend TurboModule system's module creation algorithm to create interop NativeModules.

## Details
TurboModuleManagerDelegate's capabilities:
||API| Without Interop | With Interop |
|same|getModule()|Java [NativeModule](https://www.internalfb.com/code/fbsource/[e5db2a0dc412f0656f7eeec1db9d2da4aab61f40]/xplat/js/react-native-github/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModule.java?lines=21) that also implements [TurboModule](https://www.internalfb.com/code/fbsource/[c7089c1408eda109f342a1f33252533e743614ed]/xplat/js/react-native-github/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/TurboModule.java?lines=11) |Java [NativeModule](https://www.internalfb.com/code/fbsource/[e5db2a0dc412f0656f7eeec1db9d2da4aab61f40]/xplat/js/react-native-github/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModule.java?lines=21) that also implements [TurboModule](https://www.internalfb.com/code/fbsource/[c7089c1408eda109f342a1f33252533e743614ed]/xplat/js/react-native-github/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/TurboModule.java?lines=11) |
|new|getLegacyModule()| |Java [NativeModule](https://www.internalfb.com/code/fbsource/[e5db2a0dc412f0656f7eeec1db9d2da4aab61f40]/xplat/js/react-native-github/ReactAndroid/src/main/java/com/facebook/react/bridge/NativeModule.java?lines=21) that **doesn't** implement [TurboModule](https://www.internalfb.com/code/fbsource/[c7089c1408eda109f342a1f33252533e743614ed]/xplat/js/react-native-github/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/TurboModule.java?lines=11)|

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D43751055

fbshipit-source-id: 75afb6f836b8ec270bb916525ff2fc9030d34012
This commit is contained in:
Ramanpreet Nara
2023-03-28 09:11:56 -07:00
committed by Facebook GitHub Bot
parent 7a08fbb088
commit 185bc248e4
3 changed files with 91 additions and 3 deletions
@@ -39,6 +39,11 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule
&& ReactFeatureFlags.unstable_useTurboModuleInterop;
}
private static boolean shouldCreateLegacyModules() {
return ReactFeatureFlags.enableBridgelessArchitecture
&& ReactFeatureFlags.unstable_useTurboModuleInterop;
}
protected ReactPackageTurboModuleManagerDelegate(
ReactApplicationContext reactApplicationContext, List<ReactPackage> packages) {
super();
@@ -147,6 +152,7 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule
try {
final ReactModuleInfo moduleInfo = mPackageModuleInfos.get(moduleProvider).get(moduleName);
if (moduleInfo == null
// Skip TurboModule-incompatible modules
|| !moduleInfo.isTurboModule()
|| resolvedModule != null && !moduleInfo.canOverrideExistingModule()) {
continue;
@@ -165,11 +171,52 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule
}
}
if (resolvedModule instanceof TurboModule) {
return (TurboModule) resolvedModule;
// Skip TurboModule-incompatible modules
if (!(resolvedModule instanceof TurboModule)) {
return null;
}
return null;
return (TurboModule) resolvedModule;
}
@Nullable
@Override
public NativeModule getLegacyModule(String moduleName) {
if (!shouldCreateLegacyModules()) {
return null;
}
NativeModule resolvedModule = null;
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;
}
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
* this happens, it's safe to ignore the exception because a later TurboReactPackage could
* provide the module.
*/
}
}
// Skip TurboModule-compatible modules
if (resolvedModule instanceof TurboModule) {
return null;
}
return resolvedModule;
}
@Deprecated
@@ -17,6 +17,7 @@ import com.facebook.react.bridge.CxxModuleWrapper;
import com.facebook.react.bridge.JSIModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.RuntimeExecutor;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModuleRegistry;
@@ -32,6 +33,7 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry {
private static volatile boolean sIsSoLibraryLoaded;
private final List<String> mEagerInitModuleNames;
private final ModuleProvider<TurboModule> mModuleProvider;
private final ModuleProvider<NativeModule> mLegacyModuleProvider;
// Prevents the creation of new TurboModules once cleanup as been initiated.
private final Object mModuleCleanupLock = new Object();
@@ -87,6 +89,31 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry {
return module;
}
};
mLegacyModuleProvider =
new ModuleProvider<NativeModule>() {
@Nullable
public NativeModule getModule(String moduleName) {
if (delegate == null || !shouldCreateLegacyModules()) {
return null;
}
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");
return nativeModule;
}
return nativeModule;
}
};
}
private static boolean shouldCreateLegacyModules() {
return ReactFeatureFlags.enableBridgelessArchitecture
&& ReactFeatureFlags.unstable_useTurboModuleInterop;
}
public List<String> getEagerInitModuleNames() {
@@ -187,6 +214,10 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry {
TurboModulePerfLogger.moduleCreateConstructStart(moduleName, moduleHolder.getModuleId());
NativeModule nativeModule = (NativeModule) mModuleProvider.getModule(moduleName);
if (nativeModule == null) {
nativeModule = mLegacyModuleProvider.getModule(moduleName);
}
TurboModulePerfLogger.moduleCreateConstructEnd(moduleName, moduleHolder.getModuleId());
TurboModulePerfLogger.moduleCreateSetUpStart(moduleName, moduleHolder.getModuleId());
@@ -11,6 +11,7 @@ import androidx.annotation.Nullable;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.CxxModuleWrapper;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import com.facebook.soloader.SoLoader;
import java.util.ArrayList;
@@ -48,6 +49,15 @@ public abstract class TurboModuleManagerDelegate {
@Nullable
public abstract CxxModuleWrapper getLegacyCxxModule(String moduleName);
/**
* Create an return a legacy NativeModule with name `moduleName`. If `moduleName` is a
* TurboModule, return null.
*/
@Nullable
public NativeModule getLegacyModule(String moduleName) {
return null;
}
public List<String> getEagerInitModuleNames() {
return new ArrayList<>();
}