From b70f186b53c1d43ce5af681ba0be47dd9e61bcb5 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Mon, 22 May 2023 17:32:01 -0700 Subject: [PATCH] Migrate from native CallInvoker to NativeMethodCallInvoker (#37473) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37473 ## Context The TurboModule system uses a CallInvoker interface to schedule JavaScript → native, and native → JavaScript calls. ## Problem JavaScript → native and native → JavaScript calls are different. They can have different behaviours/properties. And, in the future, we might want to evolve them differently. e.g: - JavaScript → native **always** have a method name. Native → JavaScript calls don't. - Native → JavaScript can have priorities, since D41492849. JavaScript → native don't. ## Changes Instead of tying both types of calls to the CallInvoker abstraction, this diff creates a **separate** abstraction for Native → JavaScript calls: NativeMethodCallInvoker. This way, we can evolve both abstractions separately over time: - We can evolve the CallInvoker abstraction to suit the needs of JavaScript → native calls. - We can evolve the NativeMethodCallInvoker abstraction to suite the needs of native → JavaScript calls. This ultimately makes TurboModule system more extensible. ## Motivation For the TurboModule interop layer on iOS, React Native needs to execute the "constantsToExport" method on the main queue, when the module requires main queue setup. (implementation: D45924977). The simplest way to implement this behaviour is to introduce a `methodName` to CallInvoker, and customize the legacy module's CallInvoker::invokeSync method, like so: ``` void invokeSync(std::string methodName, std::function &&work) override { if (requiresMainQueueSetup_ && methodName == "getConstants") { __block auto retainedWork = std::move(work); RCTUnsafeExecuteOnMainQueueSync(^{ retainedWork(); }); return; } work(); } ``` But, customizing CallInvoker to introduce a `methodName` parameter doesn't make sense: Native → JavaScript calls don't necessarily have method names. So, this diff forks CallInvoker into NativeMethodCallInvoker. That way, we can customize NativeMethodCallInvoker to introduce a method name (which does make sense) and resolve this problem. For the full solution, see D45924977. NOTE: Now that NativeMethodCallInvoker is different from CallInvoker, it might make sense to re-name CallInvoker back to JSCallInvoker. Changelog: [Category][Breaking] - Introduce NativeMethodCallInvoker to replace the TurboModule system's native CallInvoker Reviewed By: javache Differential Revision: D45891627 fbshipit-source-id: 39c3f450a290ad396b715288a50858d33ce78441 --- .../React/CxxBridge/RCTCxxBridge.mm | 5 ++- .../facebook/react/ReactInstanceManager.java | 2 +- .../react/bridge/CatalystInstance.java | 5 ++- .../react/bridge/CatalystInstanceImpl.java | 3 +- .../react/bridgeless/ReactInstance.java | 5 ++- .../NativeMethodCallInvokerHolderImpl.java | 37 +++++++++++++++++++ .../turbomodule/core/TurboModuleManager.java | 7 ++-- .../NativeMethodCallInvokerHolder.java | 14 +++++++ .../react/bridgeless/jni/JReactInstance.cpp | 22 ++++++----- .../jni/react/bridgeless/jni/JReactInstance.h | 7 +++- .../jni/react/jni/CatalystInstanceImpl.cpp | 37 +++++++++++-------- .../main/jni/react/jni/CatalystInstanceImpl.h | 7 +++- .../main/jni/react/turbomodule/CMakeLists.txt | 1 + .../NativeMethodCallInvokerHolder.cpp | 23 ++++++++++++ .../NativeMethodCallInvokerHolder.h | 32 ++++++++++++++++ .../ReactCommon/TurboModuleManager.cpp | 27 ++++++++------ .../ReactCommon/TurboModuleManager.h | 8 ++-- .../callinvoker/ReactCommon/CallInvoker.h | 7 ++++ .../ReactCommon/cxxreact/Instance.cpp | 8 ++-- .../ReactCommon/cxxreact/Instance.h | 14 +++---- .../ReactCommon/cxxreact/NativeToJsBridge.cpp | 31 +++++++++------- .../ReactCommon/cxxreact/NativeToJsBridge.h | 6 +-- ... => BridgelessNativeMethodCallInvoker.cpp} | 12 ++++-- ....h => BridgelessNativeMethodCallInvoker.h} | 10 +++-- .../android/ReactCommon/JavaTurboModule.cpp | 27 ++++++++------ .../android/ReactCommon/JavaTurboModule.h | 4 +- .../platform/ios/ReactCommon/RCTTurboModule.h | 8 ++-- .../ios/ReactCommon/RCTTurboModule.mm | 4 +- .../ios/ReactCommon/RCTTurboModuleManager.mm | 22 ++++++----- 29 files changed, 275 insertions(+), 120 deletions(-) create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/NativeMethodCallInvokerHolderImpl.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/NativeMethodCallInvokerHolder.java create mode 100644 packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.cpp create mode 100644 packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h rename packages/react-native/ReactCommon/react/bridgeless/{BridgelessNativeCallInvoker.cpp => BridgelessNativeMethodCallInvoker.cpp} (57%) rename packages/react-native/ReactCommon/react/bridgeless/{BridgelessNativeCallInvoker.h => BridgelessNativeMethodCallInvoker.h} (62%) diff --git a/packages/react-native/React/CxxBridge/RCTCxxBridge.mm b/packages/react-native/React/CxxBridge/RCTCxxBridge.mm index d47c4aece7d309..777268dbb7eff4 100644 --- a/packages/react-native/React/CxxBridge/RCTCxxBridge.mm +++ b/packages/react-native/React/CxxBridge/RCTCxxBridge.mm @@ -1635,9 +1635,10 @@ - (void)invokeAsync:(std::function &&)func return _reactInstance ? _reactInstance->getJSCallInvoker() : nullptr; } -- (std::shared_ptr)decorateNativeCallInvoker:(std::shared_ptr)nativeInvoker +- (std::shared_ptr)decorateNativeMethodCallInvoker: + (std::shared_ptr)nativeInvoker { - return _reactInstance ? _reactInstance->getDecoratedNativeCallInvoker(nativeInvoker) : nullptr; + return _reactInstance ? _reactInstance->getDecoratedNativeMethodCallInvoker(nativeInvoker) : nullptr; } @end diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index 42e815bc6d8b5a..0563aee2cd618d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -1379,7 +1379,7 @@ private ReactApplicationContext createReactContext( catalystInstance.getRuntimeExecutor(), tmmDelegate, catalystInstance.getJSCallInvokerHolder(), - catalystInstance.getNativeCallInvokerHolder()); + catalystInstance.getNativeMethodCallInvokerHolder()); catalystInstance.setTurboModuleManager(turboModuleManager); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java index c0b4517f7e39a9..2623190edba006 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java @@ -12,6 +12,7 @@ import com.facebook.react.bridge.queue.ReactQueueConfiguration; import com.facebook.react.common.annotations.VisibleForTesting; import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder; +import com.facebook.react.turbomodule.core.interfaces.NativeMethodCallInvokerHolder; import java.util.Collection; import java.util.List; @@ -122,10 +123,10 @@ public interface CatalystInstance CallInvokerHolder getJSCallInvokerHolder(); /** - * Returns a hybrid object that contains a pointer to a Native CallInvoker, which is used to + * Returns a hybrid object that contains a pointer to a NativeMethodCallInvoker, which is used to * schedule work on the NativeModules thread. Required for TurboModuleManager initialization. */ - CallInvokerHolder getNativeCallInvokerHolder(); + NativeMethodCallInvokerHolder getNativeMethodCallInvokerHolder(); /** * For the time being, we want code relying on the old infra to also work with TurboModules. diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java index 0329ae8e92b0b1..68817d66c7787f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java @@ -28,6 +28,7 @@ import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.turbomodule.core.CallInvokerHolderImpl; +import com.facebook.react.turbomodule.core.NativeMethodCallInvokerHolderImpl; import com.facebook.react.turbomodule.core.interfaces.TurboModuleRegistry; import com.facebook.systrace.Systrace; import com.facebook.systrace.TraceListener; @@ -111,7 +112,7 @@ public String toString() { public native CallInvokerHolderImpl getJSCallInvokerHolder(); - public native CallInvokerHolderImpl getNativeCallInvokerHolder(); + public native NativeMethodCallInvokerHolderImpl getNativeMethodCallInvokerHolder(); private CatalystInstanceImpl( final ReactQueueConfigurationSpec reactQueueConfigurationSpec, diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/ReactInstance.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/ReactInstance.java index eb3f86afcbb656..1d8d27002919a7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/ReactInstance.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/ReactInstance.java @@ -44,6 +44,7 @@ import com.facebook.react.modules.core.JavaTimerManager; import com.facebook.react.modules.core.ReactChoreographer; import com.facebook.react.turbomodule.core.CallInvokerHolderImpl; +import com.facebook.react.turbomodule.core.NativeMethodCallInvokerHolderImpl; import com.facebook.react.turbomodule.core.TurboModuleManager; import com.facebook.react.turbomodule.core.TurboModuleManagerDelegate; import com.facebook.react.uimanager.ComponentNameResolver; @@ -193,7 +194,7 @@ public void onHostDestroy() { unbufferedRuntimeExecutor, turboModuleManagerDelegate, getJSCallInvokerHolder(), - getNativeCallInvokerHolder()); + getNativeMethodCallInvokerHolder()); // Eagerly initialize TurboModules for (String moduleName : mTurboModuleManager.getEagerInitModuleNames()) { @@ -397,7 +398,7 @@ private native HybridData initHybrid( private native CallInvokerHolderImpl getJSCallInvokerHolder(); - private native CallInvokerHolderImpl getNativeCallInvokerHolder(); + private native NativeMethodCallInvokerHolderImpl getNativeMethodCallInvokerHolder(); private native RuntimeExecutor getUnbufferedRuntimeExecutor(); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/NativeMethodCallInvokerHolderImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/NativeMethodCallInvokerHolderImpl.java new file mode 100644 index 00000000000000..79b2bea4707a01 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/NativeMethodCallInvokerHolderImpl.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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.react.turbomodule.core.interfaces.NativeMethodCallInvokerHolder; +import com.facebook.soloader.SoLoader; + +/** + * NativeMethodCallInvokerHolder is created at a different time/place (i.e: in CatalystInstance) + * than TurboModuleManager. Therefore, we need to wrap NativeMethodCallInvokerHolder within a hybrid + * class so that we may pass it from CatalystInstance, through Java, to + * TurboModuleManager::initHybrid. + */ +public class NativeMethodCallInvokerHolderImpl implements NativeMethodCallInvokerHolder { + private static volatile boolean sIsSoLibraryLoaded; + + private final HybridData mHybridData; + + private NativeMethodCallInvokerHolderImpl(HybridData hd) { + maybeLoadSoLibrary(); + mHybridData = hd; + } + + // Prevents issues with initializer interruptions. See T38996825 and D13793825 for more context. + private static synchronized void maybeLoadSoLibrary() { + if (!sIsSoLibraryLoaded) { + SoLoader.loadLibrary("turbomodulejsijni"); + sIsSoLibraryLoaded = true; + } + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java index c17a99bfef88db..aa29e666d26611 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java @@ -22,6 +22,7 @@ import com.facebook.react.bridge.RuntimeExecutor; import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder; +import com.facebook.react.turbomodule.core.interfaces.NativeMethodCallInvokerHolder; import com.facebook.react.turbomodule.core.interfaces.TurboModule; import com.facebook.react.turbomodule.core.interfaces.TurboModuleRegistry; import com.facebook.soloader.SoLoader; @@ -61,14 +62,14 @@ public TurboModuleManager( RuntimeExecutor runtimeExecutor, @Nullable final TurboModuleManagerDelegate delegate, CallInvokerHolder jsCallInvokerHolder, - CallInvokerHolder nativeCallInvokerHolder) { + NativeMethodCallInvokerHolder nativeMethodCallInvokerHolder) { maybeLoadSoLibrary(); mDelegate = delegate; mHybridData = initHybrid( runtimeExecutor, (CallInvokerHolderImpl) jsCallInvokerHolder, - (CallInvokerHolderImpl) nativeCallInvokerHolder, + (NativeMethodCallInvokerHolderImpl) nativeMethodCallInvokerHolder, delegate); installJSIBindings(shouldCreateLegacyModules()); @@ -405,7 +406,7 @@ public static void logError(String message) { private native HybridData initHybrid( RuntimeExecutor runtimeExecutor, CallInvokerHolderImpl jsCallInvokerHolder, - CallInvokerHolderImpl nativeCallInvokerHolder, + NativeMethodCallInvokerHolderImpl nativeMethodCallInvoker, TurboModuleManagerDelegate tmmDelegate); private native void installJSIBindings(boolean shouldCreateLegacyModules); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/NativeMethodCallInvokerHolder.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/NativeMethodCallInvokerHolder.java new file mode 100644 index 00000000000000..c3c52f51f57f03 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/NativeMethodCallInvokerHolder.java @@ -0,0 +1,14 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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; + +/** + * This interface represents the opaque Java object that contains a pointer to and instance of + * NativeMethodCallInvoker. + */ +public interface NativeMethodCallInvokerHolder {} diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/bridgeless/jni/JReactInstance.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/bridgeless/jni/JReactInstance.cpp index d5ce7517657ac5..4df09482a59492 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/bridgeless/jni/JReactInstance.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/bridgeless/jni/JReactInstance.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -90,10 +90,12 @@ JReactInstance::JReactInstance( std::make_unique(unbufferedRuntimeExecutor); jsCallInvokerHolder_ = jni::make_global( CallInvokerHolder::newObjectCxxArgs(std::move(jsInvoker))); - auto nativeInvoker = std::make_unique( - sharedNativeMessageQueueThread); - nativeCallInvokerHolder_ = jni::make_global( - CallInvokerHolder::newObjectCxxArgs(std::move(nativeInvoker))); + auto nativeMethodCallInvoker = + std::make_unique( + sharedNativeMessageQueueThread); + nativeMethodCallInvokerHolder_ = + jni::make_global(NativeMethodCallInvokerHolder::newObjectCxxArgs( + std::move(nativeMethodCallInvoker))); // Storing this here to make sure the Java reference doesn't get destroyed unbufferedRuntimeExecutor_ = jni::make_global( @@ -156,9 +158,9 @@ JReactInstance::getJSCallInvokerHolder() { return jsCallInvokerHolder_; } -jni::alias_ref -JReactInstance::getNativeCallInvokerHolder() { - return nativeCallInvokerHolder_; +jni::alias_ref +JReactInstance::getNativeMethodCallInvokerHolder() { + return nativeMethodCallInvokerHolder_; } jni::global_ref @@ -211,8 +213,8 @@ void JReactInstance::registerNatives() { makeNativeMethod( "getJSCallInvokerHolder", JReactInstance::getJSCallInvokerHolder), makeNativeMethod( - "getNativeCallInvokerHolder", - JReactInstance::getNativeCallInvokerHolder), + "getNativeMethodCallInvokerHolder", + JReactInstance::getNativeMethodCallInvokerHolder), makeNativeMethod( "callFunctionOnModule", JReactInstance::callFunctionOnModule), makeNativeMethod( diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/bridgeless/jni/JReactInstance.h b/packages/react-native/ReactAndroid/src/main/jni/react/bridgeless/jni/JReactInstance.h index 61dfa4debee201..99e7d80ebb8778 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/bridgeless/jni/JReactInstance.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/bridgeless/jni/JReactInstance.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include #include @@ -92,14 +93,16 @@ class JReactInstance : public jni::HybridClass { bool isProfiling) noexcept; jni::alias_ref getJSCallInvokerHolder(); - jni::alias_ref getNativeCallInvokerHolder(); + jni::alias_ref + getNativeMethodCallInvokerHolder(); std::unique_ptr instance_; jni::global_ref unbufferedRuntimeExecutor_; jni::global_ref bufferedRuntimeExecutor_; jni::global_ref runtimeScheduler_; jni::global_ref jsCallInvokerHolder_; - jni::global_ref nativeCallInvokerHolder_; + jni::global_ref + nativeMethodCallInvokerHolder_; jni::global_ref jReactExceptionManager_; jni::global_ref jBindingsInstaller_; }; diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp index 043d5afcfaeb84..53688d625d4a19 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp @@ -131,8 +131,8 @@ void CatalystInstanceImpl::registerNatives() { "getJSCallInvokerHolder", CatalystInstanceImpl::getJSCallInvokerHolder), makeNativeMethod( - "getNativeCallInvokerHolder", - CatalystInstanceImpl::getNativeCallInvokerHolder), + "getNativeMethodCallInvokerHolder", + CatalystInstanceImpl::getNativeMethodCallInvokerHolder), makeNativeMethod( "jniHandleMemoryPressure", CatalystInstanceImpl::handleMemoryPressure), @@ -358,36 +358,41 @@ CatalystInstanceImpl::getJSCallInvokerHolder() { return jsCallInvokerHolder_; } -jni::alias_ref -CatalystInstanceImpl::getNativeCallInvokerHolder() { - if (!nativeCallInvokerHolder_) { - class NativeThreadCallInvoker : public CallInvoker { +jni::alias_ref +CatalystInstanceImpl::getNativeMethodCallInvokerHolder() { + if (!nativeMethodCallInvokerHolder_) { + class NativeMethodCallInvokerImpl : public NativeMethodCallInvoker { private: std::shared_ptr messageQueueThread_; public: - NativeThreadCallInvoker( + NativeMethodCallInvokerImpl( std::shared_ptr messageQueueThread) : messageQueueThread_(messageQueueThread) {} - void invokeAsync(std::function &&work) override { + void invokeAsync( + const std::string &methodName, + std::function &&work) override { messageQueueThread_->runOnQueue(std::move(work)); } - void invokeSync(std::function &&work) override { + void invokeSync( + const std::string &methodName, + std::function &&work) override { messageQueueThread_->runOnQueueSync(std::move(work)); } }; - std::shared_ptr nativeInvoker = - std::make_shared(moduleMessageQueue_); + std::shared_ptr nativeMethodCallInvoker = + std::make_shared(moduleMessageQueue_); - std::shared_ptr decoratedNativeInvoker = - instance_->getDecoratedNativeCallInvoker(nativeInvoker); + std::shared_ptr decoratedNativeMethodCallInvoker = + instance_->getDecoratedNativeMethodCallInvoker(nativeMethodCallInvoker); - nativeCallInvokerHolder_ = jni::make_global( - CallInvokerHolder::newObjectCxxArgs(decoratedNativeInvoker)); + nativeMethodCallInvokerHolder_ = + jni::make_global(NativeMethodCallInvokerHolder::newObjectCxxArgs( + decoratedNativeMethodCallInvoker)); } - return nativeCallInvokerHolder_; + return nativeMethodCallInvokerHolder_; } jni::alias_ref diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h b/packages/react-native/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h index bc07691e331a68..13d8a7db6ae65f 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -96,7 +97,8 @@ class CatalystInstanceImpl : public jni::HybridClass { NativeArray *arguments); void jniCallJSCallback(jint callbackId, NativeArray *arguments); jni::alias_ref getJSCallInvokerHolder(); - jni::alias_ref getNativeCallInvokerHolder(); + jni::alias_ref + getNativeMethodCallInvokerHolder(); jni::alias_ref getRuntimeExecutor(); jni::alias_ref getRuntimeScheduler(); void setGlobalVariable(std::string propName, std::string &&jsonValue); @@ -111,7 +113,8 @@ class CatalystInstanceImpl : public jni::HybridClass { std::shared_ptr moduleRegistry_; std::shared_ptr moduleMessageQueue_; jni::global_ref jsCallInvokerHolder_; - jni::global_ref nativeCallInvokerHolder_; + jni::global_ref + nativeMethodCallInvokerHolder_; jni::global_ref runtimeExecutor_; jni::global_ref runtimeScheduler_; }; diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/CMakeLists.txt b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/CMakeLists.txt index b5a9449bb9e1b1..748e1c6ca00f86 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/CMakeLists.txt +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/CMakeLists.txt @@ -21,6 +21,7 @@ add_library( callinvokerholder STATIC ReactCommon/CallInvokerHolder.cpp + ReactCommon/NativeMethodCallInvokerHolder.cpp ) target_include_directories(callinvokerholder diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.cpp new file mode 100644 index 00000000000000..62d9b0de182faa --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "NativeMethodCallInvokerHolder.h" + +namespace facebook::react { + +NativeMethodCallInvokerHolder::NativeMethodCallInvokerHolder( + std::shared_ptr nativeMethodCallInvoker) + : _nativeMethodCallInvoker(nativeMethodCallInvoker) {} + +std::shared_ptr +NativeMethodCallInvokerHolder::getNativeMethodCallInvoker() { + return _nativeMethodCallInvoker; +} + +void NativeMethodCallInvokerHolder::registerNatives() {} + +} // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h new file mode 100644 index 00000000000000..ef8fa3b5a42395 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) Meta Platforms, Inc. and 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::react { + +class NativeMethodCallInvokerHolder + : public jni::HybridClass { + public: + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/turbomodule/core/NativeMethodCallInvokerHolderImpl;"; + + static void registerNatives(); + std::shared_ptr getNativeMethodCallInvoker(); + + private: + friend HybridBase; + NativeMethodCallInvokerHolder( + std::shared_ptr nativeMethodCallInvoker); + std::shared_ptr _nativeMethodCallInvoker; +}; + +} // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp index 8b8f2c64611ff8..fdcee5f672d1ab 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp @@ -106,12 +106,12 @@ TurboModuleManager::TurboModuleManager( jni::alias_ref jThis, RuntimeExecutor runtimeExecutor, std::shared_ptr jsCallInvoker, - std::shared_ptr nativeCallInvoker, + std::shared_ptr nativeMethodCallInvoker, jni::alias_ref delegate) : javaPart_(jni::make_global(jThis)), runtimeExecutor_(runtimeExecutor), jsCallInvoker_(jsCallInvoker), - nativeCallInvoker_(nativeCallInvoker), + nativeMethodCallInvoker_(nativeMethodCallInvoker), delegate_(jni::make_global(delegate)), turboModuleCache_(std::make_shared()), legacyModuleCache_(std::make_shared()) {} @@ -120,13 +120,14 @@ jni::local_ref TurboModuleManager::initHybrid( jni::alias_ref jThis, jni::alias_ref runtimeExecutor, jni::alias_ref jsCallInvokerHolder, - jni::alias_ref nativeCallInvokerHolder, + jni::alias_ref + nativeMethodCallInvokerHolder, jni::alias_ref delegate) { return makeCxxInstance( jThis, runtimeExecutor->cthis()->get(), jsCallInvokerHolder->cthis()->getCallInvoker(), - nativeCallInvokerHolder->cthis()->getCallInvoker(), + nativeMethodCallInvokerHolder->cthis()->getNativeMethodCallInvoker(), delegate); } @@ -142,17 +143,18 @@ TurboModuleProviderFunctionType TurboModuleManager::createTurboModuleProvider() { return [turboModuleCache_ = std::weak_ptr(turboModuleCache_), jsCallInvoker_ = std::weak_ptr(jsCallInvoker_), - nativeCallInvoker_ = std::weak_ptr(nativeCallInvoker_), + nativeMethodCallInvoker_ = + std::weak_ptr(nativeMethodCallInvoker_), 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 nativeMethodCallInvoker = nativeMethodCallInvoker_.lock(); auto delegate = delegate_.lockLocal(); auto javaPart = javaPart_.lockLocal(); - if (!turboModuleCache || !jsCallInvoker || !nativeCallInvoker || + if (!turboModuleCache || !jsCallInvoker || !nativeMethodCallInvoker || !delegate || !javaPart) { return nullptr; } @@ -205,7 +207,7 @@ TurboModuleManager::createTurboModuleProvider() { .moduleName = name, .instance = moduleInstance, .jsInvoker = jsCallInvoker, - .nativeInvoker = nativeCallInvoker}; + .nativeMethodCallInvoker = nativeMethodCallInvoker}; auto turboModule = delegate->cthis()->getTurboModule(name, params); turboModuleCache->insert({name, turboModule}); @@ -221,17 +223,18 @@ TurboModuleProviderFunctionType TurboModuleManager::createLegacyModuleProvider() { return [legacyModuleCache_ = std::weak_ptr(legacyModuleCache_), jsCallInvoker_ = std::weak_ptr(jsCallInvoker_), - nativeCallInvoker_ = std::weak_ptr(nativeCallInvoker_), + nativeMethodCallInvoker_ = + std::weak_ptr(nativeMethodCallInvoker_), delegate_ = jni::make_weak(delegate_), javaPart_ = jni::make_weak(javaPart_)]( const std::string &name) -> std::shared_ptr { auto legacyModuleCache = legacyModuleCache_.lock(); auto jsCallInvoker = jsCallInvoker_.lock(); - auto nativeCallInvoker = nativeCallInvoker_.lock(); + auto nativeMethodCallInvoker = nativeMethodCallInvoker_.lock(); auto delegate = delegate_.lockLocal(); auto javaPart = javaPart_.lockLocal(); - if (!legacyModuleCache || !jsCallInvoker || !nativeCallInvoker || + if (!legacyModuleCache || !jsCallInvoker || !nativeMethodCallInvoker || !delegate || !javaPart) { return nullptr; } @@ -278,7 +281,7 @@ TurboModuleManager::createLegacyModuleProvider() { .moduleName = name, .instance = moduleInstance, .jsInvoker = jsCallInvoker, - .nativeInvoker = nativeCallInvoker}; + .nativeMethodCallInvoker = nativeMethodCallInvoker}; static auto getMethodDescriptorsFromModule = javaPart->getClass() diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h index 03a0ad387009a6..47c8711bb60a28 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -30,7 +31,8 @@ class TurboModuleManager : public jni::HybridClass { jni::alias_ref jThis, jni::alias_ref runtimeExecutor, jni::alias_ref jsCallInvokerHolder, - jni::alias_ref nativeCallInvokerHolder, + jni::alias_ref + nativeMethodCallInvokerHolder, jni::alias_ref delegate); static void registerNatives(); @@ -39,7 +41,7 @@ class TurboModuleManager : public jni::HybridClass { jni::global_ref javaPart_; RuntimeExecutor runtimeExecutor_; std::shared_ptr jsCallInvoker_; - std::shared_ptr nativeCallInvoker_; + std::shared_ptr nativeMethodCallInvoker_; jni::global_ref delegate_; using ModuleCache = @@ -59,7 +61,7 @@ class TurboModuleManager : public jni::HybridClass { jni::alias_ref jThis, RuntimeExecutor runtimeExecutor, std::shared_ptr jsCallInvoker, - std::shared_ptr nativeCallInvoker, + std::shared_ptr nativeMethodCallInvoker, jni::alias_ref delegate); TurboModuleProviderFunctionType createTurboModuleProvider(); diff --git a/packages/react-native/ReactCommon/callinvoker/ReactCommon/CallInvoker.h b/packages/react-native/ReactCommon/callinvoker/ReactCommon/CallInvoker.h index 55aa865bfad717..cec0abda69ee9d 100644 --- a/packages/react-native/ReactCommon/callinvoker/ReactCommon/CallInvoker.h +++ b/packages/react-native/ReactCommon/callinvoker/ReactCommon/CallInvoker.h @@ -32,4 +32,11 @@ class CallInvoker { virtual ~CallInvoker() {} }; +class NativeMethodCallInvoker { + public: + virtual void invokeAsync(const std::string &methodName, CallFunc &&func) = 0; + virtual void invokeSync(const std::string &methodName, CallFunc &&func) = 0; + virtual ~NativeMethodCallInvoker() {} +}; + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/cxxreact/Instance.cpp b/packages/react-native/ReactCommon/cxxreact/Instance.cpp index 1dfa0e682a34b6..7cf9d3a148eda6 100644 --- a/packages/react-native/ReactCommon/cxxreact/Instance.cpp +++ b/packages/react-native/ReactCommon/cxxreact/Instance.cpp @@ -233,9 +233,11 @@ RuntimeExecutor Instance::getRuntimeExecutor() { return runtimeExecutor; } -std::shared_ptr Instance::getDecoratedNativeCallInvoker( - std::shared_ptr nativeInvoker) { - return nativeToJsBridge_->getDecoratedNativeCallInvoker(nativeInvoker); +std::shared_ptr +Instance::getDecoratedNativeMethodCallInvoker( + std::shared_ptr nativeMethodCallInvoker) { + return nativeToJsBridge_->getDecoratedNativeMethodCallInvoker( + nativeMethodCallInvoker); } void Instance::JSCallInvoker::setNativeToJsBridgeAndFlushCalls( diff --git a/packages/react-native/ReactCommon/cxxreact/Instance.h b/packages/react-native/ReactCommon/cxxreact/Instance.h index 567e72fc124a84..ca0106de18f28f 100644 --- a/packages/react-native/ReactCommon/cxxreact/Instance.h +++ b/packages/react-native/ReactCommon/cxxreact/Instance.h @@ -101,10 +101,10 @@ class RN_EXPORT Instance { std::shared_ptr getJSCallInvoker(); /** - * Native CallInvoker is used by TurboModules to schedule work on the + * NativeMethodCallInvoker is used by TurboModules to schedule work on the * NativeModule thread(s). * - * Why is the bridge decorating native CallInvoker? + * Why is the bridge decorating NativeMethodCallInvoker? * * - The bridge must be informed of all TurboModule async method calls. Why? * When all queued NativeModule method calls are flushed by a call from @@ -116,16 +116,16 @@ class RN_EXPORT Instance { * since the last time the bridge was flushed. If this number is non-zero, * we fire onBatchComplete. * - * Why can't we just create and return a new native CallInvoker? + * Why can't we just create and return a new NativeMethodCallInvoker? * * - On Android, we have one NativeModule thread. That thread is created and * managed outside of NativeToJsBridge. On iOS, we have one MethodQueue per * module. Those MethodQueues are also created and managed outside of - * NativeToJsBridge. Therefore, we need to pass in a CallInvoker that - * schedules work on the respective thread. + * NativeToJsBridge. Therefore, we need to pass in a + * NativeMethodCallInvoker that schedules work on the respective thread. */ - std::shared_ptr getDecoratedNativeCallInvoker( - std::shared_ptr nativeInvoker); + std::shared_ptr getDecoratedNativeMethodCallInvoker( + std::shared_ptr nativeInvoker); /** * RuntimeExecutor is used by Fabric to access the jsi::Runtime. diff --git a/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp b/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp index 456bfca43d583f..77eee51c3b4da5 100644 --- a/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp +++ b/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.cpp @@ -310,33 +310,38 @@ void NativeToJsBridge::runOnExecutorQueue( }); } -std::shared_ptr NativeToJsBridge::getDecoratedNativeCallInvoker( - std::shared_ptr nativeInvoker) { - class NativeCallInvoker : public CallInvoker { +std::shared_ptr +NativeToJsBridge::getDecoratedNativeMethodCallInvoker( + std::shared_ptr nativeMethodCallInvoker) const { + class NativeMethodCallInvokerImpl : public NativeMethodCallInvoker { private: std::weak_ptr m_jsToNativeBridge; - std::shared_ptr m_nativeInvoker; + std::shared_ptr m_nativeInvoker; public: - NativeCallInvoker( + NativeMethodCallInvokerImpl( std::weak_ptr jsToNativeBridge, - std::shared_ptr nativeInvoker) - : m_jsToNativeBridge(jsToNativeBridge), - m_nativeInvoker(nativeInvoker) {} + std::shared_ptr nativeInvoker) + : m_jsToNativeBridge(std::move(jsToNativeBridge)), + m_nativeInvoker(std::move(nativeInvoker)) {} - void invokeAsync(std::function &&func) override { + void invokeAsync( + const std::string &methodName, + std::function &&func) override { if (auto strongJsToNativeBridge = m_jsToNativeBridge.lock()) { strongJsToNativeBridge->recordTurboModuleAsyncMethodCall(); } - m_nativeInvoker->invokeAsync(std::move(func)); + m_nativeInvoker->invokeAsync(methodName, std::move(func)); } - void invokeSync(std::function &&func) override { - m_nativeInvoker->invokeSync(std::move(func)); + void invokeSync(const std::string &methodName, std::function &&func) + override { + m_nativeInvoker->invokeSync(methodName, std::move(func)); } }; - return std::make_shared(m_delegate, nativeInvoker); + return std::make_shared( + m_delegate, std::move(nativeMethodCallInvoker)); } } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.h b/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.h index 13c358614e9bba..4d29fdd661f48a 100644 --- a/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.h +++ b/packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.h @@ -100,11 +100,11 @@ class NativeToJsBridge { void runOnExecutorQueue(std::function task); /** - * Native CallInvoker is used by TurboModules to schedule work on the + * NativeMethodCallInvoker is used by TurboModules to schedule work on the * NativeModule thread(s). */ - std::shared_ptr getDecoratedNativeCallInvoker( - std::shared_ptr nativeInvoker); + std::shared_ptr getDecoratedNativeMethodCallInvoker( + std::shared_ptr nativeInvoker) const; private: // This is used to avoid a race condition where a proxyCallback gets queued diff --git a/packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeCallInvoker.cpp b/packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeMethodCallInvoker.cpp similarity index 57% rename from packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeCallInvoker.cpp rename to packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeMethodCallInvoker.cpp index b1785bbe0ae2bb..5a924edddca623 100644 --- a/packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeCallInvoker.cpp +++ b/packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeMethodCallInvoker.cpp @@ -5,19 +5,23 @@ * LICENSE file in the root directory of this source tree. */ -#include "BridgelessNativeCallInvoker.h" +#include "BridgelessNativeMethodCallInvoker.h" namespace facebook::react { -BridgelessNativeCallInvoker::BridgelessNativeCallInvoker( +BridgelessNativeMethodCallInvoker::BridgelessNativeMethodCallInvoker( std::shared_ptr messageQueueThread) : messageQueueThread_(std::move(messageQueueThread)) {} -void BridgelessNativeCallInvoker::invokeAsync(std::function &&func) { +void BridgelessNativeMethodCallInvoker::invokeAsync( + const std::string &methodName, + std::function &&func) { messageQueueThread_->runOnQueue(std::move(func)); } -void BridgelessNativeCallInvoker::invokeSync(std::function &&func) { +void BridgelessNativeMethodCallInvoker::invokeSync( + const std::string &methodName, + std::function &&func) { messageQueueThread_->runOnQueueSync(std::move(func)); } diff --git a/packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeCallInvoker.h b/packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeMethodCallInvoker.h similarity index 62% rename from packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeCallInvoker.h rename to packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeMethodCallInvoker.h index effddf81e6a503..775ed0daabc2f8 100644 --- a/packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeCallInvoker.h +++ b/packages/react-native/ReactCommon/react/bridgeless/BridgelessNativeMethodCallInvoker.h @@ -12,12 +12,14 @@ namespace facebook::react { -class BridgelessNativeCallInvoker : public CallInvoker { +class BridgelessNativeMethodCallInvoker : public NativeMethodCallInvoker { public: - explicit BridgelessNativeCallInvoker( + explicit BridgelessNativeMethodCallInvoker( std::shared_ptr messageQueueThread); - void invokeAsync(std::function &&func) override; - void invokeSync(std::function &&func) override; + void invokeAsync(const std::string &methodName, std::function &&func) + override; + void invokeSync(const std::string &methodName, std::function &&func) + override; private: std::shared_ptr messageQueueThread_; diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp b/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp index 477d144773b852..9f57f4d2c7f59b 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp @@ -31,7 +31,7 @@ namespace TMPL = TurboModulePerfLogger; JavaTurboModule::JavaTurboModule(const InitParams ¶ms) : TurboModule(params.moduleName, params.jsInvoker), instance_(jni::make_global(params.instance)), - nativeInvoker_(params.nativeInvoker) {} + nativeMethodCallInvoker_(params.nativeMethodCallInvoker) {} JavaTurboModule::~JavaTurboModule() { /** @@ -42,15 +42,16 @@ JavaTurboModule::~JavaTurboModule() { return; } - nativeInvoker_->invokeAsync([instance = std::move(instance_)]() mutable { - /** - * Reset the global NativeModule ref on the NativeModules thread. Why: - * - ~JavaTurboModule() can be called on a non-JVM thread. If we reset the - * global ref in ~JavaTurboModule(), we might access the JVM from a - * non-JVM thread, which will crash the app. - */ - instance.reset(); - }); + nativeMethodCallInvoker_->invokeAsync( + "~" + name_, [instance = std::move(instance_)]() mutable { + /** + * Reset the global NativeModule ref on the NativeModules thread. Why: + * - ~JavaTurboModule() can be called on a non-JVM thread. If we reset + * the global ref in ~JavaTurboModule(), we might access the JVM from a + * non-JVM thread, which will crash the app. + */ + instance.reset(); + }); } namespace { @@ -742,7 +743,8 @@ jsi::Value JavaTurboModule::invokeJavaMethod( TMPL::asyncMethodCallArgConversionEnd(moduleName, methodName); TMPL::asyncMethodCallDispatch(moduleName, methodName); - nativeInvoker_->invokeAsync( + nativeMethodCallInvoker_->invokeAsync( + methodName, [jargs, globalRefs, methodID, @@ -841,7 +843,8 @@ jsi::Value JavaTurboModule::invokeJavaMethod( TMPL::asyncMethodCallArgConversionEnd(moduleName, methodName); TMPL::asyncMethodCallDispatch(moduleName, methodName); - nativeInvoker_->invokeAsync( + nativeMethodCallInvoker_->invokeAsync( + methodName, [jargs, globalRefs, methodID, diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.h b/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.h index 950d3db3aad35f..63f7d456df1eac 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.h +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.h @@ -31,7 +31,7 @@ class JSI_EXPORT JavaTurboModule : public TurboModule { std::string moduleName; jni::alias_ref instance; std::shared_ptr jsInvoker; - std::shared_ptr nativeInvoker; + std::shared_ptr nativeMethodCallInvoker; }; JavaTurboModule(const InitParams ¶ms); @@ -49,7 +49,7 @@ class JSI_EXPORT JavaTurboModule : public TurboModule { private: // instance_ can be of type JTurboModule, or JNativeModule jni::global_ref instance_; - std::shared_ptr nativeInvoker_; + std::shared_ptr nativeMethodCallInvoker_; }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h index 5b91c5b949da05..bdfbeeb596af52 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h @@ -43,7 +43,7 @@ class JSI_EXPORT ObjCTurboModule : public TurboModule { std::string moduleName; id instance; std::shared_ptr jsInvoker; - std::shared_ptr nativeInvoker; + std::shared_ptr nativeMethodCallInvoker; bool isSyncModule; }; @@ -58,7 +58,7 @@ class JSI_EXPORT ObjCTurboModule : public TurboModule { size_t count); id instance_; - std::shared_ptr nativeInvoker_; + std::shared_ptr nativeMethodCallInvoker_; protected: void setMethodArgConversionSelector(NSString *methodName, int argIndex, NSString *fnName); @@ -159,6 +159,6 @@ class JSI_EXPORT ObjCTurboModule : public TurboModule { */ @interface RCTBridge (RCTTurboModule) - (std::shared_ptr)jsCallInvoker; -- (std::shared_ptr)decorateNativeCallInvoker: - (std::shared_ptr)nativeInvoker; +- (std::shared_ptr)decorateNativeMethodCallInvoker: + (std::shared_ptr)nativeMethodCallInvoker; @end diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm index ce9a0ffcf3035d..c1ed34e282f55f 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.mm @@ -424,7 +424,7 @@ id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value, s } else { asyncCallCounter = getUniqueId(); TurboModulePerfLogger::asyncMethodCallDispatch(moduleName, methodName); - nativeInvoker_->invokeAsync([block]() -> void { block(); }); + nativeMethodCallInvoker_->invokeAsync(methodNameStr, [block]() -> void { block(); }); return nil; } } @@ -685,7 +685,7 @@ id convertJSIValueToObjCObject(jsi::Runtime &runtime, const jsi::Value &value, s ObjCTurboModule::ObjCTurboModule(const InitParams ¶ms) : TurboModule(params.moduleName, params.jsInvoker), instance_(params.instance), - nativeInvoker_(params.nativeInvoker), + nativeMethodCallInvoker_(params.nativeMethodCallInvoker), isSyncModule_(params.isSyncModule) { } diff --git a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm index 4b8ab526f04404..2b6b6883e0a63f 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm +++ b/packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.mm @@ -111,13 +111,13 @@ bool isCreatingModule() const } }; -class MethodQueueNativeCallInvoker : public CallInvoker { +class MethodQueueNativeMethodCallInvoker : public NativeMethodCallInvoker { private: dispatch_queue_t methodQueue_; public: - MethodQueueNativeCallInvoker(dispatch_queue_t methodQueue) : methodQueue_(methodQueue) {} - void invokeAsync(std::function &&work) override + MethodQueueNativeMethodCallInvoker(dispatch_queue_t methodQueue) : methodQueue_(methodQueue) {} + void invokeAsync(const std::string &methodName, std::function &&work) override { if (methodQueue_ == RCTJSThread) { work(); @@ -130,7 +130,7 @@ void invokeAsync(std::function &&work) override }); } - void invokeSync(std::function &&work) override + void invokeSync(const std::string &methodName, std::function &&work) override { if (methodQueue_ == RCTJSThread) { work(); @@ -303,14 +303,15 @@ - (void)notifyAboutTurboModuleSetup:(const char *)name /** * Step 2c: Create and native CallInvoker from the TurboModule's method queue. */ - std::shared_ptr nativeInvoker = std::make_shared(methodQueue); + std::shared_ptr nativeMethodCallInvoker = + std::make_shared(methodQueue); /** * Have RCTCxxBridge decorate native CallInvoker, so that it's aware of TurboModule async method calls. * This helps the bridge fire onBatchComplete as readily as it should. */ - if ([_bridge respondsToSelector:@selector(decorateNativeCallInvoker:)]) { - nativeInvoker = [_bridge decorateNativeCallInvoker:nativeInvoker]; + if ([_bridge respondsToSelector:@selector(decorateNativeMethodCallInvoker:)]) { + nativeMethodCallInvoker = [_bridge decorateNativeMethodCallInvoker:nativeMethodCallInvoker]; } /** @@ -336,7 +337,7 @@ - (void)notifyAboutTurboModuleSetup:(const char *)name .moduleName = moduleName, .instance = module, .jsInvoker = _jsInvoker, - .nativeInvoker = nativeInvoker, + .nativeMethodCallInvoker = nativeMethodCallInvoker, .isSyncModule = methodQueue == RCTJSThread, }; @@ -381,7 +382,8 @@ - (void)notifyAboutTurboModuleSetup:(const char *)name } // Create a native call invoker from module's method queue - std::shared_ptr nativeInvoker = std::make_shared(methodQueue); + std::shared_ptr nativeMethodCallInvoker = + std::make_shared(methodQueue); // If module is a legacy cxx module, return TurboCxxModule if ([moduleClass isSubclassOfClass:RCTCxxModule.class]) { @@ -397,7 +399,7 @@ - (void)notifyAboutTurboModuleSetup:(const char *)name .moduleName = moduleName, .instance = module, .jsInvoker = _jsInvoker, - .nativeInvoker = nativeInvoker, + .nativeMethodCallInvoker = std::move(nativeMethodCallInvoker), .isSyncModule = methodQueue == RCTJSThread, };