164f5c95fSŁukasz Kosmaty // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 264f5c95fSŁukasz Kosmaty 364f5c95fSŁukasz Kosmaty #pragma once 464f5c95fSŁukasz Kosmaty 564f5c95fSŁukasz Kosmaty #include "JavaScriptRuntime.h" 664f5c95fSŁukasz Kosmaty #include "JavaScriptModuleObject.h" 7a416e6dbSŁukasz Kosmaty #include "JavaScriptValue.h" 8a416e6dbSŁukasz Kosmaty #include "JavaScriptObject.h" 9b7d1787dSŁukasz Kosmaty #include "JavaReferencesCache.h" 10b7d1787dSŁukasz Kosmaty #include "JSReferencesCache.h" 1129e8b6f8SŁukasz Kosmaty #include "JNIDeallocator.h" 1264f5c95fSŁukasz Kosmaty 1364f5c95fSŁukasz Kosmaty #include <fbjni/fbjni.h> 1464f5c95fSŁukasz Kosmaty #include <jsi/jsi.h> 1564f5c95fSŁukasz Kosmaty #include <ReactCommon/CallInvokerHolder.h> 1664f5c95fSŁukasz Kosmaty #include <ReactCommon/CallInvoker.h> 17*db6683c6SKudo Chien #if REACT_NATIVE_TARGET_VERSION >= 73 18*db6683c6SKudo Chien #include <ReactCommon/NativeMethodCallInvokerHolder.h> 19*db6683c6SKudo Chien #endif 2064f5c95fSŁukasz Kosmaty 2164f5c95fSŁukasz Kosmaty #include <memory> 2264f5c95fSŁukasz Kosmaty 2364f5c95fSŁukasz Kosmaty namespace jni = facebook::jni; 2464f5c95fSŁukasz Kosmaty namespace jsi = facebook::jsi; 2564f5c95fSŁukasz Kosmaty namespace react = facebook::react; 2664f5c95fSŁukasz Kosmaty 2764f5c95fSŁukasz Kosmaty namespace expo { 28*db6683c6SKudo Chien 29*db6683c6SKudo Chien #if REACT_NATIVE_TARGET_VERSION >= 73 30*db6683c6SKudo Chien using NativeMethodCallInvokerHolderCompatible = react::NativeMethodCallInvokerHolder; 31*db6683c6SKudo Chien #else 32*db6683c6SKudo Chien using NativeMethodCallInvokerHolderCompatible = react::CallInvokerHolder; 33*db6683c6SKudo Chien #endif 34*db6683c6SKudo Chien 3564f5c95fSŁukasz Kosmaty /** 3664f5c95fSŁukasz Kosmaty * A JNI wrapper to initialize CPP part of modules and access all data from the module registry. 3764f5c95fSŁukasz Kosmaty */ 3864f5c95fSŁukasz Kosmaty class JSIInteropModuleRegistry : public jni::HybridClass<JSIInteropModuleRegistry> { 3964f5c95fSŁukasz Kosmaty public: 4064f5c95fSŁukasz Kosmaty static auto constexpr 4164f5c95fSŁukasz Kosmaty kJavaDescriptor = "Lexpo/modules/kotlin/jni/JSIInteropModuleRegistry;"; 4264f5c95fSŁukasz Kosmaty static auto constexpr TAG = "JSIInteropModuleRegistry"; 4364f5c95fSŁukasz Kosmaty 4464f5c95fSŁukasz Kosmaty static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis); 4564f5c95fSŁukasz Kosmaty 4664f5c95fSŁukasz Kosmaty static void registerNatives(); 4764f5c95fSŁukasz Kosmaty 4864f5c95fSŁukasz Kosmaty /** 4964f5c95fSŁukasz Kosmaty * Initializes the `ExpoModulesHostObject` and adds it to the global object. 5064f5c95fSŁukasz Kosmaty */ 5164f5c95fSŁukasz Kosmaty void installJSI( 5264f5c95fSŁukasz Kosmaty jlong jsRuntimePointer, 5329e8b6f8SŁukasz Kosmaty jni::alias_ref<JNIDeallocator::javaobject> jniDeallocator, 5464f5c95fSŁukasz Kosmaty jni::alias_ref<react::CallInvokerHolder::javaobject> jsInvokerHolder, 55*db6683c6SKudo Chien jni::alias_ref<NativeMethodCallInvokerHolderCompatible::javaobject> nativeInvokerHolder 5664f5c95fSŁukasz Kosmaty ); 5764f5c95fSŁukasz Kosmaty 5864f5c95fSŁukasz Kosmaty /** 59a416e6dbSŁukasz Kosmaty * Initializes the test runtime. Shouldn't be used in the production. 60a416e6dbSŁukasz Kosmaty */ 6129e8b6f8SŁukasz Kosmaty void installJSIForTests( 6229e8b6f8SŁukasz Kosmaty jni::alias_ref<JNIDeallocator::javaobject> jniDeallocator 6329e8b6f8SŁukasz Kosmaty ); 64a416e6dbSŁukasz Kosmaty 65a416e6dbSŁukasz Kosmaty /** 6664f5c95fSŁukasz Kosmaty * Gets a module for a given name. It will throw an exception if the module doesn't exist. 6764f5c95fSŁukasz Kosmaty * 6864f5c95fSŁukasz Kosmaty * @param moduleName 6964f5c95fSŁukasz Kosmaty * @return An instance of `JavaScriptModuleObject` 7064f5c95fSŁukasz Kosmaty */ 7164f5c95fSŁukasz Kosmaty jni::local_ref<JavaScriptModuleObject::javaobject> getModule(const std::string &moduleName) const; 7264f5c95fSŁukasz Kosmaty 73b627df43SŁukasz Kosmaty bool hasModule(const std::string &moduleName) const; 74b627df43SŁukasz Kosmaty 75a416e6dbSŁukasz Kosmaty /** 7678b3dbc7SŁukasz Kosmaty * Gets names of all available modules. 7778b3dbc7SŁukasz Kosmaty */ 7878b3dbc7SŁukasz Kosmaty jni::local_ref<jni::JArrayClass<jni::JString>> getModulesName() const; 7978b3dbc7SŁukasz Kosmaty 8078b3dbc7SŁukasz Kosmaty /** 81a416e6dbSŁukasz Kosmaty * Exposes a `JavaScriptRuntime::evaluateScript` function to Kotlin 82a416e6dbSŁukasz Kosmaty */ 83a416e6dbSŁukasz Kosmaty jni::local_ref<JavaScriptValue::javaobject> evaluateScript(jni::JString script); 84a416e6dbSŁukasz Kosmaty 85a416e6dbSŁukasz Kosmaty /** 86a416e6dbSŁukasz Kosmaty * Exposes a `JavaScriptRuntime::global` function to Kotlin 87a416e6dbSŁukasz Kosmaty */ 88a416e6dbSŁukasz Kosmaty jni::local_ref<JavaScriptObject::javaobject> global(); 89a416e6dbSŁukasz Kosmaty 90342f32d0SŁukasz Kosmaty /** 91342f32d0SŁukasz Kosmaty * Exposes a `JavaScriptRuntime::createObject` function to Kotlin 92342f32d0SŁukasz Kosmaty */ 93342f32d0SŁukasz Kosmaty jni::local_ref<JavaScriptObject::javaobject> createObject(); 94342f32d0SŁukasz Kosmaty 95a89667b6SŁukasz Kosmaty /** 96b702c83dSŁukasz Kosmaty * Gets a core module. 97b702c83dSŁukasz Kosmaty */ 98b702c83dSŁukasz Kosmaty jni::local_ref<JavaScriptModuleObject::javaobject> getCoreModule() const; 99b702c83dSŁukasz Kosmaty 100b702c83dSŁukasz Kosmaty /** 101ecb7f347SŁukasz Kosmaty * Adds a shared object to the internal registry 102ecb7f347SŁukasz Kosmaty * @param native part of the shared object 103ecb7f347SŁukasz Kosmaty * @param js part of the shared object 104ecb7f347SŁukasz Kosmaty */ 105ecb7f347SŁukasz Kosmaty void registerSharedObject( 106ecb7f347SŁukasz Kosmaty jni::local_ref<jobject> native, 107ecb7f347SŁukasz Kosmaty jni::local_ref<JavaScriptObject::javaobject> js 108ecb7f347SŁukasz Kosmaty ); 109ecb7f347SŁukasz Kosmaty 110ecb7f347SŁukasz Kosmaty /** 111a89667b6SŁukasz Kosmaty * Exposes a `JavaScriptRuntime::drainJSEventLoop` function to Kotlin 112a89667b6SŁukasz Kosmaty */ 113a89667b6SŁukasz Kosmaty void drainJSEventLoop(); 114a89667b6SŁukasz Kosmaty 11564f5c95fSŁukasz Kosmaty std::shared_ptr<react::CallInvoker> jsInvoker; 11664f5c95fSŁukasz Kosmaty std::shared_ptr<react::CallInvoker> nativeInvoker; 1176095fdc7SŁukasz Kosmaty std::shared_ptr<JavaScriptRuntime> runtimeHolder; 118b7d1787dSŁukasz Kosmaty std::unique_ptr<JSReferencesCache> jsRegistry; 11929e8b6f8SŁukasz Kosmaty jni::global_ref<JNIDeallocator::javaobject> jniDeallocator; 12064f5c95fSŁukasz Kosmaty private: 12164f5c95fSŁukasz Kosmaty friend HybridBase; 12264f5c95fSŁukasz Kosmaty jni::global_ref<JSIInteropModuleRegistry::javaobject> javaPart_; 12364f5c95fSŁukasz Kosmaty 12464f5c95fSŁukasz Kosmaty explicit JSIInteropModuleRegistry(jni::alias_ref<jhybridobject> jThis); 12564f5c95fSŁukasz Kosmaty 12664f5c95fSŁukasz Kosmaty inline jni::local_ref<JavaScriptModuleObject::javaobject> 12764f5c95fSŁukasz Kosmaty callGetJavaScriptModuleObjectMethod(const std::string &moduleName) const; 12878b3dbc7SŁukasz Kosmaty 12978b3dbc7SŁukasz Kosmaty inline jni::local_ref<jni::JArrayClass<jni::JString>> callGetJavaScriptModulesNames() const; 130b627df43SŁukasz Kosmaty 131b702c83dSŁukasz Kosmaty inline jni::local_ref<JavaScriptModuleObject::javaobject> callGetCoreModuleObject() const; 132b702c83dSŁukasz Kosmaty 133b627df43SŁukasz Kosmaty inline bool callHasModule(const std::string &moduleName) const; 13464f5c95fSŁukasz Kosmaty }; 13564f5c95fSŁukasz Kosmaty } // namespace expo 136