From af3ca90ae5657177fab73df7d7cd1a8b3cbdd431 Mon Sep 17 00:00:00 2001 From: Lyn Han Date: Mon, 8 Mar 2021 19:01:35 -0600 Subject: [PATCH] Skip shelf icon fade for low priority notifications Fix issue where low priority icons fade into the shelf then immediately fade out into the dot. Remove unused things - openedAmount: originally added to fix cutout issue but we won't show the shelf near the cutout anymore - expandedAmount: tweaks shelf transformation near the status bar but we won't show the shelf near the status bar anymore - handleCustomTransformHeight: leftover from shelf-icon to notif-icon animation, which we already removed Bug: 178479515 Test: scroll shade up and down Change-Id: I7c3e2cb6dac1ce70de1dbe575734c393f7f511de --- .../systemui/statusbar/NotificationShelf.java | 236 +++--------------- .../phone/NotificationIconContainer.java | 37 ++- 2 files changed, 54 insertions(+), 219 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 3496581b1b8af..e1199077efb93 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -16,9 +16,6 @@ package com.android.systemui.statusbar; -import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN_REVERSE; -import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE; - import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; @@ -34,7 +31,6 @@ import android.view.WindowInsets; import android.view.accessibility.AccessibilityNodeInfo; import com.android.internal.annotations.VisibleForTesting; -import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; import com.android.systemui.statusbar.notification.NotificationUtils; @@ -55,8 +51,6 @@ import com.android.systemui.statusbar.phone.NotificationIconContainer; public class NotificationShelf extends ActivatableNotificationView implements View.OnLayoutChangeListener, StateListener { - private static final boolean USE_ANIMATIONS_WHEN_OPENING = - SystemProperties.getBoolean("debug.icon_opening_animations", true); private static final boolean ICON_ANMATIONS_WHILE_SCROLLING = SystemProperties.getBoolean("debug.icon_scroll_animations", true); private static final int TAG_CONTINUOUS_CLIPPING = R.id.continuous_clipping_tag; @@ -174,18 +168,9 @@ public class NotificationShelf extends ActivatableNotificationView implements float viewEnd = lastViewState.yTranslation + lastViewState.height; viewState.copyFrom(lastViewState); viewState.height = getIntrinsicHeight(); - viewState.yTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height, getFullyClosedTranslation()); viewState.zTranslation = ambientState.getBaseZHeight(); - // For the small display size, it's not enough to make the icon not covered by - // the top cutout so the denominator add the height of cutout. - // Totally, (getIntrinsicHeight() * 2 + mCutoutHeight) should be smaller then - // mAmbientState.getTopPadding(). - float openedAmount = (viewState.yTranslation - getFullyClosedTranslation()) - / (getIntrinsicHeight() * 2 + mCutoutHeight); - openedAmount = Math.min(1.0f, openedAmount); - viewState.openedAmount = openedAmount; viewState.clipTopAmount = 0; viewState.alpha = 1; viewState.belowSpeedBump = mHostLayoutController.getSpeedBumpIndex() == 0; @@ -220,11 +205,6 @@ public class NotificationShelf extends ActivatableNotificationView implements View lastChild = mAmbientState.getLastVisibleBackgroundChild(); mNotGoneIndex = -1; float interpolationStart = mMaxLayoutHeight - getIntrinsicHeight() * 2; - float expandAmount = 0.0f; - if (shelfStart >= interpolationStart) { - expandAmount = (shelfStart - interpolationStart) / getIntrinsicHeight(); - expandAmount = Math.min(1.0f, expandAmount); - } // find the first view that doesn't overlap with the shelf int notGoneIndex = 0; int colorOfViewBeforeLast = NO_COLOR; @@ -239,7 +219,6 @@ public class NotificationShelf extends ActivatableNotificationView implements boolean scrollingFast = currentScrollVelocity > mScrollFastThreshold || (mAmbientState.isExpansionChanging() && Math.abs(mAmbientState.getExpandingVelocity()) > mScrollFastThreshold); - boolean scrolling = currentScrollVelocity > 0; boolean expandingAnimated = mAmbientState.isExpansionChanging() && !mAmbientState.isPanelTracking(); int baseZHeight = mAmbientState.getBaseZHeight(); @@ -249,8 +228,7 @@ public class NotificationShelf extends ActivatableNotificationView implements ActivatableNotificationView previousAnv = null; for (int i = 0; i < mHostLayoutController.getChildCount(); i++) { - ExpandableView child = (ExpandableView) mHostLayoutController.getChildAt(i); - + ExpandableView child = mHostLayoutController.getChildAt(i); if (!child.needsClippingToShelf() || child.getVisibility() == GONE) { continue; } @@ -268,9 +246,8 @@ public class NotificationShelf extends ActivatableNotificationView implements int clipTop = updateNotificationClipHeight(child, notificationClipEnd, notGoneIndex); clipTopAmount = Math.max(clipTop, clipTopAmount); - - float inShelfAmount = updateShelfTransformation(child, expandAmount, scrolling, - scrollingFast, expandingAnimated, isLastChild); + final float inShelfAmount = updateShelfTransformation(child, scrollingFast, + expandingAnimated, isLastChild); // If the current row is an ExpandableNotificationRow, update its color, roundedness, // and icon state. if (child instanceof ExpandableNotificationRow) { @@ -498,56 +475,40 @@ public class NotificationShelf extends ActivatableNotificationView implements /** * @return the amount how much this notification is in the shelf */ - private float updateShelfTransformation(ExpandableView view, float expandAmount, - boolean scrolling, boolean scrollingFast, boolean expandingAnimated, - boolean isLastChild) { - StatusBarIconView icon = view.getShelfIcon(); - NotificationIconContainer.IconState iconState = getIconState(icon); + private float updateShelfTransformation(ExpandableView view, boolean scrollingFast, + boolean expandingAnimated, boolean isLastChild) { // Let calculate how much the view is in the shelf float viewStart = view.getTranslationY(); int fullHeight = view.getActualHeight() + mPaddingBetweenElements; float iconTransformStart = calculateIconTransformationStart(view); - float transformDistance = getIntrinsicHeight() * 1.5f; - transformDistance *= NotificationUtils.interpolate(1.f, 1.5f, expandAmount); - transformDistance = Math.min(transformDistance, fullHeight); - // Let's make sure the transform distance is // at most to the icon (relevant for conversations) - transformDistance = Math.min(viewStart + fullHeight - iconTransformStart, - transformDistance); + float transformDistance = Math.min( + viewStart + fullHeight - iconTransformStart, + getIntrinsicHeight()); if (isLastChild) { fullHeight = Math.min(fullHeight, view.getMinHeight() - getIntrinsicHeight()); - transformDistance = Math.min(transformDistance, view.getMinHeight() - - getIntrinsicHeight()); + transformDistance = Math.min( + transformDistance, + view.getMinHeight() - getIntrinsicHeight()); } float viewEnd = viewStart + fullHeight; - handleCustomTransformHeight(view, expandingAnimated, iconState); - - float fullTransitionAmount; - float iconTransitionAmount; - float contentTransformationAmount; + float fullTransitionAmount = 0.0f; + float iconTransitionAmount = 0.0f; float shelfStart = getTranslationY(); - boolean fullyInOrOut = true; - if (viewEnd >= shelfStart && (!mAmbientState.isUnlockHintRunning() || view.isInShelf()) + + if (viewEnd >= shelfStart + && (!mAmbientState.isUnlockHintRunning() || view.isInShelf()) && (mAmbientState.isShadeExpanded() || (!view.isPinned() && !view.isHeadsUpAnimatingAway()))) { - if (viewStart < shelfStart) { - if (iconState != null && iconState.hasCustomTransformHeight()) { - fullHeight = iconState.customTransformHeight; - transformDistance = iconState.customTransformHeight; - } + if (viewStart < shelfStart) { float fullAmount = (shelfStart - viewStart) / fullHeight; fullAmount = Math.min(1.0f, fullAmount); - float interpolatedAmount = Interpolators.ACCELERATE_DECELERATE.getInterpolation( - fullAmount); - interpolatedAmount = NotificationUtils.interpolate( - interpolatedAmount, fullAmount, expandAmount); - fullTransitionAmount = 1.0f - interpolatedAmount; - + fullTransitionAmount = 1.0f - fullAmount; if (isLastChild) { // Reduce icon transform distance to completely fade in shelf icon // by the time the notification icon fades out, and vice versa @@ -558,37 +519,14 @@ public class NotificationShelf extends ActivatableNotificationView implements } iconTransitionAmount = MathUtils.constrain(iconTransitionAmount, 0.0f, 1.0f); iconTransitionAmount = 1.0f - iconTransitionAmount; - fullyInOrOut = false; } else { + // Fully in shelf. fullTransitionAmount = 1.0f; iconTransitionAmount = 1.0f; } - - // Transforming the content - contentTransformationAmount = (shelfStart - viewStart) / transformDistance; - contentTransformationAmount = Math.min(1.0f, contentTransformationAmount); - contentTransformationAmount = 1.0f - contentTransformationAmount; - } else { - fullTransitionAmount = 0.0f; - iconTransitionAmount = 0.0f; - contentTransformationAmount = 0.0f; } - if (iconState != null && fullyInOrOut && !expandingAnimated && iconState.isLastExpandIcon) { - iconState.isLastExpandIcon = false; - iconState.customTransformHeight = NO_VALUE; - } - - // Update the content transformation amount - if (view.isAboveShelf() || view.showingPulsing() - || (!isLastChild && iconState != null && !iconState.translateContent)) { - contentTransformationAmount = 0.0f; - } - view.setContentTransformationAmount(contentTransformationAmount, isLastChild); - - // Update the positioning of the icon - updateIconPositioning(view, iconTransitionAmount, fullTransitionAmount, - transformDistance, scrolling, scrollingFast, expandingAnimated, isLastChild); - + updateIconPositioning(view, iconTransitionAmount, + scrollingFast, expandingAnimated, isLastChild); return fullTransitionAmount; } @@ -607,87 +545,31 @@ public class NotificationShelf extends ActivatableNotificationView implements return start; } - private void handleCustomTransformHeight(ExpandableView view, boolean expandingAnimated, - NotificationIconContainer.IconState iconState) { - if (iconState != null && expandingAnimated && mAmbientState.getScrollY() == 0 - && !mAmbientState.isOnKeyguard() && !iconState.isLastExpandIcon) { - // We are expanding animated. Because we switch to a linear interpolation in this case, - // the last icon may be stuck in between the shelf position and the notification - // position, which looks pretty bad. We therefore optimize this case by applying a - // shorter transition such that the icon is either fully in the notification or we clamp - // it into the shelf if it's close enough. - // We need to persist this, since after the expansion, the behavior should still be the - // same. - float position = mAmbientState.getIntrinsicPadding() - + mHostLayoutController.getPositionInLinearLayout(view); - int maxShelfStart = mMaxLayoutHeight - getIntrinsicHeight(); - if (position < maxShelfStart && position + view.getIntrinsicHeight() >= maxShelfStart - && view.getTranslationY() < position) { - iconState.isLastExpandIcon = true; - iconState.customTransformHeight = NO_VALUE; - // Let's check if we're close enough to snap into the shelf - boolean forceInShelf = mMaxLayoutHeight - getIntrinsicHeight() - position - < getIntrinsicHeight(); - if (!forceInShelf) { - // We are overlapping the shelf but not enough, so the icon needs to be - // repositioned - iconState.customTransformHeight = (int) (mMaxLayoutHeight - - getIntrinsicHeight() - position); - } - } - } - } - private void updateIconPositioning(ExpandableView view, float iconTransitionAmount, - float fullTransitionAmount, float iconTransformDistance, boolean scrolling, boolean scrollingFast, boolean expandingAnimated, boolean isLastChild) { StatusBarIconView icon = view.getShelfIcon(); NotificationIconContainer.IconState iconState = getIconState(icon); if (iconState == null) { return; } - boolean forceInShelf = - iconState.isLastExpandIcon && !iconState.hasCustomTransformHeight(); boolean clampInShelf = iconTransitionAmount > 0.5f || isTargetClipped(view); float clampedAmount = clampInShelf ? 1.0f : 0.0f; if (iconTransitionAmount == clampedAmount) { - iconState.noAnimations = (scrollingFast || expandingAnimated) && !forceInShelf; - iconState.useFullTransitionAmount = iconState.noAnimations - || (!ICON_ANMATIONS_WHILE_SCROLLING && iconTransitionAmount == 0.0f - && scrolling); - iconState.useLinearTransitionAmount = !ICON_ANMATIONS_WHILE_SCROLLING - && iconTransitionAmount == 0.0f && !mAmbientState.isExpansionChanging(); - iconState.translateContent = mMaxLayoutHeight - getTranslationY() - - getIntrinsicHeight() > 0; + iconState.noAnimations = (scrollingFast || expandingAnimated) && !isLastChild; } - if (!forceInShelf && (scrollingFast || (expandingAnimated - && iconState.useFullTransitionAmount && !ViewState.isAnimatingY(icon)))) { + if (!isLastChild + && (scrollingFast || (expandingAnimated && !ViewState.isAnimatingY(icon)))) { iconState.cancelAnimations(icon); - iconState.useFullTransitionAmount = true; iconState.noAnimations = true; } - if (iconState.hasCustomTransformHeight()) { - iconState.useFullTransitionAmount = true; - } - if (iconState.isLastExpandIcon) { - iconState.translateContent = false; - } float transitionAmount; if (mAmbientState.isHiddenAtAll() && !view.isInShelf()) { transitionAmount = mAmbientState.isFullyHidden() ? 1 : 0; - } else if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING - || iconState.useFullTransitionAmount - || iconState.useLinearTransitionAmount) { - transitionAmount = iconTransitionAmount; } else { transitionAmount = iconTransitionAmount; iconState.needsCannedAnimation = iconState.clampedAppearAmount != clampedAmount && !mNoAnimationsInThisFrame; } - iconState.iconAppearAmount = !USE_ANIMATIONS_WHEN_OPENING - || iconState.useFullTransitionAmount - ? fullTransitionAmount - : transitionAmount; iconState.clampedAppearAmount = clampedAmount; setIconTransformationAmount(view, transitionAmount, isLastChild); } @@ -706,8 +588,7 @@ public class NotificationShelf extends ActivatableNotificationView implements return endOfTarget >= getTranslationY() - mPaddingBetweenElements; } - private void setIconTransformationAmount(ExpandableView view, - float transitionAmount, + private void setIconTransformationAmount(ExpandableView view, float transitionAmount, boolean isLastChild) { if (!(view instanceof ExpandableNotificationRow)) { return; @@ -718,32 +599,30 @@ public class NotificationShelf extends ActivatableNotificationView implements if (iconState == null) { return; } - iconState.hidden = transitionAmount == 0.0f && !iconState.isAnimating(icon); - boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); - if (isAppearing) { - iconState.hidden = true; - iconState.iconAppearAmount = 0.0f; - } iconState.alpha = transitionAmount; + boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); + iconState.hidden = isAppearing + || (view instanceof ExpandableNotificationRow + && ((ExpandableNotificationRow) view).isLowPriority() + && mShelfIcons.hasMaxNumDot()) + || (transitionAmount == 0.0f && !iconState.isAnimating(icon)) + || row.isAboveShelf() + || row.showingPulsing() + || (!row.isInShelf() && isLastChild) + || row.getTranslationZ() > mAmbientState.getBaseZHeight(); + iconState.iconAppearAmount = iconState.hidden? 0f : transitionAmount; + // Fade in icons at shelf start // This is important for conversation icons, which are badged and need x reset iconState.xTranslation = mShelfIcons.getActualPaddingStart(); - boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf(); + final boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf(); if (stayingInShelf) { iconState.iconAppearAmount = 1.0f; iconState.alpha = 1.0f; - iconState.scaleX = 1.0f; - iconState.scaleY = 1.0f; iconState.hidden = false; } - if (row.isAboveShelf() - || row.showingPulsing() - || (!row.isInShelf() && (isLastChild && row.areGutsExposed() - || row.getTranslationZ() > mAmbientState.getBaseZHeight()))) { - iconState.hidden = true; - } int backgroundColor = getBackgroundColorWithoutTint(); int shelfColor = icon.getContrastedStaticDrawableColor(backgroundColor); if (row.isShowingIcon() && shelfColor != StatusBarIconView.NO_COLOR) { @@ -819,42 +698,6 @@ public class NotificationShelf extends ActivatableNotificationView implements return ret; } - private void setOpenedAmount(float openedAmount) { - mNoAnimationsInThisFrame = openedAmount == 1.0f && mOpenedAmount == 0.0f; - mOpenedAmount = openedAmount; - if (!mAmbientState.isPanelFullWidth() || mAmbientState.isDozing()) { - // We don't do a transformation at all, lets just assume we are fully opened - openedAmount = 1.0f; - } - int start = mRelativeOffset; - if (isLayoutRtl()) { - start = getWidth() - start - mCollapsedIcons.getWidth(); - } - int width = (int) NotificationUtils.interpolate( - start + mCollapsedIcons.getFinalTranslationX(), - mShelfIcons.getWidth(), - FAST_OUT_SLOW_IN_REVERSE.getInterpolation(openedAmount)); - mShelfIcons.setActualLayoutWidth(width); - boolean hasOverflow = mCollapsedIcons.hasOverflow(); - int collapsedPadding = mCollapsedIcons.getPaddingEnd(); - if (!hasOverflow) { - // we have to ensure that adding the low priority notification won't lead to an - // overflow - collapsedPadding -= mCollapsedIcons.getNoOverflowExtraPadding(); - } else { - // Partial overflow padding will fill enough space to add extra dots - collapsedPadding -= mCollapsedIcons.getPartialOverflowExtraPadding(); - } - float padding = NotificationUtils.interpolate(collapsedPadding, - mShelfIcons.getPaddingEnd(), - openedAmount); - mShelfIcons.setActualPaddingEnd(padding); - float paddingStart = NotificationUtils.interpolate(start, - mShelfIcons.getPaddingStart(), openedAmount); - mShelfIcons.setActualPaddingStart(paddingStart); - mShelfIcons.setOpenedAmount(openedAmount); - } - public void setMaxLayoutHeight(int maxLayoutHeight) { mMaxLayoutHeight = maxLayoutHeight; } @@ -947,7 +790,6 @@ public class NotificationShelf extends ActivatableNotificationView implements } private class ShelfState extends ExpandableViewState { - private float openedAmount; private boolean hasItemsInStableShelf; @Override @@ -957,7 +799,6 @@ public class NotificationShelf extends ActivatableNotificationView implements } super.applyToView(view); - setOpenedAmount(openedAmount); updateAppearance(); setHasItemsInStableShelf(hasItemsInStableShelf); mShelfIcons.setAnimationsEnabled(mAnimationsEnabled); @@ -970,7 +811,6 @@ public class NotificationShelf extends ActivatableNotificationView implements } super.animateTo(child, properties); - setOpenedAmount(openedAmount); updateAppearance(); setHasItemsInStableShelf(hasItemsInStableShelf); mShelfIcons.setAnimationsEnabled(mAnimationsEnabled); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java index 9561851ab28be..89b97aef62831 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java @@ -155,7 +155,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { private int mCannedAnimationStartIndex = -1; private int mSpeedBumpIndex = -1; private int mIconSize; - private float mOpenedAmount = 0.0f; private boolean mDisallowNextAnimation; private boolean mAnimationsEnabled = true; private ArrayMap> mReplacingIcons; @@ -349,6 +348,10 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { } } + public boolean hasMaxNumDot() { + return mNumDots >= MAX_DOTS; + } + private boolean areAnimationsEnabled(StatusBarIconView icon) { return mAnimationsEnabled || icon == mIsolatedIcon; } @@ -391,7 +394,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { float overflowStart = getMaxOverflowStart(); mVisualOverflowStart = 0; mFirstVisibleIconState = null; - boolean hasAmbient = mSpeedBumpIndex != -1 && mSpeedBumpIndex < getChildCount(); for (int i = 0; i < childCount; i++) { View view = getChildAt(i); IconState iconState = mIconStates.get(view); @@ -410,10 +412,9 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { float drawingScale = mOnLockScreen && view instanceof StatusBarIconView ? ((StatusBarIconView) view).getIconScaleIncreased() : 1f; - if (mOpenedAmount != 0.0f) { - noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow; - } - iconState.visibleState = StatusBarIconView.STATE_ICON; + iconState.visibleState = iconState.hidden + ? StatusBarIconView.STATE_HIDDEN + : StatusBarIconView.STATE_ICON; boolean isOverflowing = (translationX > (noOverflowAfter ? layoutEnd - mIconSize @@ -598,10 +599,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { mSpeedBumpIndex = speedBumpIndex; } - public void setOpenedAmount(float expandAmount) { - mOpenedAmount = expandAmount; - } - public boolean hasOverflow() { return mNumDots > 0; } @@ -706,13 +703,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { public boolean justAdded = true; private boolean justReplaced; public boolean needsCannedAnimation; - public boolean useFullTransitionAmount; - public boolean useLinearTransitionAmount; - public boolean translateContent; public int iconColor = StatusBarIconView.NO_COLOR; public boolean noAnimations; - public boolean isLastExpandIcon; - public int customTransformHeight = NO_VALUE; private final View mView; private final Consumer mCannedAnimationEndListener; @@ -734,8 +726,15 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { StatusBarIconView icon = (StatusBarIconView) view; boolean animate = false; AnimationProperties animationProperties = null; - boolean animationsAllowed = areAnimationsEnabled(icon) && !mDisallowNextAnimation - && !noAnimations; + final boolean isLowPriorityIconChange = + (visibleState == StatusBarIconView.STATE_HIDDEN + && icon.getVisibleState() == StatusBarIconView.STATE_DOT) + || (visibleState == StatusBarIconView.STATE_DOT + && icon.getVisibleState() == StatusBarIconView.STATE_HIDDEN); + final boolean animationsAllowed = areAnimationsEnabled(icon) + && !mDisallowNextAnimation + && !noAnimations + && !isLowPriorityIconChange; if (animationsAllowed) { if (justAdded || justReplaced) { super.applyToView(icon); @@ -822,10 +821,6 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout { needsCannedAnimation = false; } - public boolean hasCustomTransformHeight() { - return isLastExpandIcon && customTransformHeight != NO_VALUE; - } - @Override public void initFrom(View view) { super.initFrom(view);