diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/ComponentNameResolver.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/ComponentNameResolver.java new file mode 100644 index 00000000000..0619fa1fe12 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/ComponentNameResolver.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) Facebook, Inc. and its 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.fabric; + +import com.facebook.proguard.annotations.DoNotStrip; + +@DoNotStrip +public interface ComponentNameResolver { + + /* returns a list of all the component names that are registered in React Native. */ + String[] getComponentNames(); +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/ComponentNameResolverManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/ComponentNameResolverManager.java new file mode 100644 index 00000000000..a5b5107d61d --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/ComponentNameResolverManager.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) Facebook, Inc. and its 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.fabric; + +import com.facebook.jni.HybridData; +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.bridge.RuntimeExecutor; + +public class ComponentNameResolverManager { + + static { + FabricSoLoader.staticInit(); + } + + @DoNotStrip + @SuppressWarnings("unused") + private final HybridData mHybridData; + + public ComponentNameResolverManager( + RuntimeExecutor runtimeExecutor, Object componentNameResolver) { + mHybridData = initHybrid(runtimeExecutor, componentNameResolver); + installJSIBindings(); + } + + private native HybridData initHybrid( + RuntimeExecutor runtimeExecutor, Object componentNameResolver); + + private native void installJSIBindings(); +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentNameResolverManager.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentNameResolverManager.cpp new file mode 100644 index 00000000000..cbc58f54421 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentNameResolverManager.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include + +#include +#include + +#include "ComponentNameResolverManager.h" + +#include + +namespace facebook { +namespace react { + +ComponentNameResolverManager::ComponentNameResolverManager( + jni::alias_ref jThis, + RuntimeExecutor runtimeExecutor, + jni::alias_ref componentNameResolver) + : javaPart_(jni::make_global(jThis)), + runtimeExecutor_(runtimeExecutor), + componentNameResolver_(jni::make_global(componentNameResolver)) {} + +jni::local_ref +ComponentNameResolverManager::initHybrid( + jni::alias_ref jThis, + jni::alias_ref runtimeExecutor, + jni::alias_ref componentNameResolver) { + return makeCxxInstance( + jThis, runtimeExecutor->cthis()->get(), componentNameResolver); +} + +void ComponentNameResolverManager::registerNatives() { + registerHybrid({ + makeNativeMethod("initHybrid", ComponentNameResolverManager::initHybrid), + makeNativeMethod( + "installJSIBindings", + ComponentNameResolverManager::installJSIBindings), + }); +} + +void ComponentNameResolverManager::installJSIBindings() { + runtimeExecutor_([thizz = this](jsi::Runtime &runtime) { + auto viewManagerProvider = [thizz](const std::string &name) -> bool { + if (thizz->componentNames_.size() == 0) { + static auto getComponentNames = + jni::findClassStatic(ComponentNameResolverManager:: + ComponentNameResolverJavaDescriptor) + ->getMethod>()>( + "getComponentNames"); + + auto componentNamesJArray = + getComponentNames(thizz->componentNameResolver_.get()); + auto len = componentNamesJArray->size(); + for (size_t i = 0; i < len; i++) { + jni::local_ref elem = (*componentNamesJArray)[i]; + auto componentName = elem->toStdString(); + thizz->componentNames_.insert(componentName); + } + } + + return thizz->componentNames_.find(name) != thizz->componentNames_.end(); + }; + + react::NativeComponentRegistryBinding::install( + runtime, std::move(viewManagerProvider)); + }); +} + +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentNameResolverManager.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentNameResolverManager.h new file mode 100644 index 00000000000..37391305186 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/ComponentNameResolverManager.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) Facebook, Inc. and its 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 +#include +#include +#include + +using namespace facebook::jni; +using namespace facebook::jsi; + +namespace facebook { +namespace react { + +class ComponentNameResolverManager + : public jni::HybridClass { + public: + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/fabric/ComponentNameResolverManager;"; + + constexpr static auto ComponentNameResolverJavaDescriptor = + "com/facebook/react/fabric/ComponentNameResolver"; + + static jni::local_ref initHybrid( + jni::alias_ref jThis, + jni::alias_ref runtimeExecutor, + jni::alias_ref componentNameResolver); + + static void registerNatives(); + + private: + friend HybridBase; + jni::global_ref javaPart_; + RuntimeExecutor runtimeExecutor_; + + jni::global_ref componentNameResolver_; + + std::set componentNames_; + + void installJSIBindings(); + + explicit ComponentNameResolverManager( + jni::alias_ref jThis, + RuntimeExecutor runtimeExecutor, + jni::alias_ref componentNameResolver); +}; + +} // namespace react +} // namespace facebook diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp index 03005372a65..745c39cbb5f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/OnLoad.cpp @@ -9,6 +9,7 @@ #include "Binding.h" #include "ComponentFactory.h" +#include "ComponentNameResolverManager.h" #include "CoreComponentsRegistry.h" #include "EventBeatManager.h" #include "EventEmitterWrapper.h" @@ -21,6 +22,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { facebook::react::EventEmitterWrapper::registerNatives(); facebook::react::StateWrapperImpl::registerNatives(); facebook::react::ComponentFactory::registerNatives(); + facebook::react::ComponentNameResolverManager::registerNatives(); facebook::react::CoreComponentsRegistry::registerNatives(); }); }