diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 57530f104874ea..8fb5091a125b60 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3859,6 +3859,15 @@ public final class com/facebook/react/runtime/BridgelessCatalystInstance : com/f public fun setTurboModuleRegistry (Lcom/facebook/react/internal/turbomodule/core/interfaces/TurboModuleRegistry;)V } +public class com/facebook/react/runtime/BridgelessDevSupportManager : com/facebook/react/devsupport/DevSupportManagerBase { + public fun (Lcom/facebook/react/runtime/ReactHostImpl;Landroid/content/Context;Lcom/facebook/react/devsupport/ReactInstanceDevHelper;Ljava/lang/String;ZLcom/facebook/react/devsupport/interfaces/RedBoxHandler;Lcom/facebook/react/devsupport/interfaces/DevBundleDownloadListener;ILjava/util/Map;Lcom/facebook/react/common/SurfaceDelegateFactory;Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager;Lcom/facebook/react/devsupport/interfaces/PausedInDebuggerOverlayManager;)V + public fun (Lcom/facebook/react/runtime/ReactHostImpl;Landroid/content/Context;Ljava/lang/String;)V + public static fun createInstanceDevHelper (Lcom/facebook/react/runtime/ReactHostImpl;)Lcom/facebook/react/devsupport/ReactInstanceDevHelper; + protected fun getUniqueTag ()Ljava/lang/String; + public fun handleReloadJS ()V + public fun loadSplitBundleFromServer (Ljava/lang/String;Lcom/facebook/react/devsupport/interfaces/DevSplitBundleCallback;)V +} + public class com/facebook/react/runtime/CoreReactPackage$$ReactModuleInfoProvider : com/facebook/react/module/model/ReactModuleInfoProvider { public fun ()V public fun getReactModuleInfos ()Ljava/util/Map; @@ -3897,6 +3906,7 @@ public class com/facebook/react/runtime/ReactHostImpl : com/facebook/react/React public fun onHostResume (Landroid/app/Activity;Lcom/facebook/react/modules/core/DefaultHardwareBackBtnHandler;)V public fun onNewIntent (Landroid/content/Intent;)V public fun onWindowFocusChange (Z)V + public fun overrideDevSupportManager (Lcom/facebook/react/devsupport/interfaces/DevSupportManager;)V public fun reload (Ljava/lang/String;)Lcom/facebook/react/interfaces/TaskInterface; public fun removeBeforeDestroyListener (Lkotlin/jvm/functions/Function0;)V public fun removeReactInstanceEventListener (Lcom/facebook/react/ReactInstanceEventListener;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/annotations/FrameworkAPI.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/annotations/FrameworkAPI.kt index 37e2863356003f..078552af0f12e2 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/annotations/FrameworkAPI.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/annotations/FrameworkAPI.kt @@ -8,7 +8,7 @@ package com.facebook.react.common.annotations @Retention(AnnotationRetention.RUNTIME) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) +@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR) @RequiresOptIn( level = RequiresOptIn.Level.ERROR, message = diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessDevSupportManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessDevSupportManager.java index b411f73f9e57dc..ba22f690779d64 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessDevSupportManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessDevSupportManager.java @@ -12,19 +12,28 @@ import android.os.Bundle; import android.view.View; import androidx.annotation.Nullable; +import androidx.annotation.OptIn; import com.facebook.infer.annotation.Nullsafe; import com.facebook.react.bridge.JSBundleLoader; import com.facebook.react.bridge.JavaJSExecutor; import com.facebook.react.bridge.JavaScriptExecutorFactory; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.UiThreadUtil; +import com.facebook.react.common.SurfaceDelegateFactory; +import com.facebook.react.common.annotations.FrameworkAPI; import com.facebook.react.devsupport.DevSupportManagerBase; import com.facebook.react.devsupport.HMRClient; import com.facebook.react.devsupport.ReactInstanceDevHelper; +import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; +import com.facebook.react.devsupport.interfaces.DevLoadingViewManager; import com.facebook.react.devsupport.interfaces.DevSplitBundleCallback; +import com.facebook.react.devsupport.interfaces.PausedInDebuggerOverlayManager; +import com.facebook.react.devsupport.interfaces.RedBoxHandler; import com.facebook.react.modules.core.DeviceEventManagerModule; +import com.facebook.react.packagerconnection.RequestHandler; import com.facebook.react.runtime.internal.bolts.Continuation; import com.facebook.react.runtime.internal.bolts.Task; +import java.util.Map; /** * An implementation of {@link com.facebook.react.devsupport.interfaces.DevSupportManager} that @@ -32,13 +41,15 @@ * APIs for asynchronously loading the JS bundle. */ @Nullsafe(Nullsafe.Mode.LOCAL) -class BridgelessDevSupportManager extends DevSupportManagerBase { +public class BridgelessDevSupportManager extends DevSupportManagerBase { private final ReactHostImpl mReactHost; + @OptIn(markerClass = FrameworkAPI.class) public BridgelessDevSupportManager( ReactHostImpl host, Context context, @Nullable String packagerPathForJSBundleName) { - super( + this( + host, context.getApplicationContext(), createInstanceDevHelper(host), packagerPathForJSBundleName, @@ -50,6 +61,38 @@ public BridgelessDevSupportManager( null /* surfaceDelegateFactory */, null /* devLoadingViewManager */, null /* pausedInDebuggerOverlayManager */); + } + + /** + * This constructor mirrors the same constructor we have for {@link BridgeDevSupportManager} and + * is used by Expo/ExpoGo to customize the DevMenu on Bridgeless mode. + */ + @FrameworkAPI + public BridgelessDevSupportManager( + ReactHostImpl host, + Context applicationContext, + ReactInstanceDevHelper reactInstanceManagerHelper, + @Nullable String packagerPathForJSBundleName, + boolean enableOnCreate, + @Nullable RedBoxHandler redBoxHandler, + @Nullable DevBundleDownloadListener devBundleDownloadListener, + int minNumShakes, + @Nullable Map customPackagerCommandHandlers, + @Nullable SurfaceDelegateFactory surfaceDelegateFactory, + @Nullable DevLoadingViewManager devLoadingViewManager, + @Nullable PausedInDebuggerOverlayManager pausedInDebuggerOverlayManager) { + super( + applicationContext, + reactInstanceManagerHelper, + packagerPathForJSBundleName, + enableOnCreate, + redBoxHandler, + devBundleDownloadListener, + minNumShakes, + customPackagerCommandHandlers, + surfaceDelegateFactory, + devLoadingViewManager, + pausedInDebuggerOverlayManager); mReactHost = host; } @@ -102,7 +145,7 @@ public void handleReloadJS() { mReactHost.reload("BridgelessDevSupportManager.handleReloadJS()"); } - private static ReactInstanceDevHelper createInstanceDevHelper(final ReactHostImpl reactHost) { + public static ReactInstanceDevHelper createInstanceDevHelper(final ReactHostImpl reactHost) { return new ReactInstanceDevHelper() { @Override public void onReloadWithJSDebugger(JavaJSExecutor.Factory proxyExecutorFactory) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java index 2a858271956d2c..61b9474e8af2a2 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java @@ -106,7 +106,7 @@ public class ReactHostImpl implements ReactHost { private final Context mContext; private final ReactHostDelegate mReactHostDelegate; private final ComponentFactory mComponentFactory; - private final DevSupportManager mDevSupportManager; + private DevSupportManager mDevSupportManager; private final Executor mBGExecutor; private final Executor mUIExecutor; private final Set mAttachedSurfaces = new HashSet<>(); @@ -165,6 +165,26 @@ public ReactHostImpl( Executor uiExecutor, boolean allowPackagerServerAccess, boolean useDevSupport) { + this( + context, + delegate, + componentFactory, + bgExecutor, + uiExecutor, + allowPackagerServerAccess, + useDevSupport, + null); + } + + public ReactHostImpl( + Context context, + ReactHostDelegate delegate, + ComponentFactory componentFactory, + Executor bgExecutor, + Executor uiExecutor, + boolean allowPackagerServerAccess, + boolean useDevSupport, + @Nullable DevSupportManager devSupportManager) { mContext = context; mReactHostDelegate = delegate; mComponentFactory = componentFactory; @@ -173,13 +193,16 @@ public ReactHostImpl( mMemoryPressureRouter = new MemoryPressureRouter(context); mAllowPackagerServerAccess = allowPackagerServerAccess; mUseDevSupport = useDevSupport; - - if (mUseDevSupport) { - mDevSupportManager = - new BridgelessDevSupportManager( - ReactHostImpl.this, mContext, mReactHostDelegate.getJsMainModulePath()); - } else { - mDevSupportManager = new ReleaseDevSupportManager(); + mDevSupportManager = devSupportManager; + + if (devSupportManager == null) { + if (mUseDevSupport) { + mDevSupportManager = + new BridgelessDevSupportManager( + ReactHostImpl.this, mContext, mReactHostDelegate.getJsMainModulePath()); + } else { + mDevSupportManager = new ReleaseDevSupportManager(); + } } }