diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 8512bcd07989..ee037a3c685f 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3974,8 +3974,9 @@ public abstract interface class com/facebook/react/uimanager/ComponentNameResolv public abstract fun getComponentNames ()[Ljava/lang/String; } -public class com/facebook/react/uimanager/ComponentNameResolverManager { - public fun (Lcom/facebook/react/bridge/RuntimeExecutor;Ljava/lang/Object;)V +public final class com/facebook/react/uimanager/ComponentNameResolverBinding { + public static final field INSTANCE Lcom/facebook/react/uimanager/ComponentNameResolverBinding; + public static final fun install (Lcom/facebook/react/bridge/RuntimeExecutor;Ljava/lang/Object;)V } public class com/facebook/react/uimanager/DisplayMetricsHolder { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java index e5fc1c06671b..dc0d975e26f1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java @@ -52,7 +52,7 @@ import com.facebook.react.turbomodule.core.CallInvokerHolderImpl; import com.facebook.react.turbomodule.core.NativeMethodCallInvokerHolderImpl; import com.facebook.react.uimanager.ComponentNameResolver; -import com.facebook.react.uimanager.ComponentNameResolverManager; +import com.facebook.react.uimanager.ComponentNameResolverBinding; import com.facebook.react.uimanager.DisplayMetricsHolder; import com.facebook.react.uimanager.IllegalViewOperationException; import com.facebook.react.uimanager.UIConstantsProviderManager; @@ -97,7 +97,6 @@ final class ReactInstance { private JavaScriptContextHolder mJavaScriptContextHolder; - @DoNotStrip @Nullable private ComponentNameResolverManager mComponentNameResolverManager; @DoNotStrip @Nullable private UIConstantsProviderManager mUIConstantsProviderManager; static { @@ -212,19 +211,18 @@ final class ReactInstance { new BridgelessViewManagerResolver(mReactPackages, mBridgelessReactContext); // Initialize function for JS's UIManager.hasViewManagerConfig() - mComponentNameResolverManager = - new ComponentNameResolverManager( - // Use unbuffered RuntimeExecutor to install binding - unbufferedRuntimeExecutor, - (ComponentNameResolver) - () -> { - Collection viewManagerNames = mViewManagerResolver.getViewManagerNames(); - if (viewManagerNames.size() < 1) { - FLog.e(TAG, "No ViewManager names found"); - return new String[0]; - } - return viewManagerNames.toArray(new String[0]); - }); + ComponentNameResolverBinding.install( + // Use unbuffered RuntimeExecutor to install binding + unbufferedRuntimeExecutor, + (ComponentNameResolver) + () -> { + Collection viewManagerNames = mViewManagerResolver.getViewManagerNames(); + if (viewManagerNames.size() < 1) { + FLog.e(TAG, "No ViewManager names found"); + return new String[0]; + } + return viewManagerNames.toArray(new String[0]); + }); // Initialize function for JS's UIManager.getViewManagerConfig() // It should come after getTurboModuleManagerDelegate as it relies on react packages being @@ -432,7 +430,6 @@ public Collection getNativeModules() { mFabricUIManager.invalidate(); mJavaTimerManager.onInstanceDestroy(); mHybridData.resetNative(); - mComponentNameResolverManager = null; mUIConstantsProviderManager = null; mJavaScriptContextHolder.clear(); } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ComponentNameResolverBinding.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ComponentNameResolverBinding.kt new file mode 100644 index 000000000000..3981f1181505 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ComponentNameResolverBinding.kt @@ -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. + */ + +package com.facebook.react.uimanager + +import com.facebook.proguard.annotations.DoNotStripAny +import com.facebook.react.bridge.RuntimeExecutor +import com.facebook.soloader.SoLoader +import kotlin.jvm.JvmStatic + +@DoNotStripAny +object ComponentNameResolverBinding { + init { + SoLoader.loadLibrary("uimanagerjni") + } + + @JvmStatic external fun install(runtimeExecutor: RuntimeExecutor, componentNameResolver: Object) +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ComponentNameResolverManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ComponentNameResolverManager.java deleted file mode 100644 index ac97b95c3c7e..000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ComponentNameResolverManager.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.uimanager; - -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.jni.HybridData; -import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.proguard.annotations.DoNotStripAny; -import com.facebook.react.bridge.RuntimeExecutor; -import com.facebook.soloader.SoLoader; - -@Nullsafe(Nullsafe.Mode.LOCAL) -@DoNotStripAny -public class ComponentNameResolverManager { - - static { - 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(); - - private static void staticInit() { - SoLoader.loadLibrary("uimanagerjni"); - } -} diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverBinding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverBinding.cpp new file mode 100644 index 000000000000..952f73107fc2 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverBinding.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 "ComponentNameResolverBinding.h" + +#include + +#include + +namespace facebook::react { + +using namespace facebook::jni; + +constexpr static auto ComponentNameResolverJavaDescriptor = + "com/facebook/react/uimanager/ComponentNameResolver"; + +void ComponentNameResolverBinding::registerNatives() { + javaClassStatic()->registerNatives({ + makeNativeMethod("install", ComponentNameResolverBinding::install), + }); +} + +void ComponentNameResolverBinding::install( + jni::alias_ref /* unused */, + jni::alias_ref runtimeExecutor, + jni::alias_ref componentNameResolver) { + auto executor = runtimeExecutor->cthis()->get(); + executor([componentNameResolver = make_global(componentNameResolver)]( + jsi::Runtime& runtime) mutable { + auto viewManagerProvider = + [componentNameResolver = std::move(componentNameResolver), + componentNames = std::unordered_set()]( + const std::string& name) mutable { + if (componentNames.empty()) { + static auto getComponentNames = + jni::findClassStatic(ComponentNameResolverJavaDescriptor) + ->getMethod>()>( + "getComponentNames"); + + auto componentNamesJArray = + getComponentNames(componentNameResolver); + auto len = componentNamesJArray->size(); + for (size_t i = 0; i < len; i++) { + jni::local_ref elem = (*componentNamesJArray)[i]; + componentNames.insert(elem->toStdString()); + } + } + return componentNames.find(name) != componentNames.end(); + }; + + bindHasComponentProvider(runtime, std::move(viewManagerProvider)); + }); +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverBinding.h b/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverBinding.h new file mode 100644 index 000000000000..fb0b9f7cb38f --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverBinding.h @@ -0,0 +1,29 @@ +/* + * 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 + +namespace facebook::react { + +class ComponentNameResolverBinding + : public facebook::jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/uimanager/ComponentNameResolverBinding;"; + + static void install( + jni::alias_ref /* unused */, + jni::alias_ref runtimeExecutor, + jni::alias_ref componentNameResolver); + + static void registerNatives(); +}; + +} // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverManager.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverManager.cpp deleted file mode 100644 index 27b4c1b3ceea..000000000000 --- a/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverManager.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 "ComponentNameResolverManager.h" - -#include - -namespace facebook::react { - -using namespace facebook::jni; - -constexpr static auto ComponentNameResolverJavaDescriptor = - "com/facebook/react/uimanager/ComponentNameResolver"; - -ComponentNameResolverManager::ComponentNameResolverManager( - RuntimeExecutor runtimeExecutor, - jni::alias_ref componentNameResolver) - : runtimeExecutor_(std::move(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( - runtimeExecutor->cthis()->get(), componentNameResolver); -} - -void ComponentNameResolverManager::registerNatives() { - registerHybrid({ - makeNativeMethod("initHybrid", ComponentNameResolverManager::initHybrid), - makeNativeMethod( - "installJSIBindings", - ComponentNameResolverManager::installJSIBindings), - }); -} - -void ComponentNameResolverManager::installJSIBindings() { - runtimeExecutor_([this](jsi::Runtime& runtime) { - auto viewManagerProvider = [this](const std::string& name) -> bool { - if (componentNames_.size() == 0) { - static auto getComponentNames = - jni::findClassStatic(ComponentNameResolverJavaDescriptor) - ->getMethod>()>( - "getComponentNames"); - - auto componentNamesJArray = getComponentNames(componentNameResolver_); - auto len = componentNamesJArray->size(); - for (size_t i = 0; i < len; i++) { - jni::local_ref elem = (*componentNamesJArray)[i]; - componentNames_.insert(elem->toStdString()); - } - } - return componentNames_.find(name) != componentNames_.end(); - }; - bindHasComponentProvider(runtime, std::move(viewManagerProvider)); - }); -} - -} // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverManager.h b/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverManager.h deleted file mode 100644 index c5462e510cb2..000000000000 --- a/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverManager.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 ComponentNameResolverManager - : public facebook::jni::HybridClass { - public: - static auto constexpr kJavaDescriptor = - "Lcom/facebook/react/uimanager/ComponentNameResolverManager;"; - - static facebook::jni::local_ref initHybrid( - facebook::jni::alias_ref jThis, - facebook::jni::alias_ref runtimeExecutor, - facebook::jni::alias_ref componentNameResolver); - - static void registerNatives(); - - private: - friend HybridBase; - - RuntimeExecutor runtimeExecutor_; - facebook::jni::global_ref componentNameResolver_; - std::unordered_set componentNames_; - - void installJSIBindings(); - - explicit ComponentNameResolverManager( - RuntimeExecutor runtimeExecutor, - facebook::jni::alias_ref componentNameResolver); -}; - -} // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/OnLoad.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/OnLoad.cpp index cf7ae8ea4868..620e8cff6303 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/OnLoad.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/uimanager/OnLoad.cpp @@ -7,12 +7,12 @@ #include -#include "ComponentNameResolverManager.h" +#include "ComponentNameResolverBinding.h" #include "UIConstantsProviderManager.h" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { return facebook::jni::initialize(vm, [] { - facebook::react::ComponentNameResolverManager::registerNatives(); + facebook::react::ComponentNameResolverBinding::registerNatives(); facebook::react::UIConstantsProviderManager::registerNatives(); }); }