diff --git a/ReactAndroid/src/main/java/com/facebook/react/BUCK b/ReactAndroid/src/main/java/com/facebook/react/BUCK index b9ed1bd4fd1567..743bb34bb69448 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/BUCK @@ -35,4 +35,7 @@ rn_android_library( react_native_target("java/com/facebook/react/uimanager:uimanager"), react_native_target("java/com/facebook/react/views/imagehelper:imagehelper"), ], + exported_deps = [ + react_native_target("java/com/facebook/react/packagerconnection:packagerconnection"), + ], ) diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index 680abe831ac979..e5b3bae4412301 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -78,6 +78,7 @@ import com.facebook.react.modules.core.ReactChoreographer; import com.facebook.react.modules.debug.interfaces.DeveloperSettings; import com.facebook.react.modules.fabric.ReactFabric; +import com.facebook.react.packagerconnection.RequestHandler; import com.facebook.react.uimanager.DisplayMetricsHolder; import com.facebook.react.uimanager.UIManagerHelper; import com.facebook.react.uimanager.ViewManager; @@ -90,6 +91,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import javax.annotation.Nullable; @@ -205,7 +207,8 @@ public static ReactInstanceManagerBuilder builder() { @Nullable DevBundleDownloadListener devBundleDownloadListener, int minNumShakes, int minTimeLeftInFrameForNonBatchedOperationMs, - @Nullable JSIModulePackage jsiModulePackage) { + @Nullable JSIModulePackage jsiModulePackage, + @Nullable Map customPackagerCommandHandlers) { Log.d(ReactConstants.TAG, "ReactInstanceManager.ctor()"); initializeSoLoaderIfNecessary(applicationContext); @@ -227,7 +230,8 @@ public static ReactInstanceManagerBuilder builder() { useDeveloperSupport, redBoxHandler, devBundleDownloadListener, - minNumShakes); + minNumShakes, + customPackagerCommandHandlers); mBridgeIdleDebugListener = bridgeIdleDebugListener; mLifecycleState = initialLifecycleState; mMemoryPressureRouter = new MemoryPressureRouter(applicationContext); diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java index e57d5d809d9dd1..42a4a7476a4198 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManagerBuilder.java @@ -21,8 +21,10 @@ import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; +import com.facebook.react.packagerconnection.RequestHandler; import java.util.ArrayList; import java.util.List; +import java.util.Map; import javax.annotation.Nullable; /** @@ -50,6 +52,7 @@ public class ReactInstanceManagerBuilder { private int mMinNumShakes = 1; private int mMinTimeLeftInFrameForNonBatchedOperationMs = -1; private @Nullable JSIModulePackage mJSIModulesPackage; + private @Nullable Map mCustomPackagerCommandHandlers; /* package protected */ ReactInstanceManagerBuilder() { } @@ -216,6 +219,12 @@ public ReactInstanceManagerBuilder setMinTimeLeftInFrameForNonBatchedOperationMs return this; } + public ReactInstanceManagerBuilder setCustomPackagerCommandHandlers( + Map customPackagerCommandHandlers) { + mCustomPackagerCommandHandlers = customPackagerCommandHandlers; + return this; + } + /** * Instantiates a new {@link ReactInstanceManager}. * Before calling {@code build}, the following must be called: @@ -266,6 +275,7 @@ public ReactInstanceManager build() { mDevBundleDownloadListener, mMinNumShakes, mMinTimeLeftInFrameForNonBatchedOperationMs, - mJSIModulesPackage); + mJSIModulesPackage, + mCustomPackagerCommandHandlers); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java index 3fb603f9c519ee..bcf803aa6f971b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevServerHelper.java @@ -81,6 +81,13 @@ public interface PackagerCommandListener { void onPackagerReloadCommand(); void onPackagerDevMenuCommand(); void onCaptureHeapCommand(final Responder responder); + + // Allow apps to provide listeners for custom packager commands. + @Nullable Map customCommandHandlers(); + } + + public interface PackagerCustomCommandProvider { + } public interface SymbolicationListener { @@ -162,6 +169,10 @@ public void onRequest(@Nullable Object params, Responder responder) { commandListener.onCaptureHeapCommand(responder); } }); + Map customHandlers = commandListener.customCommandHandlers(); + if (customHandlers != null) { + handlers.putAll(customHandlers); + } handlers.putAll(new FileIoHandler().handlers()); ConnectionCallback onPackagerConnectedCallback = diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerFactory.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerFactory.java index 59cc883375c9e5..590db9362dd970 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerFactory.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerFactory.java @@ -11,8 +11,10 @@ import com.facebook.react.devsupport.interfaces.DevBundleDownloadListener; import com.facebook.react.devsupport.interfaces.DevSupportManager; +import com.facebook.react.packagerconnection.RequestHandler; import java.lang.reflect.Constructor; +import java.util.Map; import javax.annotation.Nullable; @@ -41,7 +43,8 @@ public static DevSupportManager create( enableOnCreate, null, null, - minNumShakes); + minNumShakes, + null); } public static DevSupportManager create( @@ -51,7 +54,8 @@ public static DevSupportManager create( boolean enableOnCreate, @Nullable RedBoxHandler redBoxHandler, @Nullable DevBundleDownloadListener devBundleDownloadListener, - int minNumShakes) { + int minNumShakes, + @Nullable Map customPackagerCommandHandlers) { if (!enableOnCreate) { return new DisabledDevSupportManager(); } @@ -74,7 +78,8 @@ public static DevSupportManager create( boolean.class, RedBoxHandler.class, DevBundleDownloadListener.class, - int.class); + int.class, + Map.class); return (DevSupportManager) constructor.newInstance( applicationContext, reactInstanceManagerHelper, @@ -82,7 +87,8 @@ public static DevSupportManager create( true, redBoxHandler, devBundleDownloadListener, - minNumShakes); + minNumShakes, + customPackagerCommandHandlers); } catch (Exception e) { throw new RuntimeException( "Requested enabled DevSupportManager, but DevSupportManagerImpl class was not found" + diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java index b951ef2ff22213..8764597391f801 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java @@ -60,6 +60,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -150,6 +151,8 @@ private enum ErrorType { private InspectorPackagerConnection.BundleStatus mBundleStatus; + private @Nullable Map mCustomPackagerCommandHandlers; + private static class JscProfileTask extends AsyncTask { private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); @@ -196,7 +199,8 @@ public DevSupportManagerImpl( enableOnCreate, null, null, - minNumShakes); + minNumShakes, + null); } public DevSupportManagerImpl( @@ -206,7 +210,8 @@ public DevSupportManagerImpl( boolean enableOnCreate, @Nullable RedBoxHandler redBoxHandler, @Nullable DevBundleDownloadListener devBundleDownloadListener, - int minNumShakes) { + int minNumShakes, + @Nullable Map customPackagerCommandHandlers) { mReactInstanceManagerHelper = reactInstanceManagerHelper; mApplicationContext = applicationContext; mJSAppBundleName = packagerPathForJSBundleName; @@ -232,6 +237,8 @@ public void onShake() { } }, minNumShakes); + mCustomPackagerCommandHandlers = customPackagerCommandHandlers; + // Prepare reload APP broadcast receiver (will be registered/unregistered from #reload) mReloadAppBroadcastReceiver = new BroadcastReceiver() { @Override @@ -841,6 +848,11 @@ public void run() { }); } + @Override + public @Nullable Map customCommandHandlers() { + return mCustomPackagerCommandHandlers; + } + private void handleCaptureHeap(final Responder responder) { if (mCurrentContext == null) { return;