Made heads up work again

Heads up notifications were completely broken before
with the shelf, but work better now.

Test: Add heads-up observe that it's visible
Bug: 32437839
Change-Id: I9ac08f4ea54a912efd53bb849b3223f534b76915
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 28b91c8..3c00c4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -771,9 +771,17 @@
         return mChildrenContainer;
     }
 
-    public void setHeadsupDisappearRunning(boolean running) {
-        mHeadsupDisappearRunning = running;
-        mPrivateLayout.setHeadsupDisappearRunning(running);
+    public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
+        mHeadsupDisappearRunning = headsUpAnimatingAway;
+        mPrivateLayout.setHeadsUpAnimatingAway(headsUpAnimatingAway);
+    }
+
+    /**
+     * @return if the view was just heads upped and is now animating away. During such a time the
+     * layout needs to be kept consistent
+     */
+    public boolean isHeadsUpAnimatingAway() {
+        return mHeadsupDisappearRunning;
     }
 
     public View getChildAfterViewWhenDismissed() {
@@ -1795,7 +1803,7 @@
         protected void onYTranslationAnimationFinished() {
             super.onYTranslationAnimationFinished();
             if (mHeadsupDisappearRunning) {
-                setHeadsupDisappearRunning(false);
+                setHeadsUpAnimatingAway(false);
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 377d53c..b5390b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -121,7 +121,7 @@
 
     private int mContentHeightAtAnimationStart = UNDEFINED;
     private boolean mFocusOnVisibilityChange;
-    private boolean mHeadsupDisappearRunning;
+    private boolean mHeadsUpAnimatingAway;
     private boolean mIconsVisible;
     private int mClipBottomAmount;
 
@@ -458,7 +458,7 @@
                     isTransitioningFromTo(VISIBLE_TYPE_HEADSUP, VISIBLE_TYPE_EXPANDED) ||
                     isTransitioningFromTo(VISIBLE_TYPE_EXPANDED, VISIBLE_TYPE_HEADSUP);
             boolean pinned = !isVisibleOrTransitioning(VISIBLE_TYPE_CONTRACTED)
-                    && (mIsHeadsUp || mHeadsupDisappearRunning);
+                    && (mIsHeadsUp || mHeadsUpAnimatingAway);
             if (transitioningBetweenHunAndExpanded || pinned) {
                 return Math.min(mHeadsUpChild.getHeight(), mExpandedChild.getHeight());
             }
@@ -851,7 +851,7 @@
             return VISIBLE_TYPE_SINGLELINE;
         }
 
-        if ((mIsHeadsUp || mHeadsupDisappearRunning) && mHeadsUpChild != null) {
+        if ((mIsHeadsUp || mHeadsUpAnimatingAway) && mHeadsUpChild != null) {
             if (viewHeight <= mHeadsUpChild.getHeight() || noExpandedChild) {
                 return VISIBLE_TYPE_HEADSUP;
             } else {
@@ -1194,8 +1194,8 @@
         }
     }
 
-    public void setHeadsupDisappearRunning(boolean headsupDisappearRunning) {
-        mHeadsupDisappearRunning = headsupDisappearRunning;
+    public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
+        mHeadsUpAnimatingAway = headsUpAnimatingAway;
         selectLayout(false /* animate */, true /* force */);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 463d321..3a49de2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -206,6 +206,11 @@
             if (child.getClipBottomAmount() != 0) {
                 child.setClipBottomAmount(0);
             }
+            if (child instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+                row.setIconTransformationAmount(0);
+            }
+
         }
         mNotificationIconContainer.calculateIconTranslations();
         mNotificationIconContainer.applyIconStates();
@@ -216,7 +221,8 @@
     private void updateNotificationClipHeight(ExpandableNotificationRow row,
             float notificationClipEnd) {
         float viewEnd = row.getTranslationY() + row.getActualHeight();
-        if (viewEnd > notificationClipEnd) {
+        if (viewEnd > notificationClipEnd && !row.isPinned() && !row.isHeadsUpAnimatingAway()) {
+            // TODO: handle heads up clipping correctly when closing.
             row.setClipBottomAmount((int) (viewEnd - notificationClipEnd));
         } else {
             row.setClipBottomAmount(0);
@@ -229,7 +235,8 @@
         float viewStart = row.getTranslationY();
         int transformHeight = row.getActualHeight() + mPaddingBetweenElements;
         float viewEnd = viewStart + transformHeight;
-        if (viewEnd >= shelfTransformationStart) {
+        if (viewEnd >= shelfTransformationStart && !row.isPinned()
+                && !row.isHeadsUpAnimatingAway()) {
             if (viewStart < shelfTransformationStart) {
                 float linearAmount = (shelfTransformationStart - viewStart) / transformHeight;
                 float interpolatedAmount =  Interpolators.ACCELERATE_DECELERATE.getInterpolation(
@@ -269,7 +276,8 @@
         float transitionDistance = getIntrinsicHeight() * 1.5f;
         float transformationStartPosition = getTranslationY() - transitionDistance;
         float transitionAmount = 0.0f;
-        if (viewStart < transformationStartPosition) {
+        if (viewStart < transformationStartPosition || row.isPinned()
+                || row.isHeadsUpAnimatingAway()) {
             // We simply place it on the icon of the notification
             iconState.yTranslation = notificationIconPosition - shelfIconPosition;
         } else {
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 584d5c0..f2ea991 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -202,7 +202,7 @@
     private Runnable mHeadsUpExistenceChangedRunnable = new Runnable() {
         @Override
         public void run() {
-            mHeadsUpAnimatingAway = false;
+            setHeadsUpAnimatingAway(false);
             notifyBarPanelExpansionChanged();
         }
     };
@@ -2195,16 +2195,22 @@
 
     @Override
     public void onHeadsUpPinnedModeChanged(final boolean inPinnedMode) {
+        mNotificationStackScroller.setInHeadsUpPinnedMode(inPinnedMode);
         if (inPinnedMode) {
             mHeadsUpExistenceChangedRunnable.run();
             updateNotificationTranslucency();
         } else {
-            mHeadsUpAnimatingAway = true;
+            setHeadsUpAnimatingAway(true);
             mNotificationStackScroller.runAfterAnimationFinished(
                     mHeadsUpExistenceChangedRunnable);
         }
     }
 
+    public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
+        mHeadsUpAnimatingAway = headsUpAnimatingAway;
+        mNotificationStackScroller.setHeadsUpAnimatingAway(headsUpAnimatingAway);
+    }
+
     @Override
     public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
         mNotificationStackScroller.generateHeadsUpAnimation(headsUp, true);
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 ff7cc19a0..2208f78 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -356,6 +356,9 @@
     private boolean mNoAmbient;
     private final Rect mClipRect = new Rect();
     private boolean mIsClipped;
+    private Rect mRequestedClipBounds;
+    private boolean mInHeadsUpPinnedMode;
+    private boolean mHeadsUpAnimatingAway;
 
     public NotificationStackScrollLayout(Context context) {
         this(context, null);
@@ -679,16 +682,6 @@
         }
     }
 
-    @Override
-    public void setClipBounds(Rect clipBounds) {
-        super.setClipBounds(clipBounds);
-        boolean clipped = clipBounds != null;
-        if (clipped != mIsClipped) {
-            mIsClipped = clipped;
-            updateFadingState();
-        }
-    }
-
     /**
      * Update the height of the panel.
      *
@@ -696,6 +689,7 @@
      */
     public void setExpandedHeight(float height) {
         mExpandedHeight = height;
+        setIsExpanded(height > 0);
         int minExpansionHeight = getMinExpansionHeight();
         if (height < minExpansionHeight) {
             mClipRect.left = 0;
@@ -703,11 +697,10 @@
             mClipRect.top = 0;
             mClipRect.bottom = (int) height;
             height = minExpansionHeight;
-            setClipBounds(mClipRect);
+            setRequestedClipBounds(mClipRect);
         } else {
-            setClipBounds(null);
+            setRequestedClipBounds(null);
         }
-        setIsExpanded(height > getMinExpansionHeight());
         int stackHeight;
         float translationY;
         float appearEndPosition = getAppearEndPosition();
@@ -733,6 +726,26 @@
             requestChildrenUpdate();
         }
         setStackTranslation(translationY);
+        requestChildrenUpdate();
+    }
+
+    private void setRequestedClipBounds(Rect clipRect) {
+        mRequestedClipBounds = clipRect;
+        updateClipping();
+    }
+
+    public void updateClipping() {
+        boolean clipped = mRequestedClipBounds != null && !mInHeadsUpPinnedMode
+                && !mHeadsUpAnimatingAway;
+        if (mIsClipped != clipped) {
+            mIsClipped = clipped;
+            updateFadingState();
+        }
+        if (clipped) {
+            setClipBounds(mRequestedClipBounds);
+        } else {
+            setClipBounds(null);
+        }
     }
 
     /**
@@ -2508,7 +2521,7 @@
         if (hasAddEvent) {
             // This child was just added lets remove all events.
             mHeadsUpChangeAnimations.removeAll(mTmpList);
-            ((ExpandableNotificationRow ) child).setHeadsupDisappearRunning(false);
+            ((ExpandableNotificationRow ) child).setHeadsUpAnimatingAway(false);
         }
         mTmpList.clear();
         return hasAddEvent;
@@ -2768,7 +2781,7 @@
                         : AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
                 if (row.isChildInGroup()) {
                     // We can otherwise get stuck in there if it was just isolated
-                    row.setHeadsupDisappearRunning(false);
+                    row.setHeadsUpAnimatingAway(false);
                 }
             } else {
                 ExpandableViewState viewState = mCurrentStackScrollState.getViewStateForView(row);
@@ -3271,10 +3284,10 @@
             View view = getChildAt(i);
             if (view instanceof ExpandableNotificationRow) {
                 ExpandableNotificationRow row = (ExpandableNotificationRow) view;
-                row.setHeadsupDisappearRunning(false);
+                row.setHeadsUpAnimatingAway(false);
                 if (row.isSummaryWithChildren()) {
                     for (ExpandableNotificationRow child : row.getNotificationChildren()) {
-                        child.setHeadsupDisappearRunning(false);
+                        child.setHeadsUpAnimatingAway(false);
                     }
                 }
             }
@@ -3833,7 +3846,7 @@
             mHeadsUpChangeAnimations.add(new Pair<>(row, isHeadsUp));
             mNeedsAnimation = true;
             if (!mIsExpanded && !isHeadsUp) {
-                row.setHeadsupDisappearRunning(true);
+                row.setHeadsUpAnimatingAway(true);
             }
             requestChildrenUpdate();
         }
@@ -3982,6 +3995,16 @@
                         - (mShelf.getIntrinsicHeight() - mStatusBarHeight) / 2;
     }
 
+    public void setInHeadsUpPinnedMode(boolean inHeadsUpPinnedMode) {
+        mInHeadsUpPinnedMode = inHeadsUpPinnedMode;
+        updateClipping();
+    }
+
+    public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
+        mHeadsUpAnimatingAway = headsUpAnimatingAway;
+        updateClipping();
+    }
+
     /**
      * A listener that is notified when some child locations might have changed.
      */
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 a862dc3..409d415 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -53,6 +53,7 @@
     private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
     private boolean mIsExpanded;
     private int mBottomStackSlowDownLength;
+    private int mStatusBarHeight;
 
     public StackScrollAlgorithm(Context context) {
         initView(context);
@@ -82,6 +83,7 @@
                 mBottomStackPeekSize,
                 getBottomStackSlowDownLength(),
                 0.5f);
+        mStatusBarHeight = context.getResources().getDimensionPixelSize(R.dimen.status_bar_height);
     }
 
     public void getStackScrollState(AmbientState ambientState, StackScrollState resultState) {
@@ -425,6 +427,7 @@
             if (row.isPinned()) {
                 childState.yTranslation = Math.max(childState.yTranslation, 0);
                 childState.height = Math.max(row.getIntrinsicHeight(), childState.height);
+                childState.hidden = false;
                 ExpandableViewState topState = resultState.getViewStateForView(topHeadsUpEntry);
                 if (!isTopEntry && (!mIsExpanded
                         || unmodifiedEndLocation < topState.yTranslation + topState.height)) {
@@ -435,6 +438,9 @@
                             - childState.height;
                 }
             }
+            if (row.isHeadsUpAnimatingAway()) {
+                childState.hidden = false;
+            }
         }
     }
 
@@ -496,6 +502,9 @@
         if (childViewState.yTranslation >= shelfStart) {
             childViewState.hidden = true;
         }
+        if (!ambientState.isShadeExpanded()) {
+            childViewState.height = (int) (mStatusBarHeight - childViewState.yTranslation);
+        }
     }
 
     protected int getMaxAllowedChildHeight(View child) {