diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/BaseReactPackage.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/BaseReactPackage.java new file mode 100644 index 00000000000000..0a606e0c65f44e --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/BaseReactPackage.java @@ -0,0 +1,159 @@ +/* + * 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.NonNull; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.ModuleHolder; +import com.facebook.react.bridge.ModuleSpec; +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.module.model.ReactModuleInfoProvider; +import com.facebook.react.uimanager.ViewManager; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import javax.inject.Provider; + +/** Abstract class that supports lazy loading of NativeModules by default. */ +public abstract class BaseReactPackage implements ReactPackage { + + @Override + public List createNativeModules(@NonNull ReactApplicationContext reactContext) { + throw new UnsupportedOperationException( + "createNativeModules method is not supported. Use getModule() method instead."); + } + + /** + * The API needed for TurboModules. Given a module name, it returns an instance of {@link + * NativeModule} for the name + * + * @param name name of the Native Module + * @param reactContext {@link ReactApplicationContext} context for this + */ + @Override + public abstract @Nullable NativeModule getModule( + @NonNull String name, @NonNull ReactApplicationContext reactContext); + + /** + * This is a temporary method till we implement TurboModules. Once we implement TurboModules, we + * will be able to directly call {@link BaseReactPackage#getModule(String, + * ReactApplicationContext)} This method will be removed when TurboModule implementation is + * complete + * + * @param reactContext + * @return + */ + /** package */ + Iterable getNativeModuleIterator(final ReactApplicationContext reactContext) { + final Set> entrySet = + getReactModuleInfoProvider().getReactModuleInfos().entrySet(); + final Iterator> entrySetIterator = entrySet.iterator(); + // This should ideally be an IteratorConvertor, but we don't have any internal library for it + return () -> + new Iterator() { + @Nullable Map.Entry nextEntry = null; + + private void findNext() { + while (entrySetIterator.hasNext()) { + Map.Entry entry = entrySetIterator.next(); + ReactModuleInfo reactModuleInfo = entry.getValue(); + + // This Iterator is used to create the NativeModule registry. The NativeModule + // registry must not have TurboModules. Therefore, if TurboModules are enabled, and + // the current NativeModule is a TurboModule, we need to skip iterating over it. + if (ReactFeatureFlags.useTurboModules && reactModuleInfo.isTurboModule()) { + continue; + } + + nextEntry = entry; + return; + } + nextEntry = null; + } + + @Override + public boolean hasNext() { + if (nextEntry == null) { + findNext(); + } + return nextEntry != null; + } + + @Override + public ModuleHolder next() { + if (nextEntry == null) { + findNext(); + } + + if (nextEntry == null) { + throw new NoSuchElementException("ModuleHolder not found"); + } + + Map.Entry entry = nextEntry; + + // Advance iterator + findNext(); + String name = entry.getKey(); + ReactModuleInfo reactModuleInfo = entry.getValue(); + return new ModuleHolder(reactModuleInfo, new ModuleHolderProvider(name, reactContext)); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Cannot remove native modules from the list"); + } + }; + } + + /** + * @param reactContext react application context that can be used to create View Managers. + * @return list of module specs that can create the View Managers. + */ + protected List getViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } + + @Override + public List createViewManagers(@NonNull ReactApplicationContext reactContext) { + List viewManagerModuleSpecs = getViewManagers(reactContext); + if (viewManagerModuleSpecs == null || viewManagerModuleSpecs.isEmpty()) { + return Collections.emptyList(); + } + + List viewManagers = new ArrayList<>(); + for (ModuleSpec moduleSpec : viewManagerModuleSpecs) { + viewManagers.add((ViewManager) moduleSpec.getProvider().get()); + } + return viewManagers; + } + + public abstract ReactModuleInfoProvider getReactModuleInfoProvider(); + + private class ModuleHolderProvider implements Provider { + + private final String mName; + private final ReactApplicationContext mReactContext; + + public ModuleHolderProvider(String name, ReactApplicationContext reactContext) { + mName = name; + mReactContext = reactContext; + } + + @Override + public @Nullable NativeModule get() { + return getModule(mName, mReactContext); + } + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/TurboReactPackage.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/TurboReactPackage.java index 8d09923ddd200e..c8f5ea9d24d105 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/TurboReactPackage.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/TurboReactPackage.java @@ -7,153 +7,8 @@ package com.facebook.react; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import com.facebook.react.bridge.ModuleHolder; -import com.facebook.react.bridge.ModuleSpec; -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.module.model.ReactModuleInfoProvider; -import com.facebook.react.uimanager.ViewManager; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; -import javax.inject.Provider; +import com.facebook.react.common.annotations.DeprecatedInNewArchitecture; /** This will eventually replace {@link LazyReactPackage} when TurboModules are finally done. */ -public abstract class TurboReactPackage implements ReactPackage { - - @Override - public List createNativeModules(ReactApplicationContext reactContext) { - throw new UnsupportedOperationException( - "createNativeModules method is not supported. Use getModule() method instead."); - } - - /** - * The API needed for TurboModules. Given a module name, it returns an instance of {@link - * NativeModule} for the name - * - * @param name name of the Native Module - * @param reactContext {@link ReactApplicationContext} context for this - */ - @Override - public abstract @Nullable NativeModule getModule( - @NonNull String name, @NonNull ReactApplicationContext reactContext); - - /** - * This is a temporary method till we implement TurboModules. Once we implement TurboModules, we - * will be able to directly call {@link TurboReactPackage#getModule(String, - * ReactApplicationContext)} This method will be removed when TurboModule implementation is - * complete - * - * @param reactContext - * @return - */ - /** package */ - Iterable getNativeModuleIterator(final ReactApplicationContext reactContext) { - final Set> entrySet = - getReactModuleInfoProvider().getReactModuleInfos().entrySet(); - final Iterator> entrySetIterator = entrySet.iterator(); - // This should ideally be an IteratorConvertor, but we don't have any internal library for it - return () -> - new Iterator() { - @Nullable Map.Entry nextEntry = null; - - private void findNext() { - while (entrySetIterator.hasNext()) { - Map.Entry entry = entrySetIterator.next(); - ReactModuleInfo reactModuleInfo = entry.getValue(); - - // This Iterator is used to create the NativeModule registry. The NativeModule - // registry must not have TurboModules. Therefore, if TurboModules are enabled, and - // the current NativeModule is a TurboModule, we need to skip iterating over it. - if (ReactFeatureFlags.useTurboModules && reactModuleInfo.isTurboModule()) { - continue; - } - - nextEntry = entry; - return; - } - nextEntry = null; - } - - @Override - public boolean hasNext() { - if (nextEntry == null) { - findNext(); - } - return nextEntry != null; - } - - @Override - public ModuleHolder next() { - if (nextEntry == null) { - findNext(); - } - - if (nextEntry == null) { - throw new NoSuchElementException("ModuleHolder not found"); - } - - Map.Entry entry = nextEntry; - - // Advance iterator - findNext(); - String name = entry.getKey(); - ReactModuleInfo reactModuleInfo = entry.getValue(); - return new ModuleHolder(reactModuleInfo, new ModuleHolderProvider(name, reactContext)); - } - - @Override - public void remove() { - throw new UnsupportedOperationException("Cannot remove native modules from the list"); - } - }; - } - - /** - * @param reactContext react application context that can be used to create View Managers. - * @return list of module specs that can create the View Managers. - */ - protected List getViewManagers(ReactApplicationContext reactContext) { - return Collections.emptyList(); - } - - @Override - public List createViewManagers(ReactApplicationContext reactContext) { - List viewManagerModuleSpecs = getViewManagers(reactContext); - if (viewManagerModuleSpecs == null || viewManagerModuleSpecs.isEmpty()) { - return Collections.emptyList(); - } - - List viewManagers = new ArrayList<>(); - for (ModuleSpec moduleSpec : viewManagerModuleSpecs) { - viewManagers.add((ViewManager) moduleSpec.getProvider().get()); - } - return viewManagers; - } - - public abstract ReactModuleInfoProvider getReactModuleInfoProvider(); - - private class ModuleHolderProvider implements Provider { - - private final String mName; - private final ReactApplicationContext mReactContext; - - public ModuleHolderProvider(String name, ReactApplicationContext reactContext) { - mName = name; - mReactContext = reactContext; - } - - @Override - public NativeModule get() { - return getModule(mName, mReactContext); - } - } -} +@DeprecatedInNewArchitecture(message = "Use BaseReactPackage instead") +public abstract class TurboReactPackage extends BaseReactPackage {}