Skip to content

Commit e05c0e6

Browse files
rshestfacebook-github-bot
authored andcommitted
Migrate BridgelessReactContext (#50729)
Summary: Pull Request resolved: #50729 ## Changelog: [Android] [Internal] - As in the title Reviewed By: cortinico Differential Revision: D73033754 fbshipit-source-id: 624c36735ec29ce97e426289fd05cf3405fc93d7
1 parent 0f9af75 commit e05c0e6

File tree

2 files changed

+156
-209
lines changed

2 files changed

+156
-209
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/BridgelessReactContext.java

-209
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
@file:Suppress("DEPRECATION")
9+
10+
package com.facebook.react.runtime
11+
12+
import android.content.Context
13+
import android.util.Log
14+
import com.facebook.react.bridge.Arguments
15+
import com.facebook.react.bridge.Callback
16+
import com.facebook.react.bridge.CatalystInstance
17+
import com.facebook.react.bridge.JavaScriptContextHolder
18+
import com.facebook.react.bridge.JavaScriptModule
19+
import com.facebook.react.bridge.JavaScriptModuleRegistry
20+
import com.facebook.react.bridge.NativeArray
21+
import com.facebook.react.bridge.NativeModule
22+
import com.facebook.react.bridge.ReactApplicationContext
23+
import com.facebook.react.bridge.UIManager
24+
import com.facebook.react.bridge.WritableNativeArray
25+
import com.facebook.react.common.annotations.FrameworkAPI
26+
import com.facebook.react.common.annotations.UnstableReactNativeAPI
27+
import com.facebook.react.devsupport.interfaces.DevSupportManager
28+
import com.facebook.react.internal.featureflags.ReactNativeNewArchitectureFeatureFlags
29+
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler
30+
import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder
31+
import com.facebook.react.uimanager.events.EventDispatcher
32+
import com.facebook.react.uimanager.events.EventDispatcherProvider
33+
import java.lang.reflect.InvocationHandler
34+
import java.lang.reflect.Method
35+
import java.lang.reflect.Proxy
36+
import java.util.concurrent.atomic.AtomicReference
37+
38+
/**
39+
* This class is used instead of [ReactApplicationContext] when React Native is operating in
40+
* bridgeless mode. The purpose of this class is to override some methods on [ReactContext] that use
41+
* the [CatalystInstance], which doesn't exist in bridgeless mode.
42+
*/
43+
internal class BridgelessReactContext(context: Context, private val reactHost: ReactHostImpl) :
44+
ReactApplicationContext(context), EventDispatcherProvider {
45+
private val sourceURLRef = AtomicReference<String>()
46+
private val TAG: String = this.javaClass.simpleName
47+
48+
init {
49+
if (ReactNativeNewArchitectureFeatureFlags.useFabricInterop()) {
50+
initializeInteropModules()
51+
}
52+
}
53+
54+
override fun getEventDispatcher(): EventDispatcher = reactHost.eventDispatcher
55+
56+
override fun getSourceURL(): String? = sourceURLRef.get()
57+
58+
public fun setSourceURL(sourceURL: String?) {
59+
sourceURLRef.set(sourceURL)
60+
}
61+
62+
@Deprecated("This method is deprecated, please use UIManagerHelper.getUIManager() instead.")
63+
override fun getFabricUIManager(): UIManager? = reactHost.uiManager
64+
65+
override fun getCatalystInstance(): CatalystInstance {
66+
Log.w(
67+
TAG,
68+
"[WARNING] Bridgeless doesn't support CatalystInstance. Accessing an API that's not part of" +
69+
" the new architecture is not encouraged usage.")
70+
return BridgelessCatalystInstance(reactHost)
71+
}
72+
73+
@Deprecated(
74+
"This API has been deprecated due to naming consideration, please use hasActiveReactInstance() instead")
75+
override fun hasActiveCatalystInstance(): Boolean = hasActiveReactInstance()
76+
77+
@Deprecated("DO NOT USE, this method will be removed in the near future.")
78+
override fun isBridgeless(): Boolean = true
79+
80+
@Deprecated(
81+
"This API has been deprecated due to naming consideration, please use hasReactInstance() instead")
82+
override fun hasCatalystInstance(): Boolean = false
83+
84+
override fun hasActiveReactInstance(): Boolean = reactHost.isInstanceInitialized
85+
86+
override fun hasReactInstance(): Boolean = reactHost.isInstanceInitialized
87+
88+
override fun destroy() = Unit
89+
90+
val devSupportManager: DevSupportManager
91+
get() = reactHost.devSupportManager
92+
93+
override fun registerSegment(segmentId: Int, path: String, callback: Callback) {
94+
reactHost.registerSegment(segmentId, path, callback)
95+
}
96+
97+
private class BridgelessJSModuleInvocationHandler(
98+
private val reactHost: ReactHostImpl,
99+
private val jsModuleInterface: Class<out JavaScriptModule>
100+
) : InvocationHandler {
101+
override fun invoke(proxy: Any, method: Method, args: Array<Any>?): Any? {
102+
val jsArgs: NativeArray =
103+
if (args != null) Arguments.fromJavaArgs(args) else WritableNativeArray()
104+
reactHost.callFunctionOnModule(
105+
JavaScriptModuleRegistry.getJSModuleName(jsModuleInterface), method.name, jsArgs)
106+
return null
107+
}
108+
}
109+
110+
override fun <T : JavaScriptModule> getJSModule(jsInterface: Class<T>): T? {
111+
mInteropModuleRegistry?.let { reg ->
112+
if (reg.shouldReturnInteropModule(jsInterface)) {
113+
return reg.getInteropModule(jsInterface)
114+
}
115+
}
116+
117+
// TODO T189052462: ReactContext caches JavaScriptModule instances
118+
val interfaceProxy: JavaScriptModule =
119+
Proxy.newProxyInstance(
120+
jsInterface.classLoader,
121+
arrayOf<Class<*>>(jsInterface),
122+
BridgelessJSModuleInvocationHandler(reactHost, jsInterface)) as JavaScriptModule
123+
@Suppress("UNCHECKED_CAST")
124+
return interfaceProxy as? T
125+
}
126+
127+
/** Shortcut RCTDeviceEventEmitter.emit since it's frequently used */
128+
override fun emitDeviceEvent(eventName: String, args: Any?) {
129+
reactHost.callFunctionOnModule(
130+
"RCTDeviceEventEmitter", "emit", Arguments.fromJavaArgs(arrayOf(eventName, args)))
131+
}
132+
133+
override fun <T : NativeModule> hasNativeModule(nativeModuleInterface: Class<T>): Boolean =
134+
reactHost.hasNativeModule(nativeModuleInterface)
135+
136+
override fun getNativeModules(): MutableCollection<NativeModule>? = reactHost.nativeModules
137+
138+
override fun <T : NativeModule> getNativeModule(nativeModuleInterface: Class<T>): T? =
139+
reactHost.getNativeModule(nativeModuleInterface)
140+
141+
override fun getNativeModule(name: String): NativeModule? = reactHost.getNativeModule(name)
142+
143+
@UnstableReactNativeAPI
144+
@FrameworkAPI
145+
override fun getJavaScriptContextHolder(): JavaScriptContextHolder? =
146+
reactHost.javaScriptContextHolder
147+
148+
override fun handleException(e: Exception) {
149+
reactHost.handleHostException(e)
150+
}
151+
152+
override fun getJSCallInvokerHolder(): CallInvokerHolder? = reactHost.jsCallInvokerHolder
153+
154+
val defaultHardwareBackBtnHandler: DefaultHardwareBackBtnHandler
155+
get() = reactHost.defaultBackButtonHandler
156+
}

0 commit comments

Comments
 (0)