Legacy custom views now get properly layed out again

Since the minheight grew, all notifications grew.
Legacy custom notifications need to stay the same
height though.

Change-Id: I469c448014c3d3c31526466d06a60ac44838b274
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 5d82dba..3db8371 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -192,6 +192,7 @@
     protected IDreamManager mDreamManager;
     PowerManager mPowerManager;
     protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    protected int mRowMinHeightLegacy;
     protected int mRowMinHeight;
     protected int mRowMaxHeight;
 
@@ -1338,7 +1339,6 @@
         PackageManager pmUser = getPackageManagerForUser(mContext,
                 entry.notification.getUser().getIdentifier());
 
-        int maxHeight = mRowMaxHeight;
         final StatusBarNotification sbn = entry.notification;
         entry.cacheContentViews(mContext, null);
 
@@ -1537,7 +1537,7 @@
             }
         }
         entry.row = row;
-        entry.row.setHeightRange(mRowMinHeight, maxHeight);
+        updateNotificationHeightRange(entry);
         entry.row.setOnActivatedListener(this);
         entry.row.setExpandable(bigContentViewLocal != null);
 
@@ -1555,6 +1555,14 @@
         return true;
     }
 
+    private void updateNotificationHeightRange(Entry entry) {
+        boolean customView = entry.getContentView().getId()
+                != com.android.internal.R.id.status_bar_latest_event_content;
+        boolean beforeN = entry.targetSdk < Build.VERSION_CODES.N;
+        int minHeight = customView && beforeN ? mRowMinHeightLegacy : mRowMinHeight;
+        entry.row.setHeightRange(minHeight, mRowMaxHeight);
+    }
+
     /**
      * Adds RemoteInput actions from the WearableExtender; to be removed once more apps support this
      * via first-class API.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 02632d5..a0cb890 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -525,6 +525,8 @@
     public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
         mRowMinHeight = rowMinHeight;
         mMaxViewHeight = rowMaxHeight;
+        mPrivateLayout.setSmallHeight(mRowMinHeight);
+        mPublicLayout.setSmallHeight(mRowMinHeight);
     }
 
     public boolean isExpandable() {
@@ -890,12 +892,17 @@
 
     @Override
     public int getMinHeight() {
+        NotificationContentView showingLayout = getShowingLayout();
+        return showingLayout.getMinHeight();
+    }
+
+    @Override
+    public int getMinExpandHeight() {
         if (mIsSummaryWithChildren && !mOnKeyguard) {
             return mChildrenContainer.getMinHeight()
                     + mNotificationHeader.getHeight();
         }
-        NotificationContentView showingLayout = getShowingLayout();
-        return showingLayout.getMinHeight();
+        return getMinHeight();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index af59ac7..51602e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -195,6 +195,15 @@
     }
 
     /**
+     * @return The minimum height this child chan be expanded to. Note that this might be different
+     * than {@link #getMinHeight()} because some elements can't be collapsed by an expand gesture
+     * to it's absolute minimal height
+     */
+    public int getMinExpandHeight() {
+        return getHeight();
+    }
+
+    /**
      * Sets the notification as dimmed. The default implementation does nothing.
      *
      * @param dimmed Whether the notification should be dimmed.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 17d9856..528a4af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -52,7 +52,6 @@
 
     private final Rect mClipBounds = new Rect();
     private final int mSingleLineHeight;
-    private final int mSmallHeight;
     private final int mHeadsUpHeight;
     private final int mRoundRectRadius;
     private final Interpolator mLinearInterpolator = new LinearInterpolator();
@@ -77,6 +76,7 @@
     private boolean mIsHeadsUp;
     private boolean mShowingLegacyBackground;
     private boolean mIsChildInGroup;
+    private int mSmallHeight;
     private ExpandableNotificationRow mContainingNotification;
     private StatusBarNotification mStatusBarNotification;
     private NotificationGroupManager mGroupManager;
@@ -116,7 +116,6 @@
         mFadePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
         mSingleLineHeight = getResources().getDimensionPixelSize(
                 R.dimen.notification_single_line_height);
-        mSmallHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
         mHeadsUpHeight = getResources().getDimensionPixelSize(R.dimen.notification_mid_height);
         mRoundRectRadius = getResources().getDimensionPixelSize(
                 R.dimen.notification_material_rounded_rect_radius);
@@ -126,6 +125,10 @@
         setOutlineProvider(mOutlineProvider);
     }
 
+    public void setSmallHeight(int smallHeight) {
+        mSmallHeight = smallHeight;
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int heightMode = MeasureSpec.getMode(heightMeasureSpec);
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 d2fae6f..c0e3ec1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1694,7 +1694,7 @@
     }
 
     private float getFadeoutAlpha() {
-        float alpha = (getNotificationsTopY() + mNotificationStackScroller.getItemHeight())
+        float alpha = (getNotificationsTopY() + mNotificationStackScroller.getFirstItemMinHeight())
                 / (mQsMinExpansionHeight + mNotificationStackScroller.getBottomStackPeekSize()
                 - mNotificationStackScroller.getCollapseSecondCardPadding());
         alpha = Math.max(0, Math.min(alpha, 1));
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 1a0d409f..05660ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3129,6 +3129,7 @@
         mNaturalBarHeight = res.getDimensionPixelSize(
                 com.android.internal.R.dimen.status_bar_height);
 
+        mRowMinHeightLegacy =  res.getDimensionPixelSize(R.dimen.notification_min_height_legacy);
         mRowMinHeight =  res.getDimensionPixelSize(R.dimen.notification_min_height);
         mRowMaxHeight =  res.getDimensionPixelSize(R.dimen.notification_max_height);
 
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 0c55256..185d32d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -272,7 +272,7 @@
     @Override
     protected void onDraw(Canvas canvas) {
         if (DEBUG) {
-            int y = mCollapsedSize;
+            int y = mTopPadding;
             canvas.drawLine(0, y, getWidth(), y, mDebugPaint);
             y = (int) (getLayoutHeight() - mBottomStackPeekSize
                     - mBottomStackSlowDownHeight);
@@ -550,8 +550,9 @@
         return Math.min(mMaxLayoutHeight, mCurrentStackHeight);
     }
 
-    public int getItemHeight() {
-        return mCollapsedSize;
+    public int getFirstItemMinHeight() {
+        final ExpandableView firstChild = getFirstChildNotGone();
+        return firstChild != null ? firstChild.getMinHeight() : mCollapsedSize;
     }
 
     public int getBottomStackPeekSize() {
@@ -1321,14 +1322,14 @@
         ExpandableView firstChild = (ExpandableView) getFirstChildNotGone();
         if (firstChild != null) {
             int contentHeight = getContentHeight();
-            int firstChildMaxExpandHeight = getMaxExpandHeight(firstChild);
             scrollRange = Math.max(0, contentHeight - mMaxLayoutHeight + mBottomStackPeekSize
                     + mBottomStackSlowDownHeight);
             if (scrollRange > 0) {
-                View lastChild = getLastChildNotGone();
+                int firstChildMaxExpandHeight = getMaxExpandHeight(firstChild);
                 // We want to at least be able collapse the first item and not ending in a weird
                 // end state.
-                scrollRange = Math.max(scrollRange, firstChildMaxExpandHeight - mCollapsedSize);
+                scrollRange = Math.max(scrollRange, firstChildMaxExpandHeight
+                        - firstChild.getMinHeight());
             }
         }
         return scrollRange;
@@ -1337,12 +1338,12 @@
     /**
      * @return the first child which has visibility unequal to GONE
      */
-    private View getFirstChildNotGone() {
+    private ExpandableView getFirstChildNotGone() {
         int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             View child = getChildAt(i);
             if (child.getVisibility() != View.GONE) {
-                return child;
+                return (ExpandableView) child;
             }
         }
         return null;
@@ -1504,7 +1505,10 @@
     }
 
     public int getMinStackHeight() {
-        return mCollapsedSize + mBottomStackPeekSize + mCollapseSecondCardPadding;
+        final ExpandableView firstChild = getFirstChildNotGone();
+        final int firstChildMinHeight = firstChild != null ? (int) firstChild.getMinHeight()
+                : mCollapsedSize;
+        return firstChildMinHeight + mBottomStackPeekSize + mCollapseSecondCardPadding;
     }
 
     public float getTopPaddingOverflow() {
@@ -1512,7 +1516,10 @@
     }
 
     public int getPeekHeight() {
-        return mIntrinsicPadding + mCollapsedSize + mBottomStackPeekSize
+        final ExpandableView firstChild = getFirstChildNotGone();
+        final int firstChildMinHeight = firstChild != null ? (int) firstChild.getMinHeight()
+                : mCollapsedSize;
+        return mIntrinsicPadding + firstChildMinHeight + mBottomStackPeekSize
                 + mCollapseSecondCardPadding;
     }
 
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 dba027b..953f287 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -72,6 +72,7 @@
     private int mMaxNotificationHeight;
     private boolean mScaleDimmed;
     private HeadsUpManager mHeadsUpManager;
+    private int mFirstChildMinHeight;
 
     public StackScrollAlgorithm(Context context) {
         initConstants(context);
@@ -155,7 +156,7 @@
         // Due to the overScroller, the stackscroller can have negative scroll state. This is
         // already accounted for by the top padding and doesn't need an additional adaption
         scrollY = Math.max(0, scrollY);
-        algorithmState.scrollY = (int) (scrollY + mCollapsedSize + bottomOverScroll);
+        algorithmState.scrollY = (int) (scrollY + mFirstChildMinHeight + bottomOverScroll);
 
         updateVisibleChildren(resultState, algorithmState);
 
@@ -424,7 +425,8 @@
             float yPositionInScrollViewAfterElement = yPositionInScrollView
                     + childHeight
                     + mPaddingBetweenElements;
-            float scrollOffset = yPositionInScrollView - algorithmState.scrollY + mCollapsedSize;
+            float scrollOffset = yPositionInScrollView - algorithmState.scrollY +
+                    mFirstChildMinHeight;
 
             if (i == algorithmState.lastTopStackIndex + 1) {
                 // Normally the position of this child is the position in the regular scrollview,
@@ -451,10 +453,10 @@
                         >= bottomStackStart && !mIsExpansionChanging && i != 0 && mIsSmallScreen) {
                     // we just collapse this element slightly
                     int newSize = (int) Math.max(bottomStackStart - mPaddingBetweenElements -
-                            childViewState.yTranslation, mCollapsedSize);
+                            childViewState.yTranslation, child.getMinHeight());
                     childViewState.height = newSize;
                     updateStateForChildTransitioningInBottom(algorithmState, bottomStackStart,
-                            bottomPeekStart, childViewState.yTranslation, childViewState,
+                            child, childViewState.yTranslation, childViewState,
                             childHeight);
                 }
                 clampPositionToBottomStackStart(childViewState, childViewState.height,
@@ -471,7 +473,7 @@
                     // According to the regular scroll view we are currently translating out of /
                     // into the bottom of the screen
                     updateStateForChildTransitioningInBottom(algorithmState,
-                            bottomStackStart, bottomPeekStart, currentYPosition,
+                            bottomStackStart, child, currentYPosition,
                             childViewState, childHeight);
                 }
             } else {
@@ -484,12 +486,13 @@
             // The first card is always rendered.
             if (i == 0) {
                 childViewState.alpha = 1.0f;
-                childViewState.yTranslation = Math.max(mCollapsedSize - algorithmState.scrollY, 0);
+                childViewState.yTranslation = Math.max(
+                        mFirstChildMinHeight - algorithmState.scrollY, 0);
                 if (childViewState.yTranslation + childViewState.height
                         > bottomPeekStart - mCollapseSecondCardPadding) {
                     childViewState.height = (int) Math.max(
                             bottomPeekStart - mCollapseSecondCardPadding
-                                    - childViewState.yTranslation, mCollapsedSize);
+                                    - childViewState.yTranslation, mFirstChildMinHeight);
                 }
                 childViewState.location = StackViewState.LOCATION_FIRST_CARD;
             }
@@ -501,7 +504,8 @@
 
             if (ambientState.isShadeExpanded() && topHeadsUpEntry != null
                     && child != topHeadsUpEntry) {
-                childViewState.yTranslation += topHeadsUpEntry.getHeadsUpHeight() - mCollapsedSize;
+                childViewState.yTranslation += topHeadsUpEntry.getHeadsUpHeight() -
+                        mFirstChildMinHeight;
             }
             childViewState.yTranslation += ambientState.getTopPadding()
                     + ambientState.getStackTranslation();
@@ -528,7 +532,7 @@
             boolean isTopEntry = topHeadsUpEntry == row;
             if (mIsExpanded) {
                 if (isTopEntry) {
-                    childState.height += row.getHeadsUpHeight() - mCollapsedSize;
+                    childState.height += row.getHeadsUpHeight() - mFirstChildMinHeight;
                 }
                 childState.height = Math.max(childState.height, row.getHeadsUpHeight());
                 // Ensure that the heads up is always visible even when scrolled off from the bottom
@@ -588,7 +592,7 @@
     private void clampPositionToTopStackEnd(StackViewState childViewState,
             int childHeight) {
         childViewState.yTranslation = Math.max(childViewState.yTranslation,
-                mCollapsedSize - childHeight);
+                mFirstChildMinHeight - childHeight);
     }
 
     private int getMaxAllowedChildHeight(View child, AmbientState ambientState) {
@@ -597,7 +601,7 @@
             if (ambientState == null && row.isHeadsUp()
                     || ambientState != null && ambientState.getTopHeadsUpEntry() == child) {
                 int extraSize = row.getIntrinsicHeight() - row.getHeadsUpHeight();
-                return mCollapsedSize + extraSize;
+                return mFirstChildMinHeight + extraSize;
             }
             return row.getIntrinsicHeight();
         } else if (child instanceof ExpandableView) {
@@ -608,7 +612,7 @@
     }
 
     private void updateStateForChildTransitioningInBottom(StackScrollAlgorithmState algorithmState,
-            float transitioningPositionStart, float bottomPeakStart, float currentYPosition,
+            float transitioningPositionStart, ExpandableView child, float currentYPosition,
             StackViewState childViewState, int childHeight) {
 
         // This is the transitioning element on top of bottom stack, calculate how far we are in.
@@ -620,9 +624,10 @@
         float offset = mBottomStackIndentationFunctor.getValue(algorithmState.partialInBottom);
         algorithmState.itemsInBottomStack += algorithmState.partialInBottom;
         int newHeight = childHeight;
-        if (childHeight > mCollapsedSize && mIsSmallScreen) {
+        if (childHeight > child.getMinHeight() && mIsSmallScreen) {
             newHeight = (int) Math.max(Math.min(transitioningPositionStart + offset -
-                    mPaddingBetweenElements - currentYPosition, childHeight), mCollapsedSize);
+                    mPaddingBetweenElements - currentYPosition, childHeight),
+                    child.getMinHeight());
             childViewState.height = newHeight;
         }
         childViewState.yTranslation = transitioningPositionStart + offset - newHeight
@@ -689,7 +694,7 @@
                     numItemsBefore = algorithmState.itemsInTopStack - i;
                 }
                 // The end position of the current child
-                float currentChildEndY = mCollapsedSize + mTopStackTotalSize
+                float currentChildEndY = mFirstChildMinHeight + mTopStackTotalSize
                         - mTopStackIndentationFunctor.getValue(numItemsBefore);
                 childViewState.yTranslation = currentChildEndY - childHeight;
             }
@@ -701,7 +706,7 @@
                 // We are hidden behind the top card and faded out, so we can hide ourselves.
                 childViewState.alpha = 0.0f;
             }
-            childViewState.yTranslation = mCollapsedSize - childHeight;
+            childViewState.yTranslation = mFirstChildMinHeight - childHeight;
             childViewState.location = StackViewState.LOCATION_TOP_STACK_HIDDEN;
         }
 
@@ -730,7 +735,7 @@
                     + childHeight
                     + mPaddingBetweenElements;
             if (yPositionInScrollView < algorithmState.scrollY) {
-                if (i == 0 && algorithmState.scrollY <= mCollapsedSize) {
+                if (i == 0 && algorithmState.scrollY <= mFirstChildMinHeight) {
 
                     // The starting position of the bottom stack peek
                     int bottomPeekStart = ambientState.getInnerHeight() - mBottomStackPeekSize -
@@ -740,14 +745,14 @@
                             ? mFirstChildMaxHeight
                             : childHeight;
                     childViewState.height = (int) Math.max(Math.min(bottomPeekStart, maxHeight),
-                            mCollapsedSize);
+                            mFirstChildMinHeight);
                     algorithmState.itemsInTopStack = 1.0f;
 
                 } else if (yPositionInScrollViewAfterElement < algorithmState.scrollY) {
                     // According to the regular scroll view we are fully off screen
                     algorithmState.itemsInTopStack += 1.0f;
                     if (i == 0) {
-                        childViewState.height = mCollapsedSize;
+                        childViewState.height = child.getMinHeight();
                     }
                 } else {
                     // According to the regular scroll view we are partially off screen
@@ -766,8 +771,8 @@
                         // If it is expanded we have to collapse it to a new size
                         float newSize = yPositionInScrollViewAfterElement
                                 - mPaddingBetweenElements
-                                - algorithmState.scrollY + mCollapsedSize;
-                        newSize = Math.max(mCollapsedSize, newSize);
+                                - algorithmState.scrollY + mFirstChildMinHeight;
+                        newSize = Math.max(mFirstChildMinHeight, newSize);
                         algorithmState.itemsInTopStack = 1.0f;
                         childViewState.height = (int) newSize;
                     }
@@ -809,7 +814,7 @@
                     // Interpolate the index from 0 to 2 while the second item is
                     // translating in.
                     stackIndex -= 1.0f;
-                    if (algorithmState.scrollY > mCollapsedSize) {
+                    if (algorithmState.scrollY > mFirstChildMinHeight) {
 
                         // Since there is a shadow treshhold, we cant just interpolate from 0 to
                         // 2 but we interpolate from 0.1f to 2.0f when scrolled in. The jump in
@@ -863,7 +868,7 @@
                     ExpandableNotificationRow row =
                             (ExpandableNotificationRow) mFirstChildWhileExpanding;
                     if (row.isHeadsUp()) {
-                        mFirstChildMaxHeight += mCollapsedSize - row.getHeadsUpHeight();
+                        mFirstChildMaxHeight += mFirstChildMinHeight - row.getHeadsUpHeight();
                     }
                 }
             } else {
@@ -927,7 +932,11 @@
         this.mIsExpanded = isExpanded;
     }
 
-    public void notifyChildrenChanged(final ViewGroup hostView) {
+    public void notifyChildrenChanged(final NotificationStackScrollLayout hostView) {
+        int firstItemMinHeight = hostView.getFirstItemMinHeight();
+        if (firstItemMinHeight != mFirstChildMinHeight) {
+            mFirstChildMinHeight = firstItemMinHeight;
+        }
         if (mIsExpansionChanging) {
             hostView.post(new Runnable() {
                 @Override