TM Android: Avoid creating TM instance if the module is not TM enabled

Summary:
There is a flow where TM registry is creating a module instance (as registered in the TurboReactPackage), only to discard it if it's not a TM enabled module. This may be fine for many modules, but for module like `UIManagerModule`, this may cause a race condition or other issues, including potential perf regression when accessing UIManager from JS (e.g. for getting native viewConfigs).

Changelog: [Internal]

Reviewed By: RSNara

Differential Revision: D24811838

fbshipit-source-id: 6e1cce6993a6e5c9763773f175083bf52925c910
This commit is contained in:
Kevin Gozali
2020-11-09 02:24:41 -08:00
committed by Facebook GitHub Bot
parent 610dcf488b
commit 803a26cb00
3 changed files with 33 additions and 4 deletions
@@ -29,6 +29,11 @@ public class ReactFeatureFlags {
/** Enable TurboModule JS Codegen. */
public static volatile boolean useTurboModuleJSCodegen = false;
/**
* Enable the fix to validate the TurboReactPackage's module info before resolving a TurboModule.
*/
public static volatile boolean enableTurboModulePackageInfoValidation = false;
/*
* This feature flag enables logs for Fabric
*/
@@ -15,13 +15,18 @@ 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.config.ReactFeatureFlags;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModuleManagerDelegate {
private final List<TurboReactPackage> mPackages = new ArrayList<>();
private final Map<TurboReactPackage, Map<String, ReactModuleInfo>> mPackageModuleInfos =
new HashMap<>();
private final ReactApplicationContext mReactApplicationContext;
protected ReactPackageTurboModuleManagerDelegate(
@@ -30,7 +35,11 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule
mReactApplicationContext = reactApplicationContext;
for (ReactPackage reactPackage : packages) {
if (reactPackage instanceof TurboReactPackage) {
mPackages.add((TurboReactPackage) reactPackage);
TurboReactPackage pkg = (TurboReactPackage) reactPackage;
mPackages.add(pkg);
if (ReactFeatureFlags.enableTurboModulePackageInfoValidation) {
mPackageModuleInfos.put(pkg, pkg.getReactModuleInfoProvider().getReactModuleInfos());
}
}
}
}
@@ -72,9 +81,23 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule
for (final TurboReactPackage pkg : mPackages) {
try {
NativeModule module = pkg.getModule(moduleName, mReactApplicationContext);
if (resolvedModule == null || module != null && module.canOverrideExistingModule()) {
resolvedModule = module;
if (ReactFeatureFlags.enableTurboModulePackageInfoValidation) {
final ReactModuleInfo moduleInfo = mPackageModuleInfos.get(pkg).get(moduleName);
if (moduleInfo == null
|| !moduleInfo.isTurboModule()
|| resolvedModule != null && !moduleInfo.canOverrideExistingModule()) {
continue;
}
final NativeModule module = pkg.getModule(moduleName, mReactApplicationContext);
if (module != null) {
resolvedModule = module;
}
} else {
final NativeModule module = pkg.getModule(moduleName, mReactApplicationContext);
if (resolvedModule == null || module != null && module.canOverrideExistingModule()) {
resolvedModule = module;
}
}
} catch (IllegalArgumentException ex) {
/**