From 58c726a6bade42946cc28191de5f7ddb109d63f0 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 9 Jul 2024 14:59:40 -0700 Subject: [PATCH] Encapsulate float-ish border color APIs (#45338) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/45338 `CSSBackgroundDrawable` is a silly goose and reuses layout types to store color. This has extended into a really strange public API, where we use floating point colors, where the color is itself in int with packed integer color components. This hides that away, and marks some classes with `UnstableReactNativeAPI` that I plan to hide shortly. Changelog: [Internal] Reviewed By: javache Differential Revision: D59488811 fbshipit-source-id: 7dc57edc9888f8a92088d2410ee71c2768ae8ec1 --- .../ReactAndroid/api/ReactAndroid.api | 57 ++----------------- .../uimanager/drawable/BoxShadowDrawable.kt | 2 + .../drawable/CSSBackgroundDrawable.java | 11 +++- .../scroll/ReactHorizontalScrollView.java | 4 +- .../ReactHorizontalScrollViewManager.java | 8 +-- .../react/views/scroll/ReactScrollView.java | 4 +- .../views/scroll/ReactScrollViewManager.java | 7 +-- .../text/ReactTextAnchorViewManager.java | 8 +-- .../react/views/text/ReactTextView.java | 4 +- .../react/views/textinput/ReactEditText.java | 4 +- .../textinput/ReactTextInputManager.java | 19 +------ .../view/ReactViewBackgroundManager.java | 6 +- .../react/views/view/ReactViewGroup.java | 4 +- .../react/views/view/ReactViewManager.java | 8 +-- 14 files changed, 40 insertions(+), 106 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index c03cacd2b6d..98e0fc91d6e 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -5545,38 +5545,6 @@ public abstract interface class com/facebook/react/uimanager/debug/NotThreadSafe public abstract fun onViewHierarchyUpdateFinished ()V } -public class com/facebook/react/uimanager/drawable/CSSBackgroundDrawable : android/graphics/drawable/Drawable { - public fun (Landroid/content/Context;)V - public fun draw (Landroid/graphics/Canvas;)V - public fun getAlpha ()I - public fun getBorderBoxPath ()Landroid/graphics/Path; - public fun getBorderBoxRect ()Landroid/graphics/RectF; - public fun getBorderColor (I)I - public fun getBorderRadius ()Lcom/facebook/react/uimanager/style/BorderRadiusStyle; - public fun getBorderWidthOrDefaultTo (FI)F - public fun getComputedBorderRadius ()Lcom/facebook/react/uimanager/style/ComputedBorderRadius; - public fun getDirectionAwareBorderInsets ()Landroid/graphics/RectF; - public fun getFullBorderWidth ()F - public fun getLayoutDirection ()I - public fun getOpacity ()I - public fun getOutline (Landroid/graphics/Outline;)V - public fun getPaddingBoxPath ()Landroid/graphics/Path; - public fun getPaddingBoxRect ()Landroid/graphics/RectF; - public fun hasRoundedBorders ()Z - protected fun onBoundsChange (Landroid/graphics/Rect;)V - public fun setAlpha (I)V - public fun setBorderColor (IFF)V - public fun setBorderRadius (Lcom/facebook/react/uimanager/style/BorderRadiusProp;Lcom/facebook/react/uimanager/LengthPercentage;)V - public fun setBorderRadius (Lcom/facebook/react/uimanager/style/BorderRadiusStyle;)V - public fun setBorderStyle (Ljava/lang/String;)V - public fun setBorderWidth (IF)V - public fun setColor (I)V - public fun setColorFilter (Landroid/graphics/ColorFilter;)V - public fun setLayoutDirectionOverride (I)V - public fun setRadius (F)V - public fun setRadius (FI)V -} - public abstract interface class com/facebook/react/uimanager/events/BatchEventDispatchedListener { public abstract fun onBatchEventDispatched ()V } @@ -6746,7 +6714,7 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollView : android public fun scrollTo (II)V public fun scrollToPreservingMomentum (II)V public fun setBackgroundColor (I)V - public fun setBorderColor (IFF)V + public fun setBorderColor (ILjava/lang/Integer;)V public fun setBorderRadius (F)V public fun setBorderRadius (FI)V public fun setBorderStyle (Ljava/lang/String;)V @@ -6875,7 +6843,7 @@ public class com/facebook/react/views/scroll/ReactScrollView : android/widget/Sc public fun scrollTo (II)V public fun scrollToPreservingMomentum (II)V public fun setBackgroundColor (I)V - public fun setBorderColor (IFF)V + public fun setBorderColor (ILjava/lang/Integer;)V public fun setBorderRadius (F)V public fun setBorderRadius (FI)V public fun setBorderStyle (Ljava/lang/String;)V @@ -7397,7 +7365,7 @@ public class com/facebook/react/views/text/ReactTextView : androidx/appcompat/wi public fun reactTagForTouch (FF)I public fun setAdjustFontSizeToFit (Z)V public fun setBackgroundColor (I)V - public fun setBorderColor (IFF)V + public fun setBorderColor (ILjava/lang/Integer;)V public fun setBorderRadius (F)V public fun setBorderRadius (FI)V public fun setBorderStyle (Ljava/lang/String;)V @@ -7735,7 +7703,7 @@ public class com/facebook/react/views/textinput/ReactEditText : androidx/appcomp public fun setAllowFontScaling (Z)V public fun setAutoFocus (Z)V public fun setBackgroundColor (I)V - public fun setBorderColor (IFF)V + public fun setBorderColor (ILjava/lang/Integer;)V public fun setBorderRadius (F)V public fun setBorderRadius (FI)V public fun setBorderStyle (Ljava/lang/String;)V @@ -7943,21 +7911,6 @@ public class com/facebook/react/views/view/ReactViewBackgroundDrawable : com/fac public fun (Landroid/content/Context;)V } -public class com/facebook/react/views/view/ReactViewBackgroundManager { - public fun (Landroid/view/View;)V - public fun cleanup ()V - public fun getBackgroundColor ()I - public fun getBorderColor (I)I - public fun maybeClipToPaddingBox (Landroid/graphics/Canvas;)V - public fun setBackgroundColor (I)V - public fun setBorderColor (IFF)V - public fun setBorderRadius (F)V - public fun setBorderRadius (FI)V - public fun setBorderStyle (Ljava/lang/String;)V - public fun setBorderWidth (IF)V - public fun setOverflow (Ljava/lang/String;)V -} - public class com/facebook/react/views/view/ReactViewGroup : android/view/ViewGroup, com/facebook/react/touch/ReactHitSlopView, com/facebook/react/touch/ReactInterceptingViewGroup, com/facebook/react/uimanager/ReactClippingViewGroup, com/facebook/react/uimanager/ReactOverflowViewWithInset, com/facebook/react/uimanager/ReactPointerEventsView, com/facebook/react/uimanager/ReactZIndexedViewGroup { public fun (Landroid/content/Context;)V public fun addView (Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V @@ -7993,7 +7946,7 @@ public class com/facebook/react/views/view/ReactViewGroup : android/view/ViewGro public fun setBackfaceVisibilityDependantOpacity ()V public fun setBackground (Landroid/graphics/drawable/Drawable;)V public fun setBackgroundColor (I)V - public fun setBorderColor (IFF)V + public fun setBorderColor (ILjava/lang/Integer;)V public fun setBorderRadius (F)V public fun setBorderRadius (FI)V public fun setBorderRadius (Lcom/facebook/react/uimanager/style/BorderRadiusProp;Lcom/facebook/react/uimanager/LengthPercentage;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BoxShadowDrawable.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BoxShadowDrawable.kt index 6b7c3241c9a..6f14b517f69 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BoxShadowDrawable.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/BoxShadowDrawable.kt @@ -15,6 +15,7 @@ import android.graphics.RenderNode import android.graphics.drawable.Drawable import androidx.annotation.RequiresApi import com.facebook.common.logging.FLog +import com.facebook.react.common.annotations.UnstableReactNativeAPI import com.facebook.react.uimanager.FilterHelper import com.facebook.react.uimanager.LengthPercentage import com.facebook.react.uimanager.LengthPercentageType @@ -32,6 +33,7 @@ private const val BLUR_RADIUS_SIGMA_SCALE = 0.5f /** Draws an outer-box shadow https://www.w3.org/TR/css-backgrounds-3/#shadow-shape */ @RequiresApi(31) +@OptIn(UnstableReactNativeAPI::class) internal class BoxShadowDrawable( context: Context, private val background: CSSBackgroundDrawable, diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java index fc2cd0c5d0f..0e438cccc92 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/drawable/CSSBackgroundDrawable.java @@ -27,6 +27,7 @@ import androidx.annotation.Nullable; import androidx.core.graphics.ColorUtils; import androidx.core.util.Preconditions; import com.facebook.infer.annotation.Nullsafe; +import com.facebook.react.common.annotations.UnstableReactNativeAPI; import com.facebook.react.common.annotations.VisibleForTesting; import com.facebook.react.modules.i18nmanager.I18nUtil; import com.facebook.react.uimanager.FloatUtil; @@ -51,6 +52,7 @@ import java.util.Objects; * have a rectangular borders we allocate {@code mBorderWidthResult} and similar. When only * background color is set we won't allocate any extra/unnecessary objects. */ +@UnstableReactNativeAPI @Nullsafe(Nullsafe.Mode.LOCAL) public class CSSBackgroundDrawable extends Drawable { @@ -219,9 +221,12 @@ public class CSSBackgroundDrawable extends Drawable { } } - public void setBorderColor(int position, float rgb, float alpha) { - this.setBorderRGB(position, rgb); - this.setBorderAlpha(position, alpha); + public void setBorderColor(int position, @Nullable Integer color) { + float rgbComponent = color == null ? Float.NaN : (float) ((int) color & 0x00FFFFFF); + float alphaComponent = color == null ? Float.NaN : (float) ((int) color >>> 24); + + this.setBorderRGB(position, rgbComponent); + this.setBorderAlpha(position, alphaComponent); mNeedUpdatePathForBorderRadius = true; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index 7d8853ba446..5a069a809ca 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -1283,8 +1283,8 @@ public class ReactHorizontalScrollView extends HorizontalScrollView mReactBackgroundManager.setBorderWidth(position, width); } - public void setBorderColor(int position, float color, float alpha) { - mReactBackgroundManager.setBorderColor(position, color, alpha); + public void setBorderColor(int position, @Nullable Integer color) { + mReactBackgroundManager.setBorderColor(position, color); } public void setBorderRadius(float borderRadius) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java index fa3ceb951bf..dba828621b0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java @@ -27,7 +27,6 @@ import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactPropGroup; -import com.facebook.yoga.YogaConstants; import java.util.ArrayList; import java.util.List; @@ -298,11 +297,8 @@ public class ReactHorizontalScrollViewManager extends ViewGroupManager>> 24); - view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent); + public void setBorderColor(ReactHorizontalScrollView view, int index, @Nullable Integer color) { + view.setBorderColor(SPACING_TYPES[index], color); } @ReactProp(name = "overflow") diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index 56f486a23c6..7e9268e69b0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -1216,8 +1216,8 @@ public class ReactScrollView extends ScrollView mReactBackgroundManager.setBorderWidth(position, width); } - public void setBorderColor(int position, float color, float alpha) { - mReactBackgroundManager.setBorderColor(position, color, alpha); + public void setBorderColor(int position, @Nullable Integer color) { + mReactBackgroundManager.setBorderColor(position, color); } public void setBorderRadius(float borderRadius) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java index 5f695b97122..84bbd6907fd 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java @@ -28,7 +28,6 @@ import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactPropGroup; -import com.facebook.yoga.YogaConstants; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -279,10 +278,8 @@ public class ReactScrollViewManager extends ViewGroupManager "borderBottomColor" }, customType = "Color") - public void setBorderColor(ReactScrollView view, int index, Integer color) { - float rgbComponent = color == null ? YogaConstants.UNDEFINED : (float) (color & 0x00FFFFFF); - float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) (color >>> 24); - view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent); + public void setBorderColor(ReactScrollView view, int index, @Nullable Integer color) { + view.setBorderColor(SPACING_TYPES[index], color); } @ReactProp(name = "overflow") diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java index 29a67a81ae8..c170edac53a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextAnchorViewManager.java @@ -23,7 +23,6 @@ import com.facebook.react.uimanager.ViewDefaults; import com.facebook.react.uimanager.ViewProps; import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactPropGroup; -import com.facebook.yoga.YogaConstants; /** * Abstract class for anchor {@code }-ish spannable views, such as {@link TextView} or {@link @@ -180,11 +179,8 @@ public abstract class ReactTextAnchorViewManager>> 24); - view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent); + public void setBorderColor(ReactTextView view, int index, @Nullable Integer color) { + view.setBorderColor(SPACING_TYPES[index], color); } @ReactProp(name = ViewProps.INCLUDE_FONT_PADDING, defaultBoolean = true) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java index 424160192fc..029ff339685 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java @@ -686,8 +686,8 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie mReactBackgroundManager.setBorderWidth(position, width); } - public void setBorderColor(int position, float color, float alpha) { - mReactBackgroundManager.setBorderColor(position, color, alpha); + public void setBorderColor(int position, @Nullable Integer color) { + mReactBackgroundManager.setBorderColor(position, color); } public void setBorderRadius(float borderRadius) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java index 92cd700113c..231ac8b52ac 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java @@ -1077,8 +1077,8 @@ public class ReactEditText extends AppCompatEditText { mReactBackgroundManager.setBorderWidth(position, width); } - public void setBorderColor(int position, float color, float alpha) { - mReactBackgroundManager.setBorderColor(position, color, alpha); + public void setBorderColor(int position, @Nullable Integer color) { + mReactBackgroundManager.setBorderColor(position, color); } public int getBorderColor(int position) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index 983a0ae0afd..c180c6a62a0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -70,7 +70,6 @@ import com.facebook.react.views.text.TextAttributeProps; import com.facebook.react.views.text.TextLayoutManager; import com.facebook.react.views.text.TextTransform; import com.facebook.react.views.text.internal.span.TextInlineImageSpan; -import com.facebook.yoga.YogaConstants; import java.lang.reflect.Field; import java.util.HashMap; import java.util.LinkedList; @@ -702,16 +701,7 @@ public class ReactTextInputManager extends BaseViewManager>> 24); - view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent); + public void setBorderColor(ReactEditText view, int index, @Nullable Integer color) { + view.setBorderColor(SPACING_TYPES[index], color); } @ReactProp(name = "overflow") diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java index 80ed63af37e..3b8b665a157 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java @@ -17,9 +17,11 @@ import android.graphics.drawable.LayerDrawable; import android.view.View; import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; +import com.facebook.react.common.annotations.UnstableReactNativeAPI; import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable; /** Class that manages the background for views and borders. */ +@UnstableReactNativeAPI public class ReactViewBackgroundManager { private static enum Overflow { VISIBLE, @@ -76,8 +78,8 @@ public class ReactViewBackgroundManager { getOrCreateReactViewBackground().setBorderWidth(position, width); } - public void setBorderColor(int position, float color, float alpha) { - getOrCreateReactViewBackground().setBorderColor(position, color, alpha); + public void setBorderColor(int position, @Nullable Integer color) { + getOrCreateReactViewBackground().setBorderColor(position, color); } public int getBorderColor(int position) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index 3114e2cfdc1..b50a6257b25 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -305,8 +305,8 @@ public class ReactViewGroup extends ViewGroup getOrCreateReactViewBackground().setBorderWidth(position, width); } - public void setBorderColor(int position, float rgb, float alpha) { - getOrCreateReactViewBackground().setBorderColor(position, rgb, alpha); + public void setBorderColor(int position, @Nullable Integer color) { + getOrCreateReactViewBackground().setBorderColor(position, color); } /** diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java index 14a31a43669..7f7fe3f131a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java @@ -33,7 +33,6 @@ import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactPropGroup; import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.style.BorderRadiusProp; -import com.facebook.yoga.YogaConstants; import java.util.Map; /** View manager for AndroidViews (plain React Views). */ @@ -246,11 +245,8 @@ public class ReactViewManager extends ReactClippingViewManager { ViewProps.BORDER_BLOCK_START_COLOR }, customType = "Color") - public void setBorderColor(ReactViewGroup view, int index, Integer color) { - float rgbComponent = - color == null ? YogaConstants.UNDEFINED : (float) ((int) color & 0x00FFFFFF); - float alphaComponent = color == null ? YogaConstants.UNDEFINED : (float) ((int) color >>> 24); - view.setBorderColor(SPACING_TYPES[index], rgbComponent, alphaComponent); + public void setBorderColor(ReactViewGroup view, int index, @Nullable Integer color) { + view.setBorderColor(SPACING_TYPES[index], color); } @ReactProp(name = ViewProps.COLLAPSABLE)