From 1f6451bd3f92937175a1a5cd2eaf186a2eda68d9 Mon Sep 17 00:00:00 2001 From: Christoph Purrer Date: Mon, 9 May 2022 23:45:45 -0700 Subject: [PATCH] Add CompositeReactPackageTurboModuleManagerDelegate [RFC] Summary: This diff adds a CompositeReactPackageTurboModuleManagerDelegate which can be used to combine 1 or more TurboModuleManagerDelegates into a single one. This is useful when both the app and one or multiple of its libraries provides a TurboModuleManagerDelegate Changelog: [Internal] [Changed] - Add CompositeReactPackageTurboModuleManagerDelegate Reviewed By: mdvacca Differential Revision: D36187694 fbshipit-source-id: 88f1d689342345b4cb7e67186791ad5bd1a6f21b --- ...eactPackageTurboModuleManagerDelegate.java | 67 +++++++++++++++++++ .../react/turbomodule/core/jni/Android.mk | 3 +- .../facebook/react/turbomodule/core/jni/BUCK | 2 + .../react/turbomodule/core/jni/CMakeLists.txt | 3 +- .../CompositeTurboModuleManagerDelegate.cpp | 59 ++++++++++++++++ .../CompositeTurboModuleManagerDelegate.h | 49 ++++++++++++++ .../core/jni/ReactCommon/OnLoad.cpp | 3 + 7 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackageTurboModuleManagerDelegate.java create mode 100644 ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CompositeTurboModuleManagerDelegate.cpp create mode 100644 ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CompositeTurboModuleManagerDelegate.h diff --git a/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackageTurboModuleManagerDelegate.java b/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackageTurboModuleManagerDelegate.java new file mode 100644 index 00000000000..9bdf41fac04 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/CompositeReactPackageTurboModuleManagerDelegate.java @@ -0,0 +1,67 @@ +/* + * 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; + +import androidx.annotation.NonNull; +import com.facebook.jni.HybridData; +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.turbomodule.core.TurboModuleManagerDelegate; +import com.facebook.soloader.SoLoader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@DoNotStrip +public class CompositeReactPackageTurboModuleManagerDelegate + extends ReactPackageTurboModuleManagerDelegate { + + private static volatile boolean sIsSoLibraryLoaded; + + protected native HybridData initHybrid(); + + private final List mDelegates; + + private CompositeReactPackageTurboModuleManagerDelegate( + ReactApplicationContext context, + List packages, + List delegates) { + super(context, packages); + mDelegates = delegates; + for (TurboModuleManagerDelegate delegate : delegates) { + addTurboModuleManagerDelegate(delegate); + } + } + + private native void addTurboModuleManagerDelegate(TurboModuleManagerDelegate delegates); + + public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder { + private final List mDelegatesBuilder; + + public Builder(@NonNull List delegatesBuilder) { + mDelegatesBuilder = delegatesBuilder; + } + + protected ReactPackageTurboModuleManagerDelegate build( + ReactApplicationContext context, List packages) { + List delegates = new ArrayList<>(); + for (ReactPackageTurboModuleManagerDelegate.Builder delegatesBuilder : mDelegatesBuilder) { + delegates.add(delegatesBuilder.build(context, Collections.emptyList())); + } + return new CompositeReactPackageTurboModuleManagerDelegate(context, packages, delegates); + } + } + + protected synchronized void maybeLoadOtherSoLibraries() { + // Prevents issues with initializer interruptions. See T38996825 and D13793825 for more context. + if (!sIsSoLibraryLoaded) { + SoLoader.loadLibrary("turbomodulejsijni"); + sIsSoLibraryLoaded = true; + } + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/Android.mk b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/Android.mk index 5d978c9c35c..1fd20f0bdc8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/Android.mk +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/Android.mk @@ -56,8 +56,9 @@ LOCAL_SHARED_LIBRARIES = libfb libfbjni libreact_nativemodule_core libjsi LOCAL_STATIC_LIBRARIES = libcallinvokerholder libreactperfloggerjni # Compile all local c++ files -LOCAL_SRC_FILES := $(LOCAL_PATH)/ReactCommon/TurboModuleManager.cpp $(LOCAL_PATH)/ReactCommon/OnLoad.cpp +LOCAL_SRC_FILES := $(LOCAL_PATH)/ReactCommon/CompositeTurboModuleManagerDelegate.cpp $(LOCAL_PATH)/ReactCommon/OnLoad.cpp $(LOCAL_PATH)/ReactCommon/TurboModuleManager.cpp LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(LOCAL_SRC_FILES)) + # Build the files in this directory as a shared library include $(BUILD_SHARED_LIBRARY) 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 741c05949a7..06ed578353b 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 @@ -3,11 +3,13 @@ load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "FBJNI_TARGET", "react_nat rn_xplat_cxx_library( name = "jni", srcs = [ + "ReactCommon/CompositeTurboModuleManagerDelegate.cpp", "ReactCommon/OnLoad.cpp", "ReactCommon/TurboModuleManager.cpp", ], header_namespace = "", exported_headers = { + "ReactCommon/CompositeTurboModuleManagerDelegate.h": "ReactCommon/CompositeTurboModuleManagerDelegate.h", "ReactCommon/TurboModuleManager.h": "ReactCommon/TurboModuleManager.h", "ReactCommon/TurboModuleManagerDelegate.h": "ReactCommon/TurboModuleManagerDelegate.h", }, diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/CMakeLists.txt b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/CMakeLists.txt index 02cfe42beea..b5a9449bb9e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/CMakeLists.txt +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/CMakeLists.txt @@ -43,8 +43,9 @@ target_link_libraries(callinvokerholder add_library( turbomodulejsijni SHARED - ReactCommon/TurboModuleManager.cpp + ReactCommon/CompositeTurboModuleManagerDelegate.cpp ReactCommon/OnLoad.cpp + ReactCommon/TurboModuleManager.cpp ) target_include_directories( diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CompositeTurboModuleManagerDelegate.cpp b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CompositeTurboModuleManagerDelegate.cpp new file mode 100644 index 00000000000..a84c819e429 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CompositeTurboModuleManagerDelegate.cpp @@ -0,0 +1,59 @@ +/* + * 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 "CompositeTurboModuleManagerDelegate.h" + +namespace facebook { +namespace react { + +jni::local_ref +CompositeTurboModuleManagerDelegate::initHybrid(jni::alias_ref) { + return makeCxxInstance(); +} + +void CompositeTurboModuleManagerDelegate::registerNatives() { + registerHybrid({ + makeNativeMethod( + "initHybrid", CompositeTurboModuleManagerDelegate::initHybrid), + makeNativeMethod( + "addTurboModuleManagerDelegate", + CompositeTurboModuleManagerDelegate::addTurboModuleManagerDelegate), + }); +} + +std::shared_ptr +CompositeTurboModuleManagerDelegate::getTurboModule( + const std::string moduleName, + const std::shared_ptr jsInvoker) { + for (auto delegate : mDelegates_) { + if (auto turboModule = delegate->getTurboModule(moduleName, jsInvoker)) { + return turboModule; + } + } + return nullptr; +} + +std::shared_ptr +CompositeTurboModuleManagerDelegate::getTurboModule( + const std::string moduleName, + const JavaTurboModule::InitParams ¶ms) { + for (auto delegate : mDelegates_) { + if (auto turboModule = delegate->getTurboModule(moduleName, params)) { + return turboModule; + } + } + return nullptr; +} + +void CompositeTurboModuleManagerDelegate::addTurboModuleManagerDelegate( + jni::alias_ref + turboModuleManagerDelegate) { + mDelegates_.insert(turboModuleManagerDelegate->cthis()); +} + +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CompositeTurboModuleManagerDelegate.h b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CompositeTurboModuleManagerDelegate.h new file mode 100644 index 00000000000..12b370d66c6 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/CompositeTurboModuleManagerDelegate.h @@ -0,0 +1,49 @@ +/* + * 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 +#include +#include + +namespace facebook { +namespace react { + +class CompositeTurboModuleManagerDelegate + : public jni::HybridClass< + CompositeTurboModuleManagerDelegate, + TurboModuleManagerDelegate> { + public: + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/CompositeReactPackageTurboModuleManagerDelegate;"; + + static jni::local_ref initHybrid(jni::alias_ref); + + static void registerNatives(); + + std::shared_ptr getTurboModule( + const std::string moduleName, + const std::shared_ptr jsInvoker) override; + std::shared_ptr getTurboModule( + const std::string moduleName, + const JavaTurboModule::InitParams ¶ms) override; + + private: + friend HybridBase; + using HybridBase::HybridBase; + std::unordered_set mDelegates_; + + void addTurboModuleManagerDelegate( + jni::alias_ref + turboModuleManagerDelegate); +}; + +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp index ac7f63afe6c..f4c388428f2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/ReactCommon/OnLoad.cpp @@ -9,6 +9,7 @@ #include #include +#include "CompositeTurboModuleManagerDelegate.h" #include "TurboModuleManager.h" void jniEnableCppLogging( @@ -25,6 +26,8 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { // "ComponentDescriptorFactory" is defined in Fabric facebook::react::TurboModuleManager::registerNatives(); + facebook::react::CompositeTurboModuleManagerDelegate::registerNatives(); + facebook::jni::registerNatives( "com/facebook/react/turbomodule/core/TurboModulePerfLogger", {makeNativeMethod("jniEnableCppLogging", jniEnableCppLogging)});