From 7617ba8811e16808457163497a78b6ee7ae73328 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Wed, 20 May 2026 06:08:18 -0700 Subject: [PATCH] Migrate NativeViewHierarchyManager from Java to Kotlin (#56828) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/56828 Mechanical migration of the deprecated `NativeViewHierarchyManager` stub class from Java to Kotlin. All methods remain empty stubs — no behavioral changes. Key migration decisions: - Class marked `open` to preserve subclassability from Java/Kotlin - All non-final public/protected methods marked `open` to match Java virtual-by-default - `resolveView` and `resolveViewManager` remain `final` (matching the Java original) - `Nullable` return types converted to Kotlin nullable types (`?`) - `synchronized` methods use `Synchronized` annotation - Static initializer converted to companion object `init` block Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D104999732 --- .../ReactAndroid/api/ReactAndroid.api | 6 +- .../uimanager/NativeViewHierarchyManager.java | 221 ------------------ .../uimanager/NativeViewHierarchyManager.kt | 184 +++++++++++++++ 3 files changed, 188 insertions(+), 223 deletions(-) delete mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index af2c1b8dfe99..1c19f4af42d6 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3457,8 +3457,8 @@ public final class com/facebook/react/uimanager/MeasureSpecAssertions { } public class com/facebook/react/uimanager/NativeViewHierarchyManager { + public static final field Companion Lcom/facebook/react/uimanager/NativeViewHierarchyManager$Companion; public fun (Lcom/facebook/react/uimanager/ViewManagerRegistry;)V - public fun (Lcom/facebook/react/uimanager/ViewManagerRegistry;Lcom/facebook/react/uimanager/RootViewManager;)V public fun addRootView (ILandroid/view/View;)V protected final fun addRootViewGroup (ILandroid/view/View;)V public fun clearJSResponder ()V @@ -3469,7 +3469,6 @@ public class com/facebook/react/uimanager/NativeViewHierarchyManager { public fun findTargetTagForTouch (IFF)I public fun getInstanceHandle (I)J public fun getRootViewNum ()I - public fun manageChildren (I[I[Lcom/facebook/react/uimanager/ViewAtIndex;[I)V public fun measure (I[I)V public fun measureInWindow (I[I)V public fun removeRootView (I)V @@ -3486,6 +3485,9 @@ public class com/facebook/react/uimanager/NativeViewHierarchyManager { public fun updateViewExtraData (ILjava/lang/Object;)V } +public final class com/facebook/react/uimanager/NativeViewHierarchyManager$Companion { +} + public final class com/facebook/react/uimanager/NativeViewHierarchyOptimizer { public fun ()V } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java deleted file mode 100644 index 25b8e4d954e3..000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ /dev/null @@ -1,221 +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 android.view.View; -import androidx.annotation.Nullable; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.common.annotations.internal.LegacyArchitecture; -import com.facebook.react.common.annotations.internal.LegacyArchitectureLogLevel; -import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger; - -/** - * @deprecated This class is part of Legacy Architecture and has been stubbed out. It will be - * removed in a future release. - */ -@LegacyArchitecture(logLevel = LegacyArchitectureLogLevel.ERROR) -@Deprecated( - since = "This class is part of Legacy Architecture and will be removed in a future release") -public class NativeViewHierarchyManager { - - static { - LegacyArchitectureLogger.assertLegacyArchitecture( - "NativeViewHierarchyManager", LegacyArchitectureLogLevel.ERROR); - } - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public NativeViewHierarchyManager(ViewManagerRegistry viewManagers) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public NativeViewHierarchyManager(ViewManagerRegistry viewManagers, RootViewManager manager) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public final synchronized @Nullable View resolveView(int tag) { - return null; - } - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public final synchronized @Nullable ViewManager resolveViewManager(int tag) { - return null; - } - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public void setLayoutAnimationEnabled(boolean enabled) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void updateInstanceHandle(int tag, long instanceHandle) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void updateProperties(int tag, ReactStylesDiffMap props) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void updateViewExtraData(int tag, Object extraData) {} - - /** - * @deprecated Please use {@link #updateLayout(int tag, int x, int y, int width, int height, - * YogaDirection layoutDirection)} instead. - */ - @Deprecated - public void updateLayout(int tag, int x, int y, int width, int height) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void updateLayout( - int parentTag, - int tag, - int x, - int y, - int width, - int height, - com.facebook.yoga.YogaDirection layoutDirection) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized long getInstanceHandle(int reactTag) { - return 0; - } - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void createView( - ThemedReactContext themedContext, - int tag, - String className, - @Nullable ReactStylesDiffMap initialProps) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void manageChildren( - int tag, - @Nullable int[] indicesToRemove, - @Nullable ViewAtIndex[] viewsToAdd, - @Nullable int[] tagsToDelete) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void setChildren(int tag, ReadableArray childrenTags) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void addRootView(int tag, View view) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - protected final synchronized void addRootViewGroup(int tag, View view) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - protected synchronized void dropView(View view) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void removeRootView(int rootViewTag) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized int getRootViewNum() { - return 0; - } - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void measure(int tag, int[] outputBuffer) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void measureInWindow(int tag, int[] outputBuffer) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized int findTargetTagForTouch(int reactTag, float touchX, float touchY) { - return 0; - } - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void setJSResponder( - int reactTag, int initialReactTag, boolean blockNativeResponder) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void clearJSResponder() {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void dispatchCommand( - int reactTag, int commandId, @Nullable ReadableArray args) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void dispatchCommand( - int reactTag, String commandId, @Nullable ReadableArray args) {} - - /** - * @deprecated Use new architecture instead. - */ - @Deprecated - public synchronized void sendAccessibilityEvent(int tag, int eventType) {} -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.kt new file mode 100644 index 000000000000..40e1772e5b1e --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.kt @@ -0,0 +1,184 @@ +/* + * 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 android.view.View +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.common.annotations.internal.LegacyArchitecture +import com.facebook.react.common.annotations.internal.LegacyArchitectureLogLevel +import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger + +/** + * This class is part of Legacy Architecture and has been stubbed out. It will be removed in a + * future release. + */ +@LegacyArchitecture(logLevel = LegacyArchitectureLogLevel.ERROR) +@Deprecated("This class is part of Legacy Architecture and will be removed in a future release") +@Suppress("DEPRECATION") +public open class NativeViewHierarchyManager { + + @Deprecated("Use new architecture instead.") public constructor(viewManagers: ViewManagerRegistry) + + @Deprecated("Use new architecture instead.") + internal constructor(viewManagers: ViewManagerRegistry, manager: RootViewManager) + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public fun resolveView(tag: Int): View? = null + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public fun resolveViewManager(tag: Int): ViewManager<*, *>? = null + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + public open fun setLayoutAnimationEnabled(enabled: Boolean): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun updateInstanceHandle(tag: Int, instanceHandle: Long): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun updateProperties(tag: Int, props: ReactStylesDiffMap?): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun updateViewExtraData(tag: Int, extraData: Any?): Unit = Unit + + /** @deprecated Please use [updateLayout] with YogaDirection parameter instead. */ + @Deprecated("Please use updateLayout with YogaDirection parameter instead.") + public open fun updateLayout(tag: Int, x: Int, y: Int, width: Int, height: Int): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun updateLayout( + parentTag: Int, + tag: Int, + x: Int, + y: Int, + width: Int, + height: Int, + layoutDirection: com.facebook.yoga.YogaDirection, + ): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun getInstanceHandle(reactTag: Int): Long = 0 + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun createView( + themedContext: ThemedReactContext, + tag: Int, + className: String, + initialProps: ReactStylesDiffMap?, + ): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + internal open fun manageChildren( + tag: Int, + indicesToRemove: IntArray?, + viewsToAdd: Array?, + tagsToDelete: IntArray?, + ): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun setChildren(tag: Int, childrenTags: ReadableArray?): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun addRootView(tag: Int, view: View): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + protected fun addRootViewGroup(tag: Int, view: View): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + protected open fun dropView(view: View): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun removeRootView(rootViewTag: Int): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun getRootViewNum(): Int = 0 + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun measure(tag: Int, outputBuffer: IntArray): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun measureInWindow(tag: Int, outputBuffer: IntArray): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun findTargetTagForTouch(reactTag: Int, touchX: Float, touchY: Float): Int = 0 + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun setJSResponder( + reactTag: Int, + initialReactTag: Int, + blockNativeResponder: Boolean, + ): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun clearJSResponder(): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun dispatchCommand(reactTag: Int, commandId: Int, args: ReadableArray?): Unit = Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun dispatchCommand(reactTag: Int, commandId: String, args: ReadableArray?): Unit = + Unit + + /** @deprecated Use new architecture instead. */ + @Deprecated("Use new architecture instead.") + @Synchronized + public open fun sendAccessibilityEvent(tag: Int, eventType: Int): Unit = Unit + + public companion object { + init { + LegacyArchitectureLogger.assertLegacyArchitecture( + "NativeViewHierarchyManager", + LegacyArchitectureLogLevel.ERROR, + ) + } + } +}