From bccedff09b5ae17d7219f00f285889ba359323c6 Mon Sep 17 00:00:00 2001 From: Arushi Kesarwani Date: Mon, 11 Mar 2024 12:19:49 -0700 Subject: [PATCH] Implement getJSCallInvokerHolder for BridgelessCatalystInstance (#43400) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/43400 Implement `getJSCallInvokerHolder()` for BridgelessCatalystInstance Changelog: [Android][Breaking] Implement `getJSCallInvokerHolder()` for Bridgeless Catalyst Instance Reviewed By: cortinico Differential Revision: D54650305 fbshipit-source-id: effac3daaad5173c2fd78ab11bbe3f3156a9c07b --- .../ReactAndroid/api/ReactAndroid.api | 2 +- .../react/runtime/BridgelessCatalystInstance.kt | 7 ++++--- .../react/runtime/BridgelessReactContext.java | 10 ++++------ .../com/facebook/react/runtime/ReactHostImpl.java | 15 +++++++++++++++ .../com/facebook/react/runtime/ReactInstance.java | 2 +- .../react/runtime/BridgelessReactContextTest.kt | 10 ++++++---- 6 files changed, 31 insertions(+), 15 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 052bc3df4bcfdc..4d72f0ea722178 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3581,7 +3581,7 @@ public abstract class com/facebook/react/runtime/BindingsInstaller { } public final class com/facebook/react/runtime/BridgelessCatalystInstance : com/facebook/react/bridge/CatalystInstance { - public fun ()V + public fun (Lcom/facebook/react/runtime/ReactHostImpl;)V public fun addBridgeIdleDebugListener (Lcom/facebook/react/bridge/NotThreadSafeBridgeIdleDebugListener;)V public fun addJSIModules (Ljava/util/List;)V public fun callFunction (Ljava/lang/String;Ljava/lang/String;Lcom/facebook/react/bridge/NativeArray;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt index e2d87960b97555..ea9dd2cb203892 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessCatalystInstance.kt @@ -32,7 +32,8 @@ import com.facebook.react.turbomodule.core.interfaces.NativeMethodCallInvokerHol @DoNotStrip @DeprecatedInNewArchitecture -public class BridgelessCatalystInstance : CatalystInstance { +public class BridgelessCatalystInstance(private val reactHost: ReactHostImpl) : CatalystInstance { + override fun handleMemoryPressure(level: Int) { throw UnsupportedOperationException("Unimplemented method 'handleMemoryPressure'") } @@ -161,8 +162,8 @@ public class BridgelessCatalystInstance : CatalystInstance { throw UnsupportedOperationException("Unimplemented method 'addJSIModules'") } - override fun getJSCallInvokerHolder(): CallInvokerHolder { - throw UnsupportedOperationException("Unimplemented method 'getJSCallInvokerHolder'") + override fun getJSCallInvokerHolder(): CallInvokerHolder? { + return reactHost.getJSCallInvokerHolder() } override fun getNativeMethodCallInvokerHolder(): NativeMethodCallInvokerHolder { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessReactContext.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessReactContext.java index 5fa3947959105c..d1cdaa976fc1d5 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessReactContext.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessReactContext.java @@ -8,6 +8,7 @@ package com.facebook.react.runtime; import android.content.Context; +import android.util.Log; import com.facebook.infer.annotation.Nullsafe; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Callback; @@ -18,8 +19,6 @@ import com.facebook.react.bridge.NativeArray; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReactNoCrashBridgeNotAllowedSoftException; -import com.facebook.react.bridge.ReactSoftExceptionLogger; import com.facebook.react.bridge.RuntimeExecutor; import com.facebook.react.bridge.UIManager; import com.facebook.react.bridge.WritableNativeArray; @@ -84,11 +83,10 @@ public void setSourceURL(String sourceURL) { @Override public CatalystInstance getCatalystInstance() { - ReactSoftExceptionLogger.logSoftExceptionVerbose( + Log.w( TAG, - new ReactNoCrashBridgeNotAllowedSoftException( - "getCatalystInstance() cannot be called when the bridge is disabled")); - throw new UnsupportedOperationException("There is no Catalyst instance in bridgeless mode."); + "[WARNING] Bridgeless doesn't support CatalystInstance. Accessing an API that's not part of the new architecture is not encouraged usage."); + return new BridgelessCatalystInstance(mReactHost); } @Override 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 1bf665685bb17d..a5ad6a83af4f39 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 @@ -60,6 +60,7 @@ import com.facebook.react.runtime.internal.bolts.Continuation; import com.facebook.react.runtime.internal.bolts.Task; import com.facebook.react.runtime.internal.bolts.TaskCompletionSource; +import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder; import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.events.BlackHoleEventDispatcher; import com.facebook.react.uimanager.events.EventDispatcher; @@ -601,6 +602,20 @@ RuntimeExecutor getRuntimeExecutor() { return null; } + /* package */ + @Nullable + CallInvokerHolder getJSCallInvokerHolder() { + final ReactInstance reactInstance = mReactInstanceTaskRef.get().getResult(); + if (reactInstance != null) { + return reactInstance.getJSCallInvokerHolder(); + } + ReactSoftExceptionLogger.logSoftException( + TAG, + new ReactNoCrashSoftException( + "Tried to get JSCallInvokerHolder while instance is not ready")); + return null; + } + /** * To be called when the host activity receives an activity result. * diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java index 37d8d44d830a4b..80793f45f01819 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java @@ -475,7 +475,7 @@ private native HybridData initHybrid( private native void loadJSBundleFromAssets(AssetManager assetManager, String assetURL); - private native CallInvokerHolderImpl getJSCallInvokerHolder(); + /* package */ native CallInvokerHolderImpl getJSCallInvokerHolder(); private native NativeMethodCallInvokerHolderImpl getNativeMethodCallInvokerHolder(); diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/runtime/BridgelessReactContextTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/runtime/BridgelessReactContextTest.kt index d8a8c3b473091d..6f7eb6f474aed9 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/runtime/BridgelessReactContextTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/runtime/BridgelessReactContextTest.kt @@ -55,9 +55,11 @@ class BridgelessReactContextTest { Assertions.assertThat(bridgelessReactContext.getFabricUIManager()).isEqualTo(fabricUiManager) } - @Test(expected = UnsupportedOperationException::class) - fun getCatalystInstance_throwsException() { - // Disable this test for now due to mocking FabricUIManager fails - bridgelessReactContext.catalystInstance + @Test + fun getCatalystInstanceTest() { + val bridgelessCatalystInstance = BridgelessCatalystInstance(reactHost) + doReturn(bridgelessCatalystInstance).`when`(bridgelessReactContext).getCatalystInstance() + Assertions.assertThat(bridgelessReactContext.getCatalystInstance()) + .isEqualTo(bridgelessCatalystInstance) } }