Overscroll header when expanding the panel.

Bug: 14486987
Change-Id: I563aabf273328d733d7452af7f54db28934df9d9
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 c8f185c..03d164b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -45,9 +45,10 @@
 
 public class NotificationPanelView extends PanelView implements
         ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener,
-        View.OnClickListener, KeyguardPageSwipeHelper.Callback {
+        View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,
+        KeyguardPageSwipeHelper.Callback {
 
-    private static float EXPANSION_RUBBER_BAND_EXTRA_FACTOR = 0.4f;
+    private static float EXPANSION_RUBBER_BAND_EXTRA_FACTOR = 0.6f;
 
     private KeyguardPageSwipeHelper mPageSwiper;
     PhoneStatusBar mStatusBar;
@@ -86,6 +87,7 @@
     private int mQsPeekHeight;
     private float mNotificationTranslation;
     private int mStackScrollerIntrinsicPadding;
+    private boolean mStackScrollerOverscrolling;
     private boolean mQsExpansionEnabled = true;
     private ValueAnimator mQsExpansionAnimator;
     private FlingAnimationUtils mFlingAnimationUtils;
@@ -139,6 +141,7 @@
         mNotificationStackScroller = (NotificationStackScrollLayout)
                 findViewById(R.id.notification_stack_scroller);
         mNotificationStackScroller.setOnHeightChangedListener(this);
+        mNotificationStackScroller.setOverscrollTopChangedListener(this);
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
                 android.R.interpolator.fast_out_slow_in);
         mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
@@ -172,7 +175,9 @@
                 setQsStackScrollerPadding(mQsMaxExpansionHeight);
             }
         } else {
-            setQsExpansion(mQsMinExpansionHeight);
+            if (!mStackScrollerOverscrolling) {
+                setQsExpansion(mQsMinExpansionHeight);
+            }
             positionClockAndNotifications();
             mNotificationStackScroller.setStackHeight(getExpandedHeight());
         }
@@ -185,7 +190,10 @@
     private void positionClockAndNotifications() {
         boolean animateClock = mNotificationStackScroller.isAddOrRemoveAnimationPending();
         if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) {
-            mStackScrollerIntrinsicPadding = mHeader.getBottom() + mQsPeekHeight
+            int bottom = mStackScrollerOverscrolling
+                    ? mHeader.getCollapsedHeight()
+                    : mHeader.getBottom();
+            mStackScrollerIntrinsicPadding = bottom + mQsPeekHeight
                     + mNotificationTopPadding;
             mTopPaddingAdjustment = 0;
         } else {
@@ -489,6 +497,16 @@
         }
     }
 
+
+    @Override
+    public void onOverscrollTopChanged(float amount) {
+        cancelAnimation();
+        float rounded = amount >= 1f ? amount : 0f;
+        mStackScrollerOverscrolling = rounded != 0f;
+        setQsExpansion(mQsMinExpansionHeight + rounded);
+        updateQsState();
+    }
+
     private void onQsExpansionStarted() {
         onQsExpansionStarted(0);
     }
@@ -516,9 +534,10 @@
     }
 
     private void updateQsState() {
-        mHeader.setExpanded(mQsExpanded);
+        boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling;
+        mHeader.setExpanded(expandVisually, mStackScrollerOverscrolling);
         mNotificationStackScroller.setEnabled(!mQsExpanded);
-        mQsPanel.setVisibility(mQsExpanded ? View.VISIBLE : View.INVISIBLE);
+        mQsPanel.setVisibility(expandVisually ? View.VISIBLE : View.INVISIBLE);
         mQsContainer.setVisibility(mKeyguardShowing && !mQsExpanded
                 ? View.INVISIBLE
                 : View.VISIBLE);
@@ -528,7 +547,7 @@
     private void setQsExpansion(float height) {
         height = Math.min(Math.max(height, mQsMinExpansionHeight), mQsMaxExpansionHeight);
         mQsFullyExpanded = height == mQsMaxExpansionHeight;
-        if (height > mQsMinExpansionHeight && !mQsExpanded) {
+        if (height > mQsMinExpansionHeight && !mQsExpanded && !mStackScrollerOverscrolling) {
             setQsExpanded(true);
         } else if (height <= mQsMinExpansionHeight && mQsExpanded) {
             setQsExpanded(false);
@@ -536,7 +555,9 @@
         mQsExpansionHeight = height;
         mHeader.setExpansion(height - mQsPeekHeight);
         setQsTranslation(height);
-        setQsStackScrollerPadding(height);
+        if (!mStackScrollerOverscrolling) {
+            setQsStackScrollerPadding(height);
+        }
         mStatusBar.userActivity();
     }