Implement TurboModule eager initialization

Summary:
The TurboModuleManagerDelegate now supports a `getEagerInitModuleNames()` method, which is supposed to return a `java.util.List` containing the names of all NativeModules that require eager initialization. The NativeModuels are created when the `TurboModuleManager` is created. This happens inside `ReactInstanceManager.createReactContext` slightly after the NativeModuleRegistry is created, which is when our legacy NativeModules are eagerly initialized.

All NativeModules declared in `TurboReactPackages` that are wired into the `TurboModules` infra via `ReactPackageTurboModuleManagerDelegate` can use the `ReactModule(needsEagerInit = true)` annotation. Our build pipeline should correctly process the annotation into a `ModuleInfo`, and `ReactPackageTurboModuleManagerDelegate` should correctly forward the eagerly initialized module names to TurboModuleManager.

Changelog:
[Android][Added] - Implement TurboModule eager initialization support

Reviewed By: mdvacca

Differential Revision: D18819552

fbshipit-source-id: b2009a3b8f4e064362d2abeb5281637962531678
This commit is contained in:
Ramanpreet Nara
2019-12-05 13:24:43 -08:00
committed by Facebook Github Bot
parent b9491b7c51
commit b7f49a84d5
6 changed files with 47 additions and 2 deletions
@@ -54,6 +54,7 @@ import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.CatalystInstanceImpl;
import com.facebook.react.bridge.JSBundleLoader;
import com.facebook.react.bridge.JSIModule;
import com.facebook.react.bridge.JSIModulePackage;
import com.facebook.react.bridge.JSIModuleType;
import com.facebook.react.bridge.JavaJSExecutor;
@@ -92,6 +93,7 @@ import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
import com.facebook.react.modules.fabric.ReactFabric;
import com.facebook.react.packagerconnection.RequestHandler;
import com.facebook.react.surface.ReactStage;
import com.facebook.react.turbomodule.core.interfaces.TurboModuleRegistry;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.ReactRoot;
import com.facebook.react.uimanager.UIImplementationProvider;
@@ -1197,8 +1199,16 @@ public class ReactInstanceManager {
reactContext, catalystInstance.getJavaScriptContextHolder()));
if (ReactFeatureFlags.useTurboModules) {
catalystInstance.setTurboModuleManager(
catalystInstance.getJSIModule(JSIModuleType.TurboModuleManager));
JSIModule turboModuleManager =
catalystInstance.getJSIModule(JSIModuleType.TurboModuleManager);
catalystInstance.setTurboModuleManager(turboModuleManager);
TurboModuleRegistry registry = (TurboModuleRegistry) turboModuleManager;
// Eagerly initialize TurboModules
for (String moduleName : registry.getEagerInitModuleNames()) {
registry.getModule(moduleName);
}
}
}
if (mBridgeIdleDebugListener != null) {
@@ -25,6 +25,7 @@ rn_android_library(
react_native_target("java/com/facebook/react/bridge:bridge"),
react_native_target("java/com/facebook/react/config:config"),
react_native_target("java/com/facebook/react:react"),
react_native_target("java/com/facebook/react/module/model:model"),
":callinvokerholder",
],
exported_deps = [
@@ -15,6 +15,7 @@ import com.facebook.react.TurboReactPackage;
import com.facebook.react.bridge.CxxModuleWrapper;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import java.util.ArrayList;
import java.util.HashMap;
@@ -107,6 +108,21 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule
return mModules.get(moduleName);
}
@Override
public List<String> getEagerInitModuleNames() {
List<String> moduleNames = new ArrayList<>();
for (TurboReactPackage reactPackage : mPackages) {
for (ReactModuleInfo moduleInfo :
reactPackage.getReactModuleInfoProvider().getReactModuleInfos().values()) {
if (moduleInfo.isTurboModule() && moduleInfo.needsEagerInit()) {
moduleNames.add(moduleInfo.name());
}
}
}
return moduleNames;
}
public abstract static class Builder {
private @Nullable List<ReactPackage> mPackages;
private @Nullable ReactApplicationContext mContext;
@@ -51,6 +51,10 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry {
mTurbomoduleManagerDelegate = tmmDelegate;
}
public List<String> getEagerInitModuleNames() {
return mTurbomoduleManagerDelegate.getEagerInitModuleNames();
}
@DoNotStrip
@Nullable
protected TurboModule getJavaModule(String name) {
@@ -12,6 +12,8 @@ import com.facebook.jni.HybridData;
import com.facebook.react.bridge.CxxModuleWrapper;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import com.facebook.soloader.SoLoader;
import java.util.ArrayList;
import java.util.List;
public abstract class TurboModuleManagerDelegate {
static {
@@ -39,4 +41,8 @@ public abstract class TurboModuleManagerDelegate {
*/
@Nullable
public abstract CxxModuleWrapper getLegacyCxxModule(String moduleName);
public List<String> getEagerInitModuleNames() {
return new ArrayList<>();
}
}
@@ -9,6 +9,7 @@ package com.facebook.react.turbomodule.core.interfaces;
import androidx.annotation.Nullable;
import java.util.Collection;
import java.util.List;
/** Interface to allow for creating and retrieving TurboModules. */
public interface TurboModuleRegistry {
@@ -26,4 +27,11 @@ public interface TurboModuleRegistry {
/** Has the TurboModule with name `moduleName` been instantiated? */
boolean hasModule(String moduleName);
/**
* Return the names of all the NativeModules that are supposed to be eagerly initialized. By
* calling getModule on each name, this allows the application to eagerly initialize its
* NativeModules.
*/
List<String> getEagerInitModuleNames();
}