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 bool hasModule(const std::string &moduleName) const; 60 61 /** 62 * Gets names of all available modules. 63 */ 64 jni::local_ref<jni::JArrayClass<jni::JString>> getModulesName() const; 65 66 /** 67 * Exposes a `JavaScriptRuntime::evaluateScript` function to Kotlin 68 */ 69 jni::local_ref<JavaScriptValue::javaobject> evaluateScript(jni::JString script); 70 71 /** 72 * Exposes a `JavaScriptRuntime::global` function to Kotlin 73 */ 74 jni::local_ref<JavaScriptObject::javaobject> global(); 75 76 /** 77 * Exposes a `JavaScriptRuntime::createObject` function to Kotlin 78 */ 79 jni::local_ref<JavaScriptObject::javaobject> createObject(); 80 81 /** 82 * Exposes a `JavaScriptRuntime::drainJSEventLoop` function to Kotlin 83 */ 84 void drainJSEventLoop(); 85 86 std::shared_ptr<react::CallInvoker> jsInvoker; 87 std::shared_ptr<react::CallInvoker> nativeInvoker; 88 std::shared_ptr<JavaScriptRuntime> runtimeHolder; 89 std::unique_ptr<JSReferencesCache> jsRegistry; 90 private: 91 friend HybridBase; 92 jni::global_ref<JSIInteropModuleRegistry::javaobject> javaPart_; 93 94 explicit JSIInteropModuleRegistry(jni::alias_ref<jhybridobject> jThis); 95 96 inline jni::local_ref<JavaScriptModuleObject::javaobject> 97 callGetJavaScriptModuleObjectMethod(const std::string &moduleName) const; 98 99 inline jni::local_ref<jni::JArrayClass<jni::JString>> callGetJavaScriptModulesNames() const; 100 101 inline bool callHasModule(const std::string &moduleName) const; 102 }; 103 } // namespace expo 104