From b5fe1d02cbfe9fbe1d2a1158006868e1290f4f4d Mon Sep 17 00:00:00 2001 From: Lyn Date: Mon, 31 Jan 2022 14:24:24 -0600 Subject: [PATCH] Remove scroll-up effect from lockscreen swipe-up and unlock hint by skipping notif stack height updates. What caused the bug: During swipe-up and unlock hint PVC reduces stack height; since shadeBottom remains the same, expansionFraction decreases, and so do notification heights. Now that notifs are shorter, there's more room, so a new notification starts to peek in above the shelf, resulting in a scroll-up effect. Note that we disable height updates for the above cases instead of only allowing lockscreen notif stack height changes for unfurl/to-shade/etc animations, since the latter approach can miss edge cases that require stack height updates, resulting in regressions Fixes: 217232659 Test: swipe up on lockscreen => notif stack moves up, no height change Test: tap lockscreen (not on any notif) => ls bounces up and down, no height change for notif stack Test: swipe away all notifs on lockscreen, no regressions Test: open shade from top, use shade normally, no regressions Change-Id: I80099b5892880f51aa0a90cbeeb2e1d981f52bc3 --- .../notification/stack/AmbientState.java | 20 +++++++ .../stack/NotificationStackScrollLayout.java | 59 +++++++++++++------ ...tificationStackScrollLayoutController.java | 7 +++ .../NotificationPanelViewController.java | 7 +++ .../statusbar/phone/PanelViewController.java | 8 ++- 5 files changed, 82 insertions(+), 19 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java index ce3e27c55f3e6..f40a3c7186e69 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java @@ -76,7 +76,10 @@ public class AmbientState { private float mHideAmount; private boolean mAppearing; private float mPulseHeight = MAX_PULSE_HEIGHT; + + /** How we much we are sleeping. 1f fully dozing (AOD), 0f fully awake (for all other states) */ private float mDozeAmount = 0.0f; + private Runnable mOnPulseHeightChangedListener; private ExpandableNotificationRow mTrackedHeadsUpRow; private float mAppearFraction; @@ -96,6 +99,9 @@ public class AmbientState { /** Height of the notifications panel without top padding when expansion completes. */ private float mStackEndHeight; + /** Whether we are swiping up. */ + private boolean mIsSwipingUp; + /** * @return Height of the notifications panel without top padding when expansion completes. */ @@ -132,6 +138,20 @@ public class AmbientState { mExpansionFraction = expansionFraction; } + /** + * @param isSwipingUp Whether we are swiping up. + */ + public void setSwipingUp(boolean isSwipingUp) { + mIsSwipingUp = isSwipingUp; + } + + /** + * @return Whether we are swiping up. + */ + public boolean isSwipingUp() { + return mIsSwipingUp; + } + /** * @return Fraction of shade expansion. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 9f6a81d3a9eef..fda7450c09b41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -204,6 +204,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable private float mQsExpansionFraction; private final int mSplitShadeMinContentHeight; + /** Whether we are flinging the shade open or closed. */ + private boolean mIsFlinging; + /** * The algorithm which calculates the properties for our children */ @@ -1271,6 +1274,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable updateStackPosition(false /* listenerNeedsAnimation */); } + /** + * @return Whether we should skip stack height update for lockscreen swipe-up or unlock hint. + */ + private boolean shouldSkipHeightUpdate() { + // After the user swipes up on lockscreen and lets go, + // {@link PanelViewController) flings the shade back down. + return mAmbientState.isOnKeyguard() && ( + mAmbientState.isUnlockHintRunning() || mAmbientState.isSwipingUp() || mIsFlinging); + } + /** * Apply expansion fraction to the y position and height of the notifications panel. * @param listenerNeedsAnimation does the listener need to animate? @@ -1285,7 +1298,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable if (mOnStackYChanged != null) { mOnStackYChanged.accept(listenerNeedsAnimation); } - if (mQsExpansionFraction <= 0) { + if (mQsExpansionFraction <= 0 && !shouldSkipHeightUpdate()) { final float endHeight = updateStackEndHeight( getHeight(), getEmptyBottomMargin(), mTopPadding); updateStackHeight(endHeight, fraction); @@ -1327,22 +1340,27 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable @ShadeViewRefactor(RefactorComponent.COORDINATOR) public void setExpandedHeight(float height) { final float shadeBottom = getHeight() - getEmptyBottomMargin(); - final float expansionFraction = MathUtils.saturate(height / shadeBottom); - mAmbientState.setExpansionFraction(expansionFraction); + final boolean skipHeightUpdate = shouldSkipHeightUpdate(); + if (!skipHeightUpdate) { + final float expansionFraction = MathUtils.saturate(height / shadeBottom); + mAmbientState.setExpansionFraction(expansionFraction); + } updateStackPosition(); - mExpandedHeight = height; - setIsExpanded(height > 0); - int minExpansionHeight = getMinExpansionHeight(); - if (height < minExpansionHeight) { - mClipRect.left = 0; - mClipRect.right = getWidth(); - mClipRect.top = 0; - mClipRect.bottom = (int) height; - height = minExpansionHeight; - setRequestedClipBounds(mClipRect); - } else { - setRequestedClipBounds(null); + if (!skipHeightUpdate) { + mExpandedHeight = height; + setIsExpanded(height > 0); + int minExpansionHeight = getMinExpansionHeight(); + if (height < minExpansionHeight) { + mClipRect.left = 0; + mClipRect.right = getWidth(); + mClipRect.top = 0; + mClipRect.bottom = (int) height; + height = minExpansionHeight; + setRequestedClipBounds(mClipRect); + } else { + setRequestedClipBounds(null); + } } int stackHeight; float translationY; @@ -1370,7 +1388,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } } else { - stackHeight = (int) height; + stackHeight = (int) (skipHeightUpdate ? mExpandedHeight : height); } } else { appearFraction = calculateAppearFraction(height); @@ -1388,7 +1406,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable } } mAmbientState.setAppearFraction(appearFraction); - if (stackHeight != mCurrentStackHeight) { + if (stackHeight != mCurrentStackHeight && !skipHeightUpdate) { mCurrentStackHeight = stackHeight; updateAlgorithmHeightAndPadding(); requestChildrenUpdate(); @@ -5003,6 +5021,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable mAmbientState.setUnlockHintRunning(running); } + /** + * @param isFlinging Whether we are flinging the shade open or closed. + */ + public void setIsFlinging(boolean isFlinging) { + mIsFlinging = isFlinging; + } + @ShadeViewRefactor(RefactorComponent.SHADE_VIEW) public void setHeadsUpGoingAwayAnimationsAllowed(boolean headsUpGoingAwayAnimationsAllowed) { mHeadsUpGoingAwayAnimationsAllowed = headsUpGoingAwayAnimationsAllowed; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 334128a2b4ca1..ba5429445b23b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -1178,6 +1178,13 @@ public class NotificationStackScrollLayoutController { mView.setUnlockHintRunning(running); } + /** + * @param isFlinging Whether we are flinging the shade open or close. + */ + public void setIsFlinging(boolean isFlinging) { + mView.setIsFlinging(isFlinging); + } + public boolean isFooterViewNotGone() { return mView.isFooterViewNotGone(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 1870588f34aef..e507b0ddacf18 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -1875,9 +1875,16 @@ public class NotificationPanelViewController extends PanelViewController mHeadsUpTouchHelper.notifyFling(!expand); mKeyguardStateController.notifyPanelFlingStart(!expand /* flingingToDismiss */); setClosingWithAlphaFadeout(!expand && !isOnKeyguard() && getFadeoutAlpha() == 1.0f); + mNotificationStackScrollLayoutController.setIsFlinging(true); super.flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing); } + @Override + protected void onFlingEnd(boolean cancelled) { + super.onFlingEnd(cancelled); + mNotificationStackScrollLayoutController.setIsFlinging(false); + } + private boolean onQsIntercept(MotionEvent event) { int pointerIndex = event.findPointerIndex(mTrackingPointer); if (pointerIndex < 0) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java index c466a8ce6d3f4..1f2c0675c5889 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -461,7 +461,7 @@ public abstract class PanelViewController { boolean expands = onEmptySpaceClick(mInitialTouchX); onTrackingStopped(expands); } - + mAmbientState.setSwipingUp(false); mVelocityTracker.clear(); } @@ -708,7 +708,7 @@ public abstract class PanelViewController { animator.start(); } - private void onFlingEnd(boolean cancelled) { + void onFlingEnd(boolean cancelled) { mIsFlinging = false; // No overshoot when the animation ends setOverExpansionInternal(0, false /* isFromGesture */); @@ -1393,6 +1393,10 @@ public abstract class PanelViewController { mUpwardsWhenThresholdReached = isDirectionUpwards(x, y); } if ((!mGestureWaitForTouchSlop || mTracking) && !isTrackingBlocked()) { + // Count h==0 as part of swipe-up, + // otherwise {@link NotificationStackScrollLayout} + // wrongly enables stack height updates at the start of lockscreen swipe-up + mAmbientState.setSwipingUp(h <= 0); setExpandedHeightInternal(newHeight); } break;