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

Commit 17e1b695 authored by Selim Cinek's avatar Selim Cinek
Browse files

Improved the low priority behavior with the shelf

Low priority notification now don't just disappear,
but transform into an overflow such that there's still
some object permanence.

Test: add low-priority notifications, see dot transformation
Bug: 32437839
Change-Id: I90c03c7d88c01c199062bd5f7f0151629654a3a1
parent 65d418ec
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -891,7 +891,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
    }

    private void updateIconVisibilities() {
        boolean visible = isChildInGroup() || isBelowSpeedBump() || mIconsVisible;
        boolean visible = isChildInGroup()
                || (isBelowSpeedBump() && !NotificationShelf.SHOW_AMBIENT_ICONS)
                || mIconsVisible;
        mPublicLayout.setIconsVisible(visible);
        mPrivateLayout.setIconsVisible(visible);
        if (mChildrenContainer != null) {
+3 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import com.android.systemui.statusbar.stack.StackScrollState;
 */
public class NotificationShelf extends ActivatableNotificationView {

    public static final boolean SHOW_AMBIENT_ICONS = true;
    private static final boolean USE_ANIMATIONS_WHEN_OPENING =
            SystemProperties.getBoolean("debug.icon_opening_animations", true);
    private ViewInvertHelper mViewInvertHelper;
@@ -248,6 +249,7 @@ public class NotificationShelf extends ActivatableNotificationView {
            notGoneIndex++;
            previousColor = ownColorUntinted;
        }
        mShelfIcons.setSpeedBumpIndex(mAmbientState.getSpeedBumpIndex());
        mShelfIcons.calculateIconTranslations();
        mShelfIcons.applyIconStates();
        boolean hideBackground = numViewsInShelf < 1.0f;
@@ -476,6 +478,7 @@ public class NotificationShelf extends ActivatableNotificationView {
        float paddingStart = NotificationUtils.interpolate(start,
                mShelfIcons.getPaddingStart(), openedAmount);
        mShelfIcons.setActualPaddingStart(paddingStart);
        mShelfIcons.setOpenedAmount(openedAmount);
    }

    public void setMaxLayoutHeight(int maxLayoutHeight) {
+10 −7
Original line number Diff line number Diff line
@@ -127,9 +127,9 @@ public class NotificationIconAreaController {
        return mPhoneStatusBar.getStatusBarHeight();
    }

    protected boolean shouldShowNotification(NotificationData.Entry entry,
            NotificationData notificationData) {
        if (notificationData.isAmbient(entry.key)
    protected boolean shouldShowNotificationIcon(NotificationData.Entry entry,
            NotificationData notificationData, boolean showAmbient) {
        if (notificationData.isAmbient(entry.key) && !showAmbient
                && !NotificationData.showNotificationEvenIfUnprovisioned(entry.notification)) {
            return false;
        }
@@ -148,8 +148,10 @@ public class NotificationIconAreaController {
     */
    public void updateNotificationIcons(NotificationData notificationData) {

        updateIconsForLayout(notificationData, entry -> entry.icon, mNotificationIcons);
        updateIconsForLayout(notificationData, entry -> entry.expandedIcon, mShelfIcons);
        updateIconsForLayout(notificationData, entry -> entry.icon, mNotificationIcons,
                false /* showAmbient */);
        updateIconsForLayout(notificationData, entry -> entry.expandedIcon, mShelfIcons,
                NotificationShelf.SHOW_AMBIENT_ICONS);

        applyNotificationIconsTint();
        ArrayList<NotificationData.Entry> activeNotifications
@@ -173,10 +175,11 @@ public class NotificationIconAreaController {
     * @param notificationData the notification data to look up which notifications are relevant
     * @param function A function to look up an icon view based on an entry
     * @param hostLayout which layout should be updated
     * @param showAmbient should ambient notification icons be shown
     */
    private void updateIconsForLayout(NotificationData notificationData,
            Function<NotificationData.Entry, StatusBarIconView> function,
            NotificationIconContainer hostLayout) {
            NotificationIconContainer hostLayout, boolean showAmbient) {
        ArrayList<StatusBarIconView> toShow = new ArrayList<>(
                mNotificationScrollLayout.getChildCount());

@@ -185,7 +188,7 @@ public class NotificationIconAreaController {
            View view = mNotificationScrollLayout.getChildAt(i);
            if (view instanceof ExpandableNotificationRow) {
                NotificationData.Entry ent = ((ExpandableNotificationRow) view).getEntry();
                if (shouldShowNotification(ent, notificationData)) {
                if (shouldShowNotificationIcon(ent, notificationData, showAmbient)) {
                    toShow.add(function.apply(ent));
                }
            }
+52 −23
Original line number Diff line number Diff line
@@ -89,6 +89,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
    private boolean mChangingViewPositions;
    private int mAddAnimationStartIndex = -1;
    private int mCannedAnimationStartIndex = -1;
    private int mSpeedBumpIndex = -1;
    private int mIconSize;
    private float mOpenedAmount = 0.0f;

    public NotificationIconContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -119,6 +122,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        float centerY = getHeight() / 2.0f;
        // we layout all our children on the left at the top
        mIconSize = 0;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            // We need to layout all children even the GONE ones, such that the heights are
@@ -127,6 +131,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
            int height = child.getMeasuredHeight();
            int top = (int) (centerY - height / 2.0f);
            child.layout(0, top, width, top + height);
            if (i == 0) {
                mIconSize = child.getWidth();
            }
        }
        if (mShowAllIcons) {
            resetViewStates();
@@ -216,42 +223,56 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
     */
    public void calculateIconTranslations() {
        float translationX = getActualPaddingStart();
        int overflowingIconIndex = -1;
        int lastTwoIconWidth = 0;
        int firstOverflowIndex = -1;
        int childCount = getChildCount();
        float layoutEnd = getLayoutEnd();
        float overflowStart = layoutEnd - mIconSize * 2.2f;
        boolean hasAmbient = mSpeedBumpIndex != -1 && mSpeedBumpIndex < getChildCount();
        float visualOverflowStart = 0;
        for (int i = 0; i < childCount; i++) {
            View view = getChildAt(i);
            IconState iconState = mIconStates.get(view);
            iconState.xTranslation = translationX;
            boolean isAmbient = mSpeedBumpIndex != -1 && i >= mSpeedBumpIndex
                    && iconState.iconAppearAmount > 0.0f;
            boolean noOverflowAfter = i == childCount - 1;
            if (mOpenedAmount != 0.0f) {
                noOverflowAfter = noOverflowAfter && !hasAmbient;
            }
            iconState.visibleState = StatusBarIconView.STATE_ICON;
            translationX += iconState.iconAppearAmount * view.getWidth();
            if (translationX > getLayoutEnd()) {
                // we are overflowing it with this icon
                overflowingIconIndex = i - 1;
                lastTwoIconWidth = view.getWidth();
                break;
            if (firstOverflowIndex == -1 && (isAmbient
                    || (translationX >= (noOverflowAfter ? layoutEnd - mIconSize : overflowStart)))) {
                firstOverflowIndex = noOverflowAfter ? i - 1 : i;
                int totalDotLength = mStaticDotRadius * 6 + 2 * mDotPadding;
                visualOverflowStart = overflowStart + mIconSize * 1.2f - totalDotLength / 2
                        - mIconSize * 0.5f + mStaticDotRadius;
                if (isAmbient) {
                    visualOverflowStart = Math.min(translationX, visualOverflowStart
                            + mStaticDotRadius * 2 + mDotPadding);
                } else {
                    visualOverflowStart += (translationX - overflowStart) / mIconSize
                            * (mStaticDotRadius * 2 + mDotPadding);
                }
            }
        if (overflowingIconIndex != -1) {
            translationX += iconState.iconAppearAmount * view.getWidth();
        }
        if (firstOverflowIndex != -1) {
            int numDots = 1;
            View overflowIcon = getChildAt(overflowingIconIndex);
            IconState overflowState = mIconStates.get(overflowIcon);
            lastTwoIconWidth += overflowIcon.getWidth();
            int dotWidth = mStaticDotRadius * 2 + mDotPadding;
            int totalDotLength = mStaticDotRadius * 6 + 2 * mDotPadding;
            translationX = (getLayoutEnd() - lastTwoIconWidth / 2 - totalDotLength / 2)
                    - overflowIcon.getWidth() * 0.3f + mStaticDotRadius;
            float overflowStart = getLayoutEnd() - lastTwoIconWidth;
            float overlapAmount = (overflowState.xTranslation - overflowStart)
                    / overflowIcon.getWidth();
            translationX += overlapAmount * dotWidth;
            for (int i = overflowingIconIndex; i < childCount; i++) {
            translationX = visualOverflowStart;
            for (int i = firstOverflowIndex; i < childCount; i++) {
                View view = getChildAt(i);
                IconState iconState = mIconStates.get(view);
                int dotWidth = mStaticDotRadius * 2 + mDotPadding;
                iconState.xTranslation = translationX;
                if (numDots <= 3) {
                    if (numDots == 1 && iconState.iconAppearAmount < 0.8f) {
                        iconState.visibleState = StatusBarIconView.STATE_ICON;
                        numDots--;
                    } else {
                        iconState.visibleState = StatusBarIconView.STATE_DOT;
                    translationX += numDots == 3 ? 3 * dotWidth : dotWidth;
                    }
                    translationX += (numDots == 3 ? 3 * dotWidth : dotWidth)
                            * iconState.iconAppearAmount;
                } else {
                    iconState.visibleState = StatusBarIconView.STATE_HIDDEN;
                }
@@ -331,6 +352,14 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
        return mIconStates.get(icon);
    }

    public void setSpeedBumpIndex(int speedBumpIndex) {
        mSpeedBumpIndex = speedBumpIndex;
    }

    public void setOpenedAmount(float expandAmount) {
        mOpenedAmount = expandAmount;
    }

    public class IconState extends ViewState {
        public float iconAppearAmount = 1.0f;
        public float clampedAppearAmount = 1.0f;