Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07045f95 authored by Selim Cinek's avatar Selim Cinek
Browse files

Modified the way the notifications clip to the boundary

Previously the notification shade didn't clip at all to
the qs - notification boundary, which could lead to
content peaking outside of the boundary during dismissal
or other situations. We now clip to the boundary
using rounded rect clipping. This also allows us to
remove various complex clipping logic that was updating
the clipping on the top for individual notification views.

This also fixes some bugs on the split shade where the
notifications were wrongly clipped previously.

This is change 2/2 to improve the notification dismissal.

Fixes: 181887261
Test: atest SystemUITests
Merged-In: I1ebe777c50b85a500ecce22823d547c6d9c3c6d5
Change-Id: I1ebe777c50b85a500ecce22823d547c6d9c3c6d5
parent adc3f0b6
Loading
Loading
Loading
Loading
+0 −24
Original line number Diff line number Diff line
@@ -330,30 +330,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
        }
    }

    @Override
    public void setDistanceToTopRoundness(float distanceToTopRoundness) {
        super.setDistanceToTopRoundness(distanceToTopRoundness);
        mBackgroundNormal.setDistanceToTopRoundness(distanceToTopRoundness);
    }

    /** Sets whether this view is the last notification in a section. */
    @Override
    public void setLastInSection(boolean lastInSection) {
        if (lastInSection != mLastInSection) {
            super.setLastInSection(lastInSection);
            mBackgroundNormal.setLastInSection(lastInSection);
        }
    }

    /** Sets whether this view is the first notification in a section. */
    @Override
    public void setFirstInSection(boolean firstInSection) {
        if (firstInSection != mFirstInSection) {
            super.setFirstInSection(firstInSection);
            mBackgroundNormal.setFirstInSection(firstInSection);
        }
    }

    /**
     * Set an override tint color that is used for the background.
     *
+0 −20
Original line number Diff line number Diff line
@@ -846,8 +846,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        updateClickAndFocus();
        if (mNotificationParent != null) {
            setOverrideTintColor(NO_COLOR, 0.0f);
            // Let's reset the distance to top roundness, as this isn't applied to group children
            setDistanceToTopRoundness(NO_ROUNDNESS);
            mNotificationParent.updateBackgroundForGroupState();
        }
        updateBackgroundClipping();
@@ -3036,24 +3034,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
                || mExpandAnimationRunning || mChildIsExpanding));
    }

    @Override
    public boolean topAmountNeedsClipping() {
        if (isGroupExpanded()) {
            return true;
        }
        if (isGroupExpansionChanging()) {
            return true;
        }
        if (getShowingLayout().shouldClipToRounding(true /* topRounded */,
                false /* bottomRounded */)) {
            return true;
        }
        if (mGuts != null && mGuts.getAlpha() != 0.0f) {
            return true;
        }
        return false;
    }

    @Override
    protected boolean childNeedsClipping(View child) {
        if (child instanceof NotificationContentView) {
+1 −41
Original line number Diff line number Diff line
@@ -75,16 +75,13 @@ public abstract class ExpandableOutlineView extends ExpandableView {
     * it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself.
     */
    protected boolean mShouldTranslateContents;
    private boolean mTopAmountRounded;
    private float mDistanceToTopRoundness = -1;
    private float[] mTmpCornerRadii = new float[8];

    private final ViewOutlineProvider mProvider = new ViewOutlineProvider() {
        @Override
        public void getOutline(View view, Outline outline) {
            if (!mCustomOutline && getCurrentTopRoundness() == 0.0f
                    && getCurrentBottomRoundness() == 0.0f && !mAlwaysRoundBothCorners
                    && !mTopAmountRounded) {
                    && getCurrentBottomRoundness() == 0.0f && !mAlwaysRoundBothCorners) {
                int translation = mShouldTranslateContents ? (int) getTranslation() : 0;
                int left = Math.max(translation, 0);
                int top = mClipTopAmount + mBackgroundTop;
@@ -168,32 +165,14 @@ public abstract class ExpandableOutlineView extends ExpandableView {
    @Override
    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
        canvas.save();
        Path intersectPath = null;
        if (mTopAmountRounded && topAmountNeedsClipping()) {
            int left = (int) (- mExtraWidthForClipping / 2.0f);
            int top = (int) (mClipTopAmount - mDistanceToTopRoundness);
            int right = getWidth() + (int) (mExtraWidthForClipping + left);
            int bottom = (int) Math.max(mMinimumHeightForClipping,
                    Math.max(getActualHeight() - mClipBottomAmount, top + mOutlineRadius));
            getRoundedRectPath(left, top, right, bottom, mOutlineRadius, 0.0f, mClipPath);
            intersectPath = mClipPath;
        }
        boolean clipped = false;
        if (childNeedsClipping(child)) {
            Path clipPath = getCustomClipPath(child);
            if (clipPath == null) {
                clipPath = getClipPath(false /* ignoreTranslation */);
            }
            if (clipPath != null) {
                if (intersectPath != null) {
                    clipPath.op(intersectPath, Path.Op.INTERSECT);
                }
                canvas.clipPath(clipPath);
                clipped = true;
            }
            }
        if (!clipped && intersectPath != null) {
            canvas.clipPath(intersectPath);
        }
        boolean result = super.drawChild(canvas, child, drawingTime);
        canvas.restore();
@@ -212,24 +191,10 @@ public abstract class ExpandableOutlineView extends ExpandableView {
        invalidate();
    }

    @Override
    public void setDistanceToTopRoundness(float distanceToTopRoundness) {
        super.setDistanceToTopRoundness(distanceToTopRoundness);
        if (distanceToTopRoundness != mDistanceToTopRoundness) {
            mTopAmountRounded = distanceToTopRoundness >= 0;
            mDistanceToTopRoundness = distanceToTopRoundness;
            applyRoundness();
        }
    }

    protected boolean childNeedsClipping(View child) {
        return false;
    }

    public boolean topAmountNeedsClipping() {
        return true;
    }

    protected boolean isClippingNeeded() {
        return mAlwaysRoundBothCorners || mCustomOutline || getTranslation() != 0 ;
    }
@@ -272,11 +237,6 @@ public abstract class ExpandableOutlineView extends ExpandableView {
    }

    public float getCurrentBackgroundRadiusTop() {
        // If this view is top amount notification view, it should always has round corners on top.
        // It will be applied with applyRoundness()
        if (mTopAmountRounded) {
            return mOutlineRadius;
        }
        return getCurrentTopRoundness() * mOutlineRadius;
    }

+0 −9
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ import java.util.List;
public abstract class ExpandableView extends FrameLayout implements Dumpable {
    private static final String TAG = "ExpandableView";

    public static final float NO_ROUNDNESS = -1;
    protected OnHeightChangedListener mOnHeightChangedListener;
    private int mActualHeight;
    protected int mClipTopAmount;
@@ -192,14 +191,6 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
        }
    }

    /**
     * Set the distance to the top roundness, from where we should start clipping a value above
     * or equal to 0 is the effective distance, and if a value below 0 is received, there should
     * be no clipping.
     */
    public void setDistanceToTopRoundness(float distanceToTopRoundness) {
    }

    public void setActualHeight(int actualHeight) {
        setActualHeight(actualHeight, true /* notifyListeners */);
    }
+1 −35
Original line number Diff line number Diff line
@@ -42,10 +42,8 @@ public class NotificationBackgroundView extends View {
    private int mActualHeight;
    private int mClipBottomAmount;
    private int mTintColor;
    private float[] mCornerRadii = new float[8];
    private final float[] mCornerRadii = new float[8];
    private boolean mBottomIsRounded;
    private boolean mLastInSection;
    private boolean mFirstInSection;
    private int mBackgroundTop;
    private boolean mBottomAmountClips = true;
    private boolean mExpandAnimationRunning;
@@ -53,9 +51,6 @@ public class NotificationBackgroundView extends View {
    private int mDrawableAlpha = 255;
    private boolean mIsPressedAllowed;

    private boolean mTopAmountRounded;
    private float mDistanceToTopRoundness;

    public NotificationBackgroundView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mDontModifyCorners = getResources().getBoolean(
@@ -90,15 +85,6 @@ public class NotificationBackgroundView extends View {
                left = (int) ((getWidth() - mActualWidth) / 2.0f);
                right = (int) (left + mActualWidth);
            }
            if (mTopAmountRounded) {
                int clipTop = (int) (mClipTopAmount - mDistanceToTopRoundness);
                if (clipTop >= 0 || !mFirstInSection) {
                    top += clipTop;
                }
                if (clipTop >= 0 && !mLastInSection) {
                    bottom += clipTop;
                }
            }
            drawable.setBounds(left, top, right, bottom);
            drawable.draw(canvas);
        }
@@ -180,14 +166,6 @@ public class NotificationBackgroundView extends View {
        invalidate();
    }

    public void setDistanceToTopRoundness(float distanceToTopRoundness) {
        if (distanceToTopRoundness != mDistanceToTopRoundness) {
            mTopAmountRounded = distanceToTopRoundness >= 0;
            mDistanceToTopRoundness = distanceToTopRoundness;
            invalidate();
        }
    }

    @Override
    public boolean hasOverlappingRendering() {

@@ -246,18 +224,6 @@ public class NotificationBackgroundView extends View {
        }
    }

    /** Sets whether this background belongs to the last notification in a section. */
    public void setLastInSection(boolean lastInSection) {
        mLastInSection = lastInSection;
        invalidate();
    }

    /** Sets whether this background belongs to the first notification in a section. */
    public void setFirstInSection(boolean firstInSection) {
        mFirstInSection = firstInSection;
        invalidate();
    }

    private void updateBackgroundRadii() {
        if (mDontModifyCorners) {
            return;
Loading