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