Skip to content

Commit 79d3eea

Browse files
drrefactorfacebook-github-bot
authored andcommitted
refactor: Rewrite JavaModuleWrapper from Java to Kotlin (#50882)
Summary: Rewrite of JavaModuleWrapper from Java to Kotlin in scope of #50513 ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [ANDROID] [CHANGED] - Migrated JavaModuleWrapper to Kotlin Pull Request resolved: #50882 Test Plan: Test RNTester using old arch. SampleLegacyModule is the one I've used, it needs to be enabled for old arch though (RNTesterApplication.kt -> getPackages & getReactModuleInfoProvider). I may enable SampleLegacyModule for old arch to make testing easier. mateoguzmana It breaks on `getDynamic` on old arch, but I could filter these from examples or add some fallback in SampleLegacyModule.kt for old arch. Reviewed By: cortinico Differential Revision: D73576099 Pulled By: javache fbshipit-source-id: c940be27133258fa589571a600435fa478e6b51e
1 parent c443bc1 commit 79d3eea

File tree

3 files changed

+144
-157
lines changed

3 files changed

+144
-157
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/JavaModuleWrapper.java

Lines changed: 0 additions & 156 deletions
This file was deleted.
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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+
package com.facebook.react.bridge
9+
10+
import com.facebook.proguard.annotations.DoNotStrip
11+
import com.facebook.react.common.annotations.internal.LegacyArchitecture
12+
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogLevel
13+
import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger.assertLegacyArchitecture
14+
import com.facebook.react.turbomodule.core.interfaces.TurboModule
15+
import com.facebook.systrace.Systrace
16+
import com.facebook.systrace.Systrace.TRACE_TAG_REACT
17+
import com.facebook.systrace.SystraceMessage
18+
import java.lang.reflect.Method
19+
20+
/**
21+
* This is part of the glue which wraps a java BaseJavaModule in a C++ NativeModule. This could all
22+
* be in C++, but it's android-specific initialization code, and writing it this way is easier to
23+
* read and means fewer JNI calls.
24+
*/
25+
@DoNotStrip
26+
@LegacyArchitecture
27+
internal class JavaModuleWrapper(
28+
private val jsInstance: JSInstance,
29+
private val moduleHolder: ModuleHolder
30+
) {
31+
internal interface NativeMethod {
32+
fun invoke(jsInstance: JSInstance, parameters: ReadableArray)
33+
34+
val type: String
35+
}
36+
37+
@DoNotStrip
38+
class MethodDescriptor {
39+
@DoNotStrip var method: Method? = null
40+
41+
@DoNotStrip var signature: String? = null
42+
43+
@DoNotStrip var name: String? = null
44+
45+
@DoNotStrip var type: String? = null
46+
}
47+
48+
private val methods = ArrayList<NativeMethod>()
49+
private val descs = ArrayList<MethodDescriptor>()
50+
51+
@get:DoNotStrip
52+
val module: BaseJavaModule
53+
get() = moduleHolder.module as BaseJavaModule
54+
55+
@get:DoNotStrip
56+
val name: String
57+
get() = moduleHolder.name
58+
59+
@DoNotStrip
60+
private fun findMethods() {
61+
Systrace.beginSection(TRACE_TAG_REACT, "findMethods")
62+
63+
var classForMethods: Class<out NativeModule> = moduleHolder.module.javaClass
64+
val superClass = classForMethods.superclass
65+
if (TurboModule::class.java.isAssignableFrom(superClass)) {
66+
// For java module that is based on generated flow-type spec, inspect the
67+
// spec abstract class instead, which is the super class of the given Java
68+
// module.
69+
@Suppress("UNCHECKED_CAST")
70+
classForMethods = superClass as Class<out NativeModule>
71+
}
72+
73+
val targetMethods = classForMethods.declaredMethods
74+
for (targetMethod in targetMethods) {
75+
targetMethod.getAnnotation(ReactMethod::class.java)?.let { annotation ->
76+
val methodName = targetMethod.name
77+
val md = MethodDescriptor()
78+
val method = JavaMethodWrapper(this, targetMethod, annotation.isBlockingSynchronousMethod)
79+
md.name = methodName
80+
md.type = method.type
81+
if (BaseJavaModule.METHOD_TYPE_SYNC == md.type) {
82+
md.signature = method.signature
83+
md.method = targetMethod
84+
}
85+
methods.add(method)
86+
descs.add(md)
87+
}
88+
}
89+
Systrace.endSection(TRACE_TAG_REACT)
90+
}
91+
92+
@get:DoNotStrip
93+
val methodDescriptors: List<MethodDescriptor>
94+
get() {
95+
if (descs.isEmpty()) {
96+
findMethods()
97+
}
98+
return descs
99+
}
100+
101+
@get:DoNotStrip
102+
val constants: NativeMap
103+
get() {
104+
val moduleName = name
105+
SystraceMessage.beginSection(TRACE_TAG_REACT, "JavaModuleWrapper.getConstants")
106+
.arg("moduleName", moduleName)
107+
.flush()
108+
ReactMarker.logMarker(ReactMarkerConstants.GET_CONSTANTS_START, moduleName)
109+
110+
val baseJavaModule = module
111+
112+
Systrace.beginSection(TRACE_TAG_REACT, "module.getConstants")
113+
val map = baseJavaModule.constants
114+
Systrace.endSection(TRACE_TAG_REACT)
115+
116+
Systrace.beginSection(TRACE_TAG_REACT, "create WritableNativeMap")
117+
ReactMarker.logMarker(ReactMarkerConstants.CONVERT_CONSTANTS_START, moduleName)
118+
try {
119+
return Arguments.makeNativeMap(map)
120+
} finally {
121+
ReactMarker.logMarker(ReactMarkerConstants.CONVERT_CONSTANTS_END, moduleName)
122+
Systrace.endSection(TRACE_TAG_REACT)
123+
124+
ReactMarker.logMarker(ReactMarkerConstants.GET_CONSTANTS_END, moduleName)
125+
SystraceMessage.endSection(TRACE_TAG_REACT).flush()
126+
}
127+
}
128+
129+
@DoNotStrip
130+
fun invoke(methodId: Int, parameters: ReadableNativeArray) {
131+
if (methodId >= methods.size) {
132+
return
133+
}
134+
135+
methods[methodId].invoke(jsInstance, parameters)
136+
}
137+
138+
companion object {
139+
init {
140+
assertLegacyArchitecture("JavaModuleWrapper", LegacyArchitectureLogLevel.WARNING)
141+
}
142+
}
143+
}

packages/react-native/ReactAndroid/src/test/java/com/facebook/react/bridge/BaseJavaModuleTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class BaseJavaModuleTest {
3535
moduleWrapper = JavaModuleWrapper(jsInstance, moduleHolder)
3636
methods = moduleWrapper.methodDescriptors
3737
val generatedModuleHolder = ModuleHolder(GeneratedMethodsModule())
38-
generatedModuleWrapper = JavaModuleWrapper(null, generatedModuleHolder)
38+
generatedModuleWrapper = JavaModuleWrapper(jsInstance, generatedModuleHolder)
3939
generatedMethods = generatedModuleWrapper.methodDescriptors
4040
arguments = mock(ReadableNativeArray::class.java)
4141
}

0 commit comments

Comments
 (0)