Fixed the appearance of the shelf on the lockscreen

Previously the shelf algorithm wasn't applied properly
on the lockscreen.

Test: Add notifications, observe shelf on the lockscreen when collapsing
Bug: 32437839
Change-Id: I7c768e1450a86b5a8731c998ef58212550dfb4bc
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 4649d50..f9451c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -2196,10 +2196,11 @@
 
         int visibleNotifications = 0;
         boolean onKeyguard = mState == StatusBarState.KEYGUARD;
-        int maxNotifications = 0;
+        int maxNotifications = -1;
         if (onKeyguard) {
             maxNotifications = getMaxKeyguardNotifications(true /* recompute */);
         }
+        mStackScroller.setMaxDisplayedNotifications(maxNotifications);
         for (int i = 0; i < N; i++) {
             NotificationData.Entry entry = activeNotifications.get(i);
             boolean childNotification = mGroupManager.isChildInGroupWithSummary(entry.notification);
@@ -2218,8 +2219,7 @@
             boolean showOnKeyguard = shouldShowOnKeyguard(entry.notification);
             if (suppressedSummary
                     || (isLockscreenPublicMode(userId) && !mShowLockscreenNotifications)
-                    || (onKeyguard && !childWithVisibleSummary
-                            && (visibleNotifications >= maxNotifications || !showOnKeyguard))) {
+                    || (onKeyguard && !showOnKeyguard)) {
                 entry.row.setVisibility(View.GONE);
             } else {
                 boolean wasGone = entry.row.getVisibility() == View.GONE;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index 9d9f3b9..4b95f07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -97,15 +97,23 @@
         if (mCustomOutline) {
             return;
         }
-        boolean hasOutline = true;
-        if (isChildInGroup()) {
-            hasOutline = isGroupExpanded() && !isGroupExpansionChanging();
-        } else if (isSummaryWithChildren()) {
-            hasOutline = !isGroupExpanded() || isGroupExpansionChanging();
-        }
+        boolean hasOutline = needsOutline();
         setOutlineProvider(hasOutline ? mProvider : null);
     }
 
+    /**
+     * @return whether the view currently needs an outline. This is usually false in case it doesn't
+     * have a background.
+     */
+    protected boolean needsOutline() {
+        if (isChildInGroup()) {
+            return isGroupExpanded() && !isGroupExpansionChanging();
+        } else if (isSummaryWithChildren()) {
+            return !isGroupExpanded() || isGroupExpansionChanging();
+        }
+        return true;
+    }
+
     public boolean isOutlineShowing() {
         ViewOutlineProvider op = getOutlineProvider();
         return op != null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 28b9099..9dde67c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -112,10 +112,7 @@
     public void updateState(StackScrollState resultState,
             StackScrollAlgorithm.StackScrollAlgorithmState algorithmState,
             AmbientState ambientState) {
-        int shelfIndex = ambientState.getShelfIndex();
-        shelfIndex = shelfIndex == -1
-                ? algorithmState.visibleChildren.size() - 1
-                : shelfIndex - 1;
+        int shelfIndex = ambientState.getShelfIndex() - 1;
         if (shelfIndex != -1) {
             float maxShelfEnd = ambientState.getInnerHeight() + ambientState.getTopPadding()
                     + ambientState.getStackTranslation();
@@ -134,7 +131,7 @@
             mShelfState.isBottomClipped = false;
             mShelfState.hideSensitive = false;
 
-            mShelfState.resetState();
+            mShelfState.resetIcons();
             float numIconsInShelf = 0.0f;
             float viewStart;
             float maxShelfStart = maxShelfEnd - mShelfState.height;
@@ -240,6 +237,12 @@
     private void setHideBackground(boolean hideBackground) {
         mHideBackground = hideBackground;
         updateBackground();
+        updateOutline();
+    }
+
+    @Override
+    protected boolean needsOutline() {
+        return !mHideBackground && super.needsOutline();
     }
 
     @Override
@@ -258,7 +261,7 @@
             setHideBackground(hideBackground);
         }
 
-        public void resetState() {
+        public void resetIcons() {
             mNotificationIconContainer.resetViewStates(iconStates);
         }
     }
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 b847cdc..fb51f51 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -2005,6 +2005,9 @@
             }
             currentIndex++;
         }
+        if (shelfIndex == -1) {
+            shelfIndex = currentIndex;
+        }
         mStackScroller.updateShelfIndex(shelfIndex);
     }
 
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 74ca2032..39b56d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -354,6 +354,7 @@
     private boolean mForwardScrollable;
     private boolean mBackwardScrollable;
     private NotificationShelf mShelf;
+    private int mMaxDisplayedNotifications = -1;
 
     public NotificationStackScrollLayout(Context context) {
         this(context, null);
@@ -533,8 +534,7 @@
 
     public void updateShelfIndex(int newIndex) {
         mAmbientState.setShelfIndex(newIndex);
-        int iconIndex = newIndex == -1 ? getChildCount() - 3 : newIndex;
-        changeViewPosition(mShelf, iconIndex);
+        changeViewPosition(mShelf, newIndex);
     }
 
     public void setChildLocationsChangedListener(OnChildLocationsChangedListener listener) {
@@ -1847,10 +1847,17 @@
     private void updateContentHeight() {
         int height = 0;
         float previousIncreasedAmount = 0.0f;
+        int numShownItems = 0;
+        boolean finish = false;
         for (int i = 0; i < getChildCount(); i++) {
             ExpandableView expandableView = (ExpandableView) getChildAt(i);
             if (expandableView.getVisibility() != View.GONE
                     && !expandableView.hasNoContentHeight()) {
+                if (mMaxDisplayedNotifications != -1
+                        && numShownItems >= mMaxDisplayedNotifications) {
+                    expandableView = mShelf;
+                    finish = true;
+                }
                 float increasedPaddingAmount = expandableView.getIncreasedPaddingAmount();
                 if (height != 0) {
                     height += (int) NotificationUtils.interpolate(
@@ -1860,6 +1867,10 @@
                 }
                 previousIncreasedAmount = increasedPaddingAmount;
                 height += expandableView.getIntrinsicHeight();
+                numShownItems++;
+                if (finish) {
+                    break;
+                }
             }
         }
         mContentHeight = height + mTopPadding;
@@ -3083,16 +3094,10 @@
     }
 
     public int getEmptyBottomMargin() {
-        int emptyMargin = mMaxLayoutHeight - mContentHeight - mBottomStackPeekSize
-                - mBottomStackSlowDownHeight;
+        int emptyMargin = mMaxLayoutHeight - mContentHeight;
         return Math.max(emptyMargin, 0);
     }
 
-    public float getKeyguardBottomStackSize() {
-        return mBottomStackPeekSize + getResources().getDimensionPixelSize(
-                R.dimen.bottom_stack_slow_down_length);
-    }
-
     public void onExpansionStarted() {
         mIsExpansionChanging = true;
     }
@@ -3756,7 +3761,7 @@
                 // fall through
             case android.R.id.accessibilityActionScrollUp:
                 final int viewportHeight = getHeight() - mPaddingBottom - mTopPadding - mPaddingTop
-                        - mBottomStackPeekSize - mBottomStackSlowDownHeight;
+                        - mShelf.getIntrinsicHeight();
                 final int targetScrollY = Math.max(0,
                         Math.min(mOwnScrollY + direction * viewportHeight, getScrollRange()));
                 if (targetScrollY != mOwnScrollY) {
@@ -3925,6 +3930,14 @@
         return mShelf;
     }
 
+    public void setMaxDisplayedNotifications(int maxDisplayedNotifications) {
+        if (mMaxDisplayedNotifications != maxDisplayedNotifications) {
+            mMaxDisplayedNotifications = maxDisplayedNotifications;
+            updateContentHeight();
+            notifyHeightChangeListener(mShelf);
+        }
+    }
+
     /**
      * 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 4d2ea50..b8acb8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -129,7 +129,7 @@
 
             // The speed bump can also be gone, so equality needs to be taken when comparing
             // indices.
-            childViewState.belowShelf = shelfIndex != -1 && i >= shelfIndex;
+            childViewState.belowShelf = i >= shelfIndex;
         }
         NotificationShelf shelf = ambientState.getShelf();
         shelf.updateState(resultState, algorithmState, ambientState);
@@ -347,8 +347,7 @@
         if (i == 0) {
             updateFirstChildHeight(child, childViewState, childHeight, ambientState);
         }
-        int shelfIndex = ambientState.getShelfIndex();
-        boolean belowShelf = shelfIndex != -1 && i >= shelfIndex;
+        boolean belowShelf = i >= ambientState.getShelfIndex();
 
         // The y position after this element
         float nextYPosition = currentYPosition + childHeight +