expo-modules-core 0.10.0 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +3 -3
- package/android/CMakeLists.txt +14 -5
- package/android/build.gradle +78 -28
- package/android/src/main/cpp/CachedReferencesRegistry.cpp +67 -0
- package/android/src/main/cpp/CachedReferencesRegistry.h +80 -0
- package/android/src/main/cpp/JNIFunctionBody.cpp +28 -12
- package/android/src/main/cpp/JNIFunctionBody.h +2 -2
- package/android/src/main/cpp/JNIInjector.cpp +4 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +86 -5
- package/android/src/main/cpp/JavaScriptModuleObject.h +27 -5
- package/android/src/main/cpp/JavaScriptRuntime.cpp +10 -12
- package/android/src/main/cpp/MethodMetadata.cpp +181 -40
- package/android/src/main/cpp/MethodMetadata.h +43 -3
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +63 -10
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +6 -0
- package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAware.kt +49 -0
- package/android/src/main/java/expo/modules/kotlin/activityaware/AppCompatActivityAwareHelper.kt +43 -0
- package/android/src/main/java/expo/modules/kotlin/activityaware/OnActivityAvailableListener.kt +18 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/ActivityResultsManager.kt +99 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +25 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultContract.kt +27 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultFallbackCallback.kt +17 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultLauncher.kt +30 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultRegistry.kt +358 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/DataPersistor.kt +135 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +34 -1
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +7 -1
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionBuilder.kt +0 -108
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +5 -2
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +5 -2
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +9 -2
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +9 -1
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +1 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JNIFunctionBody.kt +2 -2
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +4 -2
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +1 -1
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +5 -454
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +7 -15
- package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +271 -0
- package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionData.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponent.kt +54 -0
- package/android/src/main/java/expo/modules/kotlin/objects/PropertyComponentBuilder.kt +32 -0
- package/android/src/main/java/expo/modules/kotlin/types/AnyTypeConverter.kt +36 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +7 -0
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -41
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -33
- package/build/PermissionsInterface.d.ts +29 -0
- package/build/PermissionsInterface.d.ts.map +1 -1
- package/build/PermissionsInterface.js +9 -0
- package/build/PermissionsInterface.js.map +1 -1
- package/ios/ExpoModulesCore.podspec +2 -1
- package/ios/JSI/EXJSIInstaller.mm +2 -0
- package/ios/JSI/EXJSIUtils.h +1 -0
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +4 -3
- package/ios/Swift/AppContext.swift +2 -4
- package/ios/Swift/Classes/ClassComponentElementsBuilder.swift +2 -2
- package/ios/Swift/Exceptions/ChainableException.swift +3 -3
- package/ios/Swift/ExpoBridgeModule.swift +16 -2
- package/ios/Swift/Logging/Logger.swift +3 -0
- package/ios/Swift/Promise.swift +5 -1
- package/package.json +2 -2
- package/src/PermissionsInterface.ts +29 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,28 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 0.11.2 — 2022-07-16
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- Fix dangling pointer in the fbjni from the MethodMetadata::createPromiseBody on Android. ([#18206](https://github.com/expo/expo/pull/18206) by [@lukmccall](https://github.com/lukmccall))
|
|
18
|
+
|
|
19
|
+
## 0.11.1 — 2022-07-11
|
|
20
|
+
|
|
21
|
+
### 🐛 Bug fixes
|
|
22
|
+
|
|
23
|
+
- Fixed a crash when remote debugging is enabled on Android. ([#18165](https://github.com/expo/expo/pull/18165) by [@kudo](https://github.com/kudo))
|
|
24
|
+
|
|
25
|
+
## 0.11.0 — 2022-07-07
|
|
26
|
+
|
|
27
|
+
### 🎉 New features
|
|
28
|
+
|
|
29
|
+
- Create `AppContext.registerForActivityResult` mechanism similar to [`ComponentActivity.registerForActivityResult`](https://developer.android.com/training/basics/intents/result)). ([#17572](https://github.com/expo/expo/pull/17572), ([#17987](https://github.com/expo/expo/pull/17987) by [@bbarthec](https://github.com/bbarthec))
|
|
30
|
+
|
|
31
|
+
### 🐛 Bug fixes
|
|
32
|
+
|
|
33
|
+
- Added support for React Native 0.69.x ([#18006](https://github.com/expo/expo/pull/18006) by [@kudo](https://github.com/kudo))
|
|
34
|
+
|
|
13
35
|
## 0.10.0 — 2022-06-23
|
|
14
36
|
|
|
15
37
|
### 🎉 New features
|
|
@@ -28,6 +50,7 @@
|
|
|
28
50
|
- Fix modules have not been deallocated during the application reload on iOS. ([#17285](https://github.com/expo/expo/pull/17285) by [@lukmccall](https://github.com/lukmccall))
|
|
29
51
|
- Fix view props weren't recognized in the bare workflow on iOS. ([#17411](https://github.com/expo/expo/pull/17411) by [@lukmccall](https://github.com/lukmccall))
|
|
30
52
|
- Fix support for optional function arguments on iOS. ([#17950](https://github.com/expo/expo/pull/17950) by [@barthap](https://github.com/barthap))
|
|
53
|
+
- Added support for React Native 0.69.x ([#17629](https://github.com/expo/expo/pull/17629) by [@kudo](https://github.com/kudo))
|
|
31
54
|
|
|
32
55
|
### 💡 Others
|
|
33
56
|
|
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ Many React Native libraries come with platform-specific (native) code. This nati
|
|
|
36
36
|
# Podfile
|
|
37
37
|
|
|
38
38
|
require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
|
|
39
|
-
require File.join(File.dirname(`node --print "require.resolve('
|
|
39
|
+
require File.join(File.dirname(`node --print "require.resolve('expo-modules-core/package.json')"`), "cocoapods.rb")
|
|
40
40
|
require File.join(File.dirname(`node --print "require.resolve('expo-modules-core/package.json')"`), "scripts/autolinking")
|
|
41
41
|
|
|
42
42
|
# ...
|
|
@@ -55,7 +55,7 @@ end
|
|
|
55
55
|
```groovy
|
|
56
56
|
// app/build.gradle
|
|
57
57
|
|
|
58
|
-
apply from: new File(["node", "--print", "require.resolve('
|
|
58
|
+
apply from: new File(["node", "--print", "require.resolve('expo-modules-core/package.json')"].execute(null, rootDir).text.trim(), "../gradle.groovy")
|
|
59
59
|
apply from: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../react.gradle")
|
|
60
60
|
apply from: new File(["node", "--print", "require.resolve('expo-updates/package.json')"].execute(null, rootDir).text.trim(), "../scripts/create-manifest-android.gradle")
|
|
61
61
|
|
|
@@ -68,7 +68,7 @@ applyNativeModulesAppBuildGradle(project)
|
|
|
68
68
|
```groovy
|
|
69
69
|
// settings.gradle
|
|
70
70
|
|
|
71
|
-
apply from: new File(["node", "--print", "require.resolve('
|
|
71
|
+
apply from: new File(["node", "--print", "require.resolve('expo-modules-core/package.json')"].execute(null, rootDir).text.trim(), "../gradle.groovy");
|
|
72
72
|
includeUnimodulesProjects()
|
|
73
73
|
|
|
74
74
|
apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
|
package/android/CMakeLists.txt
CHANGED
|
@@ -58,12 +58,21 @@ target_include_directories(
|
|
|
58
58
|
|
|
59
59
|
find_library(LOG_LIB log)
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
if(${REACT_NATIVE_TARGET_VERSION} LESS 69)
|
|
62
|
+
find_library(
|
|
63
|
+
FOLLY_LIB
|
|
63
64
|
folly_json
|
|
64
65
|
PATHS ${LIBRN_DIR}
|
|
65
66
|
NO_CMAKE_FIND_ROOT_PATH
|
|
66
|
-
)
|
|
67
|
+
)
|
|
68
|
+
else()
|
|
69
|
+
find_library(
|
|
70
|
+
FOLLY_LIB
|
|
71
|
+
folly_runtime
|
|
72
|
+
PATHS ${LIBRN_DIR}
|
|
73
|
+
NO_CMAKE_FIND_ROOT_PATH
|
|
74
|
+
)
|
|
75
|
+
endif()
|
|
67
76
|
|
|
68
77
|
find_library(
|
|
69
78
|
FBJNI_LIB
|
|
@@ -134,7 +143,7 @@ if (${FOR_HERMES})
|
|
|
134
143
|
${JSI_LIB}
|
|
135
144
|
${HERMES_LIB}
|
|
136
145
|
${REACT_NATIVE_JNI_LIB}
|
|
137
|
-
${
|
|
146
|
+
${FOLLY_LIB}
|
|
138
147
|
${REACT_NATIVE_MODULES_CORE}
|
|
139
148
|
android
|
|
140
149
|
)
|
|
@@ -146,7 +155,7 @@ else ()
|
|
|
146
155
|
${JSI_LIB}
|
|
147
156
|
${JSEXECUTOR_LIB}
|
|
148
157
|
${REACT_NATIVE_JNI_LIB}
|
|
149
|
-
${
|
|
158
|
+
${FOLLY_LIB}
|
|
150
159
|
${REACT_NATIVE_MODULES_CORE}
|
|
151
160
|
android
|
|
152
161
|
)
|
package/android/build.gradle
CHANGED
|
@@ -6,7 +6,7 @@ apply plugin: 'maven-publish'
|
|
|
6
6
|
apply plugin: "de.undercouch.download"
|
|
7
7
|
|
|
8
8
|
group = 'host.exp.exponent'
|
|
9
|
-
version = '0.
|
|
9
|
+
version = '0.11.2'
|
|
10
10
|
|
|
11
11
|
buildscript {
|
|
12
12
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -48,9 +48,11 @@ def isAndroidTest() {
|
|
|
48
48
|
def downloadsDir = new File("$buildDir/downloads")
|
|
49
49
|
def thirdPartyNdkDir = new File("$buildDir/third-party-ndk")
|
|
50
50
|
|
|
51
|
-
def REACT_NATIVE_DIR = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).parent
|
|
52
51
|
def REACT_NATIVE_BUILD_FROM_SOURCE = findProject(":ReactAndroid") != null
|
|
53
|
-
def
|
|
52
|
+
def REACT_NATIVE_DIR = REACT_NATIVE_BUILD_FROM_SOURCE
|
|
53
|
+
? findProject(":ReactAndroid").getProjectDir().parent
|
|
54
|
+
: new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).parent
|
|
55
|
+
def REACT_NATIVE_SO_DIR = REACT_NATIVE_BUILD_FROM_SOURCE
|
|
54
56
|
? Paths.get(findProject(":ReactAndroid").getProjectDir().toString(), "build", "intermediates", "library_*", "*", "jni")
|
|
55
57
|
: "${buildDir}/react-native-0*/jni"
|
|
56
58
|
|
|
@@ -60,6 +62,7 @@ file("$REACT_NATIVE_DIR/ReactAndroid/gradle.properties").withInputStream { react
|
|
|
60
62
|
def FOLLY_VERSION = reactProperties.getProperty("FOLLY_VERSION")
|
|
61
63
|
def BOOST_VERSION = reactProperties.getProperty("BOOST_VERSION")
|
|
62
64
|
def DOUBLE_CONVERSION_VERSION = reactProperties.getProperty("DOUBLE_CONVERSION_VERSION")
|
|
65
|
+
def REACT_NATIVE_TARGET_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger()
|
|
63
66
|
|
|
64
67
|
def reactNativeThirdParty = new File("$REACT_NATIVE_DIR/ReactAndroid/src/main/jni/third-party")
|
|
65
68
|
|
|
@@ -69,7 +72,8 @@ def reactNativeArchitectures() {
|
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
def FOR_HERMES = false
|
|
72
|
-
def
|
|
75
|
+
def HERMES_ENGINE_DIR = null
|
|
76
|
+
def HERMES_AAR = null
|
|
73
77
|
if (findProject(":app")) {
|
|
74
78
|
def appProjectExt = project(":app").ext
|
|
75
79
|
if (appProjectExt.has("react")) {
|
|
@@ -81,6 +85,25 @@ if (findProject(":app")) {
|
|
|
81
85
|
FOR_HERMES = (findProperty('expo.jsEngine') ?: "jsc") == "hermes"
|
|
82
86
|
}
|
|
83
87
|
|
|
88
|
+
if (FOR_HERMES) {
|
|
89
|
+
// The `hermes-engine` package doesn't contain the correct version of the Hermes.
|
|
90
|
+
// The AAR we need to import is located in the React Native package.
|
|
91
|
+
// However, the version from RN doesn't include header files.
|
|
92
|
+
// To get those, we must fall back to the `hermes-engine` package.
|
|
93
|
+
HERMES_ENGINE_DIR = new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim()).parent
|
|
94
|
+
if (REACT_NATIVE_BUILD_FROM_SOURCE) {
|
|
95
|
+
// TODO(@lukmccall): Use Hermes from the `ReactAndroid:hermes-engine`
|
|
96
|
+
HERMES_AAR = file("$HERMES_ENGINE_DIR/android/hermes-debug.aar")
|
|
97
|
+
} else {
|
|
98
|
+
def prebuiltAAR = fileTree(REACT_NATIVE_DIR).matching { include "**/hermes-engine/**/hermes-engine-*-debug.aar" }
|
|
99
|
+
if (prebuiltAAR.any()) {
|
|
100
|
+
HERMES_AAR = prebuiltAAR.singleFile
|
|
101
|
+
} else {
|
|
102
|
+
HERMES_AAR = file("$HERMES_ENGINE_DIR/android/hermes-debug.aar")
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
84
107
|
// Creating sources with comments
|
|
85
108
|
task androidSourcesJar(type: Jar) {
|
|
86
109
|
classifier = 'sources'
|
|
@@ -121,7 +144,7 @@ android {
|
|
|
121
144
|
targetSdkVersion safeExtGet("targetSdkVersion", 31)
|
|
122
145
|
consumerProguardFiles 'proguard-rules.pro'
|
|
123
146
|
versionCode 1
|
|
124
|
-
versionName "0.
|
|
147
|
+
versionName "0.11.2"
|
|
125
148
|
|
|
126
149
|
testInstrumentationRunner "expo.modules.TestRunner"
|
|
127
150
|
|
|
@@ -130,9 +153,10 @@ android {
|
|
|
130
153
|
abiFilters (*reactNativeArchitectures())
|
|
131
154
|
arguments "-DREACT_NATIVE_DIR=${REACT_NATIVE_DIR}",
|
|
132
155
|
"-DREACT_NATIVE_SO_DIR=${REACT_NATIVE_SO_DIR}",
|
|
156
|
+
"-DREACT_NATIVE_TARGET_VERSION=${REACT_NATIVE_TARGET_VERSION}",
|
|
133
157
|
"-DBOOST_VERSION=${BOOST_VERSION}",
|
|
134
158
|
"-DFOR_HERMES=${FOR_HERMES}",
|
|
135
|
-
"-DHERMES_DIR=${
|
|
159
|
+
"-DHERMES_DIR=${HERMES_ENGINE_DIR}"
|
|
136
160
|
}
|
|
137
161
|
}
|
|
138
162
|
}
|
|
@@ -158,6 +182,7 @@ android {
|
|
|
158
182
|
"**/libjscexecutor.so",
|
|
159
183
|
"**/libfbjni.so",
|
|
160
184
|
"**/libfolly_json.so",
|
|
185
|
+
"**/libfolly_runtime.so",
|
|
161
186
|
"**/libhermes.so",
|
|
162
187
|
"**/libjsi.so",
|
|
163
188
|
]
|
|
@@ -223,19 +248,6 @@ dependencies {
|
|
|
223
248
|
compileOnly 'com.facebook.fbjni:fbjni:0.2.2'
|
|
224
249
|
extractHeaders 'com.facebook.fbjni:fbjni:0.2.2:headers'
|
|
225
250
|
extractJNI 'com.facebook.fbjni:fbjni:0.2.2'
|
|
226
|
-
def rnAARs = fileTree("${REACT_NATIVE_DIR}/android").matching { include "**/*.aar" }
|
|
227
|
-
if (rnAARs.any()) {
|
|
228
|
-
// node_modules/react-native has a .aar, extract headers
|
|
229
|
-
if (rnAARs.size() > 1) {
|
|
230
|
-
logger.error("More than one React Native AAR file has been found:")
|
|
231
|
-
rnAARs.each { println(it) }
|
|
232
|
-
throw new GradleException("Multiple React Native AARs found:\n${rnAARs.join("\n")}" +
|
|
233
|
-
"\nRemove the old ones and try again")
|
|
234
|
-
}
|
|
235
|
-
def rnAAR = rnAARs.singleFile
|
|
236
|
-
extractJNI(files(rnAAR))
|
|
237
|
-
}
|
|
238
|
-
// else - there is no prebuilt react-native.aar, this is most likely Expo Go
|
|
239
251
|
|
|
240
252
|
testImplementation 'androidx.test:core:1.4.0'
|
|
241
253
|
testImplementation 'junit:junit:4.13.1'
|
|
@@ -252,7 +264,7 @@ dependencies {
|
|
|
252
264
|
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0"
|
|
253
265
|
|
|
254
266
|
if (FOR_HERMES) {
|
|
255
|
-
androidTestImplementation files(
|
|
267
|
+
androidTestImplementation files(HERMES_AAR)
|
|
256
268
|
} else {
|
|
257
269
|
androidTestImplementation "org.webkit:android-jsc:+"
|
|
258
270
|
}
|
|
@@ -276,6 +288,44 @@ task createNativeDepsDirectories() {
|
|
|
276
288
|
// END UTILS
|
|
277
289
|
|
|
278
290
|
// JNI
|
|
291
|
+
def extractReactNativeAAR = { buildType ->
|
|
292
|
+
def suffix = buildType == 'Debug' ? '-debug' : '-release'
|
|
293
|
+
def rnAARs = fileTree(REACT_NATIVE_DIR).matching { include "**/react-native/**/*${suffix}.aar" }
|
|
294
|
+
if (rnAARs.isEmpty()) {
|
|
295
|
+
rnAARs = fileTree(REACT_NATIVE_DIR).matching { include "**/react-native/**/*.aar" }
|
|
296
|
+
}
|
|
297
|
+
if (rnAARs.any()) {
|
|
298
|
+
// node_modules/react-native has a .aar, extract headers
|
|
299
|
+
if (rnAARs.size() > 1) {
|
|
300
|
+
logger.error("More than one React Native AAR file has been found:")
|
|
301
|
+
rnAARs.each {println(it) }
|
|
302
|
+
throw new GradleException("Multiple React Native AARs found:\n${rnAARs.join("\n")}" +
|
|
303
|
+
"\nRemove the old ones and try again")
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
def rnAAR = rnAARs.singleFile
|
|
307
|
+
def file = rnAAR.absoluteFile
|
|
308
|
+
def packageName = file.name.tokenize('-')[0]
|
|
309
|
+
copy {
|
|
310
|
+
from zipTree(file)
|
|
311
|
+
into "$buildDir/$file.name"
|
|
312
|
+
include "jni/**/*"
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
task extractReactNativeAARRelease {
|
|
317
|
+
doLast {
|
|
318
|
+
extractReactNativeAAR('Release')
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
task extractReactNativeAARDebug {
|
|
323
|
+
doLast {
|
|
324
|
+
extractReactNativeAAR('Debug')
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
|
|
279
329
|
task extractAARHeaders {
|
|
280
330
|
doLast {
|
|
281
331
|
configurations.extractHeaders.files.each {
|
|
@@ -305,7 +355,10 @@ task extractJNIFiles {
|
|
|
305
355
|
|
|
306
356
|
// BOOST
|
|
307
357
|
task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
308
|
-
|
|
358
|
+
def srcUrl = REACT_NATIVE_TARGET_VERSION >= 69
|
|
359
|
+
? "https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION.replace("_", ".")}/source/boost_${BOOST_VERSION}.tar.gz"
|
|
360
|
+
: "https://github.com/react-native-community/boost-for-react-native/releases/download/v${BOOST_VERSION.replace("_", ".")}-0/boost_${BOOST_VERSION}.tar.gz"
|
|
361
|
+
src(srcUrl)
|
|
309
362
|
onlyIfNewer(true)
|
|
310
363
|
overwrite(false)
|
|
311
364
|
dest(new File(downloadsDir, "boost_${BOOST_VERSION}.tar.gz"))
|
|
@@ -374,12 +427,7 @@ task prepareHermes() {
|
|
|
374
427
|
return
|
|
375
428
|
}
|
|
376
429
|
|
|
377
|
-
def
|
|
378
|
-
if (!hermesAAR.exists()) {
|
|
379
|
-
throw new GradleScriptException("The hermes-engine npm package is missing \"android/hermes-debug.aar\"", null)
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
def soFiles = zipTree(hermesAAR).matching({ it.include "**/*.so" })
|
|
430
|
+
def soFiles = zipTree(HERMES_AAR).matching({ it.include "**/*.so" })
|
|
383
431
|
|
|
384
432
|
copy {
|
|
385
433
|
from soFiles
|
|
@@ -397,11 +445,13 @@ afterEvaluate {
|
|
|
397
445
|
|
|
398
446
|
tasks.whenTaskAdded { task ->
|
|
399
447
|
if (!task.name.contains("Clean") && (task.name.contains('externalNativeBuild') || task.name.startsWith('configureCMake'))) {
|
|
448
|
+
def buildType = task.name.endsWith('Debug') ? 'Debug' : 'Release'
|
|
400
449
|
task.dependsOn(extractAARHeaders)
|
|
401
450
|
task.dependsOn(extractJNIFiles)
|
|
402
451
|
if (REACT_NATIVE_BUILD_FROM_SOURCE) {
|
|
403
|
-
def buildType = task.name.endsWith('Debug') ? 'Debug' : 'Release'
|
|
404
452
|
task.dependsOn(":ReactAndroid:copy${buildType}JniLibsProjectOnly")
|
|
453
|
+
} else {
|
|
454
|
+
task.dependsOn("extractReactNativeAAR${buildType}")
|
|
405
455
|
}
|
|
406
456
|
} else if (task.name.startsWith('generateJsonModel') && REACT_NATIVE_BUILD_FROM_SOURCE) {
|
|
407
457
|
def buildType = task.name.endsWith('Debug') ? 'Debug' : 'Release'
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#include "CachedReferencesRegistry.h"
|
|
4
|
+
|
|
5
|
+
#include <utility>
|
|
6
|
+
|
|
7
|
+
namespace expo {
|
|
8
|
+
std::shared_ptr<CachedReferencesRegistry> CachedReferencesRegistry::instance() {
|
|
9
|
+
static std::shared_ptr<CachedReferencesRegistry> singleton{new CachedReferencesRegistry};
|
|
10
|
+
return singleton;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
void CachedReferencesRegistry::loadJClasses(JNIEnv *env) {
|
|
14
|
+
loadJClass(env, "java/lang/Double", {
|
|
15
|
+
{"<init>", "(D)V"}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
loadJClass(env, "java/lang/Boolean", {
|
|
19
|
+
{"<init>", "(Z)V"}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
loadJClass(env, "com/facebook/react/bridge/PromiseImpl", {
|
|
23
|
+
{"<init>", "(Lcom/facebook/react/bridge/Callback;Lcom/facebook/react/bridge/Callback;)V"}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
loadJClass(env, "java/lang/Object", {});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
void CachedReferencesRegistry::loadJClass(
|
|
30
|
+
JNIEnv *env,
|
|
31
|
+
const std::string &name,
|
|
32
|
+
const std::vector<std::pair<std::string, std::string>> &methodsNames
|
|
33
|
+
) {
|
|
34
|
+
// Note this clazz variable points to a leaked global reference.
|
|
35
|
+
// This is appropriate for classes that are never unloaded which is any class in an Android app.
|
|
36
|
+
auto clazz = (jclass) env->NewGlobalRef(env->FindClass(name.c_str()));
|
|
37
|
+
|
|
38
|
+
MethodHashMap methods;
|
|
39
|
+
methods.reserve(methodsNames.size());
|
|
40
|
+
|
|
41
|
+
for (auto &method: methodsNames) {
|
|
42
|
+
methods.insert(
|
|
43
|
+
{method, env->GetMethodID(clazz, method.first.c_str(), method.second.c_str())}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
jClassRegistry.insert(
|
|
48
|
+
{name, CachedJClass(clazz, std::move(methods))}
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
CachedReferencesRegistry::CachedJClass &CachedReferencesRegistry::getJClass(
|
|
53
|
+
const std::string &className
|
|
54
|
+
) {
|
|
55
|
+
return jClassRegistry.at(className);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
jmethodID CachedReferencesRegistry::CachedJClass::getMethod(const std::string &name,
|
|
59
|
+
const std::string &signature) {
|
|
60
|
+
return methods.at({name, signature});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
CachedReferencesRegistry::CachedJClass::CachedJClass(
|
|
64
|
+
jclass clazz,
|
|
65
|
+
MethodHashMap methods
|
|
66
|
+
) : clazz(clazz), methods(std::move(methods)) {}
|
|
67
|
+
} // namespace expo
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include <jsi/jsi.h>
|
|
6
|
+
#include <fbjni/fbjni.h>
|
|
7
|
+
#include "boost/functional/hash.hpp"
|
|
8
|
+
|
|
9
|
+
#include <memory>
|
|
10
|
+
#include <unordered_map>
|
|
11
|
+
|
|
12
|
+
namespace jni = facebook::jni;
|
|
13
|
+
namespace jsi = facebook::jsi;
|
|
14
|
+
|
|
15
|
+
namespace expo {
|
|
16
|
+
using MethodHashMap = std::unordered_map<
|
|
17
|
+
std::pair<std::string, std::string>,
|
|
18
|
+
jmethodID,
|
|
19
|
+
boost::hash<std::pair<std::string, std::string>>
|
|
20
|
+
>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Singleton registry used to store references to often used Java classes.
|
|
24
|
+
*
|
|
25
|
+
* TODO(@lukmccall): also store reference to jsi objects like `Promise`.
|
|
26
|
+
*/
|
|
27
|
+
class CachedReferencesRegistry {
|
|
28
|
+
public:
|
|
29
|
+
/**
|
|
30
|
+
* An entry in the Java class registry.
|
|
31
|
+
*/
|
|
32
|
+
class CachedJClass {
|
|
33
|
+
public:
|
|
34
|
+
CachedJClass(jclass clazz, MethodHashMap methods);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A bare reference to the class object.
|
|
38
|
+
*/
|
|
39
|
+
jclass clazz;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns a cached method id for provided method name and signature.
|
|
43
|
+
*/
|
|
44
|
+
jmethodID getMethod(const std::string &name, const std::string &signature);
|
|
45
|
+
|
|
46
|
+
private:
|
|
47
|
+
MethodHashMap methods;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
CachedReferencesRegistry(CachedReferencesRegistry const &) = delete;
|
|
51
|
+
|
|
52
|
+
CachedReferencesRegistry &operator=(CachedReferencesRegistry const &) = delete;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Gets a singleton instance
|
|
56
|
+
*/
|
|
57
|
+
static std::shared_ptr<CachedReferencesRegistry> instance();
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Gets a cached Java class entry.
|
|
61
|
+
*/
|
|
62
|
+
CachedJClass &getJClass(const std::string &className);
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Loads predefined set of Java classes and stores them
|
|
66
|
+
*/
|
|
67
|
+
void loadJClasses(JNIEnv *env);
|
|
68
|
+
|
|
69
|
+
private:
|
|
70
|
+
CachedReferencesRegistry() = default;
|
|
71
|
+
|
|
72
|
+
std::unordered_map<std::string, CachedJClass> jClassRegistry;
|
|
73
|
+
|
|
74
|
+
void loadJClass(
|
|
75
|
+
JNIEnv *env,
|
|
76
|
+
const std::string &name,
|
|
77
|
+
const std::vector<std::pair<std::string, std::string>> &methods
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
} // namespace expo
|
|
@@ -1,28 +1,44 @@
|
|
|
1
1
|
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
2
|
|
|
3
3
|
#include "JNIFunctionBody.h"
|
|
4
|
+
#include "CachedReferencesRegistry.h"
|
|
4
5
|
|
|
5
6
|
namespace jni = facebook::jni;
|
|
6
7
|
namespace react = facebook::react;
|
|
7
8
|
|
|
8
9
|
namespace expo {
|
|
9
10
|
jni::local_ref<react::ReadableNativeArray::javaobject>
|
|
10
|
-
JNIFunctionBody::invoke(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
JNIFunctionBody::invoke(jobjectArray args) {
|
|
12
|
+
// Do NOT use getClass here!
|
|
13
|
+
// Method obtained from `getClass` will point to the overridden version of the method.
|
|
14
|
+
// Because of that, it can't be cached - we will try to invoke the nonexistent method
|
|
15
|
+
// if we receive an object of a different class than the one used to obtain the method id.
|
|
16
|
+
// The only cacheable method id can be obtain from the base class.
|
|
17
|
+
static const auto method = jni::findClassLocal("expo/modules/kotlin/jni/JNIFunctionBody")
|
|
18
|
+
->getMethod<jni::local_ref<react::ReadableNativeArray::javaobject>(jobjectArray)>(
|
|
19
|
+
"invoke",
|
|
20
|
+
"([Ljava/lang/Object;)Lcom/facebook/react/bridge/ReadableNativeArray;"
|
|
21
|
+
);
|
|
16
22
|
|
|
17
23
|
return method(this->self(), args);
|
|
18
24
|
}
|
|
19
25
|
|
|
20
|
-
void JNIAsyncFunctionBody::invoke(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
void JNIAsyncFunctionBody::invoke(
|
|
27
|
+
jobjectArray args,
|
|
28
|
+
jobject promise
|
|
29
|
+
) {
|
|
30
|
+
// Do NOT use getClass here!
|
|
31
|
+
// Method obtained from `getClass` will point to the overridden version of the method.
|
|
32
|
+
// Because of that, it can't be cached - we will try to invoke the nonexistent method
|
|
33
|
+
// if we receive an object of a different class than the one used to obtain the method id.
|
|
34
|
+
// The only cacheable method id can be obtain from the base class.
|
|
35
|
+
static const auto method = jni::findClassLocal("expo/modules/kotlin/jni/JNIAsyncFunctionBody")
|
|
36
|
+
->getMethod<
|
|
37
|
+
void(jobjectArray , jobject)
|
|
38
|
+
>(
|
|
39
|
+
"invoke",
|
|
40
|
+
"([Ljava/lang/Object;Ljava/lang/Object;)V"
|
|
41
|
+
);
|
|
26
42
|
|
|
27
43
|
method(this->self(), args, promise);
|
|
28
44
|
}
|
|
@@ -24,7 +24,7 @@ public:
|
|
|
24
24
|
* @return result of the Kotlin function
|
|
25
25
|
*/
|
|
26
26
|
jni::local_ref<react::ReadableNativeArray::javaobject> invoke(
|
|
27
|
-
|
|
27
|
+
jobjectArray args
|
|
28
28
|
);
|
|
29
29
|
};
|
|
30
30
|
|
|
@@ -43,7 +43,7 @@ public:
|
|
|
43
43
|
* @param promise that will be resolve or rejected in the Kotlin's implementation
|
|
44
44
|
*/
|
|
45
45
|
void invoke(
|
|
46
|
-
|
|
46
|
+
jobjectArray args,
|
|
47
47
|
jobject promise
|
|
48
48
|
);
|
|
49
49
|
};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#include "JavaScriptModuleObject.h"
|
|
5
5
|
#include "JavaScriptValue.h"
|
|
6
6
|
#include "JavaScriptObject.h"
|
|
7
|
+
#include "CachedReferencesRegistry.h"
|
|
7
8
|
|
|
8
9
|
#include <jni.h>
|
|
9
10
|
#include <fbjni/fbjni.h>
|
|
@@ -11,6 +12,9 @@
|
|
|
11
12
|
// Install all jni bindings
|
|
12
13
|
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
|
13
14
|
return facebook::jni::initialize(vm, [] {
|
|
15
|
+
// Loads references to often use Java classes
|
|
16
|
+
expo::CachedReferencesRegistry::instance()->loadJClasses(jni::Environment::current());
|
|
17
|
+
|
|
14
18
|
expo::JSIInteropModuleRegistry::registerNatives();
|
|
15
19
|
expo::JavaScriptModuleObject::registerNatives();
|
|
16
20
|
expo::JavaScriptValue::registerNatives();
|