expo-modules-core 1.2.6 → 1.3.0
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 +33 -4
- package/ExpoModulesCore.podspec +1 -0
- package/README.md +1 -1
- package/android/ExpoModulesCorePlugin.gradle +16 -0
- package/android/build.gradle +3 -2
- package/android/src/main/cpp/Exceptions.cpp +8 -0
- package/android/src/main/cpp/Exceptions.h +11 -0
- package/android/src/main/cpp/ExpoModulesHostObject.cpp +22 -5
- package/android/src/main/cpp/ExpoModulesHostObject.h +5 -0
- package/android/src/main/cpp/JNIInjector.cpp +2 -0
- package/android/src/main/cpp/JSIInteropModuleRegistry.cpp +25 -1
- package/android/src/main/cpp/JSIInteropModuleRegistry.h +14 -0
- package/android/src/main/cpp/JSIObjectWrapper.h +15 -4
- package/android/src/main/cpp/JSITypeConverter.h +3 -2
- package/android/src/main/cpp/JavaReferencesCache.cpp +2 -0
- package/android/src/main/cpp/JavaScriptFunction.cpp +56 -0
- package/android/src/main/cpp/JavaScriptFunction.h +54 -0
- package/android/src/main/cpp/JavaScriptModuleObject.cpp +225 -105
- package/android/src/main/cpp/JavaScriptModuleObject.h +67 -34
- package/android/src/main/cpp/JavaScriptObject.cpp +55 -1
- package/android/src/main/cpp/JavaScriptObject.h +17 -13
- package/android/src/main/cpp/JavaScriptRuntime.cpp +12 -3
- package/android/src/main/cpp/JavaScriptRuntime.h +9 -1
- package/android/src/main/cpp/JavaScriptValue.cpp +9 -0
- package/android/src/main/cpp/JavaScriptValue.h +4 -0
- package/android/src/main/cpp/MethodMetadata.cpp +66 -87
- package/android/src/main/cpp/MethodMetadata.h +18 -16
- package/android/src/main/cpp/ObjectDeallocator.h +25 -0
- package/android/src/main/cpp/WeakRuntimeHolder.cpp +7 -0
- package/android/src/main/cpp/WeakRuntimeHolder.h +4 -0
- package/android/src/main/cpp/types/CppType.h +4 -1
- package/android/src/main/cpp/types/FrontendConverter.cpp +58 -0
- package/android/src/main/cpp/types/FrontendConverter.h +45 -0
- package/android/src/main/cpp/types/FrontendConverterProvider.cpp +3 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.cpp +88 -0
- package/android/src/main/cpp/types/JNIToJSIConverter.h +22 -0
- package/android/src/main/java/com/facebook/react/uimanager/ReactStylesDiffMapHelper.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/AppContext.kt +18 -25
- package/android/src/main/java/expo/modules/kotlin/FilteredIterator.kt +37 -0
- package/android/src/main/java/expo/modules/kotlin/KotlinInteropModuleRegistry.kt +1 -1
- package/android/src/main/java/expo/modules/kotlin/ModuleHolder.kt +34 -21
- package/android/src/main/java/expo/modules/kotlin/ModuleRegistry.kt +13 -3
- package/android/src/main/java/expo/modules/kotlin/Utils.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt +21 -1
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassComponentBuilder.kt +112 -0
- package/android/src/main/java/expo/modules/kotlin/classcomponent/ClassDefinitionData.kt +10 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CodedException.kt +21 -0
- package/android/src/main/java/expo/modules/kotlin/exception/CommonExceptions.kt +15 -0
- package/android/src/main/java/expo/modules/kotlin/functions/AnyFunction.kt +17 -4
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunction.kt +38 -8
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/AsyncFunctionWithPromiseComponent.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/functions/SuspendFunctionComponent.kt +1 -0
- package/android/src/main/java/expo/modules/kotlin/functions/SyncFunctionComponent.kt +18 -11
- package/android/src/main/java/expo/modules/kotlin/jni/CppType.kt +4 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JNIDeallocator.kt +73 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JSIInteropModuleRegistry.kt +28 -2
- package/android/src/main/java/expo/modules/kotlin/jni/JavaCallback.kt +8 -1
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptFunction.kt +48 -0
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptModuleObject.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptObject.kt +23 -3
- package/android/src/main/java/expo/modules/kotlin/jni/JavaScriptValue.kt +26 -1
- package/android/src/main/java/expo/modules/kotlin/modules/Module.kt +0 -11
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionBuilder.kt +26 -16
- package/android/src/main/java/expo/modules/kotlin/modules/ModuleDefinitionData.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObject.kt +12 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectRegistry.kt +62 -0
- package/android/src/main/java/expo/modules/kotlin/sharedobjects/SharedObjectTypeConverter.kt +27 -0
- package/android/src/main/java/expo/modules/kotlin/types/AnyType.kt +2 -1
- package/android/src/main/java/expo/modules/kotlin/types/EitherTypeConverter.kt +7 -6
- package/android/src/main/java/expo/modules/kotlin/types/JavaScriptFunctionTypeConverter.kt +22 -0
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverter.kt +30 -24
- package/android/src/main/java/expo/modules/kotlin/types/TypeConverterProvider.kt +45 -1
- package/android/src/main/java/expo/modules/kotlin/types/TypedArrayTypeConverter.kt +3 -2
- package/android/src/main/java/expo/modules/kotlin/views/AnyViewProp.kt +3 -1
- package/android/src/main/java/expo/modules/kotlin/views/ConcreteViewProp.kt +3 -3
- package/android/src/main/java/expo/modules/kotlin/views/FilteredReadableMap.kt +53 -0
- package/android/src/main/java/expo/modules/kotlin/views/GroupViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/SimpleViewManagerWrapper.kt +25 -5
- package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +161 -10
- package/android/src/main/java/expo/modules/kotlin/views/ViewGroupDefinitionBuilder.kt +0 -67
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinition.kt +7 -8
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerWrapperDelegate.kt +40 -3
- package/android/src/main/java/expo/modules/kotlin/views/ViewTypeConverter.kt +44 -0
- package/android-annotation/build.gradle +45 -0
- package/android-annotation/src/main/java/expo/modules/annotation/Config.kt +7 -0
- package/android-annotation/src/main/java/expo/modules/annotation/ConverterBinder.kt +7 -0
- package/android-annotation-processor/build.gradle +51 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessor.kt +175 -0
- package/android-annotation-processor/src/main/java/expo/modules/annotationprocessor/ExpoSymbolProcessorProvider.kt +10 -0
- package/android-annotation-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +1 -0
- package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
- package/build/NativeViewManagerAdapter.native.js +36 -23
- package/build/NativeViewManagerAdapter.native.js.map +1 -1
- package/build/requireNativeModule.js +2 -2
- package/build/requireNativeModule.js.map +1 -1
- package/common/cpp/fabric/ExpoViewProps.cpp +18 -3
- package/common/cpp/fabric/ExpoViewProps.h +4 -1
- package/ios/Fabric/ExpoFabricView.swift +10 -10
- package/ios/Fabric/ExpoFabricViewObjC.h +2 -0
- package/ios/Fabric/ExpoFabricViewObjC.mm +17 -2
- package/ios/JSI/EXJSIInstaller.mm +1 -1
- package/ios/JSI/EXJSIUtils.h +5 -0
- package/ios/JSI/EXJSIUtils.mm +17 -0
- package/ios/JSI/EXJavaScriptRuntime.h +5 -0
- package/ios/JSI/EXJavaScriptRuntime.mm +6 -0
- package/ios/JSI/EXJavaScriptValue.h +2 -0
- package/ios/JSI/EXJavaScriptValue.mm +8 -0
- package/ios/JSI/EXJavaScriptWeakObject.mm +29 -8
- package/ios/JSI/EXRawJavaScriptFunction.h +24 -0
- package/ios/JSI/EXRawJavaScriptFunction.mm +52 -0
- package/ios/JSI/ExpoModulesHostObject.mm +1 -1
- package/ios/JSI/JavaScriptValue.swift +28 -1
- package/ios/ModuleRegistry/EXModuleRegistry.h +0 -4
- package/ios/ModuleRegistry/EXModuleRegistry.m +0 -23
- package/ios/ModuleRegistryAdapter/EXModuleRegistryAdapter.m +0 -16
- package/ios/ModuleRegistryProvider/EXModuleRegistryProvider.m +0 -6
- package/ios/NativeModulesProxy/EXNativeModulesProxy.mm +1 -31
- package/ios/Swift/AppContext.swift +46 -6
- package/ios/Swift/Arguments/Convertible.swift +3 -3
- package/ios/Swift/Arguments/Convertibles.swift +5 -5
- package/ios/Swift/Classes/ClassComponent.swift +18 -12
- package/ios/Swift/Classes/ClassRegistry.swift +31 -0
- package/ios/Swift/Conversions.swift +19 -3
- package/ios/Swift/Convertibles/Convertibles+Color.swift +3 -3
- package/ios/Swift/Convertibles/Either.swift +6 -4
- package/ios/Swift/DynamicTypes/AnyDynamicType.swift +18 -2
- package/ios/Swift/DynamicTypes/DynamicArrayType.swift +3 -3
- package/ios/Swift/DynamicTypes/DynamicConvertibleType.swift +2 -2
- package/ios/Swift/DynamicTypes/DynamicEnumType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicJavaScriptType.swift +27 -0
- package/ios/Swift/DynamicTypes/DynamicOptionalType.swift +9 -2
- package/ios/Swift/DynamicTypes/DynamicRawType.swift +1 -1
- package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +16 -2
- package/ios/Swift/DynamicTypes/DynamicType.swift +6 -0
- package/ios/Swift/DynamicTypes/DynamicTypedArrayType.swift +15 -4
- package/ios/Swift/DynamicTypes/DynamicViewType.swift +68 -0
- package/ios/Swift/ExpoBridgeModule.swift +1 -1
- package/ios/Swift/Functions/AnyFunction.swift +5 -4
- package/ios/Swift/Functions/AsyncFunctionComponent.swift +22 -19
- package/ios/Swift/Functions/ConcurrentFunctionDefinition.swift +29 -13
- package/ios/Swift/Functions/SyncFunctionComponent.swift +26 -15
- package/ios/Swift/JavaScriptFunction.swift +68 -0
- package/ios/Swift/JavaScriptUtils.swift +57 -18
- package/ios/Swift/ModuleHolder.swift +22 -10
- package/ios/Swift/Modules/ModuleDefinition.swift +8 -2
- package/ios/Swift/Objects/JavaScriptObjectBuilder.swift +8 -8
- package/ios/Swift/Objects/ObjectDefinition.swift +17 -15
- package/ios/Swift/Objects/PropertyComponent.swift +23 -17
- package/ios/Swift/Records/AnyField.swift +1 -1
- package/ios/Swift/Records/Field.swift +2 -2
- package/ios/Swift/Records/Record.swift +5 -5
- package/ios/Swift/SharedObjects/SharedObjectRegistry.swift +4 -0
- package/ios/Swift/Views/AnyViewProp.swift +1 -1
- package/ios/Swift/Views/ComponentData.swift +37 -2
- package/ios/Swift/Views/ConcreteViewProp.swift +2 -2
- package/ios/Swift/Views/ViewDefinition.swift +39 -0
- package/ios/Swift/Views/ViewModuleWrapper.swift +0 -29
- package/ios/Tests/ClassComponentSpec.swift +39 -27
- package/ios/Tests/ConvertiblesSpec.swift +75 -49
- package/ios/Tests/DynamicTypeSpec.swift +29 -27
- package/ios/Tests/EitherSpec.swift +9 -7
- package/ios/Tests/ExpoModulesSpec.swift +13 -13
- package/ios/Tests/FunctionSpec.swift +38 -22
- package/ios/Tests/JavaScriptRuntimeSpec.swift +4 -0
- package/ios/Tests/PropertyComponentSpec.swift +33 -30
- package/ios/Tests/RecordSpec.swift +7 -5
- package/ios/Tests/SharedObjectRegistrySpec.swift +12 -12
- package/ios/Tests/TypedArraysSpec.swift +1 -1
- package/ios/Tests/ViewDefinitionSpec.swift +4 -2
- package/package.json +2 -2
- package/src/NativeViewManagerAdapter.native.tsx +33 -29
- package/src/requireNativeModule.ts +2 -2
- package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +0 -132
- package/ios/EXViewManager.h +0 -21
- package/ios/EXViewManager.m +0 -128
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.h +0 -17
- package/ios/ModuleRegistryAdapter/EXViewManagerAdapterClassesRegistry.m +0 -67
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.h +0 -17
- package/ios/ViewManagerAdapter/EXViewManagerAdapter.m +0 -45
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
#include "../JSIInteropModuleRegistry.h"
|
|
10
10
|
#include "../JavaScriptObject.h"
|
|
11
11
|
#include "../JavaScriptValue.h"
|
|
12
|
+
#include "../JavaScriptFunction.h"
|
|
12
13
|
#include "../javaclasses/Collections.h"
|
|
13
14
|
|
|
14
15
|
#include "react/jni/ReadableNativeMap.h"
|
|
@@ -207,6 +208,25 @@ bool JavaScriptObjectFrontendConverter::canConvert(
|
|
|
207
208
|
return value.isObject();
|
|
208
209
|
}
|
|
209
210
|
|
|
211
|
+
jobject JavaScriptFunctionFrontendConverter::convert(
|
|
212
|
+
jsi::Runtime &rt,
|
|
213
|
+
JNIEnv *env,
|
|
214
|
+
JSIInteropModuleRegistry *moduleRegistry,
|
|
215
|
+
const jsi::Value &value
|
|
216
|
+
) const {
|
|
217
|
+
return JavaScriptFunction::newObjectCxxArgs(
|
|
218
|
+
moduleRegistry->runtimeHolder->weak_from_this(),
|
|
219
|
+
std::make_shared<jsi::Function>(value.getObject(rt).asFunction(rt))
|
|
220
|
+
).release();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
bool JavaScriptFunctionFrontendConverter::canConvert(
|
|
224
|
+
jsi::Runtime &rt,
|
|
225
|
+
const jsi::Value &value
|
|
226
|
+
) const {
|
|
227
|
+
return value.isObject() && value.asObject(rt).isFunction(rt);
|
|
228
|
+
}
|
|
229
|
+
|
|
210
230
|
jobject UnknownFrontendConverter::convert(
|
|
211
231
|
jsi::Runtime &rt,
|
|
212
232
|
JNIEnv *env,
|
|
@@ -429,4 +449,42 @@ bool MapFrontendConverter::canConvert(
|
|
|
429
449
|
) const {
|
|
430
450
|
return value.isObject();
|
|
431
451
|
}
|
|
452
|
+
|
|
453
|
+
jobject ViewTagFrontendConverter::convert(jsi::Runtime &rt, JNIEnv *env,
|
|
454
|
+
JSIInteropModuleRegistry *moduleRegistry,
|
|
455
|
+
const jsi::Value &value) const {
|
|
456
|
+
auto nativeTag = value.getObject(rt).getProperty(rt, "nativeTag");
|
|
457
|
+
if (nativeTag.isNull()) {
|
|
458
|
+
return nullptr;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
auto viewTag = (int) nativeTag.getNumber();
|
|
462
|
+
auto &integerClass = JavaReferencesCache::instance()
|
|
463
|
+
->getJClass("java/lang/Integer");
|
|
464
|
+
jmethodID integerConstructor = integerClass.getMethod("<init>", "(I)V");
|
|
465
|
+
return env->NewObject(integerClass.clazz, integerConstructor, viewTag);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
bool ViewTagFrontendConverter::canConvert(jsi::Runtime &rt, const jsi::Value &value) const {
|
|
469
|
+
return value.isObject() && value.getObject(rt).hasProperty(rt, "nativeTag");
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
jobject SharedObjectIdConverter::convert(jsi::Runtime &rt, JNIEnv *env,
|
|
473
|
+
JSIInteropModuleRegistry *moduleRegistry,
|
|
474
|
+
const jsi::Value &value) const {
|
|
475
|
+
auto objectId = value.getObject(rt).getProperty(rt, "__expo_shared_object_id__");
|
|
476
|
+
if (objectId.isNull()) {
|
|
477
|
+
return nullptr;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
auto viewTag = (int) objectId.getNumber();
|
|
481
|
+
auto &integerClass = JavaReferencesCache::instance()
|
|
482
|
+
->getJClass("java/lang/Integer");
|
|
483
|
+
jmethodID integerConstructor = integerClass.getMethod("<init>", "(I)V");
|
|
484
|
+
return env->NewObject(integerClass.clazz, integerConstructor, viewTag);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
bool SharedObjectIdConverter::canConvert(jsi::Runtime &rt, const jsi::Value &value) const {
|
|
488
|
+
return value.isObject() && value.getObject(rt).hasProperty(rt, "__expo_shared_object_id__");
|
|
489
|
+
}
|
|
432
490
|
} // namespace expo
|
|
@@ -205,6 +205,51 @@ public:
|
|
|
205
205
|
bool canConvert(jsi::Runtime &rt, const jsi::Value &value) const override;
|
|
206
206
|
};
|
|
207
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Converter from js function to [expo.modules.kotlin.jni.JavaScriptFunction].
|
|
210
|
+
*/
|
|
211
|
+
class JavaScriptFunctionFrontendConverter : public FrontendConverter {
|
|
212
|
+
public:
|
|
213
|
+
jobject convert(
|
|
214
|
+
jsi::Runtime &rt,
|
|
215
|
+
JNIEnv *env,
|
|
216
|
+
JSIInteropModuleRegistry *moduleRegistry,
|
|
217
|
+
const jsi::Value &value
|
|
218
|
+
) const override;
|
|
219
|
+
|
|
220
|
+
bool canConvert(jsi::Runtime &rt, const jsi::Value &value) const override;
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Converter from js view object to int.
|
|
225
|
+
*/
|
|
226
|
+
class ViewTagFrontendConverter : public FrontendConverter {
|
|
227
|
+
public:
|
|
228
|
+
jobject convert(
|
|
229
|
+
jsi::Runtime &rt,
|
|
230
|
+
JNIEnv *env,
|
|
231
|
+
JSIInteropModuleRegistry *moduleRegistry,
|
|
232
|
+
const jsi::Value &value
|
|
233
|
+
) const override;
|
|
234
|
+
|
|
235
|
+
bool canConvert(jsi::Runtime &rt, const jsi::Value &value) const override;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Converter from js shared object to int.
|
|
240
|
+
*/
|
|
241
|
+
class SharedObjectIdConverter : public FrontendConverter {
|
|
242
|
+
public:
|
|
243
|
+
jobject convert(
|
|
244
|
+
jsi::Runtime &rt,
|
|
245
|
+
JNIEnv *env,
|
|
246
|
+
JSIInteropModuleRegistry *moduleRegistry,
|
|
247
|
+
const jsi::Value &value
|
|
248
|
+
) const override;
|
|
249
|
+
|
|
250
|
+
bool canConvert(jsi::Runtime &rt, const jsi::Value &value) const override;
|
|
251
|
+
};
|
|
252
|
+
|
|
208
253
|
/**
|
|
209
254
|
* Converter that always fails.
|
|
210
255
|
* Used to not fail when the function is created.
|
|
@@ -19,9 +19,12 @@ void FrontendConverterProvider::createConverters() {
|
|
|
19
19
|
RegisterConverter(CppType::TYPED_ARRAY, TypedArrayFrontendConverter);
|
|
20
20
|
RegisterConverter(CppType::JS_OBJECT, JavaScriptObjectFrontendConverter);
|
|
21
21
|
RegisterConverter(CppType::JS_VALUE, JavaScriptValueFrontendConverter);
|
|
22
|
+
RegisterConverter(CppType::JS_FUNCTION, JavaScriptFunctionFrontendConverter);
|
|
22
23
|
RegisterConverter(CppType::STRING, StringFrontendConverter);
|
|
23
24
|
RegisterConverter(CppType::READABLE_MAP, ReadableNativeMapArrayFrontendConverter);
|
|
24
25
|
RegisterConverter(CppType::READABLE_ARRAY, ReadableNativeArrayFrontendConverter);
|
|
26
|
+
RegisterConverter(CppType::VIEW_TAG, ViewTagFrontendConverter);
|
|
27
|
+
RegisterConverter(CppType::SHARED_OBJECT_ID, SharedObjectIdConverter);
|
|
25
28
|
#undef RegisterConverter
|
|
26
29
|
|
|
27
30
|
auto registerPolyConverter = [this](const std::vector<CppType> &types) {
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#include "JNIToJSIConverter.h"
|
|
4
|
+
#include "../JavaReferencesCache.h"
|
|
5
|
+
#include "../ObjectDeallocator.h"
|
|
6
|
+
|
|
7
|
+
#include <react/jni/ReadableNativeMap.h>
|
|
8
|
+
#include <react/jni/ReadableNativeArray.h>
|
|
9
|
+
#include <react/jni/WritableNativeArray.h>
|
|
10
|
+
#include <react/jni/WritableNativeMap.h>
|
|
11
|
+
|
|
12
|
+
namespace react = facebook::react;
|
|
13
|
+
|
|
14
|
+
namespace expo {
|
|
15
|
+
|
|
16
|
+
jsi::Value convert(
|
|
17
|
+
JSIInteropModuleRegistry *moduleRegistry,
|
|
18
|
+
JNIEnv *env,
|
|
19
|
+
jsi::Runtime &rt,
|
|
20
|
+
jni::local_ref<jobject> value
|
|
21
|
+
) {
|
|
22
|
+
if (value == nullptr) {
|
|
23
|
+
return jsi::Value::undefined();
|
|
24
|
+
}
|
|
25
|
+
auto unpackedValue = value.get();
|
|
26
|
+
auto cache = JavaReferencesCache::instance();
|
|
27
|
+
if (env->IsInstanceOf(unpackedValue, cache->getJClass("java/lang/Double").clazz)) {
|
|
28
|
+
return {jni::static_ref_cast<jni::JDouble>(value)->value()};
|
|
29
|
+
}
|
|
30
|
+
if (env->IsInstanceOf(unpackedValue, cache->getJClass("java/lang/Integer").clazz)) {
|
|
31
|
+
return {jni::static_ref_cast<jni::JInteger>(value)->value()};
|
|
32
|
+
}
|
|
33
|
+
if (env->IsInstanceOf(unpackedValue, cache->getJClass("java/lang/Long").clazz)) {
|
|
34
|
+
return {(double) jni::static_ref_cast<jni::JLong>(value)->value()};
|
|
35
|
+
}
|
|
36
|
+
if (env->IsInstanceOf(unpackedValue, cache->getJClass("java/lang/String").clazz)) {
|
|
37
|
+
return jsi::String::createFromUtf8(
|
|
38
|
+
rt,
|
|
39
|
+
jni::static_ref_cast<jni::JString>(value)->toStdString()
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
if (env->IsInstanceOf(unpackedValue, cache->getJClass("java/lang/Boolean").clazz)) {
|
|
43
|
+
return {(bool) jni::static_ref_cast<jni::JBoolean>(value)->value()};
|
|
44
|
+
}
|
|
45
|
+
if (env->IsInstanceOf(unpackedValue, cache->getJClass("java/lang/Float").clazz)) {
|
|
46
|
+
return {(double) jni::static_ref_cast<jni::JFloat>(value)->value()};
|
|
47
|
+
}
|
|
48
|
+
if (env->IsInstanceOf(
|
|
49
|
+
unpackedValue,
|
|
50
|
+
cache->getJClass("com/facebook/react/bridge/WritableNativeArray").clazz
|
|
51
|
+
)) {
|
|
52
|
+
auto dynamic = jni::static_ref_cast<react::WritableNativeArray::javaobject>(value)
|
|
53
|
+
->cthis()
|
|
54
|
+
->consume();
|
|
55
|
+
return jsi::valueFromDynamic(rt, dynamic);
|
|
56
|
+
}
|
|
57
|
+
if (env->IsInstanceOf(
|
|
58
|
+
unpackedValue,
|
|
59
|
+
cache->getJClass("com/facebook/react/bridge/WritableNativeMap").clazz
|
|
60
|
+
)) {
|
|
61
|
+
auto dynamic = jni::static_ref_cast<react::WritableNativeMap::javaobject>(value)
|
|
62
|
+
->cthis()
|
|
63
|
+
->consume();
|
|
64
|
+
return jsi::valueFromDynamic(rt, dynamic);
|
|
65
|
+
}
|
|
66
|
+
if (env->IsInstanceOf(unpackedValue, JavaScriptModuleObject::javaClassStatic().get())) {
|
|
67
|
+
auto anonymousObject = jni::static_ref_cast<JavaScriptModuleObject::javaobject>(value)
|
|
68
|
+
->cthis();
|
|
69
|
+
anonymousObject->jsiInteropModuleRegistry = moduleRegistry;
|
|
70
|
+
auto jsiObject = anonymousObject->getJSIObject(rt);
|
|
71
|
+
|
|
72
|
+
jni::global_ref<jobject> globalRef = jni::make_global(value);
|
|
73
|
+
std::shared_ptr<expo::ObjectDeallocator> deallocator = std::make_shared<ObjectDeallocator>(
|
|
74
|
+
[globalRef = std::move(globalRef)]() mutable {
|
|
75
|
+
globalRef.reset();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
auto descriptor = JavaScriptObject::preparePropertyDescriptor(rt, 0);
|
|
79
|
+
descriptor.setProperty(rt, "value", jsi::Object::createFromHostObject(rt, deallocator));
|
|
80
|
+
JavaScriptObject::defineProperty(rt, jsiObject.get(), "__expo_object_deallocator__",
|
|
81
|
+
std::move(descriptor));
|
|
82
|
+
|
|
83
|
+
return jsi::Value(rt, *jsiObject);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return jsi::Value::undefined();
|
|
87
|
+
}
|
|
88
|
+
} // namespace expo
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Copyright © 2021-present 650 Industries, Inc. (aka Expo)
|
|
2
|
+
|
|
3
|
+
#pragma once
|
|
4
|
+
|
|
5
|
+
#include "../JSIInteropModuleRegistry.h"
|
|
6
|
+
|
|
7
|
+
#include <fbjni/fbjni.h>
|
|
8
|
+
#include <jsi/jsi.h>
|
|
9
|
+
|
|
10
|
+
namespace jni = facebook::jni;
|
|
11
|
+
namespace jsi = facebook::jsi;
|
|
12
|
+
|
|
13
|
+
namespace expo {
|
|
14
|
+
|
|
15
|
+
jsi::Value convert(
|
|
16
|
+
JSIInteropModuleRegistry *moduleRegistry,
|
|
17
|
+
JNIEnv *env,
|
|
18
|
+
jsi::Runtime &rt,
|
|
19
|
+
jni::local_ref<jobject> value
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
} // namespace expo
|
|
@@ -6,7 +6,6 @@ import android.content.Intent
|
|
|
6
6
|
import android.os.Handler
|
|
7
7
|
import android.os.HandlerThread
|
|
8
8
|
import android.view.View
|
|
9
|
-
import androidx.annotation.MainThread
|
|
10
9
|
import androidx.annotation.UiThread
|
|
11
10
|
import androidx.appcompat.app.AppCompatActivity
|
|
12
11
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
@@ -28,10 +27,7 @@ import expo.modules.interfaces.permissions.Permissions
|
|
|
28
27
|
import expo.modules.interfaces.sensors.SensorServiceInterface
|
|
29
28
|
import expo.modules.interfaces.taskManager.TaskManagerInterface
|
|
30
29
|
import expo.modules.kotlin.activityresult.ActivityResultsManager
|
|
31
|
-
import expo.modules.kotlin.activityresult.
|
|
32
|
-
import expo.modules.kotlin.activityresult.AppContextActivityResultContract
|
|
33
|
-
import expo.modules.kotlin.activityresult.AppContextActivityResultFallbackCallback
|
|
34
|
-
import expo.modules.kotlin.activityresult.AppContextActivityResultLauncher
|
|
30
|
+
import expo.modules.kotlin.activityresult.DefaultAppContextActivityResultCaller
|
|
35
31
|
import expo.modules.kotlin.defaultmodules.ErrorManagerModule
|
|
36
32
|
import expo.modules.kotlin.defaultmodules.NativeModulesProxyModule
|
|
37
33
|
import expo.modules.kotlin.events.EventEmitter
|
|
@@ -39,9 +35,11 @@ import expo.modules.kotlin.events.EventName
|
|
|
39
35
|
import expo.modules.kotlin.events.KEventEmitterWrapper
|
|
40
36
|
import expo.modules.kotlin.events.KModuleEventEmitterWrapper
|
|
41
37
|
import expo.modules.kotlin.events.OnActivityResultPayload
|
|
38
|
+
import expo.modules.kotlin.jni.JNIDeallocator
|
|
42
39
|
import expo.modules.kotlin.jni.JSIInteropModuleRegistry
|
|
43
40
|
import expo.modules.kotlin.modules.Module
|
|
44
41
|
import expo.modules.kotlin.providers.CurrentActivityProvider
|
|
42
|
+
import expo.modules.kotlin.sharedobjects.SharedObjectRegistry
|
|
45
43
|
import kotlinx.coroutines.CoroutineName
|
|
46
44
|
import kotlinx.coroutines.CoroutineScope
|
|
47
45
|
import kotlinx.coroutines.Dispatchers
|
|
@@ -49,25 +47,35 @@ import kotlinx.coroutines.SupervisorJob
|
|
|
49
47
|
import kotlinx.coroutines.android.asCoroutineDispatcher
|
|
50
48
|
import kotlinx.coroutines.cancel
|
|
51
49
|
import java.io.File
|
|
52
|
-
import java.io.Serializable
|
|
53
50
|
import java.lang.ref.WeakReference
|
|
54
51
|
|
|
55
52
|
class AppContext(
|
|
56
53
|
modulesProvider: ModulesProvider,
|
|
57
54
|
val legacyModuleRegistry: expo.modules.core.ModuleRegistry,
|
|
58
55
|
private val reactContextHolder: WeakReference<ReactApplicationContext>
|
|
59
|
-
) : CurrentActivityProvider
|
|
56
|
+
) : CurrentActivityProvider {
|
|
60
57
|
val registry = ModuleRegistry(WeakReference(this))
|
|
61
58
|
private val reactLifecycleDelegate = ReactLifecycleDelegate(this)
|
|
62
59
|
|
|
63
60
|
// We postpone creating the `JSIInteropModuleRegistry` to not load so files in unit tests.
|
|
64
61
|
private lateinit var jsiInterop: JSIInteropModuleRegistry
|
|
65
62
|
|
|
63
|
+
internal val sharedObjectRegistry = SharedObjectRegistry()
|
|
64
|
+
|
|
66
65
|
private val modulesQueueDispatcher = HandlerThread("expo.modules.AsyncFunctionQueue")
|
|
67
66
|
.apply { start() }
|
|
68
67
|
.looper.let { Handler(it) }
|
|
69
68
|
.asCoroutineDispatcher()
|
|
70
69
|
|
|
70
|
+
/**
|
|
71
|
+
* A scope used to dispatch all background work.
|
|
72
|
+
*/
|
|
73
|
+
val backgroundCoroutineScope = CoroutineScope(
|
|
74
|
+
Dispatchers.IO +
|
|
75
|
+
SupervisorJob() +
|
|
76
|
+
CoroutineName("expo.modules.BackgroundCoroutineScope")
|
|
77
|
+
)
|
|
78
|
+
|
|
71
79
|
/**
|
|
72
80
|
* A queue used to dispatch all async methods that are called via JSI.
|
|
73
81
|
*/
|
|
@@ -86,6 +94,7 @@ class AppContext(
|
|
|
86
94
|
internal var legacyModulesProxyHolder: WeakReference<NativeModulesProxy>? = null
|
|
87
95
|
|
|
88
96
|
private val activityResultsManager = ActivityResultsManager(this)
|
|
97
|
+
internal val appContextActivityResultCaller = DefaultAppContextActivityResultCaller(activityResultsManager)
|
|
89
98
|
|
|
90
99
|
init {
|
|
91
100
|
requireNotNull(reactContextHolder.get()) {
|
|
@@ -265,6 +274,8 @@ class AppContext(
|
|
|
265
274
|
registry.cleanUp()
|
|
266
275
|
modulesQueue.cancel(ContextDestroyedException())
|
|
267
276
|
mainQueue.cancel(ContextDestroyedException())
|
|
277
|
+
backgroundCoroutineScope.cancel(ContextDestroyedException())
|
|
278
|
+
JNIDeallocator.deallocate()
|
|
268
279
|
logger.info("✅ AppContext was destroyed")
|
|
269
280
|
}
|
|
270
281
|
|
|
@@ -334,23 +345,5 @@ class AppContext(
|
|
|
334
345
|
return activityProvider?.currentActivity
|
|
335
346
|
}
|
|
336
347
|
|
|
337
|
-
// endregion
|
|
338
|
-
|
|
339
|
-
// region AppContextActivityResultCaller
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* For the time being [fallbackCallback] is not working.
|
|
343
|
-
* There are some problems with saving and restoring the state of [activityResultsManager]
|
|
344
|
-
* connected with [Activity]'s lifecycle and [AppContext] lifespan. So far, we've failed with identifying
|
|
345
|
-
* what parts of the application outlives the Activity destruction (especially [AppContext] and other [Bridge]-related parts).
|
|
346
|
-
*/
|
|
347
|
-
@MainThread
|
|
348
|
-
@Deprecated(message = "`registerForActivityResult` was deprecated. Please use `RegisterActivityContracts` component instead.")
|
|
349
|
-
override suspend fun <I : Serializable, O> registerForActivityResult(
|
|
350
|
-
contract: AppContextActivityResultContract<I, O>,
|
|
351
|
-
fallbackCallback: AppContextActivityResultFallbackCallback<I, O>
|
|
352
|
-
): AppContextActivityResultLauncher<I, O> =
|
|
353
|
-
activityResultsManager.registerForActivityResult(contract, fallbackCallback)
|
|
354
|
-
|
|
355
348
|
// endregion
|
|
356
349
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
package expo.modules.kotlin
|
|
2
|
+
|
|
3
|
+
fun interface Filter<T> {
|
|
4
|
+
fun apply(type: T): Boolean
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
class FilteredIterator<E>(
|
|
8
|
+
private val iterator: Iterator<E>,
|
|
9
|
+
private val filter: Filter<E>
|
|
10
|
+
) : Iterator<E> {
|
|
11
|
+
private var next: E? = null
|
|
12
|
+
|
|
13
|
+
init {
|
|
14
|
+
this.findNext()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override fun hasNext(): Boolean {
|
|
18
|
+
return next != null
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
override fun next(): E {
|
|
22
|
+
val returnValue = next!!
|
|
23
|
+
this.findNext()
|
|
24
|
+
return returnValue
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private fun findNext() {
|
|
28
|
+
while (iterator.hasNext()) {
|
|
29
|
+
val next = iterator.next()
|
|
30
|
+
this.next = next
|
|
31
|
+
if (filter.apply(next)) {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
next = null
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -22,7 +22,7 @@ class KotlinInteropModuleRegistry(
|
|
|
22
22
|
legacyModuleRegistry: expo.modules.core.ModuleRegistry,
|
|
23
23
|
reactContext: WeakReference<ReactApplicationContext>
|
|
24
24
|
) {
|
|
25
|
-
|
|
25
|
+
val appContext = AppContext(modulesProvider, legacyModuleRegistry, reactContext)
|
|
26
26
|
|
|
27
27
|
private val registry: ModuleRegistry
|
|
28
28
|
get() = appContext.registry
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
package expo.modules.kotlin
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import android.view.View
|
|
4
4
|
import com.facebook.react.bridge.ReadableArray
|
|
5
5
|
import expo.modules.kotlin.events.BasicEventListener
|
|
6
6
|
import expo.modules.kotlin.events.EventListenerWithPayload
|
|
@@ -12,6 +12,7 @@ import expo.modules.kotlin.exception.exceptionDecorator
|
|
|
12
12
|
import expo.modules.kotlin.jni.JavaScriptModuleObject
|
|
13
13
|
import expo.modules.kotlin.modules.Module
|
|
14
14
|
import kotlinx.coroutines.launch
|
|
15
|
+
import kotlin.reflect.KClass
|
|
15
16
|
|
|
16
17
|
class ModuleHolder(val module: Module) {
|
|
17
18
|
val definition = module.definition()
|
|
@@ -22,24 +23,36 @@ class ModuleHolder(val module: Module) {
|
|
|
22
23
|
* Cached instance of HybridObject used by CPP to interact with underlying [expo.modules.kotlin.modules.Module] object.
|
|
23
24
|
*/
|
|
24
25
|
val jsObject by lazy {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
.properties
|
|
39
|
-
.forEach { (_, prop) ->
|
|
40
|
-
prop.attachToJSObject(this)
|
|
41
|
-
}
|
|
26
|
+
val appContext = module.appContext
|
|
27
|
+
|
|
28
|
+
JavaScriptModuleObject(name).apply {
|
|
29
|
+
initUsingObjectDefinition(appContext, definition.objectDefinition)
|
|
30
|
+
|
|
31
|
+
val viewFunctions = definition.viewManagerDefinition?.asyncFunctions
|
|
32
|
+
if (viewFunctions?.isNotEmpty() == true) {
|
|
33
|
+
val viewPrototype = JavaScriptModuleObject("${name}_${definition.viewManagerDefinition?.viewType?.name}")
|
|
34
|
+
viewFunctions.forEach { function ->
|
|
35
|
+
function.attachToJSObject(appContext, viewPrototype)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
registerViewPrototype(viewPrototype)
|
|
42
39
|
}
|
|
40
|
+
|
|
41
|
+
definition.classData.forEach { clazz ->
|
|
42
|
+
val clazzModuleObject = JavaScriptModuleObject(clazz.name)
|
|
43
|
+
.initUsingObjectDefinition(module.appContext, clazz.objectDefinition)
|
|
44
|
+
|
|
45
|
+
val constructor = clazz.constructor
|
|
46
|
+
registerClass(
|
|
47
|
+
clazz.name,
|
|
48
|
+
clazzModuleObject,
|
|
49
|
+
constructor.takesOwner,
|
|
50
|
+
constructor.argsCount,
|
|
51
|
+
constructor.getCppRequiredTypes().toTypedArray(),
|
|
52
|
+
constructor.getJNIFunctionBody(clazz.name, appContext)
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
/**
|
|
@@ -85,12 +98,12 @@ class ModuleHolder(val module: Module) {
|
|
|
85
98
|
fun registerContracts() {
|
|
86
99
|
definition.registerContracts?.let {
|
|
87
100
|
module.appContext.mainQueue.launch {
|
|
88
|
-
it.invoke(module.appContext)
|
|
101
|
+
it.invoke(module.appContext.appContextActivityResultCaller)
|
|
89
102
|
}
|
|
90
103
|
}
|
|
91
104
|
}
|
|
92
105
|
|
|
93
|
-
fun
|
|
94
|
-
|
|
106
|
+
fun viewClass(): KClass<out View>? {
|
|
107
|
+
return definition.viewManagerDefinition?.viewType?.kotlin
|
|
95
108
|
}
|
|
96
109
|
}
|
|
@@ -6,7 +6,9 @@ import kotlinx.coroutines.CoroutineName
|
|
|
6
6
|
import kotlinx.coroutines.CoroutineScope
|
|
7
7
|
import kotlinx.coroutines.Dispatchers
|
|
8
8
|
import kotlinx.coroutines.SupervisorJob
|
|
9
|
+
import kotlinx.coroutines.launch
|
|
9
10
|
import java.lang.ref.WeakReference
|
|
11
|
+
import kotlin.reflect.full.declaredMemberProperties
|
|
10
12
|
|
|
11
13
|
class ModuleRegistry(
|
|
12
14
|
private val appContext: WeakReference<AppContext>
|
|
@@ -26,6 +28,17 @@ class ModuleRegistry(
|
|
|
26
28
|
}
|
|
27
29
|
holder.post(EventName.MODULE_CREATE)
|
|
28
30
|
holder.registerContracts()
|
|
31
|
+
// The initial invocation of `declaredMemberProperties` appears to be slow,
|
|
32
|
+
// as Kotlin must deserialize metadata internally.
|
|
33
|
+
// This is a known issue that may be resolved by the new K2 compiler in the future.
|
|
34
|
+
// However, until then, we must find a way to address this problem.
|
|
35
|
+
// Therefore, we have decided to dispatch a lambda
|
|
36
|
+
// that invokes `declaredMemberProperties` during module creation.
|
|
37
|
+
holder.viewClass()?.let { viewType ->
|
|
38
|
+
appContext.get()?.backgroundCoroutineScope?.launch {
|
|
39
|
+
viewType.declaredMemberProperties
|
|
40
|
+
}
|
|
41
|
+
}
|
|
29
42
|
registry[holder.name] = holder
|
|
30
43
|
}
|
|
31
44
|
|
|
@@ -72,9 +85,6 @@ class ModuleRegistry(
|
|
|
72
85
|
override fun iterator(): Iterator<ModuleHolder> = registry.values.iterator()
|
|
73
86
|
|
|
74
87
|
fun cleanUp() {
|
|
75
|
-
forEach {
|
|
76
|
-
it.cleanUp()
|
|
77
|
-
}
|
|
78
88
|
registry.clear()
|
|
79
89
|
logger.info("✅ ModuleRegistry was destroyed")
|
|
80
90
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
package expo.modules.kotlin
|
|
2
|
+
|
|
3
|
+
import android.os.Looper
|
|
4
|
+
import expo.modules.kotlin.exception.Exceptions
|
|
5
|
+
|
|
6
|
+
object Utils {
|
|
7
|
+
@Suppress("UseExpressionBody")
|
|
8
|
+
inline fun assertMainThread() {
|
|
9
|
+
if (Thread.currentThread() !== Looper.getMainLooper().thread) {
|
|
10
|
+
throw Exceptions.IncorrectThreadException(
|
|
11
|
+
Thread.currentThread().name,
|
|
12
|
+
Looper.getMainLooper().thread.name
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@Suppress("NOTHING_TO_INLINE")
|
|
19
|
+
inline fun AppContext?.toStrongReference(): AppContext {
|
|
20
|
+
return this ?: throw Exceptions.AppContextLost()
|
|
21
|
+
}
|
package/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultCaller.kt
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package expo.modules.kotlin.activityresult
|
|
2
2
|
|
|
3
|
+
import android.app.Activity
|
|
3
4
|
import androidx.annotation.MainThread
|
|
5
|
+
import expo.modules.kotlin.AppContext
|
|
4
6
|
import java.io.Serializable
|
|
5
7
|
|
|
6
8
|
/**
|
|
@@ -20,6 +22,24 @@ interface AppContextActivityResultCaller {
|
|
|
20
22
|
@MainThread
|
|
21
23
|
suspend fun <I : Serializable, O> registerForActivityResult(
|
|
22
24
|
contract: AppContextActivityResultContract<I, O>,
|
|
23
|
-
fallbackCallback: AppContextActivityResultFallbackCallback<I, O
|
|
25
|
+
fallbackCallback: AppContextActivityResultFallbackCallback<I, O> = AppContextActivityResultFallbackCallback { _, _ -> /* NOOP */ },
|
|
24
26
|
): AppContextActivityResultLauncher<I, O>
|
|
25
27
|
}
|
|
28
|
+
|
|
29
|
+
internal class DefaultAppContextActivityResultCaller(
|
|
30
|
+
private val activityResultsManager: ActivityResultsManager
|
|
31
|
+
) : AppContextActivityResultCaller {
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* For the time being [fallbackCallback] is not working.
|
|
35
|
+
* There are some problems with saving and restoring the state of [activityResultsManager]
|
|
36
|
+
* connected with [Activity]'s lifecycle and [AppContext] lifespan. So far, we've failed with identifying
|
|
37
|
+
* what parts of the application outlives the Activity destruction (especially [AppContext] and other [Bridge]-related parts).
|
|
38
|
+
*/
|
|
39
|
+
override suspend fun <I : Serializable, O> registerForActivityResult(
|
|
40
|
+
contract: AppContextActivityResultContract<I, O>,
|
|
41
|
+
fallbackCallback: AppContextActivityResultFallbackCallback<I, O>
|
|
42
|
+
): AppContextActivityResultLauncher<I, O> {
|
|
43
|
+
return activityResultsManager.registerForActivityResult(contract, fallbackCallback)
|
|
44
|
+
}
|
|
45
|
+
}
|