From ef4955fefe3483d299b01a7ce1abdc9b7fa9ee54 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Fri, 3 May 2019 13:25:56 -0700 Subject: [PATCH] Make async calls work Summary: JSCallInvoker requires a `std::weak_ptr` to create. In our C++, `CatalystInstance` is responsible for creating this `Instance` object. This `CatalystInstance` C++ initialization is separate from the `TurboModuleManager` C++ initialization. Therefore, in this diff, I made `CatalystInstance` responsible for creating the `JSCallInvoker`. It then exposes the `JSCallInvoker` using a hybrid class called `JSCallInvokerHolder`, which contains a `std::shared_ptr` member variable. Using `CatalystInstance.getJSCallInvokerHolder()` in TurboModuleManager.java, we get a handle to this hybrid container. Then, we pass it this hybrid object to `TurboModuleManager::initHybrid`, which retrieves the `std::shared_ptr` from the `JavaJSCallInvokerHandler`. There were a few cyclic dependencies, so I had to break down the buck targets: - `CatalystInstanceImpl.java` depends on `JSCallInvokerHolderImpl.java`, and `TurboModuleManager.java` depends on classes that are packaged with `CatalystInstanceImpl.java`. So, I had to put `JSCallInvokerHolderImpl.java` in its own buck target. - `CatalystInstance.cpp` depends on `JavaJSCallInvokerHolder.cpp`, and `TurboModuleManager.cpp` depends on classes that are build with `CatalystInstance.cpp`. So, I had to put `JavaJSCallInvokerHolder.cpp` in its own buck target. To make things simpler, I also moved `JSCallInvoker.{cpp,h}` files into the same buck target as `JavaJSCallInvokerHolder.{cpp,h}`. I think these steps should be enough to create the TurboModuleManager without needing a bridge: 1. Make `JSCallInvoker` an abstract base class. 2. On Android, create another derived class of `JSCallInvoker` that doesn't depend on Instance. 3. Create `JavaJSCallInvokerHolder` using an instance of this new class somewhere in C++. 4. Pass this instance of `JavaJSCallInvokerHolder` to Java and use it to create/instatiate `TurboModuleManager`. Regarding steps 1 and 2, we can also make JSCallInvoker accept a lambda. Reviewed By: mdvacca Differential Revision: D15055511 fbshipit-source-id: 0ad72a86599819ec35d421dbee7e140959a26ab6 --- .../main/java/com/facebook/react/bridge/BUCK | 1 + .../react/bridge/CatalystInstance.java | 7 ++ .../react/bridge/CatalystInstanceImpl.java | 2 + .../com/facebook/react/turbomodule/core/BUCK | 16 +++++ .../core/JSCallInvokerHolderImpl.java | 30 +++++++++ .../turbomodule/core/TurboModuleManager.java | 11 ++-- .../react/turbomodule/core/interfaces/BUCK | 6 +- .../core/interfaces/JSCallInvokerHolder.java | 21 ++++++ .../facebook/react/turbomodule/core/jni/BUCK | 66 ++++++++++++++++--- .../core/jni/JSCallInvokerHolder.cpp | 17 +++++ .../core/jni/JSCallInvokerHolder.h | 33 ++++++++++ .../core/jni/TurboModuleManager.cpp | 19 +++--- .../turbomodule/core/jni/TurboModuleManager.h | 9 +-- ReactAndroid/src/main/jni/react/jni/BUCK | 3 +- .../jni/react/jni/CatalystInstanceImpl.cpp | 11 ++++ .../main/jni/react/jni/CatalystInstanceImpl.h | 4 ++ ReactCommon/jscallinvoker/BUCK | 36 ++++++++++ .../core => jscallinvoker}/JSCallInvoker.cpp | 7 +- .../core => jscallinvoker}/JSCallInvoker.h | 0 ReactCommon/turbomodule/core/BUCK | 5 +- ReactCommon/turbomodule/core/TurboModule.h | 2 +- .../turbomodule/core/TurboModuleUtils.h | 2 +- 22 files changed, 266 insertions(+), 42 deletions(-) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/JSCallInvokerHolderImpl.java create mode 100644 ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/JSCallInvokerHolder.java create mode 100644 ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/JSCallInvokerHolder.cpp create mode 100644 ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/JSCallInvokerHolder.h create mode 100644 ReactCommon/jscallinvoker/BUCK rename ReactCommon/{turbomodule/core => jscallinvoker}/JSCallInvoker.cpp (78%) rename ReactCommon/{turbomodule/core => jscallinvoker}/JSCallInvoker.h (100%) diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK b/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK index 5efe29273..154c36303 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK @@ -47,6 +47,7 @@ rn_android_library( react_native_target("java/com/facebook/react/uimanager/common:common"), react_native_target("java/com/facebook/react/module/annotations:annotations"), react_native_target("java/com/facebook/react/turbomodule/core/interfaces:interfaces"), + react_native_target("java/com/facebook/react/turbomodule/core:jscallinvokerholder"), ] + ([react_native_target("jni/react/jni:jni")] if not IS_OSS_BUILD else []), exported_deps = [ react_native_dep("java/com/facebook/jni:jni"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java index aba8879f6..c7b6ced62 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java @@ -10,6 +10,7 @@ package com.facebook.react.bridge; import com.facebook.proguard.annotations.DoNotStrip; import com.facebook.react.bridge.queue.ReactQueueConfiguration; import com.facebook.react.common.annotations.VisibleForTesting; +import com.facebook.react.turbomodule.core.interfaces.JSCallInvokerHolder; import java.util.Collection; import java.util.List; import javax.annotation.Nullable; @@ -103,4 +104,10 @@ public interface CatalystInstance JavaScriptContextHolder getJavaScriptContextHolder(); void addJSIModules(List jsiModules); + + /** + * Returns a hybrid object that contains a pointer to JSCallInvoker. + * Required for TurboModuleManager initialization. + */ + JSCallInvokerHolder getJSCallInvokerHolder(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java index d1aff6c8b..b2325fdcb 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java @@ -24,6 +24,7 @@ import com.facebook.react.bridge.queue.ReactQueueConfigurationSpec; import com.facebook.react.common.ReactConstants; import com.facebook.react.common.annotations.VisibleForTesting; import com.facebook.react.module.annotations.ReactModule; +import com.facebook.react.turbomodule.core.JSCallInvokerHolderImpl; import com.facebook.systrace.Systrace; import com.facebook.systrace.TraceListener; import java.lang.annotation.Annotation; @@ -99,6 +100,7 @@ public class CatalystInstanceImpl implements CatalystInstance { // C++ parts private final HybridData mHybridData; private native static HybridData initHybrid(); + public native JSCallInvokerHolderImpl getJSCallInvokerHolder(); private CatalystInstanceImpl( final ReactQueueConfigurationSpec reactQueueConfigurationSpec, diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK index 08483b1c1..75450c476 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK @@ -6,6 +6,7 @@ rn_android_library( [ "*.java", ], + exclude = ["JSCallInvokerHolderImpl.java"], ), required_for_source_only_abi = True, visibility = [ @@ -21,5 +22,20 @@ rn_android_library( react_native_target("java/com/facebook/debug/holder:holder"), react_native_target("java/com/facebook/react/bridge:interfaces"), react_native_target("java/com/facebook/react/bridge:bridge"), + ":jscallinvokerholder", + ], +) + +rn_android_library( + name = "jscallinvokerholder", + srcs = ["JSCallInvokerHolderImpl.java"], + required_for_source_only_abi = True, + visibility = [ + "PUBLIC", + ], + deps = [ + react_native_dep("libraries/soloader/java/com/facebook/soloader:soloader"), + react_native_target("java/com/facebook/react/turbomodule/core/interfaces:interfaces"), + react_native_dep("libraries/fbjni:java"), ], ) diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/JSCallInvokerHolderImpl.java b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/JSCallInvokerHolderImpl.java new file mode 100644 index 000000000..e5f0ed587 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/JSCallInvokerHolderImpl.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.turbomodule.core; + +import com.facebook.jni.HybridData; +import com.facebook.soloader.SoLoader; +import com.facebook.react.turbomodule.core.interfaces.JSCallInvokerHolder; + +/** + * JSCallInvoker is created at a different time/place (i.e: in CatalystInstance) + * than TurboModuleManager. Therefore, we need to wrap JSCallInvoker + * within a hybrid class so that we may pass it from CatalystInstance, through + * Java, to TurboMoudleManager::initHybrid. + */ +public class JSCallInvokerHolderImpl implements JSCallInvokerHolder { + static { + SoLoader.loadLibrary("turbomodulejsijni"); + } + + private final HybridData mHybridData; + + private JSCallInvokerHolderImpl(HybridData hd) { + mHybridData = hd; + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java index aa9029dd1..77a1c21bc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java @@ -36,12 +36,11 @@ public class TurboModuleManager implements JSIModule { public TurboModuleManager( ReactApplicationContext reactApplicationContext, JavaScriptContextHolder jsContext, ModuleProvider moduleProvider) { mReactApplicationContext = reactApplicationContext; - MessageQueueThread jsMessageQueueThread = - mReactApplicationContext + JSCallInvokerHolderImpl instanceHolder = + (JSCallInvokerHolderImpl) mReactApplicationContext .getCatalystInstance() - .getReactQueueConfiguration() - .getJSQueueThread(); - mHybridData = initHybrid(jsContext.get(), jsMessageQueueThread); + .getJSCallInvokerHolder(); + mHybridData = initHybrid(jsContext.get(), instanceHolder); mModuleProvider = moduleProvider; } @@ -51,7 +50,7 @@ public class TurboModuleManager implements JSIModule { return mModuleProvider.getModule(name, mReactApplicationContext); } - protected native HybridData initHybrid(long jsContext, MessageQueueThread jsQueue); + protected native HybridData initHybrid(long jsContext, JSCallInvokerHolderImpl jsQueue); protected native void installJSIBindings(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/BUCK b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/BUCK index 26200c1fe..d18e484bf 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/BUCK @@ -2,9 +2,9 @@ load("//tools/build_defs/oss:rn_defs.bzl", "rn_android_library") rn_android_library( name = "interfaces", - srcs = [ - "TurboModule.java", - ], + srcs = glob( + ["*.java"], + ), required_for_source_only_abi = True, visibility = [ "PUBLIC", diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/JSCallInvokerHolder.java b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/JSCallInvokerHolder.java new file mode 100644 index 000000000..beba6d77a --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/JSCallInvokerHolder.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.turbomodule.core.interfaces; + +/** + * JSCallInvoker is created by CatalystInstance.cpp, but used by + * TurboModuleManager.cpp. Both C++ classes are instantiated at different + * times/places. Therefore, to pass the JSCallInvoker instance from + * CatalystInstance to TurboModuleManager, we make it take a trip through + * Java. + * + * This interface represents the opaque Java object that contains a pointer to + * and instance of JSCallInvoker. + */ +public interface JSCallInvokerHolder { +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/BUCK b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/BUCK index aab5a3f42..d6ad08ba8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/BUCK @@ -1,24 +1,34 @@ -load("@fbsource//tools/build_defs:glob_defs.bzl", "subdir_glob") -load("@fbsource//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "react_native_target", "react_native_xplat_target", "rn_xplat_cxx_library") +load("@fbsource//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "FBJNI_TARGET", "react_native_target", "react_native_xplat_target", "rn_xplat_cxx_library") rn_xplat_cxx_library( name = "jni", - srcs = glob(["**/*.cpp"]), + platforms = ANDROID, + preferred_linkage = "static", + visibility = [ + "PUBLIC", + ], + exported_deps = [ + ":turbomodulemanager", + ], +) + +rn_xplat_cxx_library( + name = "turbomodulemanager", + srcs = [ + "TurboModuleManager.cpp", + ], header_namespace = "", - exported_headers = subdir_glob( - [ - ("", "**/*.h"), - ], - prefix = "jsireact", - ), + exported_headers = { + "jsireact/TurboModuleManager.h": "TurboModuleManager.h", + }, compiler_flags = [ "-fexceptions", "-frtti", "-std=c++14", "-Wall", ], - force_static = True, platforms = ANDROID, + preferred_linkage = "static", preprocessor_flags = [ "-DLOG_TAG=\"ReactNative\"", "-DWITH_FBSYSTRACE=1", @@ -30,6 +40,7 @@ rn_xplat_cxx_library( react_native_target("jni/react/jni:jni"), "fbsource//xplat/jsi:JSIDynamic", "fbsource//xplat/jsi:jsi", + ":jscallinvokerholder", ], exported_deps = [ "fbsource//xplat/jsi:jsi", @@ -37,3 +48,38 @@ rn_xplat_cxx_library( react_native_xplat_target("turbomodule/core:core"), ], ) + +rn_xplat_cxx_library( + name = "jscallinvokerholder", + srcs = [ + "JSCallInvokerHolder.cpp", + ], + header_namespace = "", + exported_headers = { + "jsireact/JSCallInvokerHolder.h": "JSCallInvokerHolder.h", + }, + compiler_flags = [ + "-fexceptions", + "-frtti", + "-std=c++14", + "-Wall", + ], + fbandroid_deps = [ + FBJNI_TARGET, + ], + platforms = ANDROID, + preferred_linkage = "static", + preprocessor_flags = [ + "-DLOG_TAG=\"ReactNative\"", + "-DWITH_FBSYSTRACE=1", + ], + visibility = [ + "PUBLIC", + ], + deps = [ + react_native_xplat_target("cxxreact:bridge"), + ], + exported_deps = [ + react_native_xplat_target("jscallinvoker:jscallinvoker"), + ], +) diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/JSCallInvokerHolder.cpp b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/JSCallInvokerHolder.cpp new file mode 100644 index 000000000..b23912b5a --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/JSCallInvokerHolder.cpp @@ -0,0 +1,17 @@ +#include "JSCallInvokerHolder.h" + +namespace facebook { +namespace react { + +JSCallInvokerHolder::JSCallInvokerHolder( + std::shared_ptr jsCallInvoker) + : _jsCallInvoker(jsCallInvoker) {} + +std::shared_ptr JSCallInvokerHolder::getJSCallInvoker() { + return _jsCallInvoker; +} + +void JSCallInvokerHolder::registerNatives() {} + +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/JSCallInvokerHolder.h b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/JSCallInvokerHolder.h new file mode 100644 index 000000000..8886af04d --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/JSCallInvokerHolder.h @@ -0,0 +1,33 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace facebook { +namespace react { + +class JSCallInvokerHolder + : public jni::HybridClass { + public: + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/turbomodule/core/JSCallInvokerHolderImpl;"; + + static void registerNatives(); + std::shared_ptr getJSCallInvoker(); + + private: + friend HybridBase; + JSCallInvokerHolder(std::shared_ptr jsCallInvoker); + std::shared_ptr _jsCallInvoker; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/TurboModuleManager.cpp b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/TurboModuleManager.cpp index 7fbf35eb8..ca9844826 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/TurboModuleManager.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/TurboModuleManager.cpp @@ -26,20 +26,21 @@ static JTurboModuleProviderFunctionType moduleProvider_ = nullptr; TurboModuleManager::TurboModuleManager( jni::alias_ref jThis, jsi::Runtime* rt, - std::shared_ptr jsMessageQueueThread + std::shared_ptr jsCallInvoker ): - javaPart_(make_global(jThis)), + javaPart_(jni::make_global(jThis)), runtime_(rt), - jsMessageQueueThread_(jsMessageQueueThread) + jsCallInvoker_(jsCallInvoker) {} jni::local_ref TurboModuleManager::initHybrid( jni::alias_ref jThis, jlong jsContext, - jni::alias_ref jsQueue + jni::alias_ref jsCallInvokerHolder ) { - auto sharedJSMessageQueueThread = std::make_shared (jsQueue); - return makeCxxInstance(jThis, (jsi::Runtime *) jsContext, sharedJSMessageQueueThread); + auto jsCallInvoker = jsCallInvokerHolder->cthis()->getJSCallInvoker(); + + return makeCxxInstance(jThis, (jsi::Runtime *) jsContext, jsCallInvoker); } void TurboModuleManager::registerNatives() { @@ -56,11 +57,7 @@ void TurboModuleManager::installJSIBindings() { TurboModuleBinding::install(*runtime_, std::make_shared( [this](const std::string &name) { const auto moduleInstance = getJavaModule(name); - // TODO: Pass in react Instance to JSCallInvoker instead. - std::shared_ptr instance = nullptr; - std::weak_ptr weakInstance = instance; - const auto jsInvoker = std::make_shared(weakInstance); - return moduleProvider_(name, moduleInstance, jsInvoker); + return moduleProvider_(name, moduleInstance, jsCallInvoker_); }) ); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/TurboModuleManager.h b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/TurboModuleManager.h index 24273ac3a..34cd1194d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/TurboModuleManager.h +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/TurboModuleManager.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace facebook { namespace react { @@ -26,7 +27,7 @@ public: static jni::local_ref initHybrid( jni::alias_ref jThis, jlong jsContext, - jni::alias_ref jsQueue + jni::alias_ref jsCallInvokerHolder ); static void registerNatives(); static void setModuleProvider(JTurboModuleProviderFunctionType moduleProvider); @@ -34,14 +35,14 @@ private: friend HybridBase; jni::global_ref javaPart_; jsi::Runtime* runtime_; - std::shared_ptr jsMessageQueueThread_; + std::shared_ptr jsCallInvoker_; jni::global_ref getJavaModule(std::string name); void installJSIBindings(); explicit TurboModuleManager( jni::alias_ref jThis, - jsi::Runtime* rt, - std::shared_ptr jsMessageQueueThread + jsi::Runtime *rt, + std::shared_ptr jsCallInvoker ); }; diff --git a/ReactAndroid/src/main/jni/react/jni/BUCK b/ReactAndroid/src/main/jni/react/jni/BUCK index 44737e393..ecf74d542 100644 --- a/ReactAndroid/src/main/jni/react/jni/BUCK +++ b/ReactAndroid/src/main/jni/react/jni/BUCK @@ -1,4 +1,4 @@ -load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "FBJNI_TARGET", "IS_OSS_BUILD", "react_native_xplat_dep", "react_native_xplat_target", "rn_xplat_cxx_library") +load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "FBJNI_TARGET", "IS_OSS_BUILD", "react_native_target", "react_native_xplat_dep", "react_native_xplat_target", "rn_xplat_cxx_library") EXPORTED_HEADERS = [ "CxxModuleWrapper.h", @@ -58,6 +58,7 @@ rn_xplat_cxx_library( "fbsource//xplat/folly:molly", "fbandroid//xplat/fbgloginit:fbgloginit", "fbsource//xplat/fbsystrace:fbsystrace", + react_native_target("java/com/facebook/react/turbomodule/core/jni:jscallinvokerholder"), react_native_xplat_target("cxxreact:bridge"), react_native_xplat_target("cxxreact:jsbigstring"), react_native_xplat_target("cxxreact:module"), diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp index db4e0aa49..486e05b56 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "CxxModuleWrapper.h" #include "JavaScriptExecutorHolder.h" @@ -111,6 +112,7 @@ void CatalystInstanceImpl::registerNatives() { makeNativeMethod("jniCallJSCallback", CatalystInstanceImpl::jniCallJSCallback), makeNativeMethod("setGlobalVariable", CatalystInstanceImpl::setGlobalVariable), makeNativeMethod("getJavaScriptContext", CatalystInstanceImpl::getJavaScriptContext), + makeNativeMethod("getJSCallInvokerHolder", CatalystInstanceImpl::getJSCallInvokerHolder), makeNativeMethod("jniHandleMemoryPressure", CatalystInstanceImpl::handleMemoryPressure), }); @@ -264,4 +266,13 @@ void CatalystInstanceImpl::handleMemoryPressure(int pressureLevel) { instance_->handleMemoryPressure(pressureLevel); } +jni::alias_ref CatalystInstanceImpl::getJSCallInvokerHolder() { + if (javaInstanceHolder_ == nullptr) { + jsCallInvoker_ = std::make_shared(instance_); + javaInstanceHolder_ = jni::make_global(JSCallInvokerHolder::newObjectCxxArgs(jsCallInvoker_)); + } + + return javaInstanceHolder_; +} + }} diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h index 005c6ac97..826d55411 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h @@ -7,6 +7,7 @@ #include #include +#include #include "CxxModuleWrapper.h" #include "JavaModuleWrapper.h" @@ -73,6 +74,7 @@ class CatalystInstanceImpl : public jni::HybridClass { void jniLoadScriptFromDeltaBundle(const std::string& sourceURL, jni::alias_ref deltaClient, bool loadSynchronously); void jniCallJSFunction(std::string module, std::string method, NativeArray* arguments); void jniCallJSCallback(jint callbackId, NativeArray* arguments); + jni::alias_ref getJSCallInvokerHolder(); void setGlobalVariable(std::string propName, std::string&& jsonValue); jlong getJavaScriptContext(); @@ -83,6 +85,8 @@ class CatalystInstanceImpl : public jni::HybridClass { std::shared_ptr instance_; std::shared_ptr moduleRegistry_; std::shared_ptr moduleMessageQueue_; + jni::global_ref javaInstanceHolder_; + std::shared_ptr jsCallInvoker_; }; }} diff --git a/ReactCommon/jscallinvoker/BUCK b/ReactCommon/jscallinvoker/BUCK new file mode 100644 index 000000000..085dbab1a --- /dev/null +++ b/ReactCommon/jscallinvoker/BUCK @@ -0,0 +1,36 @@ +load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "APPLE", "FBJNI_TARGET", "react_native_xplat_target", "rn_xplat_cxx_library", "subdir_glob") + +rn_xplat_cxx_library( + name = "jscallinvoker", + srcs = glob( + ["*.cpp"], + ), + header_namespace = "", + exported_headers = subdir_glob( + [ + ("", "*.h"), + ], + prefix = "jsireact", + ), + compiler_flags = [ + "-fexceptions", + "-frtti", + "-std=c++14", + "-Wall", + ], + fbandroid_deps = [ + FBJNI_TARGET, + ], + platforms = (ANDROID, APPLE), + preferred_linkage = "static", + preprocessor_flags = [ + "-DLOG_TAG=\"ReactNative\"", + "-DWITH_FBSYSTRACE=1", + ], + visibility = [ + "PUBLIC", + ], + deps = [ + react_native_xplat_target("cxxreact:bridge"), + ], +) diff --git a/ReactCommon/turbomodule/core/JSCallInvoker.cpp b/ReactCommon/jscallinvoker/JSCallInvoker.cpp similarity index 78% rename from ReactCommon/turbomodule/core/JSCallInvoker.cpp rename to ReactCommon/jscallinvoker/JSCallInvoker.cpp index f58adb91f..c513697d4 100644 --- a/ReactCommon/turbomodule/core/JSCallInvoker.cpp +++ b/ReactCommon/jscallinvoker/JSCallInvoker.cpp @@ -5,17 +5,16 @@ * LICENSE file in the root directory of this source tree. */ -#include "JSCallInvoker.h" - +#include #include namespace facebook { namespace react { JSCallInvoker::JSCallInvoker(std::weak_ptr reactInstance) - : reactInstance_(reactInstance) {} + : reactInstance_(reactInstance) {} -void JSCallInvoker::invokeAsync(std::function&& func) { +void JSCallInvoker::invokeAsync(std::function &&func) { auto instance = reactInstance_.lock(); if (instance == nullptr) { return; diff --git a/ReactCommon/turbomodule/core/JSCallInvoker.h b/ReactCommon/jscallinvoker/JSCallInvoker.h similarity index 100% rename from ReactCommon/turbomodule/core/JSCallInvoker.h rename to ReactCommon/jscallinvoker/JSCallInvoker.h diff --git a/ReactCommon/turbomodule/core/BUCK b/ReactCommon/turbomodule/core/BUCK index 9ed99960a..692896bf1 100644 --- a/ReactCommon/turbomodule/core/BUCK +++ b/ReactCommon/turbomodule/core/BUCK @@ -3,7 +3,9 @@ load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "APPLE", "react_native_tar rn_xplat_cxx_library( name = "core", - srcs = glob(["*.cpp"]), + srcs = glob( + ["*.cpp"], + ), header_namespace = "", exported_headers = subdir_glob( [ @@ -76,6 +78,7 @@ rn_xplat_cxx_library( "fbsource//xplat/third-party/glog:glog", react_native_xplat_target("cxxreact:bridge"), react_native_xplat_target("cxxreact:module"), + react_native_xplat_target("jscallinvoker:jscallinvoker"), ], exported_deps = [ "fbsource//xplat/jsi:jsi", diff --git a/ReactCommon/turbomodule/core/TurboModule.h b/ReactCommon/turbomodule/core/TurboModule.h index 4bb398a0c..54a39fd76 100644 --- a/ReactCommon/turbomodule/core/TurboModule.h +++ b/ReactCommon/turbomodule/core/TurboModule.h @@ -12,7 +12,7 @@ #include -#include "JSCallInvoker.h" +#include namespace facebook { namespace react { diff --git a/ReactCommon/turbomodule/core/TurboModuleUtils.h b/ReactCommon/turbomodule/core/TurboModuleUtils.h index 4a71f8e73..61615ac77 100644 --- a/ReactCommon/turbomodule/core/TurboModuleUtils.h +++ b/ReactCommon/turbomodule/core/TurboModuleUtils.h @@ -11,7 +11,7 @@ #include -#include "JSCallInvoker.h" +#include using namespace facebook;