Update notifications list limit integration

Modify implementation to reflect changes in base adapter

Bug: 168245031
Test: manual, make -j50 RunCarNotificationRoboTests
Change-Id: I8dbf843cc6796fd8190509171092a1e87f7125a8
diff --git a/src/com/android/car/notification/CarNotificationViewAdapter.java b/src/com/android/car/notification/CarNotificationViewAdapter.java
index 5a46765..b0004f5 100644
--- a/src/com/android/car/notification/CarNotificationViewAdapter.java
+++ b/src/com/android/car/notification/CarNotificationViewAdapter.java
@@ -27,6 +27,7 @@
 
 import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.DiffUtil;
+import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.car.notification.template.CarNotificationBaseViewHolder;
@@ -59,6 +60,7 @@
     private final CarNotificationItemController mNotificationItemController;
 
     private List<NotificationGroup> mNotifications = new ArrayList<>();
+    private LinearLayoutManager mLayoutManager;
     private RecyclerView.RecycledViewPool mViewPool;
     private CarUxRestrictions mCarUxRestrictions;
     private NotificationClickHandlerFactory mClickHandlerFactory;
@@ -94,6 +96,18 @@
     }
 
     @Override
+    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
+        super.onAttachedToRecyclerView(recyclerView);
+        mLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
+    }
+
+    @Override
+    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
+        super.onDetachedFromRecyclerView(recyclerView);
+        mLayoutManager = null;
+    }
+
+    @Override
     public RecyclerView.ViewHolder onCreateViewHolderImpl(@NonNull ViewGroup parent, int viewType) {
         RecyclerView.ViewHolder viewHolder;
         View view;
@@ -121,23 +135,15 @@
 
     @Override
     public void onBindViewHolderImpl(RecyclerView.ViewHolder holder, int position) {
-        if (position == 0 && mHasHeaderAndFooter) {
-            // The first element of the main recyclerview should always be the header
-            ((CarNotificationHeaderViewHolder) holder).bind(hasNotifications());
-            return;
-        }
-
-        if (position == getItemCount() - 1 && mHasHeaderAndFooter) {
-            // The last element shown in the main recyclerview should always be the footer, even
-            // if the element at this position in mNotifications is not the footer due to Uxr
-            // limiting the item count
-            ((CarNotificationFooterViewHolder) holder).bind(hasNotifications());
-            return;
-        }
-
         NotificationGroup notificationGroup = mNotifications.get(position);
         int viewType = holder.getItemViewType();
         switch (viewType) {
+            case NotificationViewType.HEADER:
+                ((CarNotificationHeaderViewHolder) holder).bind(hasNotifications());
+                return;
+            case NotificationViewType.FOOTER:
+                ((CarNotificationFooterViewHolder) holder).bind(hasNotifications());
+                return;
             case NotificationViewType.GROUP_EXPANDED:
                 ((GroupNotificationViewHolder) holder)
                         .bind(notificationGroup, this, /* isExpanded= */ true);
@@ -166,20 +172,16 @@
 
     @Override
     public int getItemViewTypeImpl(int position) {
-        if (position == 0 && mHasHeaderAndFooter) {
-            // The first element of the main recyclerview should always be the header
+        NotificationGroup notificationGroup = mNotifications.get(position);
+
+        if (notificationGroup.isHeader()) {
             return NotificationViewType.HEADER;
         }
 
-        if (position == getItemCount() - 1 && mHasHeaderAndFooter) {
-            // The last element shown in the main recyclerview should always be the footer, even
-            // if the element at this position in mNotifications is not the footer due to Uxr
-            // limiting the item count
+        if (notificationGroup.isFooter()) {
             return NotificationViewType.FOOTER;
         }
 
-        NotificationGroup notificationGroup = mNotifications.get(position);
-
         if (notificationGroup.isGroup()) {
             if (mExpandedNotifications.contains(notificationGroup.getGroupKey())) {
                 return NotificationViewType.GROUP_EXPANDED;
@@ -272,19 +274,22 @@
         if (maxItems == ContentLimitingAdapter.UNLIMITED || !mHasHeaderAndFooter) {
             mMaxItems = maxItems;
         } else {
-            // Adding two so the notification header and footer don't count toward the limit.
-            mMaxItems = maxItems + 2;
+            // Adding one so the notification header doesn't count toward the limit.
+            mMaxItems = maxItems + 1;
         }
         super.setMaxItems(mMaxItems);
     }
 
     @Override
-    protected int getScrollingLimitedMessagePosition() {
-        if (mHasHeaderAndFooter) {
-            // Place the message as the second to last element so it is above the footer
-            return getItemCount() - 2;
+    protected int getScrollToPositionWhenRestricted() {
+        if (mLayoutManager == null) {
+            return -1;
         }
-        return getItemCount() - 1;
+        int firstItem = mLayoutManager.findFirstVisibleItemPosition();
+        if (firstItem >= getItemCount() - 1) {
+            return getItemCount() - 1;
+        }
+        return -1;
     }
 
     @Override
@@ -374,6 +379,7 @@
                         new CarNotificationDiff(mContext, mNotifications, notificationGroupList, mMaxItems),
                         /* detectMoves= */ false);
         mNotifications = notificationGroupList;
+        updateUnderlyingDataChanged(getUnrestrictedItemCount(), /* newAnchorIndex= */ 0);
         diffResult.dispatchUpdatesTo(this);
     }
     /**
diff --git a/tests/robotests/src/com/android/car/notification/CarNotificationViewAdapterTest.java b/tests/robotests/src/com/android/car/notification/CarNotificationViewAdapterTest.java
index 5318605..eebf328 100644
--- a/tests/robotests/src/com/android/car/notification/CarNotificationViewAdapterTest.java
+++ b/tests/robotests/src/com/android/car/notification/CarNotificationViewAdapterTest.java
@@ -793,7 +793,7 @@
     }
 
     @Test
-    public void setMaxItems_footerShouldBeLastVisibleElement() {
+    public void setMaxItems_limitedMessageShouldBeLastVisibleElement() {
         initializeWithFactory(true);
         NotificationGroup notificationGroup = new NotificationGroup();
         notificationGroup.addNotification(mNotification1);
@@ -806,7 +806,7 @@
 
         assertThat(mCarNotificationViewAdapter.getItemViewType(
                 mCarNotificationViewAdapter.getItemCount() - 1)).isEqualTo(
-                NotificationViewType.FOOTER);
+                mCarNotificationViewAdapter.getScrollingLimitedMessageViewType());
     }
 
     @Test
@@ -826,7 +826,7 @@
     }
 
     @Test
-    public void setMaxItems_hasHeaderAndFooter_getItemCount_shouldReturnFour() {
+    public void setMaxItems_hasHeaderAndFooter_getItemCount_shouldReturnThree() {
         initializeWithFactory(true);
         NotificationGroup notificationGroup = new NotificationGroup();
         notificationGroup.addNotification(mNotification1);
@@ -837,9 +837,9 @@
 
         mCarNotificationViewAdapter.setMaxItems(1);
 
-        // Count should be four - one for the allotted notification, one for the limited message,
-        // and two for the header and footer
-        assertThat(mCarNotificationViewAdapter.getItemCount()).isEqualTo(4);
+        // Count should be three - one for the allotted notification, one for the limited message,
+        // and one for the header
+        assertThat(mCarNotificationViewAdapter.getItemCount()).isEqualTo(3);
     }