Skip to content

Commit

Permalink
Reduce the amount of C++ code in user space for RN-Tester
Browse files Browse the repository at this point in the history
Summary:
This diff reduces the amount of C++ code in user space by:
- Moving all the C++ implementation of the .defaults package inside a `react_newarchdefaults` shared library
- Exposing only the entrypoint logic inside the RN-Tester's `OnLoad.cpp` file.

Changelog:
[Android] [Changed] - Reduce the amount of C++ code in user space for New Architecture

Reviewed By: cipolleschi

Differential Revision: D39381820

fbshipit-source-id: 9c4b5596b67b5a7ee58824319c80e325348ed06c
  • Loading branch information
cortinico authored and facebook-github-bot committed Sep 12, 2022
1 parent 90e7f51 commit e89bd4a
Show file tree
Hide file tree
Showing 19 changed files with 245 additions and 132 deletions.
8 changes: 8 additions & 0 deletions ReactAndroid/Android-prebuilt.mk
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ LOCAL_EXPORT_C_INCLUDES := \
$(REACT_COMMON_DIR)/react/renderer/componentregistry
include $(PREBUILT_SHARED_LIBRARY)

# react_newarchdefaults
include $(CLEAR_VARS)
LOCAL_MODULE := react_newarchdefaults
LOCAL_SRC_FILES := $(REACT_NDK_EXPORT_DIR)/$(TARGET_ARCH_ABI)/libreact_newarchdefaults.so
LOCAL_EXPORT_C_INCLUDES := \
$(REACT_ANDROID_SRC_DIR)/jni/react/newarchdefaults
include $(PREBUILT_SHARED_LIBRARY)

# jsi
include $(CLEAR_VARS)
LOCAL_MODULE := jsi
Expand Down
1 change: 1 addition & 0 deletions ReactAndroid/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ android {
"jsijniprofiler",
"reactnativeblob",
"reactperfloggerjni",
"react_newarchdefaults",
"turbomodulejsijni",
"fabricjni"
}
Expand Down
8 changes: 8 additions & 0 deletions ReactAndroid/cmake-utils/Android-prebuilt.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,14 @@ set_target_properties(react_render_componentregistry
${REACT_NDK_EXPORT_DIR}/${ANDROID_ABI}/libreact_render_componentregistry.so)
target_include_directories(react_render_componentregistry INTERFACE ${REACT_COMMON_DIR}/react/renderer/componentregistry)

## react_newarchdefaults
add_library(react_newarchdefaults SHARED IMPORTED GLOBAL)
set_target_properties(react_newarchdefaults
PROPERTIES
IMPORTED_LOCATION
${REACT_NDK_EXPORT_DIR}/${ANDROID_ABI}/libreact_newarchdefaults.so)
target_include_directories(react_newarchdefaults INTERFACE ${REACT_ANDROID_SRC_DIR}/jni/react/newarchdefaults)

## jsi
add_library(jsi SHARED IMPORTED GLOBAL)
set_target_properties(jsi
Expand Down
1 change: 1 addition & 0 deletions ReactAndroid/cmake-utils/ReactNative-application.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ target_link_libraries(${CMAKE_PROJECT_NAME}
react_codegen_rncore
react_debug
react_nativemodule_core
react_newarchdefaults
react_render_componentregistry
react_render_core
react_render_debug
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ import com.facebook.react.fabric.ComponentFactory
* A utility class that provides users a ComponentRegistry they can customize with a C++
* implementation of its native methods.
*
* Please note that you need to provide a native implementation for the method initHybrid for this
* class, making sure the Java Descriptor is:
* Lcom/facebook/react/defaults/DefaultComponentsRegistry;
* This class works together with the [DefaultNativeEntryPoint] and it's C++ implementation is
* hosted inside the React Native framwork
*/
@DoNotStrip
class DefaultComponentsRegistry
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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.defaults

import com.facebook.jni.HybridData
import com.facebook.proguard.annotations.DoNotStrip
import com.facebook.soloader.SoLoader

/**
* A utility class that serves as an entry point for users to register all the custom Fabric
* Components and Turbo Native Modules.
*
* This class needs to be invoked as `DefaultNativeEntryPoint.load("...")` by passing the name of
* the dynamic library to load.
*
* This class works together with the [DefaultNativeEntryPoint] and it's C++ implementation is
* hosted inside the React Native framework
*/
@DoNotStrip
class DefaultNativeEntryPoint @DoNotStrip private constructor() {

@DoNotStrip private val hybridData: HybridData = initHybrid()

@DoNotStrip private external fun initHybrid(): HybridData

companion object {
@JvmStatic
fun load(dynamicLibraryName: String) {
SoLoader.loadLibrary("react_newarchdefaults")
SoLoader.loadLibrary(dynamicLibraryName)
DefaultNativeEntryPoint()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ import com.facebook.react.bridge.ReactApplicationContext
* A utility class that allows you to simplify the setup of a
* [ReactPackageTurboModuleManagerDelegate] for new apps in Open Source.
*
* Please note that you need to provide a native implementation for the method initHybrid for this
* class, making sure the Java Descriptor is:
* Lcom/facebook/react/defaults/DefaultTurboModuleManagerDelegate;
* This class works together with the [DefaultNativeEntryPoint] and it's C++ implementation is
* hosted inside the React Native framwork
*/
class DefaultTurboModuleManagerDelegate
private constructor(context: ReactApplicationContext, packages: List<ReactPackage>) :
Expand Down
1 change: 1 addition & 0 deletions ReactAndroid/src/main/jni/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ add_react_android_subdir(src/main/jni/react/uimanager)
add_react_android_subdir(src/main/jni/react/mapbuffer)
add_react_android_subdir(src/main/jni/react/reactnativeblob)
add_react_android_subdir(src/main/jni/react/fabric)
add_react_android_subdir(src/main/jni/react/newarchdefaults)
add_react_android_subdir(src/main/jni/react/hermes/reactexecutor)
add_react_android_subdir(src/main/jni/react/hermes/instrumentation/)

22 changes: 22 additions & 0 deletions ReactAndroid/src/main/jni/react/newarchdefaults/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# 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.

cmake_minimum_required(VERSION 3.13)
set(CMAKE_VERBOSE_MAKEFILE on)

add_compile_options(-fexceptions -frtti -std=c++17 -Wall -DLOG_TAG=\"ReactNative\")

file(GLOB react_newarchdefaults_SRC CONFIGURE_DEPENDS *.cpp)

add_library(react_newarchdefaults SHARED ${react_newarchdefaults_SRC})

target_include_directories(react_newarchdefaults PUBLIC .)

target_link_libraries(react_newarchdefaults
fbjni
fabricjni
react_nativemodule_core
react_codegen_rncore
jsi)
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,34 @@
* LICENSE file in the root directory of this source tree.
*/

#include "RNTesterComponentsRegistry.h"
#include "DefaultComponentsRegistry.h"

#include <CoreComponentsRegistry.h>
#include <fbjni/fbjni.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/components/AppSpecs/ComponentDescriptors.h>
#include <react/renderer/components/rncore/ComponentDescriptors.h>

namespace facebook {
namespace react {

RNTesterComponentsRegistry::RNTesterComponentsRegistry(
ComponentFactory *delegate)
std::function<void(std::shared_ptr<ComponentDescriptorProviderRegistry const>)>
DefaultComponentsRegistry::registerComponentDescriptorsFromEntryPoint{};

DefaultComponentsRegistry::DefaultComponentsRegistry(ComponentFactory *delegate)
: delegate_(delegate) {}

std::shared_ptr<ComponentDescriptorProviderRegistry const>
RNTesterComponentsRegistry::sharedProviderRegistry() {
DefaultComponentsRegistry::sharedProviderRegistry() {
auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();

providerRegistry->add(concreteComponentDescriptorProvider<
RNTMyNativeViewComponentDescriptor>());
(DefaultComponentsRegistry::registerComponentDescriptorsFromEntryPoint)(
providerRegistry);

return providerRegistry;
}

jni::local_ref<RNTesterComponentsRegistry::jhybriddata>
RNTesterComponentsRegistry::initHybrid(
jni::local_ref<DefaultComponentsRegistry::jhybriddata>
DefaultComponentsRegistry::initHybrid(
jni::alias_ref<jclass>,
ComponentFactory *delegate) {
auto instance = makeCxxInstance(delegate);
Expand All @@ -40,7 +41,7 @@ RNTesterComponentsRegistry::initHybrid(
[](EventDispatcher::Weak const &eventDispatcher,
ContextContainer::Shared const &contextContainer)
-> ComponentDescriptorRegistry::Shared {
auto registry = RNTesterComponentsRegistry::sharedProviderRegistry()
auto registry = DefaultComponentsRegistry::sharedProviderRegistry()
->createComponentDescriptorRegistry(
{eventDispatcher, contextContainer});

Expand All @@ -59,9 +60,9 @@ RNTesterComponentsRegistry::initHybrid(
return instance;
}

void RNTesterComponentsRegistry::registerNatives() {
void DefaultComponentsRegistry::registerNatives() {
registerHybrid({
makeNativeMethod("initHybrid", RNTesterComponentsRegistry::initHybrid),
makeNativeMethod("initHybrid", DefaultComponentsRegistry::initHybrid),
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,24 @@
#include <fbjni/fbjni.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>

namespace facebook {
namespace react {

class RNTesterComponentsRegistry
: public facebook::jni::HybridClass<RNTesterComponentsRegistry> {
class DefaultComponentsRegistry
: public facebook::jni::HybridClass<DefaultComponentsRegistry> {
public:
constexpr static auto kJavaDescriptor =
"Lcom/facebook/react/defaults/DefaultComponentsRegistry;";

static void registerNatives();

RNTesterComponentsRegistry(ComponentFactory *delegate);
static std::function<void(
std::shared_ptr<ComponentDescriptorProviderRegistry const>)>
registerComponentDescriptorsFromEntryPoint;

DefaultComponentsRegistry(ComponentFactory *delegate);

private:
friend HybridBase;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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 "DefaultTurboModuleManagerDelegate.h"

#include <rncore.h>

namespace facebook {
namespace react {

std::function<std::shared_ptr<TurboModule>(
const std::string &,
const JavaTurboModule::InitParams &)>
DefaultTurboModuleManagerDelegate::moduleProvidersFromEntryPoint{nullptr};

jni::local_ref<DefaultTurboModuleManagerDelegate::jhybriddata>
DefaultTurboModuleManagerDelegate::initHybrid(jni::alias_ref<jhybridobject>) {
return makeCxxInstance();
}

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

std::shared_ptr<TurboModule> DefaultTurboModuleManagerDelegate::getTurboModule(
const std::string &name,
const std::shared_ptr<CallInvoker> &jsInvoker) {
// Not implemented yet: provide pure-C++ NativeModules here.
return nullptr;
}

std::shared_ptr<TurboModule> DefaultTurboModuleManagerDelegate::getTurboModule(
const std::string &name,
const JavaTurboModule::InitParams &params) {
auto resolvedModule = (DefaultTurboModuleManagerDelegate::
moduleProvidersFromEntryPoint)(name, params);
if (resolvedModule != nullptr) {
return resolvedModule;
}
return rncore_ModuleProvider(name, params);
}

} // namespace react
} // namespace facebook
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@
#include <memory>
#include <string>

#include <ReactCommon/JavaTurboModule.h>
#include <ReactCommon/TurboModule.h>
#include <ReactCommon/TurboModuleManagerDelegate.h>
#include <fbjni/fbjni.h>

namespace facebook {
namespace react {

class RNTesterTurboModuleManagerDelegate
: public jni::HybridClass<
RNTesterTurboModuleManagerDelegate,
TurboModuleManagerDelegate> {
class DefaultTurboModuleManagerDelegate : public jni::HybridClass<
DefaultTurboModuleManagerDelegate,
TurboModuleManagerDelegate> {
public:
static constexpr auto kJavaDescriptor =
"Lcom/facebook/react/defaults/DefaultTurboModuleManagerDelegate;";
Expand All @@ -26,6 +27,11 @@ class RNTesterTurboModuleManagerDelegate

static void registerNatives();

static std::function<std::shared_ptr<TurboModule>(
const std::string &,
const JavaTurboModule::InitParams &)>
moduleProvidersFromEntryPoint;

std::shared_ptr<TurboModule> getTurboModule(
const std::string &name,
const std::shared_ptr<CallInvoker> &jsInvoker) override;
Expand Down
18 changes: 18 additions & 0 deletions ReactAndroid/src/main/jni/react/newarchdefaults/OnLoad.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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 <fbjni/fbjni.h>

#include "DefaultComponentsRegistry.h"
#include "DefaultTurboModuleManagerDelegate.h"

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
return facebook::jni::initialize(vm, [] {
facebook::react::DefaultTurboModuleManagerDelegate::registerNatives();
facebook::react::DefaultComponentsRegistry::registerNatives();
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.defaults.DefaultNativeEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;
Expand Down Expand Up @@ -122,7 +123,7 @@ public void onCreate() {
ReactFontManager.getInstance().addCustomFont(this, "Rubik", R.font.rubik);
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
SoLoader.loadLibrary(BuildConfig.DYNAMIC_LIBRARY_NAME);
DefaultNativeEntryPoint.load(BuildConfig.DYNAMIC_LIBRARY_NAME);
ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}

Expand Down
Loading

0 comments on commit e89bd4a

Please sign in to comment.