Revert D55964787: Push ReactContext logic in derived classes

Differential Revision:
D55964787

Original commit changeset: b404efe0c709

Original Phabricator Diff: D55964787

fbshipit-source-id: 0742b9aa870a08fed603cf6f33774d4813f5050c
This commit is contained in:
Fabrizio Cucci
2024-04-12 06:11:04 -07:00
committed by Facebook GitHub Bot
parent b7812a8b6c
commit 7131f94895
6 changed files with 200 additions and 349 deletions
@@ -543,25 +543,8 @@ public abstract class com/facebook/react/bridge/BaseJavaModule : com/facebook/re
public fun invalidate ()V
}
public class com/facebook/react/bridge/BridgeReactContext : com/facebook/react/bridge/ReactApplicationContext {
public final class com/facebook/react/bridge/BridgeReactContext : com/facebook/react/bridge/ReactApplicationContext {
public fun <init> (Landroid/content/Context;)V
public fun destroy ()V
public fun getCatalystInstance ()Lcom/facebook/react/bridge/CatalystInstance;
public fun getFabricUIManager ()Lcom/facebook/react/bridge/UIManager;
public fun getJSModule (Ljava/lang/Class;)Lcom/facebook/react/bridge/JavaScriptModule;
public fun getJavaScriptContextHolder ()Lcom/facebook/react/bridge/JavaScriptContextHolder;
public fun getNativeModule (Ljava/lang/Class;)Lcom/facebook/react/bridge/NativeModule;
public fun getNativeModules ()Ljava/util/Collection;
public fun getRuntimeExecutor ()Lcom/facebook/react/bridge/RuntimeExecutor;
public fun getSourceURL ()Ljava/lang/String;
public fun handleException (Ljava/lang/Exception;)V
public fun hasActiveCatalystInstance ()Z
public fun hasActiveReactInstance ()Z
public fun hasCatalystInstance ()Z
public fun hasNativeModule (Ljava/lang/Class;)Z
public fun initializeWithInstance (Lcom/facebook/react/bridge/CatalystInstance;)V
public fun isBridgeless ()Z
public fun registerSegment (ILjava/lang/String;Lcom/facebook/react/bridge/Callback;)V
}
public abstract interface class com/facebook/react/bridge/Callback {
@@ -1107,35 +1090,36 @@ public abstract class com/facebook/react/bridge/ReactContext : android/content/C
public fun assertOnNativeModulesQueueThread ()V
public fun assertOnNativeModulesQueueThread (Ljava/lang/String;)V
public fun assertOnUiQueueThread ()V
public abstract fun destroy ()V
public fun destroy ()V
public fun emitDeviceEvent (Ljava/lang/String;)V
public fun emitDeviceEvent (Ljava/lang/String;Ljava/lang/Object;)V
public abstract fun getCatalystInstance ()Lcom/facebook/react/bridge/CatalystInstance;
public fun getCatalystInstance ()Lcom/facebook/react/bridge/CatalystInstance;
public fun getCurrentActivity ()Landroid/app/Activity;
public fun getExceptionHandler ()Lcom/facebook/react/bridge/JSExceptionHandler;
public abstract fun getFabricUIManager ()Lcom/facebook/react/bridge/UIManager;
public fun getFabricUIManager ()Lcom/facebook/react/bridge/UIManager;
public fun getJSExceptionHandler ()Lcom/facebook/react/bridge/JSExceptionHandler;
public fun getJSMessageQueueThread ()Lcom/facebook/react/bridge/queue/MessageQueueThread;
public abstract fun getJSModule (Ljava/lang/Class;)Lcom/facebook/react/bridge/JavaScriptModule;
public abstract fun getJavaScriptContextHolder ()Lcom/facebook/react/bridge/JavaScriptContextHolder;
public fun getJSModule (Ljava/lang/Class;)Lcom/facebook/react/bridge/JavaScriptModule;
public fun getJavaScriptContextHolder ()Lcom/facebook/react/bridge/JavaScriptContextHolder;
public fun getLifecycleState ()Lcom/facebook/react/common/LifecycleState;
public abstract fun getNativeModule (Ljava/lang/Class;)Lcom/facebook/react/bridge/NativeModule;
public abstract fun getNativeModules ()Ljava/util/Collection;
public fun getNativeModule (Ljava/lang/Class;)Lcom/facebook/react/bridge/NativeModule;
public fun getNativeModules ()Ljava/util/Collection;
public fun getNativeModulesMessageQueueThread ()Lcom/facebook/react/bridge/queue/MessageQueueThread;
public abstract fun getSourceURL ()Ljava/lang/String;
public fun getSourceURL ()Ljava/lang/String;
public fun getSystemService (Ljava/lang/String;)Ljava/lang/Object;
public fun getUiMessageQueueThread ()Lcom/facebook/react/bridge/queue/MessageQueueThread;
public abstract fun handleException (Ljava/lang/Exception;)V
public abstract fun hasActiveCatalystInstance ()Z
public abstract fun hasActiveReactInstance ()Z
public abstract fun hasCatalystInstance ()Z
public fun handleException (Ljava/lang/Exception;)V
public fun hasActiveCatalystInstance ()Z
public fun hasActiveReactInstance ()Z
public fun hasCatalystInstance ()Z
public fun hasCurrentActivity ()Z
public abstract fun hasNativeModule (Ljava/lang/Class;)Z
protected fun initializeFromOther (Lcom/facebook/react/bridge/ReactContext;)V
public fun hasNativeModule (Ljava/lang/Class;)Z
protected fun initializeInteropModules ()V
protected fun initializeInteropModules (Lcom/facebook/react/bridge/ReactContext;)V
public fun initializeMessageQueueThreads (Lcom/facebook/react/bridge/queue/ReactQueueConfiguration;)V
public fun initializeWithInstance (Lcom/facebook/react/bridge/CatalystInstance;)V
public fun internal_registerInteropModule (Ljava/lang/Class;Ljava/lang/Object;)V
public abstract fun isBridgeless ()Z
public fun isBridgeless ()Z
public fun isOnJSQueueThread ()Z
public fun isOnNativeModulesQueueThread ()Z
public fun isOnUiQueueThread ()Z
@@ -1145,7 +1129,7 @@ public abstract class com/facebook/react/bridge/ReactContext : android/content/C
public fun onHostResume (Landroid/app/Activity;)V
public fun onNewIntent (Landroid/app/Activity;Landroid/content/Intent;)V
public fun onWindowFocusChange (Z)V
public abstract fun registerSegment (ILjava/lang/String;Lcom/facebook/react/bridge/Callback;)V
public fun registerSegment (ILjava/lang/String;Lcom/facebook/react/bridge/Callback;)V
public fun removeActivityEventListener (Lcom/facebook/react/bridge/ActivityEventListener;)V
public fun removeLifecycleEventListener (Lcom/facebook/react/bridge/LifecycleEventListener;)V
public fun removeWindowFocusChangeListener (Lcom/facebook/react/bridge/WindowFocusChangeListener;)V
@@ -4909,25 +4893,16 @@ public class com/facebook/react/uimanager/ThemedReactContext : com/facebook/reac
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;Landroid/content/Context;)V
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;Landroid/content/Context;Ljava/lang/String;)V
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;Landroid/content/Context;Ljava/lang/String;I)V
public fun destroy ()V
public fun getCatalystInstance ()Lcom/facebook/react/bridge/CatalystInstance;
public fun addLifecycleEventListener (Lcom/facebook/react/bridge/LifecycleEventListener;)V
public fun getCurrentActivity ()Landroid/app/Activity;
public fun getFabricUIManager ()Lcom/facebook/react/bridge/UIManager;
public fun getJSModule (Ljava/lang/Class;)Lcom/facebook/react/bridge/JavaScriptModule;
public fun getJavaScriptContextHolder ()Lcom/facebook/react/bridge/JavaScriptContextHolder;
public fun getModuleName ()Ljava/lang/String;
public fun getNativeModule (Ljava/lang/Class;)Lcom/facebook/react/bridge/NativeModule;
public fun getNativeModules ()Ljava/util/Collection;
public fun getReactApplicationContext ()Lcom/facebook/react/bridge/ReactApplicationContext;
public fun getSourceURL ()Ljava/lang/String;
public fun getSurfaceID ()Ljava/lang/String;
public fun getSurfaceId ()I
public fun handleException (Ljava/lang/Exception;)V
public fun hasActiveCatalystInstance ()Z
public fun hasActiveReactInstance ()Z
public fun hasCatalystInstance ()Z
public fun hasNativeModule (Ljava/lang/Class;)Z
public fun hasCurrentActivity ()Z
public fun isBridgeless ()Z
public fun registerSegment (ILjava/lang/String;Lcom/facebook/react/bridge/Callback;)V
public fun removeLifecycleEventListener (Lcom/facebook/react/bridge/LifecycleEventListener;)V
}
public class com/facebook/react/uimanager/TouchTargetHelper {
@@ -1,189 +0,0 @@
/*
* 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.bridge;
import android.content.Context;
import androidx.annotation.Nullable;
import com.facebook.common.logging.FLog;
import com.facebook.infer.annotation.Assertions;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.bridge.queue.ReactQueueConfiguration;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture;
import java.util.Collection;
/**
* This is the bridge-specific concrete subclass of ReactContext. ReactContext has many methods that
* delegate to the react instance. This subclass implements those methods, by delegating to the
* CatalystInstance. If you need to create a ReactContext within an "bridge context", please create
* BridgeReactContext.
*/
@DeprecatedInNewArchitecture
@Nullsafe(Nullsafe.Mode.LOCAL)
public class BridgeReactContext extends ReactApplicationContext {
private static final String TAG = "BridgeReactContext";
private static final String EARLY_CALL_EXCEPTION_MESSAGE =
"Called %s before setting the Catalyst instance!";
private static final String LATE_CALL_EXCEPTION_MESSAGE =
"Called %s after destroying the Catalyst instance!";
private volatile boolean mDestroyed = false;
private @Nullable CatalystInstance mCatalystInstance;
public BridgeReactContext(Context context) {
super(context);
}
public void initializeWithInstance(CatalystInstance catalystInstance) {
if (catalystInstance == null) {
throw new IllegalArgumentException("CatalystInstance cannot be null.");
}
if (mCatalystInstance != null) {
throw new IllegalStateException("ReactContext has been already initialized");
}
if (mDestroyed) {
ReactSoftExceptionLogger.logSoftException(
TAG,
new IllegalStateException("Cannot initialize ReactContext after it has been destroyed."));
}
mCatalystInstance = catalystInstance;
ReactQueueConfiguration queueConfig = catalystInstance.getReactQueueConfiguration();
initializeMessageQueueThreads(queueConfig);
initializeInteropModules();
}
@Override
public void destroy() {
UiThreadUtil.assertOnUiThread();
mDestroyed = true;
if (mCatalystInstance != null) {
mCatalystInstance.destroy();
}
}
@Override
public CatalystInstance getCatalystInstance() {
return Assertions.assertNotNull(mCatalystInstance);
}
@Override
public @Nullable UIManager getFabricUIManager() {
CatalystInstance catalystInstance = getNonNullableCatalystInstanceOrThrow("getFabricUIManager");
UIManager uiManager = catalystInstance.getFabricUIManager();
return uiManager != null
? uiManager
: (UIManager) catalystInstance.getJSIModule(JSIModuleType.UIManager);
}
@Override
public @Nullable JavaScriptContextHolder getJavaScriptContextHolder() {
return mCatalystInstance != null ? mCatalystInstance.getJavaScriptContextHolder() : null;
}
@Override
public <T extends JavaScriptModule> T getJSModule(Class<T> jsInterface) {
CatalystInstance catalystInstance = getNonNullableCatalystInstanceOrThrow("getJSModule");
if (mInteropModuleRegistry != null
&& mInteropModuleRegistry.shouldReturnInteropModule(jsInterface)) {
return mInteropModuleRegistry.getInteropModule(jsInterface);
}
return catalystInstance.getJSModule(jsInterface);
}
@Override
public @Nullable <T extends NativeModule> T getNativeModule(Class<T> nativeModuleInterface) {
CatalystInstance catalystInstance = getNonNullableCatalystInstanceOrThrow("getNativeModule");
return catalystInstance.getNativeModule(nativeModuleInterface);
}
@Override
public Collection<NativeModule> getNativeModules() {
CatalystInstance catalystInstance = getNonNullableCatalystInstanceOrThrow("getNativeModules");
return catalystInstance.getNativeModules();
}
@Override
public @Nullable RuntimeExecutor getRuntimeExecutor() {
CatalystInstance catalystInstance = getNonNullableCatalystInstanceOrThrow("getRuntimeExecutor");
return catalystInstance.getRuntimeExecutor();
}
@Override
public @Nullable String getSourceURL() {
return mCatalystInstance != null ? mCatalystInstance.getSourceURL() : null;
}
@Override
public void handleException(Exception e) {
JSExceptionHandler jsExceptionHandler = getJSExceptionHandler();
if (hasActiveReactInstance() && jsExceptionHandler != null) {
jsExceptionHandler.handleException(e);
} else {
FLog.e(
ReactConstants.TAG,
"Unable to handle Exception - catalystInstanceVariableExists: "
+ (mCatalystInstance != null)
+ " - isCatalystInstanceAlive: "
+ hasActiveReactInstance()
+ " - hasExceptionHandler: "
+ (jsExceptionHandler != null),
e);
throw new IllegalStateException(e);
}
}
@Deprecated
@Override
public boolean hasActiveCatalystInstance() {
return hasActiveReactInstance();
}
@Override
public boolean hasActiveReactInstance() {
return mCatalystInstance != null && !mCatalystInstance.isDestroyed();
}
@Override
public boolean hasCatalystInstance() {
return mCatalystInstance != null;
}
@Override
public <T extends NativeModule> boolean hasNativeModule(Class<T> nativeModuleInterface) {
CatalystInstance catalystInstance = getNonNullableCatalystInstanceOrThrow("hasNativeModule");
return catalystInstance.hasNativeModule(nativeModuleInterface);
}
@Override
public boolean isBridgeless() {
return false;
}
@Override
public void registerSegment(int segmentId, String path, Callback callback) {
Assertions.assertNotNull(mCatalystInstance).registerSegment(segmentId, path);
Assertions.assertNotNull(callback).invoke();
}
private CatalystInstance getNonNullableCatalystInstanceOrThrow(String accessTarget) {
if (mCatalystInstance != null) {
return mCatalystInstance;
}
throw new IllegalStateException(
String.format(
mDestroyed ? LATE_CALL_EXCEPTION_MESSAGE : EARLY_CALL_EXCEPTION_MESSAGE, accessTarget));
}
}
@@ -0,0 +1,20 @@
/*
* 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.bridge
import android.content.Context
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture
/**
* This is the bridge-specific concrete subclass of ReactContext. ReactContext has many methods that
* delegate to the react instance. This subclass will implement those methods, by delegating to the
* CatalystInstance. If you need to create a ReactContext within an "bridge context", please create
* BridgeReactContext.
*/
@DeprecatedInNewArchitecture
public class BridgeReactContext(base: Context) : ReactApplicationContext(base) {}
@@ -25,6 +25,7 @@ import com.facebook.react.bridge.interop.InteropModuleRegistry;
import com.facebook.react.bridge.queue.MessageQueueThread;
import com.facebook.react.bridge.queue.ReactQueueConfiguration;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.annotations.DeprecatedInNewArchitecture;
import com.facebook.react.common.annotations.FrameworkAPI;
import com.facebook.react.common.annotations.UnstableReactNativeAPI;
@@ -44,6 +45,16 @@ public abstract class ReactContext extends ContextWrapper {
}
private static final String TAG = "ReactContext";
private static final String EARLY_JS_ACCESS_EXCEPTION_MESSAGE =
"Tried to access a JS module before the React instance was fully set up. Calls to "
+ "ReactContext#getJSModule should only happen once initialize() has been called on your "
+ "native module.";
private static final String LATE_JS_ACCESS_EXCEPTION_MESSAGE =
"Tried to access a JS module after the React instance was destroyed.";
private static final String EARLY_NATIVE_MODULE_EXCEPTION_MESSAGE =
"Trying to call native module before CatalystInstance has been set!";
private static final String LATE_NATIVE_MODULE_EXCEPTION_MESSAGE =
"Trying to call native module after CatalystInstance has been destroyed!";
private final CopyOnWriteArraySet<LifecycleEventListener> mLifecycleEventListeners =
new CopyOnWriteArraySet<>();
@@ -54,8 +65,9 @@ public abstract class ReactContext extends ContextWrapper {
private LifecycleState mLifecycleState = LifecycleState.BEFORE_CREATE;
private volatile boolean mDestroyed = false;
private @Nullable CatalystInstance mCatalystInstance;
private @Nullable LayoutInflater mInflater;
private @Nullable ReactQueueConfiguration mQueueConfig;
private @Nullable MessageQueueThread mUiMessageQueueThread;
private @Nullable MessageQueueThread mNativeModulesMessageQueueThread;
private @Nullable MessageQueueThread mJSMessageQueueThread;
@@ -70,9 +82,25 @@ public abstract class ReactContext extends ContextWrapper {
super(base);
}
protected void initializeFromOther(ReactContext other) {
initializeMessageQueueThreads(other.mQueueConfig);
mInteropModuleRegistry = other.mInteropModuleRegistry;
/** Set and initialize CatalystInstance for this Context. This should be called exactly once. */
public void initializeWithInstance(CatalystInstance catalystInstance) {
if (catalystInstance == null) {
throw new IllegalArgumentException("CatalystInstance cannot be null.");
}
if (mCatalystInstance != null) {
throw new IllegalStateException("ReactContext has been already initialized");
}
if (mDestroyed) {
ReactSoftExceptionLogger.logSoftException(
TAG,
new IllegalStateException("Cannot initialize ReactContext after it has been destroyed."));
}
mCatalystInstance = catalystInstance;
ReactQueueConfiguration queueConfig = catalystInstance.getReactQueueConfiguration();
initializeMessageQueueThreads(queueConfig);
initializeInteropModules();
}
/** Initialize message queue threads using a ReactQueueConfiguration. */
@@ -83,7 +111,6 @@ public abstract class ReactContext extends ContextWrapper {
|| mJSMessageQueueThread != null) {
throw new IllegalStateException("Message queue threads already initialized");
}
mQueueConfig = queueConfig;
mUiMessageQueueThread = queueConfig.getUIQueueThread();
mNativeModulesMessageQueueThread = queueConfig.getNativeModulesQueueThread();
mJSMessageQueueThread = queueConfig.getJSQueueThread();
@@ -105,6 +132,10 @@ public abstract class ReactContext extends ContextWrapper {
mInteropModuleRegistry = new InteropModuleRegistry();
}
protected void initializeInteropModules(ReactContext reactContext) {
mInteropModuleRegistry = reactContext.mInteropModuleRegistry;
}
public void resetPerfStats() {
if (mNativeModulesMessageQueueThread != null) {
mNativeModulesMessageQueueThread.resetPerfStats();
@@ -118,6 +149,11 @@ public abstract class ReactContext extends ContextWrapper {
mJSExceptionHandler = jSExceptionHandler;
}
private void raiseCatalystInstanceMissingException() {
throw new IllegalStateException(
mDestroyed ? LATE_NATIVE_MODULE_EXCEPTION_MESSAGE : EARLY_NATIVE_MODULE_EXCEPTION_MESSAGE);
}
// We override the following method so that views inflated with the inflater obtained from this
// context return the ReactContext in #getContext(). The default implementation uses the base
// context instead, so it couldn't be cast to ReactContext.
@@ -136,17 +172,44 @@ public abstract class ReactContext extends ContextWrapper {
/**
* @return handle to the specified JS module for the CatalystInstance associated with this Context
*/
public abstract <T extends JavaScriptModule> T getJSModule(Class<T> jsInterface);
public <T extends JavaScriptModule> T getJSModule(Class<T> jsInterface) {
if (mCatalystInstance == null) {
if (mDestroyed) {
throw new IllegalStateException(LATE_JS_ACCESS_EXCEPTION_MESSAGE);
}
throw new IllegalStateException(EARLY_JS_ACCESS_EXCEPTION_MESSAGE);
}
if (mInteropModuleRegistry != null
&& mInteropModuleRegistry.shouldReturnInteropModule(jsInterface)) {
return mInteropModuleRegistry.getInteropModule(jsInterface);
}
return mCatalystInstance.getJSModule(jsInterface);
}
public abstract <T extends NativeModule> boolean hasNativeModule(Class<T> nativeModuleInterface);
public <T extends NativeModule> boolean hasNativeModule(Class<T> nativeModuleInterface) {
if (mCatalystInstance == null) {
raiseCatalystInstanceMissingException();
}
return mCatalystInstance.hasNativeModule(nativeModuleInterface);
}
public abstract Collection<NativeModule> getNativeModules();
public Collection<NativeModule> getNativeModules() {
if (mCatalystInstance == null) {
raiseCatalystInstanceMissingException();
}
return mCatalystInstance.getNativeModules();
}
/**
* @return the instance of the specified module interface associated with this ReactContext.
*/
@Nullable
public abstract <T extends NativeModule> T getNativeModule(Class<T> nativeModuleInterface);
public <T extends NativeModule> T getNativeModule(Class<T> nativeModuleInterface) {
if (mCatalystInstance == null) {
raiseCatalystInstanceMissingException();
}
return mCatalystInstance.getNativeModule(nativeModuleInterface);
}
/**
* @return the RuntimeExecutor, a thread-safe handler for accessing the runtime.
@@ -155,7 +218,12 @@ public abstract class ReactContext extends ContextWrapper {
@Nullable
@FrameworkAPI
@UnstableReactNativeAPI
public abstract RuntimeExecutor getRuntimeExecutor();
public RuntimeExecutor getRuntimeExecutor() {
if (mCatalystInstance == null) {
raiseCatalystInstanceMissingException();
}
return mCatalystInstance.getRuntimeExecutor();
}
/**
* Calls RCTDeviceEventEmitter.emit to JavaScript, with given event name and an optional list of
@@ -172,7 +240,9 @@ public abstract class ReactContext extends ContextWrapper {
emitDeviceEvent(eventName, null);
}
public abstract CatalystInstance getCatalystInstance();
public CatalystInstance getCatalystInstance() {
return Assertions.assertNotNull(mCatalystInstance);
}
/**
* This API has been deprecated due to naming consideration, please use hasActiveReactInstance()
@@ -181,14 +251,20 @@ public abstract class ReactContext extends ContextWrapper {
* @return
*/
@Deprecated
public abstract boolean hasActiveCatalystInstance();
public boolean hasActiveCatalystInstance() {
return hasActiveReactInstance();
}
/**
* @return true if there is an non-null, alive react native instance
*/
public abstract boolean hasActiveReactInstance();
public boolean hasActiveReactInstance() {
return mCatalystInstance != null && !mCatalystInstance.isDestroyed();
}
public abstract boolean hasCatalystInstance();
public boolean hasCatalystInstance() {
return mCatalystInstance != null;
}
public LifecycleState getLifecycleState() {
return mLifecycleState;
@@ -304,7 +380,14 @@ public abstract class ReactContext extends ContextWrapper {
/** Destroy this instance, making it unusable. */
@ThreadConfined(UI)
public abstract void destroy();
public void destroy() {
UiThreadUtil.assertOnUiThread();
mDestroyed = true;
if (mCatalystInstance != null) {
mCatalystInstance.destroy();
}
}
/** Should be called by the hosting Fragment in {@link Fragment#onActivityResult} */
public void onActivityResult(
@@ -397,7 +480,27 @@ public abstract class ReactContext extends ContextWrapper {
* Passes the given exception to the current {@link JSExceptionHandler} if one exists, rethrowing
* otherwise.
*/
public abstract void handleException(Exception e);
public void handleException(Exception e) {
boolean catalystInstanceVariableExists = mCatalystInstance != null;
boolean isCatalystInstanceAlive =
catalystInstanceVariableExists && !mCatalystInstance.isDestroyed();
boolean hasExceptionHandler = mJSExceptionHandler != null;
if (isCatalystInstanceAlive && hasExceptionHandler) {
mJSExceptionHandler.handleException(e);
} else {
FLog.e(
ReactConstants.TAG,
"Unable to handle Exception - catalystInstanceVariableExists: "
+ catalystInstanceVariableExists
+ " - isCatalystInstanceAlive: "
+ isCatalystInstanceAlive
+ " - hasExceptionHandler: "
+ hasExceptionHandler,
e);
throw new IllegalStateException(e);
}
}
public class ExceptionHandlerWrapper implements JSExceptionHandler {
@Override
@@ -451,7 +554,9 @@ public abstract class ReactContext extends ContextWrapper {
* @deprecated DO NOT USE, this method will be removed in the near future.
*/
@Deprecated
public abstract boolean isBridgeless();
public boolean isBridgeless() {
return false;
}
/**
* Get the C pointer (as a long) to the JavaScriptCore context associated with this instance. Use
@@ -459,7 +564,12 @@ public abstract class ReactContext extends ContextWrapper {
* JavaScriptContextHolder jsContext = reactContext.getJavaScriptContextHolder()
* synchronized(jsContext) { nativeThingNeedingJsContext(jsContext.get()); }
*/
public abstract @Nullable JavaScriptContextHolder getJavaScriptContextHolder();
public @Nullable JavaScriptContextHolder getJavaScriptContextHolder() {
if (mCatalystInstance != null) {
return mCatalystInstance.getJavaScriptContextHolder();
}
return null;
}
@DeprecatedInNewArchitecture(
message =
@@ -470,7 +580,12 @@ public abstract class ReactContext extends ContextWrapper {
*
* @return The UIManager when CatalystInstance is active.
*/
public abstract @Nullable UIManager getFabricUIManager();
public @Nullable UIManager getFabricUIManager() {
UIManager uiManager = mCatalystInstance.getFabricUIManager();
return uiManager != null
? uiManager
: (UIManager) mCatalystInstance.getJSIModule(JSIModuleType.UIManager);
}
/**
* Get the sourceURL for the JS bundle from the CatalystInstance. This method is needed for
@@ -478,13 +593,18 @@ public abstract class ReactContext extends ContextWrapper {
*
* @return The JS bundle URL set when the bundle was loaded
*/
public abstract @Nullable String getSourceURL();
public @Nullable String getSourceURL() {
return mCatalystInstance == null ? null : mCatalystInstance.getSourceURL();
}
/**
* Register a JS segment after loading it from cache or server, make sure mCatalystInstance is
* properly initialised and not null before calling.
*/
public abstract void registerSegment(int segmentId, String path, Callback callback);
public void registerSegment(int segmentId, String path, Callback callback) {
Assertions.assertNotNull(mCatalystInstance).registerSegment(segmentId, path);
Assertions.assertNotNull(callback).invoke();
}
/**
* Register a {@link JavaScriptModule} within the Interop Layer so that can be consumed whenever
@@ -90,25 +90,11 @@ class BridgelessReactContext extends ReactApplicationContext implements EventDis
return new BridgelessCatalystInstance(mReactHost);
}
@Deprecated
@Override
public boolean hasActiveCatalystInstance() {
return hasActiveReactInstance();
}
@Override
public boolean hasActiveReactInstance() {
return mReactHost.isInstanceInitialized();
}
@Override
public boolean hasCatalystInstance() {
return false;
}
@Override
public void destroy() {}
DevSupportManager getDevSupportManager() {
return mReactHost.getDevSupportManager();
}
@@ -7,20 +7,13 @@
package com.facebook.react.uimanager;
import android.app.Activity;
import android.content.Context;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.JavaScriptContextHolder;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.RuntimeExecutor;
import com.facebook.react.bridge.UIManager;
import com.facebook.react.common.annotations.FrameworkAPI;
import com.facebook.react.common.annotations.UnstableReactNativeAPI;
import java.util.Collection;
/**
* Wraps {@link ReactContext} with the base {@link Context} passed into the constructor. It provides
@@ -53,67 +46,33 @@ public class ThemedReactContext extends ReactContext {
@Nullable String moduleName,
int surfaceId) {
super(base);
if (reactApplicationContext.hasActiveReactInstance()) {
initializeFromOther(reactApplicationContext);
if (reactApplicationContext.hasCatalystInstance()) {
initializeWithInstance(reactApplicationContext.getCatalystInstance());
}
initializeInteropModules(reactApplicationContext);
mReactApplicationContext = reactApplicationContext;
mModuleName = moduleName;
mSurfaceId = surfaceId;
}
@Override
public <T extends JavaScriptModule> T getJSModule(Class<T> jsInterface) {
return mReactApplicationContext.getJSModule(jsInterface);
public void addLifecycleEventListener(LifecycleEventListener listener) {
mReactApplicationContext.addLifecycleEventListener(listener);
}
@Override
public <T extends NativeModule> boolean hasNativeModule(Class<T> nativeModuleInterface) {
return mReactApplicationContext.hasNativeModule(nativeModuleInterface);
public void removeLifecycleEventListener(LifecycleEventListener listener) {
mReactApplicationContext.removeLifecycleEventListener(listener);
}
@Override
public Collection<NativeModule> getNativeModules() {
return mReactApplicationContext.getNativeModules();
}
@Nullable
@Override
public <T extends NativeModule> T getNativeModule(Class<T> nativeModuleInterface) {
return mReactApplicationContext.getNativeModule(nativeModuleInterface);
}
@Nullable
@Override
@FrameworkAPI
@UnstableReactNativeAPI
public RuntimeExecutor getRuntimeExecutor() {
return mReactApplicationContext.getRuntimeExecutor();
public boolean hasCurrentActivity() {
return mReactApplicationContext.hasCurrentActivity();
}
@Override
public CatalystInstance getCatalystInstance() {
return mReactApplicationContext.getCatalystInstance();
}
@Deprecated
@Override
public boolean hasActiveCatalystInstance() {
return mReactApplicationContext.hasActiveCatalystInstance();
}
@Override
public boolean hasActiveReactInstance() {
return mReactApplicationContext.hasActiveCatalystInstance();
}
@Override
public boolean hasCatalystInstance() {
return mReactApplicationContext.hasCatalystInstance();
}
@Override
public void destroy() {
mReactApplicationContext.destroy();
public @Nullable Activity getCurrentActivity() {
return mReactApplicationContext.getCurrentActivity();
}
/**
@@ -144,36 +103,16 @@ public class ThemedReactContext extends ReactContext {
return mReactApplicationContext;
}
@Override
public void handleException(Exception e) {
mReactApplicationContext.handleException(e);
}
@Deprecated
@Override
public boolean isBridgeless() {
return mReactApplicationContext.isBridgeless();
}
@Nullable
@Override
public JavaScriptContextHolder getJavaScriptContextHolder() {
return mReactApplicationContext.getJavaScriptContextHolder();
}
@Override
public UIManager getFabricUIManager() {
return mReactApplicationContext.getFabricUIManager();
}
@Nullable
@Override
public String getSourceURL() {
return mReactApplicationContext.getSourceURL();
}
@Override
public void registerSegment(int segmentId, String path, Callback callback) {
mReactApplicationContext.registerSegment(segmentId, path, callback);
if (isBridgeless()) {
return mReactApplicationContext.getFabricUIManager();
}
return super.getFabricUIManager();
}
}