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 205bf491f798af..6c0f91b6c591de 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 @@ -327,13 +327,6 @@ public float getInnerBorderRadius(float computedRadius, float borderWidth) { return Math.max(computedRadius - borderWidth, 0); } - // TODO: This API is unsafe and should be removed when - // BackgroundStyleApplicator is rolled out - @Deprecated(forRemoval = true, since = "0.76.0") - public ComputedBorderRadius getComputedBorderRadius() { - return mComputedBorderRadius; - } - public void setColor(int color) { mColor = color; invalidateSelf(); 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 57b1d8eeeae9b2..c3dc2964c9fae3 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 @@ -18,9 +18,7 @@ import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; -import android.graphics.RectF; import android.graphics.drawable.Drawable; -import android.graphics.drawable.LayerDrawable; import android.os.Build; import android.view.MotionEvent; import android.view.View; @@ -31,20 +29,16 @@ import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; import com.facebook.react.R; -import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactNoCrashSoftException; import com.facebook.react.bridge.ReactSoftExceptionLogger; import com.facebook.react.bridge.UiThreadUtil; -import com.facebook.react.common.annotations.UnstableReactNativeAPI; import com.facebook.react.common.annotations.VisibleForTesting; import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; -import com.facebook.react.modules.i18nmanager.I18nUtil; import com.facebook.react.touch.OnInterceptTouchEventListener; import com.facebook.react.touch.ReactHitSlopView; import com.facebook.react.touch.ReactInterceptingViewGroup; import com.facebook.react.uimanager.BackgroundStyleApplicator; -import com.facebook.react.uimanager.IllegalViewOperationException; import com.facebook.react.uimanager.LengthPercentage; import com.facebook.react.uimanager.LengthPercentageType; import com.facebook.react.uimanager.MeasureSpecAssertions; @@ -56,20 +50,14 @@ import com.facebook.react.uimanager.ReactOverflowViewWithInset; import com.facebook.react.uimanager.ReactPointerEventsView; import com.facebook.react.uimanager.ReactZIndexedViewGroup; -import com.facebook.react.uimanager.RootView; -import com.facebook.react.uimanager.RootViewUtil; import com.facebook.react.uimanager.ViewGroupDrawingOrderHelper; import com.facebook.react.uimanager.common.UIManagerType; import com.facebook.react.uimanager.common.ViewUtil; import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable; -import com.facebook.react.uimanager.style.BackgroundImageLayer; import com.facebook.react.uimanager.style.BorderRadiusProp; import com.facebook.react.uimanager.style.BorderStyle; -import com.facebook.react.uimanager.style.ComputedBorderRadius; -import com.facebook.react.uimanager.style.CornerRadii; import com.facebook.react.uimanager.style.LogicalEdge; import com.facebook.react.uimanager.style.Overflow; -import java.util.List; /** * Backing for a React View. Has support for borders, but since borders aren't common, lazy @@ -238,44 +226,12 @@ public void dispatchProvideStructure(ViewStructure structure) { @Override public void setBackgroundColor(int color) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setBackgroundColor(this, color); - } else { - if (color == Color.TRANSPARENT && mCSSBackgroundDrawable == null) { - // don't do anything, no need to allocate ReactBackgroundDrawable for transparent background - } else { - getOrCreateReactViewBackground().setColor(color); - } - } - } - - @UnstableReactNativeAPI - /*package*/ void setBackgroundImage(@Nullable List backgroundImageLayers) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setBackgroundImage(this, backgroundImageLayers); - } else { - getOrCreateReactViewBackground().setBackgroundImage(backgroundImageLayers); - } + BackgroundStyleApplicator.setBackgroundColor(this, color); } @Deprecated(since = "0.76.0", forRemoval = true) public void setTranslucentBackgroundDrawable(@Nullable Drawable background) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setFeedbackUnderlay(this, background); - } else { - // it's required to call setBackground to null, as in some of the cases we may set new - // background to be a layer drawable that contains a drawable that has been setup - // as a background previously. This will not work correctly as the drawable callback logic is - // messed up in AOSP - updateBackgroundDrawable(null); - if (mCSSBackgroundDrawable != null && background != null) { - LayerDrawable layerDrawable = - new LayerDrawable(new Drawable[] {mCSSBackgroundDrawable, background}); - updateBackgroundDrawable(layerDrawable); - } else if (background != null) { - updateBackgroundDrawable(background); - } - } + BackgroundStyleApplicator.setFeedbackUnderlay(this, background); } @Override @@ -344,20 +300,12 @@ public void setNeedsOffscreenAlphaCompositing(boolean needsOffscreenAlphaComposi } public void setBorderWidth(int position, float width) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setBorderWidth( - this, LogicalEdge.values()[position], PixelUtil.toDIPFromPixel(width)); - } else { - getOrCreateReactViewBackground().setBorderWidth(position, width); - } + BackgroundStyleApplicator.setBorderWidth( + this, LogicalEdge.values()[position], PixelUtil.toDIPFromPixel(width)); } public void setBorderColor(int position, @Nullable Integer color) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setBorderColor(this, LogicalEdge.values()[position], color); - } else { - getOrCreateReactViewBackground().setBorderColor(position, color); - } + BackgroundStyleApplicator.setBorderColor(this, LogicalEdge.values()[position], color); } /** @@ -373,34 +321,21 @@ public void setBorderRadius(float borderRadius) { */ @Deprecated(since = "0.75.0", forRemoval = true) public void setBorderRadius(float borderRadius, int position) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - @Nullable - LengthPercentage radius = - Float.isNaN(borderRadius) - ? null - : new LengthPercentage(borderRadius, LengthPercentageType.POINT); - BackgroundStyleApplicator.setBorderRadius(this, BorderRadiusProp.values()[position], radius); - } else { - getOrCreateReactViewBackground().setRadius(borderRadius, position); - } + @Nullable + LengthPercentage radius = + Float.isNaN(borderRadius) + ? null + : new LengthPercentage(borderRadius, LengthPercentageType.POINT); + BackgroundStyleApplicator.setBorderRadius(this, BorderRadiusProp.values()[position], radius); } public void setBorderRadius(BorderRadiusProp property, @Nullable LengthPercentage borderRadius) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setBorderRadius(this, property, borderRadius); - } else { - CSSBackgroundDrawable backgroundDrawable = getOrCreateReactViewBackground(); - backgroundDrawable.setBorderRadius(property, borderRadius); - } + BackgroundStyleApplicator.setBorderRadius(this, property, borderRadius); } public void setBorderStyle(@Nullable String style) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setBorderStyle( - this, style == null ? null : BorderStyle.fromString(style)); - } else { - getOrCreateReactViewBackground().setBorderStyle(style); - } + BackgroundStyleApplicator.setBorderStyle( + this, style == null ? null : BorderStyle.fromString(style)); } @Override @@ -861,39 +796,8 @@ private boolean needsIsolatedLayer() { @VisibleForTesting public int getBackgroundColor() { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - @Nullable Integer color = BackgroundStyleApplicator.getBackgroundColor(this); - return color == null ? DEFAULT_BACKGROUND_COLOR : color; - } else { - if (getBackground() != null) { - return ((CSSBackgroundDrawable) getBackground()).getColor(); - } - return DEFAULT_BACKGROUND_COLOR; - } - } - - /* package */ CSSBackgroundDrawable getOrCreateReactViewBackground() { - if (mCSSBackgroundDrawable == null) { - mCSSBackgroundDrawable = new CSSBackgroundDrawable(getContext()); - Drawable backgroundDrawable = getBackground(); - updateBackgroundDrawable( - null); // required so that drawable callback is cleared before we add the - // drawable back as a part of LayerDrawable - if (backgroundDrawable == null) { - updateBackgroundDrawable(mCSSBackgroundDrawable); - } else { - LayerDrawable layerDrawable = - new LayerDrawable(new Drawable[] {mCSSBackgroundDrawable, backgroundDrawable}); - updateBackgroundDrawable(layerDrawable); - } - if (!ReactNativeFeatureFlags.setAndroidLayoutDirection()) { - mCSSBackgroundDrawable.setLayoutDirectionOverride( - I18nUtil.getInstance().isRTL(getContext()) - ? LAYOUT_DIRECTION_RTL - : LAYOUT_DIRECTION_LTR); - } - } - return mCSSBackgroundDrawable; + @Nullable Integer color = BackgroundStyleApplicator.getBackgroundColor(this); + return color == null ? DEFAULT_BACKGROUND_COLOR : color; } @Override @@ -983,33 +887,10 @@ && needsIsolatedLayer()) { @Override protected void dispatchDraw(Canvas canvas) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - if (mOverflow != Overflow.VISIBLE || getTag(R.id.filter) != null) { - BackgroundStyleApplicator.clipToPaddingBox(this, canvas); - } - super.dispatchDraw(canvas); - return; - } - - try { - dispatchOverflowDraw(canvas); - super.dispatchDraw(canvas); - } catch (NullPointerException | StackOverflowError e) { - // Adding special exception management for StackOverflowError for logging purposes. - // This will be removed in the future. - RootView rootView = RootViewUtil.getRootView(ReactViewGroup.this); - if (rootView != null) { - rootView.handleException(e); - } else { - if (getContext() instanceof ReactContext) { - ReactContext reactContext = (ReactContext) getContext(); - reactContext.handleException( - new IllegalViewOperationException("StackOverflowException", this, e)); - } else { - throw e; - } - } + if (mOverflow != Overflow.VISIBLE || getTag(R.id.filter) != null) { + BackgroundStyleApplicator.clipToPaddingBox(this, canvas); } + super.dispatchDraw(canvas); } @Override @@ -1048,83 +929,6 @@ protected boolean drawChild(Canvas canvas, View child, long drawingTime) { return result; } - private void dispatchOverflowDraw(Canvas canvas) { - Overflow tempOverflow = mOverflow; - - // If the view contains a filter, we clip to the padding box. - if (getTag(R.id.filter) != null) { - tempOverflow = Overflow.HIDDEN; - } - - switch (tempOverflow) { - case VISIBLE: - if (mPath != null) { - mPath.rewind(); - } - break; - case HIDDEN: - case SCROLL: - float left = 0f; - float top = 0f; - float right = getWidth(); - float bottom = getHeight(); - - boolean hasClipPath = false; - - if (mCSSBackgroundDrawable != null) { - final RectF borderWidth = mCSSBackgroundDrawable.getDirectionAwareBorderInsets(); - - if (borderWidth.top > 0 - || borderWidth.left > 0 - || borderWidth.bottom > 0 - || borderWidth.right > 0) { - left += borderWidth.left; - top += borderWidth.top; - right -= borderWidth.right; - bottom -= borderWidth.bottom; - } - - final ComputedBorderRadius borderRadius = - mCSSBackgroundDrawable.getComputedBorderRadius(); - - if (borderRadius.hasRoundedBorders()) { - if (mPath == null) { - mPath = new Path(); - } - - CornerRadii topLeftRadius = borderRadius.getTopLeft().toPixelFromDIP(); - CornerRadii topRightRadius = borderRadius.getTopRight().toPixelFromDIP(); - CornerRadii bottomLeftRadius = borderRadius.getBottomLeft().toPixelFromDIP(); - CornerRadii bottomRightRadius = borderRadius.getBottomRight().toPixelFromDIP(); - - mPath.rewind(); - mPath.addRoundRect( - new RectF(left, top, right, bottom), - new float[] { - Math.max(topLeftRadius.getHorizontal() - borderWidth.left, 0), - Math.max(topLeftRadius.getVertical() - borderWidth.top, 0), - Math.max(topRightRadius.getHorizontal() - borderWidth.right, 0), - Math.max(topRightRadius.getVertical() - borderWidth.top, 0), - Math.max(bottomRightRadius.getHorizontal() - borderWidth.right, 0), - Math.max(bottomRightRadius.getVertical() - borderWidth.bottom, 0), - Math.max(bottomLeftRadius.getHorizontal() - borderWidth.left, 0), - Math.max(bottomLeftRadius.getVertical() - borderWidth.bottom, 0), - }, - Path.Direction.CW); - canvas.clipPath(mPath); - hasClipPath = true; - } - } - - if (!hasClipPath) { - canvas.clipRect(new RectF(left, top, right, bottom)); - } - break; - default: - break; - } - } - public void setOpacityIfPossible(float opacity) { mBackfaceOpacity = opacity; setBackfaceVisibilityDependantOpacity(); 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 0ddf094171cf29..97acb1a2f7a298 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 @@ -22,7 +22,6 @@ import com.facebook.react.common.MapBuilder; import com.facebook.react.common.ReactConstants; import com.facebook.react.common.annotations.VisibleForTesting; -import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.uimanager.BackgroundStyleApplicator; import com.facebook.react.uimanager.LengthPercentage; @@ -110,9 +109,9 @@ public void setBackgroundImage(ReactViewGroup view, @Nullable ReadableArray back BackgroundImageLayer layer = new BackgroundImageLayer(backgroundImageMap); backgroundImageLayers.add(layer); } - view.setBackgroundImage(backgroundImageLayers); + BackgroundStyleApplicator.setBackgroundImage(view, backgroundImageLayers); } else { - view.setBackgroundImage(null); + BackgroundStyleApplicator.setBackgroundImage(view, null); } } } @@ -169,12 +168,7 @@ public void setBorderRadius(ReactViewGroup view, int index, Dynamic rawBorderRad borderRadius = null; } - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setBorderRadius( - view, BorderRadiusProp.values()[index], borderRadius); - } else { - view.setBorderRadius(BorderRadiusProp.values()[index], borderRadius); - } + BackgroundStyleApplicator.setBorderRadius(view, BorderRadiusProp.values()[index], borderRadius); } /** @@ -187,14 +181,10 @@ public void setBorderRadius(ReactViewGroup view, int index, float borderRadius) @ReactProp(name = "borderStyle") public void setBorderStyle(ReactViewGroup view, @Nullable String borderStyle) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - @Nullable - BorderStyle parsedBorderStyle = - borderStyle == null ? null : BorderStyle.fromString(borderStyle); - BackgroundStyleApplicator.setBorderStyle(view, parsedBorderStyle); - } else { - view.setBorderStyle(borderStyle); - } + @Nullable + BorderStyle parsedBorderStyle = + borderStyle == null ? null : BorderStyle.fromString(borderStyle); + BackgroundStyleApplicator.setBorderStyle(view, parsedBorderStyle); } @ReactProp(name = "hitSlop") @@ -269,19 +259,7 @@ public void setNeedsOffscreenAlphaCompositing( }, defaultFloat = Float.NaN) public void setBorderWidth(ReactViewGroup view, int index, float width) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setBorderWidth(view, LogicalEdge.values()[index], width); - } else { - if (!Float.isNaN(width) && width < 0) { - width = Float.NaN; - } - - if (!Float.isNaN(width)) { - width = PixelUtil.toPixelFromDIP(width); - } - - view.setBorderWidth(SPACING_TYPES[index], width); - } + BackgroundStyleApplicator.setBorderWidth(view, LogicalEdge.values()[index], width); } @ReactPropGroup( @@ -299,12 +277,8 @@ public void setBorderWidth(ReactViewGroup view, int index, float width) { }, customType = "Color") public void setBorderColor(ReactViewGroup view, int index, @Nullable Integer color) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setBorderColor( - view, LogicalEdge.fromSpacingType(SPACING_TYPES[index]), color); - } else { - view.setBorderColor(SPACING_TYPES[index], color); - } + BackgroundStyleApplicator.setBorderColor( + view, LogicalEdge.fromSpacingType(SPACING_TYPES[index]), color); } @ReactProp(name = ViewProps.COLLAPSABLE) @@ -374,18 +348,12 @@ protected void setTransformProperty( @ReactProp(name = ViewProps.BOX_SHADOW, customType = "BoxShadow") public void setBoxShadow(ReactViewGroup view, @Nullable ReadableArray shadows) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setBoxShadow(view, shadows); - } + BackgroundStyleApplicator.setBoxShadow(view, shadows); } @Override public void setBackgroundColor(ReactViewGroup view, @ColorInt int backgroundColor) { - if (ReactNativeFeatureFlags.enableBackgroundStyleApplicator()) { - BackgroundStyleApplicator.setBackgroundColor(view, backgroundColor); - } else { - super.setBackgroundColor(view, backgroundColor); - } + BackgroundStyleApplicator.setBackgroundColor(view, backgroundColor); } @Override