From 69bb46b55ee7b1830deb246af880cca703f072a5 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Fri, 31 Jan 2020 10:02:19 -0800 Subject: [PATCH] Install TM bindings on JS thread Summary: Previously, users of the TurboModuleManager system would have to `TurboModuleManager.installBindings()` themselves, which synchronously attached the `__turboModuleProxy` function on the JS `global` object. After these changes, the TurboModuleManager, when created will schedule work on the JS thread to install the global `__turboModuleProxy` function. As long as you create the TurboModuleManager before you run the bundle, we'll install the bindings before any TurboModules are accessed. Changelog: [Android][Fixed] - Install TM Bindings on JS thread Reviewed By: ejanzer Differential Revision: D19335956 fbshipit-source-id: 967ac2d3a0510392f6f0e42efe79b1a0ff6768c4 --- .../turbomodule/core/TurboModuleManager.java | 5 +- .../jni/ReactCommon/TurboModuleManager.cpp | 92 ++++++++++--------- 2 files changed, 49 insertions(+), 48 deletions(-) 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 431a82512c8..3496ba3b4d2 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 @@ -50,6 +50,7 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { (CallInvokerHolderImpl) nativeCallInvokerHolder, tmmDelegate); mTurbomoduleManagerDelegate = tmmDelegate; + installJSIBindings(); } public List getEagerInitModuleNames() { @@ -121,10 +122,6 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { private native void installJSIBindings(); - public void installBindings() { - installJSIBindings(); - } - @Override public void initialize() {} diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp index 73cfd4f994b..6131f06a9ac 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/TurboModuleManager.cpp @@ -59,67 +59,71 @@ void TurboModuleManager::registerNatives() { } void TurboModuleManager::installJSIBindings() { - if (!runtime_) { + if (!runtime_ || !jsCallInvoker_) { return; // Runtime doesn't exist when attached to Chrome debugger. } - TurboModuleBinding::install( - *runtime_, + auto turboModuleProvider = [turboModuleCache_ = std::weak_ptr(turboModuleCache_), jsCallInvoker_ = std::weak_ptr(jsCallInvoker_), nativeCallInvoker_ = std::weak_ptr(nativeCallInvoker_), delegate_ = jni::make_weak(delegate_), javaPart_ = jni::make_weak(javaPart_)]( const std::string &name) -> std::shared_ptr { - auto turboModuleCache = turboModuleCache_.lock(); - auto jsCallInvoker = jsCallInvoker_.lock(); - auto nativeCallInvoker = nativeCallInvoker_.lock(); - auto delegate = delegate_.lockLocal(); - auto javaPart = javaPart_.lockLocal(); + auto turboModuleCache = turboModuleCache_.lock(); + auto jsCallInvoker = jsCallInvoker_.lock(); + auto nativeCallInvoker = nativeCallInvoker_.lock(); + auto delegate = delegate_.lockLocal(); + auto javaPart = javaPart_.lockLocal(); - if (!turboModuleCache || !jsCallInvoker || !nativeCallInvoker || - !delegate || !javaPart) { - return nullptr; - } + if (!turboModuleCache || !jsCallInvoker || !nativeCallInvoker || + !delegate || !javaPart) { + return nullptr; + } - auto turboModuleLookup = turboModuleCache->find(name); - if (turboModuleLookup != turboModuleCache->end()) { - return turboModuleLookup->second; - } + auto turboModuleLookup = turboModuleCache->find(name); + if (turboModuleLookup != turboModuleCache->end()) { + return turboModuleLookup->second; + } - auto cxxModule = delegate->cthis()->getTurboModule(name, jsCallInvoker); - if (cxxModule) { - turboModuleCache->insert({name, cxxModule}); - return cxxModule; - } + auto cxxModule = delegate->cthis()->getTurboModule(name, jsCallInvoker); + if (cxxModule) { + turboModuleCache->insert({name, cxxModule}); + return cxxModule; + } - static auto getLegacyCxxModule = - delegate->getClass() - ->getMethod( - const std::string &)>("getLegacyCxxModule"); - auto legacyCxxModule = getLegacyCxxModule(delegate.get(), name); + static auto getLegacyCxxModule = + delegate->getClass() + ->getMethod( + const std::string &)>("getLegacyCxxModule"); + auto legacyCxxModule = getLegacyCxxModule(delegate.get(), name); - if (legacyCxxModule) { - auto turboModule = std::make_shared( - legacyCxxModule->cthis()->getModule(), jsCallInvoker); - turboModuleCache->insert({name, turboModule}); - return turboModule; - } + if (legacyCxxModule) { + auto turboModule = std::make_shared( + legacyCxxModule->cthis()->getModule(), jsCallInvoker); + turboModuleCache->insert({name, turboModule}); + return turboModule; + } - static auto getJavaModule = - javaPart->getClass() - ->getMethod(const std::string &)>( - "getJavaModule"); - auto moduleInstance = getJavaModule(javaPart.get(), name); + static auto getJavaModule = + javaPart->getClass() + ->getMethod(const std::string &)>( + "getJavaModule"); + auto moduleInstance = getJavaModule(javaPart.get(), name); - if (moduleInstance) { - auto turboModule = delegate->cthis()->getTurboModule( - name, moduleInstance, jsCallInvoker, nativeCallInvoker); - turboModuleCache->insert({name, turboModule}); - return turboModule; - } + if (moduleInstance) { + auto turboModule = delegate->cthis()->getTurboModule( + name, moduleInstance, jsCallInvoker, nativeCallInvoker); + turboModuleCache->insert({name, turboModule}); + return turboModule; + } - return nullptr; + return nullptr; + }; + + jsCallInvoker_->invokeAsync( + [this, turboModuleProvider = std::move(turboModuleProvider)]() -> void { + TurboModuleBinding::install(*runtime_, std::move(turboModuleProvider)); }); }