1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 2 3 #pragma once 4 5 #include "JavaScriptRuntime.h" 6 #include "JavaScriptModuleObject.h" 7 #include "JavaScriptValue.h" 8 #include "JavaScriptObject.h" 9 10 #include <fbjni/fbjni.h> 11 #include <jsi/jsi.h> 12 #include <ReactCommon/CallInvokerHolder.h> 13 #include <ReactCommon/CallInvoker.h> 14 15 #include <memory> 16 17 namespace jni = facebook::jni; 18 namespace jsi = facebook::jsi; 19 namespace react = facebook::react; 20 21 namespace expo { 22 /** 23 * A JNI wrapper to initialize CPP part of modules and access all data from the module registry. 24 */ 25 class JSIInteropModuleRegistry : public jni::HybridClass<JSIInteropModuleRegistry> { 26 public: 27 static auto constexpr 28 kJavaDescriptor = "Lexpo/modules/kotlin/jni/JSIInteropModuleRegistry;"; 29 static auto constexpr TAG = "JSIInteropModuleRegistry"; 30 31 static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis); 32 33 static void registerNatives(); 34 35 /** 36 * Initializes the `ExpoModulesHostObject` and adds it to the global object. 37 */ 38 void installJSI( 39 jlong jsRuntimePointer, 40 jni::alias_ref<react::CallInvokerHolder::javaobject> jsInvokerHolder, 41 jni::alias_ref<react::CallInvokerHolder::javaobject> nativeInvokerHolder 42 ); 43 44 /** 45 * Initializes the test runtime. Shouldn't be used in the production. 46 */ 47 void installJSIForTests(); 48 49 /** 50 * Gets a module for a given name. It will throw an exception if the module doesn't exist. 51 * 52 * @param moduleName 53 * @return An instance of `JavaScriptModuleObject` 54 */ 55 jni::local_ref<JavaScriptModuleObject::javaobject> getModule(const std::string &moduleName) const; 56 57 /** 58 * Gets names of all available modules. 59 */ 60 jni::local_ref<jni::JArrayClass<jni::JString>> getModulesName() const; 61 62 /** 63 * Exposes a `JavaScriptRuntime::evaluateScript` function to Kotlin 64 */ 65 jni::local_ref<JavaScriptValue::javaobject> evaluateScript(jni::JString script); 66 67 /** 68 * Exposes a `JavaScriptRuntime::global` function to Kotlin 69 */ 70 jni::local_ref<JavaScriptObject::javaobject> global(); 71 72 /** 73 * Exposes a `JavaScriptRuntime::createObject` function to Kotlin 74 */ 75 jni::local_ref<JavaScriptObject::javaobject> createObject(); 76 77 /** 78 * Exposes a `JavaScriptRuntime::drainJSEventLoop` function to Kotlin 79 */ 80 void drainJSEventLoop(); 81 82 std::shared_ptr<react::CallInvoker> jsInvoker; 83 std::shared_ptr<react::CallInvoker> nativeInvoker; 84 std::shared_ptr<JavaScriptRuntime> runtimeHolder; 85 private: 86 friend HybridBase; 87 jni::global_ref<JSIInteropModuleRegistry::javaobject> javaPart_; 88 89 explicit JSIInteropModuleRegistry(jni::alias_ref<jhybridobject> jThis); 90 91 inline jni::local_ref<JavaScriptModuleObject::javaobject> 92 callGetJavaScriptModuleObjectMethod(const std::string &moduleName) const; 93 94 inline jni::local_ref<jni::JArrayClass<jni::JString>> callGetJavaScriptModulesNames() const; 95 }; 96 } // namespace expo 97