Cleaned up the clipping logic for the dismiss motion.

Notifications are now not clipped anymore during the animation
and it is ensured that the State is always correctly reset after
the animation.

Bug: 22232352
Change-Id: Ic873a0b119d5f71c29f5fd9b76a7bee1ae74638b
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 08a6603..ccec759 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -44,6 +44,7 @@
     private int mClipTopOptimization;
     private static Rect mClipRect = new Rect();
     private boolean mWillBeGone;
+    private int mMinClipTopAmount = 0;
 
     public ExpandableView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -400,6 +401,14 @@
         mWillBeGone = willBeGone;
     }
 
+    public int getMinClipTopAmount() {
+        return mMinClipTopAmount;
+    }
+
+    public void setMinClipTopAmount(int minClipTopAmount) {
+        mMinClipTopAmount = minClipTopAmount;
+    }
+
     /**
      * A listener notifying when {@link #getActualHeight} changes.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index ea59ecd1..b996724 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -941,6 +941,7 @@
         addPostCollapseAction(new Runnable() {
             @Override
             public void run() {
+                mStackScroller.setDismissAllInProgress(false);
                 try {
                     mBarService.onClearAllNotifications(mCurrentUserId);
                 } catch (Exception ex) { }
@@ -955,12 +956,6 @@
         Runnable animationFinishAction = new Runnable() {
             @Override
             public void run() {
-                mStackScroller.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        mStackScroller.setDismissAllInProgress(false);
-                    }
-                });
                 animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
             }
         };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index 4a7ea96..3a97be6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -43,6 +43,7 @@
     private int mTopPadding;
     private boolean mShadeExpanded;
     private float mMaxHeadsUpTranslation;
+    private boolean mDismissAllInProgress;
 
     public int getScrollY() {
         return mScrollY;
@@ -183,4 +184,12 @@
         HeadsUpManager.HeadsUpEntry topEntry = mHeadsUpManager.getTopEntry();
         return topEntry == null ? null : topEntry.entry.row;
     }
+
+    public void setDismissAllInProgress(boolean dismissAllInProgress) {
+        mDismissAllInProgress = dismissAllInProgress;
+    }
+
+    public boolean isDismissAllInProgress() {
+        return mDismissAllInProgress;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index bde07de..0d89b21 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -773,8 +773,7 @@
     }
 
     public boolean canChildBeDismissed(View v) {
-        final View veto = v.findViewById(R.id.veto);
-        return (veto != null && veto.getVisibility() != View.GONE);
+        return StackScrollAlgorithm.canChildBeDismissed(v);
     }
 
     @Override
@@ -2610,9 +2609,28 @@
     public void setDismissAllInProgress(boolean dismissAllInProgress) {
         mDismissAllInProgress = dismissAllInProgress;
         mDismissView.setDismissAllInProgress(dismissAllInProgress);
+        mAmbientState.setDismissAllInProgress(dismissAllInProgress);
         if (dismissAllInProgress) {
             disableClipOptimization();
         }
+        handleDismissAllClipping();
+    }
+
+    private void handleDismissAllClipping() {
+        final int count = getChildCount();
+        boolean previousChildWillBeDismissed = false;
+        for (int i = 0; i < count; i++) {
+            ExpandableView child = (ExpandableView) getChildAt(i);
+            if (child.getVisibility() == GONE) {
+                continue;
+            }
+            if (mDismissAllInProgress && previousChildWillBeDismissed) {
+                child.setMinClipTopAmount(child.getClipTopAmount());
+            } else {
+                child.setMinClipTopAmount(0);
+            }
+            previousChildWillBeDismissed = canChildBeDismissed(child);
+        }
     }
 
     private void disableClipOptimization() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 5c604b6..5d2e5b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -202,6 +202,7 @@
 
     private void updateClipping(StackScrollState resultState,
             StackScrollAlgorithmState algorithmState, AmbientState ambientState) {
+        boolean dismissAllInProgress = ambientState.isDismissAllInProgress();
         float previousNotificationEnd = 0;
         float previousNotificationStart = 0;
         boolean previousNotificationIsSwiped = false;
@@ -237,16 +238,29 @@
             updateChildClippingAndBackground(state, newHeight, clipHeight,
                     newHeight - (previousNotificationStart - newYTranslation));
 
+            if (dismissAllInProgress) {
+                state.clipTopAmount = Math.max(child.getMinClipTopAmount(), state.clipTopAmount);
+            }
+
             if (!child.isTransparent()) {
                 // Only update the previous values if we are not transparent,
                 // otherwise we would clip to a transparent view.
-                previousNotificationStart = newYTranslation + state.clipTopAmount * state.scale;
-                previousNotificationEnd = newNotificationEnd;
-                previousNotificationIsSwiped = ambientState.getDraggedViews().contains(child);
+                if ((dismissAllInProgress && canChildBeDismissed(child))) {
+                    previousNotificationIsSwiped = true;
+                } else {
+                    previousNotificationIsSwiped = ambientState.getDraggedViews().contains(child);
+                    previousNotificationEnd = newNotificationEnd;
+                    previousNotificationStart = newYTranslation + state.clipTopAmount * state.scale;
+                }
             }
         }
     }
 
+    public static boolean canChildBeDismissed(View v) {
+        final View veto = v.findViewById(R.id.veto);
+        return (veto != null && veto.getVisibility() != View.GONE);
+    }
+
     /**
      * Updates the shadow outline and the clipping for a view.
      *