From 90b2c3fe43672aeb7d6e28647b5a25ccea7f045a Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Sun, 19 Nov 2023 18:46:12 -0800 Subject: [PATCH] Merge ReactModuleInfo removal logic into core (#41468) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/41468 Currently ReactPackageTurboModuleManagerDelegate uses ReactModuleInfos to create turbo modules. We want to see if it's possible to remove ReactModuleInfo from React Native's public API. Therefore, we are forking the implementation of each each method inside ReactPackageTurboModuleManagerDelegate: - **lazy mode:** doesn't use ReactModuleInfo - **control:** uses ReactModuleInfo This optimization was previosuly implemented outside of ReactPackageTurboModuleManagerDelegate. But, to simplify things, we are just pulling it inside the ReactPackageTurboModuleManagerDelegate. Changelog: [Internal] Reviewed By: philIip, mdvacca Differential Revision: D51093697 fbshipit-source-id: 6eb11020e0bf87eb704b35b990a0f14f157eea66 --- .../react/LazyTurboModuleManagerDelegate.java | 101 ------------------ ...eactPackageTurboModuleManagerDelegate.java | 75 ++++++++++++- 2 files changed, 74 insertions(+), 102 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/LazyTurboModuleManagerDelegate.java diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/LazyTurboModuleManagerDelegate.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/LazyTurboModuleManagerDelegate.java deleted file mode 100644 index be7c47f1611..00000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/LazyTurboModuleManagerDelegate.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react; - -import androidx.annotation.Nullable; -import com.facebook.react.bridge.NativeModule; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.common.annotations.UnstableReactNativeAPI; -import com.facebook.react.internal.turbomodule.core.interfaces.TurboModule; -import java.util.List; - -/** - * This abstract class provides a simple Lazy implementation of TurboModuleManagerDelegate. Main - * difference between this class and ReactPackageTurboModuleManagerDelegate is that - * LazyTurboModuleManagerDelegate does not require NativeModules to be annotated using a - * ReactModule, also this class does not use the {@link - * TurboReactPackage#getReactModuleInfoProvider} method. This class is for experimentation purposes - * only, not to meant to be used in production. - */ -@UnstableReactNativeAPI -public abstract class LazyTurboModuleManagerDelegate - extends ReactPackageTurboModuleManagerDelegate { - - private final List mPackages; - private final ReactApplicationContext mReactContext; - - public LazyTurboModuleManagerDelegate( - ReactApplicationContext reactApplicationContext, List packages) { - super(); - mPackages = packages; - mReactContext = reactApplicationContext; - } - - @Override - @Nullable - public TurboModule getModule(String moduleName) { - /* - * Returns first TurboModule found with the name received as a parameter. There's no - * warning or error if there are more than one TurboModule registered with the same name in - * different packages. This method relies on the order of insertion of ReactPackage into - * mPackages. Usually the size of mPackages is very small (2 or 3 packages in the majority of - * the cases) - */ - for (ReactPackage reactPackage : mPackages) { - if (reactPackage instanceof BaseReactPackage) { - BaseReactPackage baseReactPackage = (BaseReactPackage) reactPackage; - try { - TurboModule nativeModule = - (TurboModule) baseReactPackage.getModule(moduleName, mReactContext); - if (nativeModule != null) { - return nativeModule; - } - } 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. - */ - } - } else { - throw new IllegalArgumentException("ReactPackage must be an instance of TurboReactPackage"); - } - } - return null; - } - - @Override - public boolean unstable_isModuleRegistered(String moduleName) { - throw new UnsupportedOperationException("unstable_isModuleRegistered is not supported"); - } - - @Override - public boolean unstable_isLazyTurboModuleDelegate() { - return true; - } - - @Override - public boolean unstable_shouldEnableLegacyModuleInterop() { - return false; - } - - @Override - public boolean unstable_shouldRouteTurboModulesThroughLegacyModuleInterop() { - return false; - } - - @Override - public NativeModule getLegacyModule(String moduleName) { - throw new UnsupportedOperationException("Legacy Modules are not supported"); - } - - @Override - public boolean unstable_isLegacyModuleRegistered(String moduleName) { - return false; - }; -} 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 50b1c6fd320..c05f893d1c1 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 @@ -45,6 +45,12 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule private final boolean mEnableTurboModuleSyncVoidMethods = ReactFeatureFlags.unstable_enableTurboModuleSyncVoidMethods; + private final boolean mIsLazy = ReactFeatureFlags.enableTurboModuleStableAPI; + + // Lazy Props + private List mPackages; + private ReactApplicationContext mReactContext; + protected ReactPackageTurboModuleManagerDelegate() { super(); } @@ -52,6 +58,12 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule protected ReactPackageTurboModuleManagerDelegate( ReactApplicationContext reactApplicationContext, List packages) { super(); + if (mIsLazy) { + mPackages = packages; + mReactContext = reactApplicationContext; + return; + } + final ReactApplicationContext applicationContext = reactApplicationContext; for (ReactPackage reactPackage : packages) { if (reactPackage instanceof BaseReactPackage) { @@ -130,21 +142,65 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule @Override public boolean unstable_shouldEnableLegacyModuleInterop() { + if (mIsLazy) { + return false; + } + return mShouldEnableLegacyModuleInterop; } @Override public boolean unstable_shouldRouteTurboModulesThroughLegacyModuleInterop() { + if (mIsLazy) { + return false; + } + return mShouldRouteTurboModulesThroughLegacyModuleInterop; } public boolean unstable_enableSyncVoidMethods() { + if (mIsLazy) { + return false; + } + return mEnableTurboModuleSyncVoidMethods; } @Nullable @Override public TurboModule getModule(String moduleName) { + if (mIsLazy) { + /* + * Returns first TurboModule found with the name received as a parameter. There's no + * warning or error if there are more than one TurboModule registered with the same name in + * different packages. This method relies on the order of insertion of ReactPackage into + * mPackages. Usually the size of mPackages is very small (2 or 3 packages in the majority of + * the cases) + */ + for (ReactPackage reactPackage : mPackages) { + if (reactPackage instanceof BaseReactPackage) { + BaseReactPackage baseReactPackage = (BaseReactPackage) reactPackage; + try { + TurboModule nativeModule = + (TurboModule) baseReactPackage.getModule(moduleName, mReactContext); + if (nativeModule != null) { + return nativeModule; + } + } 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. + */ + } + } else { + throw new IllegalArgumentException( + "ReactPackage must be an instance of TurboReactPackage"); + } + } + return null; + } + NativeModule resolvedModule = null; for (final ModuleProvider moduleProvider : mModuleProviders) { @@ -180,11 +236,15 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule @Override public boolean unstable_isLazyTurboModuleDelegate() { - return false; + return mIsLazy; } @Override public boolean unstable_isModuleRegistered(String moduleName) { + if (mIsLazy) { + throw new UnsupportedOperationException("unstable_isModuleRegistered is not supported"); + } + for (final ModuleProvider moduleProvider : mModuleProviders) { final ReactModuleInfo moduleInfo = mPackageModuleInfos.get(moduleProvider).get(moduleName); if (moduleInfo != null && moduleInfo.isTurboModule()) { @@ -196,6 +256,10 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule @Override public boolean unstable_isLegacyModuleRegistered(String moduleName) { + if (mIsLazy) { + return false; + } + for (final ModuleProvider moduleProvider : mModuleProviders) { final ReactModuleInfo moduleInfo = mPackageModuleInfos.get(moduleProvider).get(moduleName); if (moduleInfo != null && !moduleInfo.isTurboModule()) { @@ -208,6 +272,10 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule @Nullable @Override public NativeModule getLegacyModule(String moduleName) { + if (mIsLazy) { + throw new UnsupportedOperationException("Legacy Modules are not supported"); + } + if (!unstable_shouldEnableLegacyModuleInterop()) { return null; } @@ -247,6 +315,11 @@ public abstract class ReactPackageTurboModuleManagerDelegate extends TurboModule @Override public List getEagerInitModuleNames() { + if (mIsLazy) { + throw new UnsupportedOperationException( + "Running delegate in lazy mode. Please override getEagerInitModuleNames() and return a list of module names that need to be initialized eagerly."); + } + List moduleNames = new ArrayList<>(); for (final ModuleProvider moduleProvider : mModuleProviders) { for (final ReactModuleInfo moduleInfo : mPackageModuleInfos.get(moduleProvider).values()) {