diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 2c1f2c179692..de3902feb928 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -4348,37 +4348,39 @@ public abstract interface class com/facebook/react/uimanager/UIManagerModule$Cus public abstract fun resolveCustomEventName (Ljava/lang/String;)Ljava/lang/String; } -public class com/facebook/react/uimanager/UIViewOperationQueue { +public final class com/facebook/react/uimanager/UIViewOperationQueue { + public static final field Companion Lcom/facebook/react/uimanager/UIViewOperationQueue$Companion; public static final field DEFAULT_MIN_TIME_LEFT_IN_FRAME_FOR_NONBATCHED_OPERATION_MS I public fun (Lcom/facebook/react/bridge/ReactApplicationContext;I)V - public fun addRootView (ILandroid/view/View;)V - public fun dispatchViewUpdates (IJJ)V - public fun enqueueClearJSResponder ()V - public fun enqueueConfigureLayoutAnimation (Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Callback;)V - public fun enqueueCreateView (Lcom/facebook/react/uimanager/ThemedReactContext;ILjava/lang/String;Lcom/facebook/react/uimanager/ReactStylesDiffMap;)V - public fun enqueueDispatchCommand (IILcom/facebook/react/bridge/ReadableArray;)V - public fun enqueueDispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V - public fun enqueueFindTargetForTouch (IFFLcom/facebook/react/bridge/Callback;)V - public fun enqueueLayoutUpdateFinished (Lcom/facebook/react/uimanager/ReactShadowNode;Lcom/facebook/react/uimanager/UIImplementation$LayoutUpdateListener;)V - public fun enqueueManageChildren (I[I[Lcom/facebook/react/uimanager/ViewAtIndex;[I)V - public fun enqueueMeasure (ILcom/facebook/react/bridge/Callback;)V - public fun enqueueMeasureInWindow (ILcom/facebook/react/bridge/Callback;)V - public fun enqueueRemoveRootView (I)V - public fun enqueueSendAccessibilityEvent (II)V - public fun enqueueSetChildren (ILcom/facebook/react/bridge/ReadableArray;)V - public fun enqueueSetJSResponder (IIZ)V - public fun enqueueSetLayoutAnimationEnabled (Z)V - public fun enqueueUIBlock (Lcom/facebook/react/uimanager/UIBlock;)V - protected fun enqueueUIOperation (Lcom/facebook/react/uimanager/UIViewOperationQueue$UIOperation;)V - public fun enqueueUpdateExtraData (ILjava/lang/Object;)V - public fun enqueueUpdateInstanceHandle (IJ)V - public fun enqueueUpdateLayout (IIIIII)V - public fun enqueueUpdateLayout (IIIIIILcom/facebook/yoga/YogaDirection;)V - public fun enqueueUpdateProperties (ILjava/lang/String;Lcom/facebook/react/uimanager/ReactStylesDiffMap;)V - public fun getProfiledBatchPerfCounters ()Ljava/util/Map; - public fun isEmpty ()Z - public fun prependUIBlock (Lcom/facebook/react/uimanager/UIBlock;)V - public fun profileNextBatch ()V + public final fun addRootView (ILandroid/view/View;)V + public final fun dispatchViewUpdates (IJJ)V + public final fun enqueueClearJSResponder ()V + public final fun enqueueConfigureLayoutAnimation (Lcom/facebook/react/bridge/ReadableMap;Lcom/facebook/react/bridge/Callback;)V + public final fun enqueueCreateView (Lcom/facebook/react/uimanager/ThemedReactContext;ILjava/lang/String;Lcom/facebook/react/uimanager/ReactStylesDiffMap;)V + public final fun enqueueDispatchCommand (IILcom/facebook/react/bridge/ReadableArray;)V + public final fun enqueueDispatchCommand (ILjava/lang/String;Lcom/facebook/react/bridge/ReadableArray;)V + public final fun enqueueFindTargetForTouch (IFFLcom/facebook/react/bridge/Callback;)V + public final fun enqueueLayoutUpdateFinished (Lcom/facebook/react/uimanager/ReactShadowNode;Lcom/facebook/react/uimanager/UIImplementation$LayoutUpdateListener;)V + public final fun enqueueMeasure (ILcom/facebook/react/bridge/Callback;)V + public final fun enqueueMeasureInWindow (ILcom/facebook/react/bridge/Callback;)V + public final fun enqueueRemoveRootView (I)V + public final fun enqueueSendAccessibilityEvent (II)V + public final fun enqueueSetChildren (ILcom/facebook/react/bridge/ReadableArray;)V + public final fun enqueueSetJSResponder (IIZ)V + public final fun enqueueSetLayoutAnimationEnabled (Z)V + public final fun enqueueUIBlock (Lcom/facebook/react/uimanager/UIBlock;)V + public final fun enqueueUpdateExtraData (ILjava/lang/Object;)V + public final fun enqueueUpdateInstanceHandle (IJ)V + public final fun enqueueUpdateLayout (IIIIII)V + public final fun enqueueUpdateLayout (IIIIIILcom/facebook/yoga/YogaDirection;)V + public final fun enqueueUpdateProperties (ILjava/lang/String;Lcom/facebook/react/uimanager/ReactStylesDiffMap;)V + public final fun getProfiledBatchPerfCounters ()Ljava/util/Map; + public final fun isEmpty ()Z + public final fun prependUIBlock (Lcom/facebook/react/uimanager/UIBlock;)V + public final fun profileNextBatch ()V +} + +public final class com/facebook/react/uimanager/UIViewOperationQueue$Companion { } public abstract interface class com/facebook/react/uimanager/UIViewOperationQueue$UIOperation { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java deleted file mode 100644 index 1de4dbdd31cb..000000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java +++ /dev/null @@ -1,147 +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.Callback; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.common.annotations.internal.LegacyArchitecture; -import com.facebook.react.common.annotations.internal.LegacyArchitectureLogLevel; -import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger; -import com.facebook.yoga.YogaDirection; -import java.util.HashMap; -import java.util.Map; - -/** - * This class acts as a buffer for command executed on {@link NativeViewHierarchyManager}. It expose - * similar methods as mentioned classes but instead of executing commands immediately it enqueues - * those operations in a queue that is then flushed from {@link UIManagerModule} once JS batch of ui - * operations is finished. This is to make sure that we execute all the JS operation coming from a - * single batch a single loop of the main (UI) android looper. - * - *

TODO(7135923): Pooling of operation objects TODO(5694019): Consider a better data structure - * for operations queue to save on allocations - * - * @deprecated This class is stubbed out and 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 UIViewOperationQueue { - - static { - LegacyArchitectureLogger.assertLegacyArchitecture( - "UIViewOperationQueue", LegacyArchitectureLogLevel.ERROR); - } - - public static final int DEFAULT_MIN_TIME_LEFT_IN_FRAME_FOR_NONBATCHED_OPERATION_MS = 8; - - /** A mutation or animation operation on the view hierarchy. */ - public interface UIOperation { - - void execute(); - } - - public UIViewOperationQueue( - ReactApplicationContext reactContext, int minTimeLeftInFrameForNonBatchedOperationMs) {} - - public void profileNextBatch() {} - - public Map getProfiledBatchPerfCounters() { - return new HashMap<>(); - } - - public boolean isEmpty() { - return true; - } - - public void addRootView(final int tag, final View rootView) {} - - protected void enqueueUIOperation(UIOperation operation) {} - - public void enqueueRemoveRootView(int rootViewTag) {} - - public void enqueueSetJSResponder(int tag, int initialTag, boolean blockNativeResponder) {} - - public void enqueueClearJSResponder() {} - - @Deprecated - public void enqueueDispatchCommand( - int reactTag, int commandId, @Nullable ReadableArray commandArgs) {} - - public void enqueueDispatchCommand( - int reactTag, String commandId, @Nullable ReadableArray commandArgs) {} - - public void enqueueUpdateExtraData(int reactTag, Object extraData) {} - - public void enqueueCreateView( - ThemedReactContext themedContext, - int viewReactTag, - String viewClassName, - @Nullable ReactStylesDiffMap initialProps) {} - - public void enqueueUpdateInstanceHandle(int reactTag, long instanceHandle) {} - - public void enqueueUpdateProperties(int reactTag, String className, ReactStylesDiffMap props) {} - - /** - * @deprecated Use {@link #enqueueUpdateLayout(int, int, int, int, int, int, YogaDirection)} - * instead. - */ - @Deprecated - public void enqueueUpdateLayout( - int parentTag, int reactTag, int x, int y, int width, int height) {} - - public void enqueueUpdateLayout( - int parentTag, - int reactTag, - int x, - int y, - int width, - int height, - YogaDirection layoutDirection) {} - - public void enqueueManageChildren( - int reactTag, - @Nullable int[] indicesToRemove, - @Nullable ViewAtIndex[] viewsToAdd, - @Nullable int[] tagsToDelete) {} - - public void enqueueSetChildren(int reactTag, ReadableArray childrenTags) {} - - public void enqueueSetLayoutAnimationEnabled(final boolean enabled) {} - - public void enqueueConfigureLayoutAnimation( - final ReadableMap config, final Callback onAnimationComplete) {} - - public void enqueueMeasure(final int reactTag, final Callback callback) {} - - public void enqueueMeasureInWindow(final int reactTag, final Callback callback) {} - - public void enqueueFindTargetForTouch( - final int reactTag, final float targetX, final float targetY, final Callback callback) {} - - public void enqueueSendAccessibilityEvent(int tag, int eventType) {} - - public void enqueueLayoutUpdateFinished( - ReactShadowNode node, UIImplementation.LayoutUpdateListener listener) {} - - public void enqueueUIBlock(UIBlock block) {} - - public void prependUIBlock(UIBlock block) {} - - public void dispatchViewUpdates( - final int batchId, final long commitStartTime, final long layoutTime) {} - - /* package */ void resumeFrameCallback() {} - - /* package */ void pauseFrameCallback() {} -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.kt new file mode 100644 index 000000000000..f8c3a08835de --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.kt @@ -0,0 +1,196 @@ +/* + * 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.Callback +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.bridge.ReadableArray +import com.facebook.react.bridge.ReadableMap +import com.facebook.react.common.annotations.internal.LegacyArchitecture +import com.facebook.react.common.annotations.internal.LegacyArchitectureLogLevel +import com.facebook.react.common.annotations.internal.LegacyArchitectureLogger +import com.facebook.yoga.YogaDirection + +/** + * This class acts as a buffer for command executed on [NativeViewHierarchyManager]. It expose + * similar methods as mentioned classes but instead of executing commands immediately it enqueues + * those operations in a queue that is then flushed from [UIManagerModule] once JS batch of ui + * operations is finished. This is to make sure that we execute all the JS operation coming from a + * single batch a single loop of the main (UI) android looper. + * + * @deprecated This class is stubbed out and will be removed in a future release. + * + * TODO(7135923): Pooling of operation objects TODO(5694019): Consider a better data structure for + * operations queue to save on allocations + */ +@LegacyArchitecture(logLevel = LegacyArchitectureLogLevel.ERROR) +@Deprecated("This class is part of Legacy Architecture and will be removed in a future release") +public class UIViewOperationQueue( + reactContext: ReactApplicationContext, + minTimeLeftInFrameForNonBatchedOperationMs: Int, +) { + + /** A mutation or animation operation on the view hierarchy. */ + public interface UIOperation { + /** Executes the UI operation. */ + public fun execute() + } + + public companion object { + /** Default minimum time left in frame for non-batched operations, in milliseconds. */ + public const val DEFAULT_MIN_TIME_LEFT_IN_FRAME_FOR_NONBATCHED_OPERATION_MS: Int = 8 + + init { + LegacyArchitectureLogger.assertLegacyArchitecture( + "UIViewOperationQueue", + LegacyArchitectureLogLevel.ERROR, + ) + } + } + + /** Profiles the next batch of UI operations. */ + public fun profileNextBatch() {} + + /** Returns profiled batch performance counters. */ + public fun getProfiledBatchPerfCounters(): Map = HashMap() + + /** Returns whether the operation queue is empty. */ + public fun isEmpty(): Boolean = true + + /** Adds a root view with the given tag. */ + public fun addRootView(tag: Int, rootView: View) {} + + /** Enqueues a UI operation for execution. */ + protected fun enqueueUIOperation(operation: UIOperation) {} + + /** Enqueues removal of a root view with the given tag. */ + public fun enqueueRemoveRootView(rootViewTag: Int) {} + + /** Enqueues setting the JS responder for the given tag. */ + public fun enqueueSetJSResponder(tag: Int, initialTag: Int, blockNativeResponder: Boolean) {} + + /** Enqueues clearing the JS responder. */ + public fun enqueueClearJSResponder() {} + + /** + * Enqueues dispatching a command with an integer command ID. + * + * @deprecated Use [enqueueDispatchCommand] with a String commandId instead. + */ + @Deprecated("Use enqueueDispatchCommand with a String commandId instead") + public fun enqueueDispatchCommand(reactTag: Int, commandId: Int, commandArgs: ReadableArray?) {} + + /** Enqueues dispatching a command with a string command ID. */ + public fun enqueueDispatchCommand( + reactTag: Int, + commandId: String, + commandArgs: ReadableArray?, + ) {} + + /** Enqueues updating extra data for the given react tag. */ + public fun enqueueUpdateExtraData(reactTag: Int, extraData: Any?) {} + + /** Enqueues creating a view with the given properties. */ + public fun enqueueCreateView( + themedContext: ThemedReactContext, + viewReactTag: Int, + viewClassName: String, + initialProps: ReactStylesDiffMap?, + ) {} + + /** Enqueues updating the instance handle for the given react tag. */ + public fun enqueueUpdateInstanceHandle(reactTag: Int, instanceHandle: Long) {} + + /** Enqueues updating properties for the given react tag. */ + public fun enqueueUpdateProperties(reactTag: Int, className: String, props: ReactStylesDiffMap) {} + + /** + * Enqueues updating layout for the given react tag without layout direction. + * + * @deprecated Use [enqueueUpdateLayout] with [YogaDirection] instead. + */ + @Deprecated("Use enqueueUpdateLayout with YogaDirection instead") + public fun enqueueUpdateLayout( + parentTag: Int, + reactTag: Int, + x: Int, + y: Int, + width: Int, + height: Int, + ) {} + + /** Enqueues updating layout for the given react tag with layout direction. */ + public fun enqueueUpdateLayout( + parentTag: Int, + reactTag: Int, + x: Int, + y: Int, + width: Int, + height: Int, + layoutDirection: YogaDirection, + ) {} + + /** Enqueues managing children for the given react tag. */ + internal fun enqueueManageChildren( + reactTag: Int, + indicesToRemove: IntArray?, + viewsToAdd: Array?, + tagsToDelete: IntArray?, + ) {} + + /** Enqueues setting children for the given react tag. */ + public fun enqueueSetChildren(reactTag: Int, childrenTags: ReadableArray?) {} + + /** Enqueues setting whether layout animation is enabled. */ + public fun enqueueSetLayoutAnimationEnabled(enabled: Boolean) {} + + /** Enqueues configuring layout animation with the given config and completion callback. */ + public fun enqueueConfigureLayoutAnimation( + config: ReadableMap?, + onAnimationComplete: Callback?, + ) {} + + /** Enqueues measuring the view with the given react tag. */ + public fun enqueueMeasure(reactTag: Int, callback: Callback) {} + + /** Enqueues measuring the view in window coordinates with the given react tag. */ + public fun enqueueMeasureInWindow(reactTag: Int, callback: Callback) {} + + /** Enqueues finding the target view for a touch at the given coordinates. */ + public fun enqueueFindTargetForTouch( + reactTag: Int, + targetX: Float, + targetY: Float, + callback: Callback, + ) {} + + /** Enqueues sending an accessibility event for the given tag. */ + public fun enqueueSendAccessibilityEvent(tag: Int, eventType: Int) {} + + /** Enqueues a layout update finished notification for the given node. */ + public fun enqueueLayoutUpdateFinished( + node: ReactShadowNode<*>, + listener: UIImplementation.LayoutUpdateListener, + ) {} + + /** Enqueues a UI block for execution. */ + public fun enqueueUIBlock(block: UIBlock) {} + + /** Prepends a UI block for execution before existing queued operations. */ + public fun prependUIBlock(block: UIBlock) {} + + /** Dispatches view updates for the given batch. */ + public fun dispatchViewUpdates(batchId: Int, commitStartTime: Long, layoutTime: Long) {} + + /** Resumes the frame callback. */ + internal fun resumeFrameCallback() {} + + /** Pauses the frame callback. */ + internal fun pauseFrameCallback() {} +}