Skip to content

Commit

Permalink
Add CompositeReactPackageTurboModuleManagerDelegate [RFC]
Browse files Browse the repository at this point in the history
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
  • Loading branch information
christophpurrer authored and facebook-github-bot committed May 10, 2022
1 parent 7c581f3 commit 1f6451b
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -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<TurboModuleManagerDelegate> mDelegates;

private CompositeReactPackageTurboModuleManagerDelegate(
ReactApplicationContext context,
List<ReactPackage> packages,
List<TurboModuleManagerDelegate> 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<ReactPackageTurboModuleManagerDelegate.Builder> mDelegatesBuilder;

public Builder(@NonNull List<ReactPackageTurboModuleManagerDelegate.Builder> delegatesBuilder) {
mDelegatesBuilder = delegatesBuilder;
}

protected ReactPackageTurboModuleManagerDelegate build(
ReactApplicationContext context, List<ReactPackage> packages) {
List<TurboModuleManagerDelegate> delegates = new ArrayList<>();
for (ReactPackageTurboModuleManagerDelegate.Builder delegatesBuilder : mDelegatesBuilder) {
delegates.add(delegatesBuilder.build(context, Collections.<ReactPackage>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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
@@ -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::jhybriddata>
CompositeTurboModuleManagerDelegate::initHybrid(jni::alias_ref<jhybridobject>) {
return makeCxxInstance();
}

void CompositeTurboModuleManagerDelegate::registerNatives() {
registerHybrid({
makeNativeMethod(
"initHybrid", CompositeTurboModuleManagerDelegate::initHybrid),
makeNativeMethod(
"addTurboModuleManagerDelegate",
CompositeTurboModuleManagerDelegate::addTurboModuleManagerDelegate),
});
}

std::shared_ptr<TurboModule>
CompositeTurboModuleManagerDelegate::getTurboModule(
const std::string moduleName,
const std::shared_ptr<CallInvoker> jsInvoker) {
for (auto delegate : mDelegates_) {
if (auto turboModule = delegate->getTurboModule(moduleName, jsInvoker)) {
return turboModule;
}
}
return nullptr;
}

std::shared_ptr<TurboModule>
CompositeTurboModuleManagerDelegate::getTurboModule(
const std::string moduleName,
const JavaTurboModule::InitParams &params) {
for (auto delegate : mDelegates_) {
if (auto turboModule = delegate->getTurboModule(moduleName, params)) {
return turboModule;
}
}
return nullptr;
}

void CompositeTurboModuleManagerDelegate::addTurboModuleManagerDelegate(
jni::alias_ref<TurboModuleManagerDelegate::javaobject>
turboModuleManagerDelegate) {
mDelegates_.insert(turboModuleManagerDelegate->cthis());
}

} // namespace react
} // namespace facebook
Original file line number Diff line number Diff line change
@@ -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 <ReactCommon/TurboModuleManagerDelegate.h>
#include <fbjni/fbjni.h>
#include <memory>
#include <string>
#include <unordered_set>

namespace facebook {
namespace react {

class CompositeTurboModuleManagerDelegate
: public jni::HybridClass<
CompositeTurboModuleManagerDelegate,
TurboModuleManagerDelegate> {
public:
static auto constexpr kJavaDescriptor =
"Lcom/facebook/react/CompositeReactPackageTurboModuleManagerDelegate;";

static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>);

static void registerNatives();

std::shared_ptr<TurboModule> getTurboModule(
const std::string moduleName,
const std::shared_ptr<CallInvoker> jsInvoker) override;
std::shared_ptr<TurboModule> getTurboModule(
const std::string moduleName,
const JavaTurboModule::InitParams &params) override;

private:
friend HybridBase;
using HybridBase::HybridBase;
std::unordered_set<TurboModuleManagerDelegate *> mDelegates_;

void addTurboModuleManagerDelegate(
jni::alias_ref<TurboModuleManagerDelegate::javaobject>
turboModuleManagerDelegate);
};

} // namespace react
} // namespace facebook
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <fbjni/fbjni.h>
#include <reactperflogger/JNativeModulePerfLogger.h>

#include "CompositeTurboModuleManagerDelegate.h"
#include "TurboModuleManager.h"

void jniEnableCppLogging(
Expand All @@ -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)});
Expand Down

0 comments on commit 1f6451b

Please sign in to comment.