Clear all notifications improvements

- Fix a bug with visibility.
- Improve fling behavior such that the shade open animation still
  looks like that we are decelerating towards the last card.

Change-Id: I1ad167ce0001ff6850f49e819bab944943fa529d
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 909972a..b80a33b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1289,6 +1289,22 @@
     }
 
     @Override
+    protected boolean fullyExpandedClearAllVisible() {
+        return mNotificationStackScroller.isDismissViewNotGone()
+                && mNotificationStackScroller.isScrolledToBottom();
+    }
+
+    @Override
+    protected boolean isClearAllVisible() {
+        return mNotificationStackScroller.isDismissViewVisible();
+    }
+
+    @Override
+    protected int getClearAllHeight() {
+        return mNotificationStackScroller.getDismissViewHeight();
+    }
+
+    @Override
     protected boolean isTrackingBlocked() {
         return mConflictingQsExpansionGesture && mQsExpanded;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 7fb5693..3ec2395 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -462,6 +462,16 @@
     protected void fling(float vel, boolean expand) {
         cancelPeek();
         float target = expand ? getMaxPanelHeight() : 0.0f;
+
+        // Hack to make the expand transition look nice when clear all button is visible - we make
+        // the animation only to the last notification, and then jump to the maximum panel height so
+        // clear all just fades in and the decelerating motion is towards the last notification.
+        final boolean clearAllExpandHack = expand && fullyExpandedClearAllVisible()
+                && mExpandedHeight < getMaxPanelHeight() - getClearAllHeight()
+                && !isClearAllVisible();
+        if (clearAllExpandHack) {
+            target = getMaxPanelHeight() - getClearAllHeight();
+        }
         if (target == mExpandedHeight || getOverExpansionAmount() > 0f && expand) {
             notifyExpandingFinished();
             return;
@@ -490,9 +500,32 @@
 
             @Override
             public void onAnimationEnd(Animator animation) {
-                mHeightAnimator = null;
-                if (!mCancelled) {
-                    notifyExpandingFinished();
+                if (clearAllExpandHack && !mCancelled) {
+                    mHeightAnimator = createHeightAnimator(getMaxPanelHeight());
+                    mHeightAnimator.setInterpolator(mLinearOutSlowInInterpolator);
+                    mHeightAnimator.setDuration(350);
+                    mHeightAnimator.addListener(new AnimatorListenerAdapter() {
+                        private boolean mCancelled;
+
+                        @Override
+                        public void onAnimationCancel(Animator animation) {
+                            mCancelled = true;
+                        }
+
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            mHeightAnimator = null;
+                            if (!mCancelled) {
+                                notifyExpandingFinished();
+                            }
+                        }
+                    });
+                    mHeightAnimator.start();
+                } else {
+                    mHeightAnimator = null;
+                    if (!mCancelled) {
+                        notifyExpandingFinished();
+                    }
                 }
             }
         });
@@ -878,4 +911,16 @@
     protected abstract float getPeekHeight();
 
     protected abstract float getCannedFlingDurationFactor();
+
+    /**
+     * @return whether "Clear all" button will be visible when the panel is fully expanded
+     */
+    protected abstract boolean fullyExpandedClearAllVisible();
+
+    protected abstract boolean isClearAllVisible();
+
+    /**
+     * @return the height of the clear all button, in pixels
+     */
+    protected abstract int getClearAllHeight();
 }