Kotlinify react.bridge.CatalystInstance interface (#44545)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/44545

# Changelog:
[Internal] -

As in the title.

Reviewed By: javache

Differential Revision: D57253633

fbshipit-source-id: d8631f5d25c00bdf4c94fcd0d56746c35e5b2fc3
This commit is contained in:
Ruslan Shestopalyuk
2024-05-14 11:51:39 -07:00
committed by Facebook GitHub Bot
parent 13dff7cdf2
commit 734ac42d61
6 changed files with 102 additions and 105 deletions
@@ -792,6 +792,10 @@ public abstract interface class com/facebook/react/bridge/JSExceptionHandler {
public abstract fun handleException (Ljava/lang/Exception;)V
}
public abstract interface class com/facebook/react/bridge/JSInstance {
public abstract fun invokeCallback (ILcom/facebook/react/bridge/NativeArrayInterface;)V
}
public class com/facebook/react/bridge/JSONArguments {
public fun <init> ()V
public static fun fromJSONArray (Lorg/json/JSONArray;)Lcom/facebook/react/bridge/ReadableArray;
@@ -5,17 +5,15 @@
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.bridge;
package com.facebook.react.bridge
import androidx.annotation.Nullable;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.queue.ReactQueueConfiguration;
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModuleRegistry;
import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder;
import com.facebook.react.turbomodule.core.interfaces.NativeMethodCallInvokerHolder;
import java.util.Collection;
import com.facebook.proguard.annotations.DoNotStrip
import com.facebook.react.bridge.queue.ReactQueueConfiguration
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture
import com.facebook.react.common.annotations.VisibleForTesting
import com.facebook.react.internal.turbomodule.core.interfaces.TurboModuleRegistry
import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder
import com.facebook.react.turbomodule.core.interfaces.NativeMethodCallInvokerHolder
/**
* A higher level API on top of the asynchronous JSC bridge. This provides an environment allowing
@@ -23,61 +21,53 @@ import java.util.Collection;
* well.
*/
@DoNotStrip
public interface CatalystInstance
extends MemoryPressureListener, JSInstance, JSBundleLoaderDelegate {
void runJSBundle();
public interface CatalystInstance : MemoryPressureListener, JSInstance, JSBundleLoaderDelegate {
public fun runJSBundle()
// Returns the status of running the JS bundle; waits for an answer if runJSBundle is running
boolean hasRunJSBundle();
public fun hasRunJSBundle(): Boolean
/**
* Return the source URL of the JS Bundle that was run, or {@code null} if no JS bundle has been
* run yet.
* Return the source URL of the JS Bundle that was run, or `null` if no JS bundle has been run
* yet.
*/
@Nullable
String getSourceURL();
public val sourceURL: String?
// This is called from java code, so it won't be stripped anyway, but proguard will rename it,
// which this prevents.
@Override
@DoNotStrip
void invokeCallback(int callbackID, NativeArrayInterface arguments);
@DoNotStrip public override fun invokeCallback(callbackID: Int, arguments: NativeArrayInterface)
@DoNotStrip
void callFunction(String module, String method, NativeArray arguments);
@DoNotStrip public fun callFunction(module: String, method: String, arguments: NativeArray?)
/**
* Destroys this catalyst instance, waiting for any other threads in ReactQueueConfiguration
* (besides the UI thread) to finish running. Must be called from the UI thread so that we can
* fully shut down other threads.
*/
void destroy();
public fun destroy()
boolean isDestroyed();
public val isDestroyed: Boolean
/** Initialize all the native modules */
@VisibleForTesting
void initialize();
@VisibleForTesting public fun initialize()
ReactQueueConfiguration getReactQueueConfiguration();
public val reactQueueConfiguration: ReactQueueConfiguration
<T extends JavaScriptModule> T getJSModule(Class<T> jsInterface);
public fun <T : JavaScriptModule> getJSModule(jsInterface: Class<T>): T?
<T extends NativeModule> boolean hasNativeModule(Class<T> nativeModuleInterface);
public fun <T : NativeModule> hasNativeModule(nativeModuleInterface: Class<T>): Boolean
@Nullable
<T extends NativeModule> T getNativeModule(Class<T> nativeModuleInterface);
public fun <T : NativeModule> getNativeModule(nativeModuleInterface: Class<T>): T?
@Nullable
NativeModule getNativeModule(String moduleName);
public fun getNativeModule(moduleName: String): NativeModule?
Collection<NativeModule> getNativeModules();
public val nativeModules: Collection<NativeModule>
/**
* This method permits a CatalystInstance to extend the known Native modules. This provided
* registry contains only the new modules to load.
*/
void extendNativeModules(NativeModuleRegistry modules);
public fun extendNativeModules(modules: NativeModuleRegistry)
/**
* Adds a idle listener for this Catalyst instance. The listener will receive notifications
@@ -85,19 +75,18 @@ public interface CatalystInstance
* defined as there being some non-zero number of calls to JS that haven't resolved via a
* onBatchCompleted call. The listener should be purely passive and not affect application logic.
*/
void addBridgeIdleDebugListener(NotThreadSafeBridgeIdleDebugListener listener);
public fun addBridgeIdleDebugListener(listener: NotThreadSafeBridgeIdleDebugListener)
/**
* Removes a NotThreadSafeBridgeIdleDebugListener previously added with {@link
* #addBridgeIdleDebugListener}
* Removes a NotThreadSafeBridgeIdleDebugListener previously added with
* [ ][.addBridgeIdleDebugListener]
*/
void removeBridgeIdleDebugListener(NotThreadSafeBridgeIdleDebugListener listener);
public fun removeBridgeIdleDebugListener(listener: NotThreadSafeBridgeIdleDebugListener)
/** This method registers the file path of an additional JS segment by its ID. */
void registerSegment(int segmentId, String path);
public fun registerSegment(segmentId: Int, path: String)
@VisibleForTesting
void setGlobalVariable(String propName, String jsonValue);
@VisibleForTesting public fun setGlobalVariable(propName: String, jsonValue: String)
/**
* Do not use this anymore. Use {@link #getRuntimeExecutor()} instead. Get the C pointer (as a
@@ -107,41 +96,39 @@ public interface CatalystInstance
* it: JavaScriptContextHolder jsContext = reactContext.getJavaScriptContextHolder()
* synchronized(jsContext) { nativeThingNeedingJsContext(jsContext.get()); }
*/
@Deprecated
JavaScriptContextHolder getJavaScriptContextHolder();
@get:Deprecated("Use getRuntimeExecutor() instead.")
public val javaScriptContextHolder: JavaScriptContextHolder
RuntimeExecutor getRuntimeExecutor();
RuntimeScheduler getRuntimeScheduler();
public val runtimeExecutor: RuntimeExecutor?
public val runtimeScheduler: RuntimeScheduler?
/**
* Returns a hybrid object that contains a pointer to a JS CallInvoker, which is used to schedule
* work on the JS Thread. Required for TurboModuleManager initialization.
*/
@Deprecated
CallInvokerHolder getJSCallInvokerHolder();
@get:Deprecated("") public val jSCallInvokerHolder: CallInvokerHolder
/**
* Returns a hybrid object that contains a pointer to a NativeMethodCallInvoker, which is used to
* schedule work on the NativeModules thread. Required for TurboModuleManager initialization.
*/
NativeMethodCallInvokerHolder getNativeMethodCallInvokerHolder();
public val nativeMethodCallInvokerHolder: NativeMethodCallInvokerHolder
@DeprecatedInNewArchitecture(
message =
"This method will be deprecated later as part of Stable APIs with bridge removal and not"
+ " encouraged usage.")
void setTurboModuleRegistry(TurboModuleRegistry turboModuleRegistry);
"This method will be deprecated later as part of Stable APIs with bridge removal and not" +
" encouraged usage.")
public fun setTurboModuleRegistry(turboModuleRegistry: TurboModuleRegistry)
@DeprecatedInNewArchitecture(
message =
"This method will be deprecated later as part of Stable APIs with bridge removal and not"
+ " encouraged usage.")
void setFabricUIManager(UIManager fabricUIManager);
"This method will be deprecated later as part of Stable APIs with bridge removal and not" +
" encouraged usage.")
public fun setFabricUIManager(fabricUIManager: UIManager)
@DeprecatedInNewArchitecture(
message =
"This method will be deprecated later as part of Stable APIs with bridge removal and not"
+ " encouraged usage.")
UIManager getFabricUIManager();
"This method will be deprecated later as part of Stable APIs with bridge removal and not" +
" encouraged usage.")
public fun getFabricUIManager(): UIManager?
}
@@ -11,7 +11,7 @@ package com.facebook.react.bridge
* This interface includes the methods needed to use a running JS instance, without specifying any
* of the bridge-specific initialization or lifecycle management.
*/
internal interface JSInstance {
public interface JSInstance {
public fun invokeCallback(callbackID: Int, arguments: NativeArrayInterface)
// TODO if this interface survives refactoring, think about adding
@@ -10,6 +10,8 @@ package com.facebook.react.fabric;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.RuntimeExecutor;
import com.facebook.react.bridge.RuntimeScheduler;
import com.facebook.react.bridge.UIManager;
import com.facebook.react.bridge.UIManagerProvider;
import com.facebook.react.fabric.events.EventBeatManager;
@@ -49,13 +51,22 @@ public class FabricUIManagerProviderImpl implements UIManagerProvider {
CatalystInstance catalystInstance = reactApplicationContext.getCatalystInstance();
binding.register(
catalystInstance.getRuntimeExecutor(),
catalystInstance.getRuntimeScheduler(),
fabricUIManager,
eventBeatManager,
mComponentFactory,
mConfig);
RuntimeExecutor runtimeExecutor = catalystInstance.getRuntimeExecutor();
RuntimeScheduler runtimeScheduler = catalystInstance.getRuntimeScheduler();
if (runtimeExecutor != null && runtimeScheduler != null) {
binding.register(
runtimeExecutor,
runtimeScheduler,
fabricUIManager,
eventBeatManager,
mComponentFactory,
mConfig);
} else {
throw new IllegalStateException(
"Unable to register FabricUIManager with CatalystInstance, runtimeExecutor and"
+ " runtimeScheduler must not be null");
}
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
@@ -63,16 +63,12 @@ public class BridgelessCatalystInstance(private val reactHost: ReactHostImpl) :
throw UnsupportedOperationException("Unimplemented method 'hasRunJSBundle'")
}
override fun getSourceURL(): String? {
throw UnsupportedOperationException("Unimplemented method 'getSourceURL'")
}
@DoNotStrip
override fun invokeCallback(callbackID: Int, arguments: NativeArrayInterface) {
throw UnsupportedOperationException("Unimplemented method 'invokeCallback'")
}
override fun callFunction(module: String, method: String, arguments: NativeArray) {
override fun callFunction(module: String, method: String, arguments: NativeArray?) {
throw UnsupportedOperationException("Unimplemented method 'callFunction'")
}
@@ -80,20 +76,27 @@ public class BridgelessCatalystInstance(private val reactHost: ReactHostImpl) :
throw UnsupportedOperationException("Unimplemented method 'destroy'")
}
override fun isDestroyed(): Boolean {
throw UnsupportedOperationException("Unimplemented method 'isDestroyed'")
}
override public val isDestroyed: Boolean
get() = throw UnsupportedOperationException("Unimplemented method 'isDestroyed'")
@VisibleForTesting
override fun initialize() {
throw UnsupportedOperationException("Unimplemented method 'initialize'")
}
override fun getReactQueueConfiguration(): ReactQueueConfiguration =
reactHost.reactQueueConfiguration!!
override fun <T : JavaScriptModule> getJSModule(jsInterface: Class<T>): T? =
reactHost.currentReactContext?.getJSModule(jsInterface)
override fun <T : JavaScriptModule> getJSModule(jsInterface: Class<T>): T =
reactHost.currentReactContext?.getJSModule(jsInterface)!!
override public val javaScriptContextHolder: JavaScriptContextHolder
get() = reactHost.getJavaScriptContextHolder()!!
override public val jSCallInvokerHolder: CallInvokerHolder
get() = reactHost.getJSCallInvokerHolder()!!
override public val nativeMethodCallInvokerHolder: NativeMethodCallInvokerHolder
get() =
throw UnsupportedOperationException(
"Unimplemented method 'getNativeMethodCallInvokerHolder'")
override fun <T : NativeModule> hasNativeModule(nativeModuleInterface: Class<T>): Boolean =
reactHost.hasNativeModule(nativeModuleInterface)
@@ -104,12 +107,25 @@ public class BridgelessCatalystInstance(private val reactHost: ReactHostImpl) :
override fun getNativeModule(moduleName: String): NativeModule? =
reactHost.getNativeModule(moduleName)
override fun getNativeModules(): Collection<NativeModule> = reactHost.getNativeModules()
override public val nativeModules: Collection<NativeModule>
get() = reactHost.getNativeModules()
override fun extendNativeModules(modules: NativeModuleRegistry) {
override public val reactQueueConfiguration: ReactQueueConfiguration
get() = reactHost.reactQueueConfiguration!!
override public val runtimeExecutor: RuntimeExecutor?
get() = reactHost.getRuntimeExecutor()
override public val runtimeScheduler: RuntimeScheduler?
get() = throw UnsupportedOperationException("Unimplemented method 'getRuntimeScheduler'")
override public fun extendNativeModules(modules: NativeModuleRegistry) {
throw UnsupportedOperationException("Unimplemented method 'extendNativeModules'")
}
override public val sourceURL: String?
get() = throw UnsupportedOperationException("Unimplemented method 'getSourceURL'")
override fun addBridgeIdleDebugListener(listener: NotThreadSafeBridgeIdleDebugListener) {
throw UnsupportedOperationException("Unimplemented method 'addBridgeIdleDebugListener'")
}
@@ -127,27 +143,6 @@ public class BridgelessCatalystInstance(private val reactHost: ReactHostImpl) :
throw UnsupportedOperationException("Unimplemented method 'setGlobalVariable'")
}
@Deprecated(message = "This API is unsupported in the New Architecture.")
override fun getJavaScriptContextHolder(): JavaScriptContextHolder? {
return reactHost.getJavaScriptContextHolder()
}
override fun getRuntimeExecutor(): RuntimeExecutor? {
return reactHost.getRuntimeExecutor()
}
override fun getRuntimeScheduler(): RuntimeScheduler {
throw UnsupportedOperationException("Unimplemented method 'getRuntimeScheduler'")
}
override fun getJSCallInvokerHolder(): CallInvokerHolder? {
return reactHost.getJSCallInvokerHolder()
}
override fun getNativeMethodCallInvokerHolder(): NativeMethodCallInvokerHolder {
throw UnsupportedOperationException("Unimplemented method 'getNativeMethodCallInvokerHolder'")
}
@DeprecatedInNewArchitecture(
message =
"This method will be deprecated later as part of Stable APIs with bridge removal and not encouraged usage.")
@@ -39,10 +39,10 @@ object ReactTestHelper {
val reactQueueConfiguration: ReactQueueConfiguration =
ReactQueueConfigurationImpl.create(spec) { e -> throw RuntimeException(e) }
val reactInstance: CatalystInstance = mock(CatalystInstance::class.java)
whenever(reactInstance.getReactQueueConfiguration()).thenReturn(reactQueueConfiguration)
whenever(reactInstance.reactQueueConfiguration).thenReturn(reactQueueConfiguration)
whenever(reactInstance.getNativeModule(UIManagerModule::class.java))
.thenReturn(mock(UIManagerModule::class.java))
whenever(reactInstance.isDestroyed()).thenReturn(false)
whenever(reactInstance.isDestroyed).thenReturn(false)
return reactInstance
}
}