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

Commit 11bfc967 authored by Lyn Han's avatar Lyn Han Committed by Android (Google) Code Review
Browse files

Merge "Fix notification shelf issues" into tm-dev

parents 26e995aa 50f61bfd
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.NotificationBackgroundView;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
@@ -411,7 +410,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
        setBackgroundTop(backgroundTop);
        setFirstElementRoundness(firstElementRoundness);
        mShelfIcons.setSpeedBumpIndex(mHostLayoutController.getSpeedBumpIndex());
        mShelfIcons.calculateIconTranslations();
        mShelfIcons.calculateIconXTranslations();
        mShelfIcons.applyIconStates();
        for (int i = 0; i < mHostLayoutController.getChildCount(); i++) {
            View child = mHostLayoutController.getChildAt(i);
@@ -636,7 +635,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
        float viewEnd = viewStart + fullHeight;
        float fullTransitionAmount = 0.0f;
        float iconTransitionAmount = 0.0f;
        float shelfStart = getTranslationY();
        float shelfStart = getTranslationY() - mPaddingBetweenElements;
        if (mAmbientState.isExpansionChanging() && !mAmbientState.isOnKeyguard()) {
            // TODO(b/172289889) handle icon placement for notification that is clipped by the shelf
            if (mIndexOfFirstViewInShelf != -1 && i >= mIndexOfFirstViewInShelf) {
+1 −3
Original line number Diff line number Diff line
@@ -207,9 +207,7 @@ constructor(
        visibleIndex: Int
    ): Float {
        var height = stack.calculateGapHeight(previous, current, visibleIndex)
        if (visibleIndex != 0) {
        height += dividerHeight
        }
        return height
    }

+5 −3
Original line number Diff line number Diff line
@@ -314,7 +314,8 @@ public class StackScrollAlgorithm {

            if (ambientState.getShelf() != null) {
                final float shelfStart = ambientState.getStackEndHeight()
                        - ambientState.getShelf().getIntrinsicHeight();
                        - ambientState.getShelf().getIntrinsicHeight()
                        - mPaddingBetweenElements;
                if (currentY >= shelfStart
                        && !(view instanceof FooterView)
                        && state.firstViewInShelf == null) {
@@ -507,8 +508,9 @@ public class StackScrollAlgorithm {
                                    || bypassPulseNotExpanding
                                    ? ambientState.getInnerHeight()
                                    : (int) ambientState.getStackHeight();
                    final int shelfStart =
                            stackBottom - ambientState.getShelf().getIntrinsicHeight();
                    final int shelfStart = stackBottom
                            - ambientState.getShelf().getIntrinsicHeight()
                            - mPaddingBetweenElements;
                    viewState.yTranslation = Math.min(viewState.yTranslation, shelfStart);
                    if (viewState.yTranslation >= shelfStart) {
                        viewState.hidden = !view.isExpandAnimationRunning()
+17 −21
Original line number Diff line number Diff line
@@ -27,11 +27,13 @@ import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.util.Property;
import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.animation.Interpolator;

import androidx.annotation.VisibleForTesting;
import androidx.collection.ArrayMap;

import com.android.internal.statusbar.StatusBarIcon;
@@ -136,6 +138,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
    }.setDuration(CONTENT_FADE_DURATION);

    private static final int MAX_ICONS_ON_AOD = 3;

    /* Maximum number of icons in short shelf on lockscreen when also showing overflow dot. */
    public static final int MAX_ICONS_ON_LOCKSCREEN = 3;
    public static final int MAX_STATIC_ICONS = 4;
    private static final int MAX_DOTS = 1;
@@ -145,7 +149,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
    private int mDotPadding;
    private int mStaticDotRadius;
    private int mStaticDotDiameter;
    private int mOverflowWidth;
    private int mActualLayoutWidth = NO_VALUE;
    private float mActualPaddingEnd = NO_VALUE;
    private float mActualPaddingStart = NO_VALUE;
@@ -219,10 +222,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {

            paint.setColor(Color.RED);
            canvas.drawLine(mVisualOverflowStart, 0, mVisualOverflowStart, height, paint);

            paint.setColor(Color.YELLOW);
            float overflow = getMaxOverflowStart();
            canvas.drawLine(overflow, 0, overflow, height, paint);
        }
    }

@@ -255,14 +254,14 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
        }
    }

    private void setIconSize(int size) {
    @VisibleForTesting
    public void setIconSize(int size) {
        mIconSize = size;
        mOverflowWidth = mIconSize + (MAX_DOTS - 1) * (mStaticDotDiameter + mDotPadding);
    }

    private void updateState() {
        resetViewStates();
        calculateIconTranslations();
        calculateIconXTranslations();
        applyIconStates();
    }

@@ -390,12 +389,11 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
     * @return Width of shelf for the given number of icons
     */
    public float calculateWidthFor(float numIcons) {
        if (getChildCount() == 0) {
        if (numIcons == 0) {
            return 0f;
        }
        final float contentWidth = numIcons <= MAX_ICONS_ON_LOCKSCREEN + 1
                ? numIcons * mIconSize
                : MAX_ICONS_ON_LOCKSCREEN * mIconSize + (float) mOverflowWidth;
        final float contentWidth =
                mIconSize * MathUtils.min(numIcons, MAX_ICONS_ON_LOCKSCREEN + 1);
        return getActualPaddingStart()
                + contentWidth
                + getActualPaddingEnd();
@@ -406,14 +404,13 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
     * are inserted into the notification container.
     * If this is not a whole number, the fraction means by how much the icon is appearing.
     */
    public void calculateIconTranslations() {
    public void calculateIconXTranslations() {
        float translationX = getActualPaddingStart();
        int firstOverflowIndex = -1;
        int childCount = getChildCount();
        int maxVisibleIcons = mOnLockScreen ? MAX_ICONS_ON_AOD :
                mIsStaticLayout ? MAX_STATIC_ICONS : childCount;
        float layoutEnd = getLayoutEnd();
        float overflowStart = getMaxOverflowStart();
        mVisualOverflowStart = 0;
        mFirstVisibleIconState = null;
        for (int i = 0; i < childCount; i++) {
@@ -438,12 +435,12 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
                    ? StatusBarIconView.STATE_HIDDEN
                    : StatusBarIconView.STATE_ICON;

            boolean isOverflowing =
                    (translationX > (isLastChild ? layoutEnd - mIconSize
                            : overflowStart - mIconSize));
            final float overflowDotX = layoutEnd - mIconSize;
            boolean isOverflowing = translationX > overflowDotX;

            if (firstOverflowIndex == -1 && (forceOverflow || isOverflowing)) {
                firstOverflowIndex = isLastChild && !forceOverflow ? i - 1 : i;
                mVisualOverflowStart = layoutEnd - mOverflowWidth;
                mVisualOverflowStart = layoutEnd - mIconSize;
                if (forceOverflow || mIsStaticLayout) {
                    mVisualOverflowStart = Math.min(translationX, mVisualOverflowStart);
                }
@@ -477,7 +474,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
            mLastVisibleIconState = mIconStates.get(lastChild);
            mFirstVisibleIconState = mIconStates.get(getChildAt(0));
        }

        if (isLayoutRtl()) {
            for (int i = 0; i < childCount; i++) {
                View view = getChildAt(i);
@@ -568,7 +564,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
    }

    private float getMaxOverflowStart() {
        return getLayoutEnd() - mOverflowWidth;
        return getLayoutEnd() - mIconSize;
    }

    public void setChangingViewPositions(boolean changingViewPositions) {
@@ -635,7 +631,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
            return 0;
        }

        int collapsedPadding = mOverflowWidth;
        int collapsedPadding = mIconSize;

        if (collapsedPadding + getFinalTranslationX() > getWidth()) {
            collapsedPadding = getWidth() - getFinalTranslationX();
+20 −15
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
    @Mock private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
    @Mock private lateinit var stackLayout: NotificationStackScrollLayout

    private val testableResources = mContext.getOrCreateTestableResources()
    private val testableResources = mContext.orCreateTestableResources

    private lateinit var sizeCalculator: NotificationStackSizeCalculator

@@ -121,17 +121,16 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
    }

    @Test
    fun computeHeight_returnsAtMostSpaceAvailable_withGapBeforeShelf() {
    fun computeHeight_gapBeforeShelf_returnsSpaceUsed() {
        // Each row in separate section.
        setGapHeight(gapHeight)
        val shelfHeight = shelfHeight
        val availableSpace =
        val spaceUsed =
            listOf(
                    rowHeight + dividerHeight,
                    gapHeight + rowHeight + dividerHeight,
                    gapHeight + dividerHeight + shelfHeight)
                    dividerHeight + rowHeight,
                    dividerHeight + gapHeight + rowHeight,
                    dividerHeight + gapHeight + shelfHeight)
                .sum()

        // All rows in separate sections (default setup).
        val availableSpace = spaceUsed + 1;
        val rows =
            listOf(createMockRow(rowHeight), createMockRow(rowHeight), createMockRow(rowHeight))

@@ -139,23 +138,29 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
        assertThat(maxNotifications).isEqualTo(2)

        val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, this.shelfHeight)
        assertThat(height).isAtMost(availableSpace)
        assertThat(height).isEqualTo(spaceUsed)
    }

    @Test
    fun computeHeight_noGapBeforeShelf_returnsAtMostSpaceAvailable() {
    fun computeHeight_noGapBeforeShelf_returnsSpaceUsed() {
        // Both rows are in the same section.
        setGapHeight(0f)

        val rowHeight = rowHeight
        val shelfHeight = shelfHeight
        val availableSpace = listOf(rowHeight + dividerHeight, dividerHeight + shelfHeight).sum()
        val spaceUsed =
            listOf(
                dividerHeight + rowHeight,
                dividerHeight + shelfHeight)
                .sum()
        val availableSpace = spaceUsed + 1
        val rows = listOf(createMockRow(rowHeight), createMockRow(rowHeight))

        val maxNotifications = computeMaxKeyguardNotifications(rows, availableSpace, shelfHeight)
        assertThat(maxNotifications).isEqualTo(1)

        val height = sizeCalculator.computeHeight(stackLayout, maxNotifications, this.shelfHeight)
        assertThat(height).isAtMost(availableSpace)
        assertThat(height).isEqualTo(spaceUsed)
    }

    @Test
@@ -190,7 +195,7 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {

        val space = sizeCalculator.spaceNeeded(expandableView, visibleIndex = 0,
                previousView = null, stack = stackLayout, onLockscreen = true)
        assertThat(space).isEqualTo(5)
        assertThat(space).isEqualTo(5 + dividerHeight)
    }

    @Test
@@ -204,7 +209,7 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {

        val space = sizeCalculator.spaceNeeded(expandableView, visibleIndex = 0,
                previousView = null, stack = stackLayout, onLockscreen = false)
        assertThat(space).isEqualTo(10)
        assertThat(space).isEqualTo(10 + dividerHeight)
    }

    private fun computeMaxKeyguardNotifications(
Loading