Fix QS expansion weirdness

- Fix that the clock/avatar could get too large.
- Fix QS collapsing when on Keyguard and scroll view is scrolled
- Fix that clock/avatar didn't grow after a layout when expanding
- Fix flicker in header when overexpanding the panel
- Fix flicker from QS panel when it changes size
- Fix that scroll view still was scrolled after collapsing QS

Bug: 16869692
Bug: 16894194
Change-Id: Ic0f89ab860979db4d0438007b4d0d044d3e8c4ae
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 55b147a..55b82fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -117,6 +117,7 @@
     private int mQsPeekHeight;
     private boolean mStackScrollerOverscrolling;
     private boolean mQsExpansionFromOverscroll;
+    private float mLastOverscroll;
     private boolean mQsExpansionEnabled = true;
     private ValueAnimator mQsExpansionAnimator;
     private FlingAnimationUtils mFlingAnimationUtils;
@@ -273,9 +274,7 @@
                 requestScrollerTopPaddingUpdate(false /* animate */);
             }
         } else {
-            if (!mStackScrollerOverscrolling) {
-                setQsExpansion(mQsMinExpansionHeight);
-            }
+            setQsExpansion(mQsMinExpansionHeight + mLastOverscroll);
             positionClockAndNotifications();
             mNotificationStackScroller.setStackHeight(getExpandedHeight());
         }
@@ -552,8 +551,8 @@
     }
 
     private float getQsExpansionFraction() {
-        return (mQsExpansionHeight - mQsMinExpansionHeight)
-                / (getTempQsMaxExpansion() - mQsMinExpansionHeight);
+        return Math.min(1f, (mQsExpansionHeight - mQsMinExpansionHeight)
+                / (getTempQsMaxExpansion() - mQsMinExpansionHeight));
     }
 
     @Override
@@ -727,6 +726,7 @@
         float rounded = amount >= 1f ? amount : 0f;
         mStackScrollerOverscrolling = rounded != 0f && isRubberbanded;
         mQsExpansionFromOverscroll = rounded != 0f;
+        mLastOverscroll = rounded;
         updateQsState();
         setQsExpansion(mQsMinExpansionHeight + rounded);
     }
@@ -1034,7 +1034,9 @@
     }
 
     private float calculateQsTopPadding() {
-        if (mKeyguardShowing) {
+        // We can only do the smoother transition on Keyguard when we also are not collapsing from a
+        // scrolled quick settings.
+        if (mKeyguardShowing && mScrollYOverride == -1) {
             return interpolate(getQsExpansionFraction(),
                     mNotificationStackScroller.getIntrinsicPadding() - mNotificationTopPadding,
                     mQsMaxExpansionHeight);
@@ -1090,6 +1092,7 @@
             }
             return;
         }
+        mScrollView.setBlockFlinging(true);
         ValueAnimator animator = ValueAnimator.ofFloat(mQsExpansionHeight, target);
         mFlingAnimationUtils.apply(animator, mQsExpansionHeight, target, vel);
         animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@@ -1101,6 +1104,7 @@
         animator.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
+                mScrollView.setBlockFlinging(false);
                 mScrollYOverride = -1;
                 mQsExpansionAnimator = null;
                 if (onFinishRunnable != null) {