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

Commit d1695408 authored by Selim Cinek's avatar Selim Cinek
Browse files

Clipping headers to the shelf as well

Headers were not clipped to the shelf previously
so they could peak out below the shelf

Fixes: 150176626
Test: atest SystemUITests, visual
Change-Id: I2c6d40eebef0ee0693890bb306bec6c39b822a0f
parent 9fa3a870
Loading
Loading
Loading
Loading
+49 −47
Original line number Diff line number Diff line
@@ -269,47 +269,38 @@ public class NotificationShelf extends ActivatableNotificationView implements
        int backgroundTop = 0;
        int clipTopAmount = 0;
        float firstElementRoundness = 0.0f;
        ActivatableNotificationView previousRow = null;
        ActivatableNotificationView previousAnv = null;

        for (int i = 0; i < mHostLayout.getChildCount(); i++) {
            ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);

            if (!(child instanceof ActivatableNotificationView)
                    || child.getVisibility() == GONE || child == this) {
            if (!child.needsClippingToShelf() || child.getVisibility() == GONE) {
                continue;
            }

            ActivatableNotificationView row = (ActivatableNotificationView) child;
            float notificationClipEnd;
            boolean aboveShelf = ViewState.getFinalTranslationZ(row) > baseZHeight
                    || row.isPinned();
            boolean aboveShelf = ViewState.getFinalTranslationZ(child) > baseZHeight
                    || child.isPinned();
            boolean isLastChild = child == lastChild;
            float rowTranslationY = row.getTranslationY();
            float rowTranslationY = child.getTranslationY();
            if ((isLastChild && !child.isInShelf()) || aboveShelf || backgroundForceHidden) {
                notificationClipEnd = shelfStart + getIntrinsicHeight();
            } else {
                notificationClipEnd = shelfStart - mPaddingBetweenElements;
                float height = notificationClipEnd - rowTranslationY;
                if (!row.isBelowSpeedBump() && height <= getNotificationMergeSize()) {
                    // We want the gap to close when we reached the minimum size and only shrink
                    // before
                    notificationClipEnd = Math.min(shelfStart,
                            rowTranslationY + getNotificationMergeSize());
            }
            }
            int clipTop = updateNotificationClipHeight(row, notificationClipEnd, notGoneIndex);
            int clipTop = updateNotificationClipHeight(child, notificationClipEnd, notGoneIndex);
            clipTopAmount = Math.max(clipTop, clipTopAmount);

            // If the current row is an ExpandableNotificationRow, update its color, roundedness,
            // and icon state.
            if (row instanceof ExpandableNotificationRow) {
                ExpandableNotificationRow expandableRow = (ExpandableNotificationRow) row;
            if (child instanceof ExpandableNotificationRow) {
                ExpandableNotificationRow expandableRow = (ExpandableNotificationRow) child;

                float inShelfAmount = updateIconAppearance(expandableRow, expandAmount, scrolling,
                        scrollingFast,
                        expandingAnimated, isLastChild);
                numViewsInShelf += inShelfAmount;
                int ownColorUntinted = row.getBackgroundColorWithoutTint();
                int ownColorUntinted = expandableRow.getBackgroundColorWithoutTint();
                if (rowTranslationY >= shelfStart && mNotGoneIndex == -1) {
                    mNotGoneIndex = notGoneIndex;
                    setTintColor(previousColor);
@@ -326,10 +317,10 @@ public class NotificationShelf extends ActivatableNotificationView implements
                    if (colorOfViewBeforeLast == NO_COLOR) {
                        colorOfViewBeforeLast = ownColorUntinted;
                    }
                    row.setOverrideTintColor(colorOfViewBeforeLast, inShelfAmount);
                    expandableRow.setOverrideTintColor(colorOfViewBeforeLast, inShelfAmount);
                } else {
                    colorOfViewBeforeLast = ownColorUntinted;
                    row.setOverrideTintColor(NO_COLOR, 0 /* overrideAmount */);
                    expandableRow.setOverrideTintColor(NO_COLOR, 0 /* overrideAmount */);
                }
                if (notGoneIndex != 0 || !aboveShelf) {
                    expandableRow.setAboveShelf(false);
@@ -342,8 +333,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
                    // since they don't show up on AOD
                    if (iconState != null && iconState.clampedAppearAmount == 1.0f) {
                        // only if the first icon is fully in the shelf we want to clip to it!
                        backgroundTop = (int) (row.getTranslationY() - getTranslationY());
                        firstElementRoundness = row.getCurrentTopRoundness();
                        backgroundTop = (int) (child.getTranslationY() - getTranslationY());
                        firstElementRoundness = expandableRow.getCurrentTopRoundness();
                    }
                }

@@ -351,25 +342,31 @@ public class NotificationShelf extends ActivatableNotificationView implements
                notGoneIndex++;
            }

            if (row.isFirstInSection() && previousRow != null && previousRow.isLastInSection()) {
                // If the top of the shelf is between the view before a gap and the view after a gap
                // then we need to adjust the shelf's top roundness.
                float distanceToGapBottom = row.getTranslationY() - getTranslationY();
            if (child instanceof ActivatableNotificationView) {
                ActivatableNotificationView anv =
                        (ActivatableNotificationView) child;
                if (anv.isFirstInSection() && previousAnv != null
                        && previousAnv.isLastInSection()) {
                    // If the top of the shelf is between the view before a gap and the view after a
                    // gap then we need to adjust the shelf's top roundness.
                    float distanceToGapBottom = child.getTranslationY() - getTranslationY();
                    float distanceToGapTop = getTranslationY()
                        - (previousRow.getTranslationY() + previousRow.getActualHeight());
                            - (previousAnv.getTranslationY() + previousAnv.getActualHeight());
                    if (distanceToGapTop > 0) {
                    // We interpolate our top roundness so that it's fully rounded if we're at the
                    // bottom of the gap, and not rounded at all if we're at the top of the gap
                    // (directly up against the bottom of previousRow)
                    // Then we apply the same roundness to the bottom of previousRow so that the
                    // corners join together as the shelf approaches previousRow.
                    firstElementRoundness = (float) Math.min(1.0, distanceToGapTop / mGapHeight);
                    previousRow.setBottomRoundness(firstElementRoundness,
                        // We interpolate our top roundness so that it's fully rounded if we're at
                        // the bottom of the gap, and not rounded at all if we're at the top of the
                        // gap (directly up against the bottom of previousAnv)
                        // Then we apply the same roundness to the bottom of previousAnv so that the
                        // corners join together as the shelf approaches previousAnv.
                        firstElementRoundness = (float) Math.min(1.0,
                                distanceToGapTop / mGapHeight);
                        previousAnv.setBottomRoundness(firstElementRoundness,
                                false /* don't animate */);
                        backgroundTop = (int) distanceToGapBottom;
                    }
                }
            previousRow = row;
                previousAnv = anv;
            }
        }
        clipTransientViews();

@@ -489,27 +486,27 @@ public class NotificationShelf extends ActivatableNotificationView implements
     * Update the clipping of this view.
     * @return the amount that our own top should be clipped
     */
    private int updateNotificationClipHeight(ActivatableNotificationView row,
    private int updateNotificationClipHeight(ExpandableView view,
            float notificationClipEnd, int childIndex) {
        float viewEnd = row.getTranslationY() + row.getActualHeight();
        boolean isPinned = (row.isPinned() || row.isHeadsUpAnimatingAway())
                && !mAmbientState.isDozingAndNotPulsing(row);
        float viewEnd = view.getTranslationY() + view.getActualHeight();
        boolean isPinned = (view.isPinned() || view.isHeadsUpAnimatingAway())
                && !mAmbientState.isDozingAndNotPulsing(view);
        boolean shouldClipOwnTop;
        if (mAmbientState.isPulseExpanding()) {
            shouldClipOwnTop = childIndex == 0;
        } else {
            shouldClipOwnTop = row.showingPulsing();
            shouldClipOwnTop = view.showingPulsing();
        }
        if (viewEnd > notificationClipEnd && !shouldClipOwnTop
                && (mAmbientState.isShadeExpanded() || !isPinned)) {
            int clipBottomAmount = (int) (viewEnd - notificationClipEnd);
            if (isPinned) {
                clipBottomAmount = Math.min(row.getIntrinsicHeight() - row.getCollapsedHeight(),
                clipBottomAmount = Math.min(view.getIntrinsicHeight() - view.getCollapsedHeight(),
                        clipBottomAmount);
            }
            row.setClipBottomAmount(clipBottomAmount);
            view.setClipBottomAmount(clipBottomAmount);
        } else {
            row.setClipBottomAmount(0);
            view.setClipBottomAmount(0);
        }
        if (shouldClipOwnTop) {
            return (int) (viewEnd - getTranslationY());
@@ -946,6 +943,11 @@ public class NotificationShelf extends ActivatableNotificationView implements
        updateRelativeOffset();
    }

    @Override
    public boolean needsClippingToShelf() {
        return false;
    }

    public void onUiModeChanged() {
        updateBackgroundColors();
    }
+0 −8
Original line number Diff line number Diff line
@@ -968,14 +968,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
        return mCurrentBackgroundTint;
    }

    public boolean isPinned() {
        return false;
    }

    public boolean isHeadsUpAnimatingAway() {
        return false;
    }

    public boolean isHeadsUp() {
        return false;
    }
+16 −0
Original line number Diff line number Diff line
@@ -139,6 +139,22 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
                localY < (bottom + slop);
    }

    /**
     * @return if this view needs to be clipped to the shelf
     */
    public boolean needsClippingToShelf() {
        return true;
    }


    public boolean isPinned() {
        return false;
    }

    public boolean isHeadsUpAnimatingAway() {
        return false;
    }

    /**
     * Sets the actual height of this notification. This is different than the laid out
     * {@link View#getHeight()}, as we want to avoid layouting during scrolling and expanding.
+5 −0
Original line number Diff line number Diff line
@@ -205,6 +205,11 @@ public abstract class StackScrollerDecorView extends ExpandableView {
        setContentVisible(true);
    }

    @Override
    public boolean needsClippingToShelf() {
        return false;
    }

    @Override
    public boolean hasOverlappingRendering() {
        return false;
+4 −0
Original line number Diff line number Diff line
@@ -76,6 +76,10 @@ class PeopleHubView(context: Context, attrs: AttributeSet) :
            }
        }

    override fun needsClippingToShelf(): Boolean {
        return true
    }

    private inner class PersonDataListenerImpl(val avatarView: ImageView) :
            DataListener<PersonViewModel?> {

Loading