diff --git a/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/PopupMenuPackage.kt b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/PopupMenuPackage.kt index 1ef89db1f6c..1be27fb2bec 100644 --- a/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/PopupMenuPackage.kt +++ b/packages/react-native-popup-menu-android/android/src/main/java/com/facebook/react/popupmenu/PopupMenuPackage.kt @@ -28,7 +28,7 @@ public class PopupMenuPackage() : BaseReactPackage(), ViewManagerOnDemandReactPa return null } - protected override fun getViewManagers(context: ReactApplicationContext): List { + protected override fun getViewManagers(reactContext: ReactApplicationContext): List { return viewManagersMap.values.toList() } 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 deleted file mode 100644 index 2e10cc9dc29..00000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/BaseReactPackage.java +++ /dev/null @@ -1,159 +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.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.internal.featureflags.ReactNativeFeatureFlags; -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 (ReactNativeFeatureFlags.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/BaseReactPackage.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/BaseReactPackage.kt new file mode 100644 index 00000000000..b8c5ed5dfed --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/BaseReactPackage.kt @@ -0,0 +1,131 @@ +/* + * 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 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.internal.featureflags.ReactNativeFeatureFlags +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.NoSuchElementException +import javax.inject.Provider + +/** Abstract class that supports lazy loading of NativeModules by default. */ +public abstract class BaseReactPackage : ReactPackage { + + override fun createNativeModules(reactContext: ReactApplicationContext): List { + throw UnsupportedOperationException( + "createNativeModules method is not supported. Use getModule() method instead.") + } + + /** + * The API needed for TurboModules. Given a module name, it returns an instance of [NativeModule] + * for the name + * + * @param name name of the Native Module + * @param reactContext [ReactApplicationContext] context for this + */ + abstract override fun getModule( + name: String, + reactContext: ReactApplicationContext + ): NativeModule? + + /** + * This is a temporary method till we implement TurboModules. Once we implement TurboModules, we + * will be able to directly call [BaseReactPackage#getModule(String, ReactApplicationContext)] + * This method will be removed when TurboModule implementation is complete + * + * @param reactContext [ReactApplicationContext] + * @return + */ + internal fun getNativeModuleIterator( + reactContext: ReactApplicationContext + ): Iterable { + val entrySet = getReactModuleInfoProvider().getReactModuleInfos().entries + val entrySetIterator = entrySet.iterator() + // This should ideally be an IteratorConvertor, but we don't have any internal library for it + return Iterable { + object : Iterator { + var nextEntry: Map.Entry? = null + + private fun findNext() { + while (entrySetIterator.hasNext()) { + val entry = entrySetIterator.next() + val reactModuleInfo = entry.value + + // 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 (ReactNativeFeatureFlags.useTurboModules() && reactModuleInfo.isTurboModule) { + continue + } + + nextEntry = entry + return + } + nextEntry = null + } + + override fun hasNext(): Boolean { + if (nextEntry == null) { + findNext() + } + return nextEntry != null + } + + override fun next(): ModuleHolder { + if (nextEntry == null) { + findNext() + } + + val entry = nextEntry ?: throw NoSuchElementException("ModuleHolder not found") + + // Advance iterator + findNext() + + return ModuleHolder(entry.value, ModuleHolderProvider(entry.key, reactContext)) + } + } + } + } + + /** + * @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 open fun getViewManagers(reactContext: ReactApplicationContext): List = + emptyList() + + override fun createViewManagers( + reactContext: ReactApplicationContext + ): List> { + val viewManagerModuleSpecs = getViewManagers(reactContext) + if (viewManagerModuleSpecs.isNullOrEmpty()) { + return emptyList() + } + + val viewManagers: MutableList> = ArrayList() + for (moduleSpec in viewManagerModuleSpecs) { + viewManagers.add((moduleSpec.provider.get() as ViewManager<*, *>)) + } + return viewManagers + } + + public abstract fun getReactModuleInfoProvider(): ReactModuleInfoProvider + + private inner class ModuleHolderProvider( + private val name: String, + private val reactContext: ReactApplicationContext + ) : Provider { + override fun get(): NativeModule? = getModule(name, reactContext) + } +}