diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/BridgelessReactPackage.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/BridgelessReactPackage.java new file mode 100644 index 00000000000000..14d361b0499475 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/BridgelessReactPackage.java @@ -0,0 +1,118 @@ +/* + * 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.infer.annotation.Nullsafe; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.devsupport.LogBoxModule; +import com.facebook.react.devsupport.interfaces.DevSupportManager; +import com.facebook.react.module.annotations.ReactModule; +import com.facebook.react.module.annotations.ReactModuleList; +import com.facebook.react.module.model.ReactModuleInfo; +import com.facebook.react.module.model.ReactModuleInfoProvider; +import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; +import com.facebook.react.modules.core.DeviceEventManagerModule; +import com.facebook.react.modules.debug.DevSettingsModule; +import com.facebook.react.modules.debug.SourceCodeModule; +import com.facebook.react.modules.deviceinfo.DeviceInfoModule; +import com.facebook.react.modules.systeminfo.AndroidInfoModule; +import com.facebook.react.turbomodule.core.interfaces.TurboModule; +import java.util.HashMap; +import java.util.Map; + +@Nullsafe(Nullsafe.Mode.LOCAL) +@ReactModuleList( + nativeModules = { + AndroidInfoModule.class, + DeviceInfoModule.class, + DevSettingsModule.class, + SourceCodeModule.class, + LogBoxModule.class, + DeviceEventManagerModule.class, + }) +public class BridgelessReactPackage extends TurboReactPackage { + + private DevSupportManager mDevSupportManager; + private DefaultHardwareBackBtnHandler mHardwareBackBtnHandler; + + public BridgelessReactPackage( + DevSupportManager devSupportManager, DefaultHardwareBackBtnHandler hardwareBackBtnHandler) { + mDevSupportManager = devSupportManager; + mHardwareBackBtnHandler = hardwareBackBtnHandler; + } + + @Override + public NativeModule getModule(String name, ReactApplicationContext reactContext) { + switch (name) { + case AndroidInfoModule.NAME: + return new AndroidInfoModule(reactContext); + case DeviceInfoModule.NAME: + return new DeviceInfoModule(reactContext); + case SourceCodeModule.NAME: + return new SourceCodeModule(reactContext); + case DevSettingsModule.NAME: + return new DevSettingsModule(reactContext, mDevSupportManager); + case DeviceEventManagerModule.NAME: + return new DeviceEventManagerModule(reactContext, mHardwareBackBtnHandler); + case LogBoxModule.NAME: + return new LogBoxModule(reactContext, mDevSupportManager); + default: + throw new IllegalArgumentException( + "In BridgelessReactPackage, could not find Native module for " + name); + } + } + + @Override + public ReactModuleInfoProvider getReactModuleInfoProvider() { + try { + Class reactModuleInfoProviderClass = + Class.forName("com.facebook.react.CoreModulesPackage$$ReactModuleInfoProvider"); + return (ReactModuleInfoProvider) reactModuleInfoProviderClass.newInstance(); + } catch (ClassNotFoundException e) { + // In OSS case, the annotation processor does not run. We fall back on creating this byhand + Class[] moduleList = + new Class[] { + AndroidInfoModule.class, + DeviceInfoModule.class, + SourceCodeModule.class, + DevSettingsModule.class, + DeviceEventManagerModule.class, + LogBoxModule.class, + }; + final Map reactModuleInfoMap = new HashMap<>(); + for (Class moduleClass : moduleList) { + ReactModule reactModule = moduleClass.getAnnotation(ReactModule.class); + if (reactModule != null) { + reactModuleInfoMap.put( + reactModule.name(), + new ReactModuleInfo( + reactModule.name(), + moduleClass.getName(), + reactModule.canOverrideExistingModule(), + reactModule.needsEagerInit(), + reactModule.hasConstants(), + reactModule.isCxxModule(), + TurboModule.class.isAssignableFrom(moduleClass))); + } + } + return new ReactModuleInfoProvider() { + @Override + public Map getReactModuleInfos() { + return reactModuleInfoMap; + } + }; + } catch (InstantiationException e) { + throw new RuntimeException( + "No ReactModuleInfoProvider for CoreModulesPackage$$ReactModuleInfoProvider", e); + } catch (IllegalAccessException e) { + throw new RuntimeException( + "No ReactModuleInfoProvider for CoreModulesPackage$$ReactModuleInfoProvider", e); + } + } +}