Snap for 7510676 from 8b5e5b64825e42c4e5be831ecce93ebe6b50002e to sc-release
Change-Id: Iab6446c5b944c89a23912921882e13dd17130b57
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapterTest.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapterTest.java
index 3908df8..b3ad0c1 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapterTest.java
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapterTest.java
@@ -21,12 +21,16 @@
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.OrientationHelper;
+import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
import androidx.test.core.app.ActivityScenario;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
@@ -36,6 +40,7 @@
import org.junit.Rule;
import org.junit.Test;
+import java.util.ArrayList;
import java.util.Objects;
public class DelegatingContentLimitingAdapterTest {
@@ -127,4 +132,150 @@
onView(withText(mDelegateAdapter.getItemText(15))).check(matches(isDisplayed()));
}
+
+ @Test
+ public void testChangeItem_callsObservers() {
+ mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
+ mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
+
+ AdapterDataObserver observer = mock(AdapterDataObserver.class);
+ mContentLimitingAdapter.registerAdapterDataObserver(observer);
+
+ onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+ CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+ mActivity.runOnUiThread(() -> {
+ carUiRecyclerView.setAdapter(mContentLimitingAdapter);
+ carUiRecyclerView.setVisibility(View.VISIBLE);
+ mContentLimitingAdapter.setMaxItems(10);
+ mDelegateAdapter.changeItemRange(5, 3);
+ });
+
+ onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
+
+ verify(observer).onItemRangeChanged(5, 3, null);
+ }
+
+ @Test
+ public void testInsertItem_callsObservers() {
+ mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
+ mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
+
+ AdapterDataObserver observer = mock(AdapterDataObserver.class);
+ mContentLimitingAdapter.registerAdapterDataObserver(observer);
+
+ onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+ CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+ mActivity.runOnUiThread(() -> {
+ carUiRecyclerView.setAdapter(mContentLimitingAdapter);
+ carUiRecyclerView.setVisibility(View.VISIBLE);
+ mContentLimitingAdapter.setMaxItems(10);
+ mDelegateAdapter.insertItemRange(5, "new item 1", "new item 2");
+ });
+
+ onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
+
+ verify(observer).onItemRangeInserted(5, 2);
+ }
+
+ @Test
+ public void testRemoveItem_callsObservers() {
+ mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
+ mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
+
+ AdapterDataObserver observer = mock(AdapterDataObserver.class);
+ mContentLimitingAdapter.registerAdapterDataObserver(observer);
+
+ onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+ CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+ mActivity.runOnUiThread(() -> {
+ carUiRecyclerView.setAdapter(mContentLimitingAdapter);
+ carUiRecyclerView.setVisibility(View.VISIBLE);
+ mContentLimitingAdapter.setMaxItems(10);
+ mDelegateAdapter.removeItemRange(5, 2);
+ });
+
+ onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
+
+ verify(observer).onItemRangeRemoved(5, 2);
+ }
+
+ @Test
+ public void testMoveItem_callsObservers() {
+ mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
+ mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
+
+ AdapterDataObserver observer = mock(AdapterDataObserver.class);
+ mContentLimitingAdapter.registerAdapterDataObserver(observer);
+
+ onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+ CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+ mActivity.runOnUiThread(() -> {
+ carUiRecyclerView.setAdapter(mContentLimitingAdapter);
+ carUiRecyclerView.setVisibility(View.VISIBLE);
+ mContentLimitingAdapter.setMaxItems(10);
+ mDelegateAdapter.moveItem(5, 2);
+ });
+
+ onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
+
+ verify(observer).onChanged();
+ }
+
+ @Test
+ public void testChangeDataSet_callsObservers() {
+ mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
+ mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
+
+ AdapterDataObserver observer = mock(AdapterDataObserver.class);
+ mContentLimitingAdapter.registerAdapterDataObserver(observer);
+
+ onView(withId(R.id.list)).check(matches(isDisplayed()));
+
+ CarUiRecyclerView carUiRecyclerView = mActivity.requireViewById(R.id.list);
+ mActivity.runOnUiThread(() -> {
+ carUiRecyclerView.setAdapter(mContentLimitingAdapter);
+ carUiRecyclerView.setVisibility(View.VISIBLE);
+ mContentLimitingAdapter.setMaxItems(10);
+ });
+
+ onView(withText(mDelegateAdapter.getItemText(0))).check(matches(isDisplayed()));
+
+ mActivity.runOnUiThread(() -> {
+ ArrayList<String> newItems = new ArrayList<>();
+ for (int i = 0; i < 40; i++) {
+ newItems.add("New Item " + i);
+ }
+ mDelegateAdapter.changeList(newItems);
+ });
+
+ onView(withText("New Item 0")).check(matches(isDisplayed()));
+
+ verify(observer).onChanged();
+ }
+
+ @Test
+ public void testSetHasStableId_setsDelegateToo() {
+ mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
+ mDelegateAdapter.setHasStableIds(false);
+
+ mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
+
+ mContentLimitingAdapter.setHasStableIds(true);
+
+ assertTrue(mDelegateAdapter.hasStableIds());
+ }
+
+ @Test
+ public void testGetIds_callsDelegate() {
+ mDelegateAdapter = new TestDelegatingContentLimitingAdapter(50);
+ mContentLimitingAdapter = new DelegatingContentLimitingAdapter<>(mDelegateAdapter, 1);
+
+ for (int i = 0; i < 50; i++) {
+ assertEquals(mDelegateAdapter.getItemId(i), mContentLimitingAdapter.getItemId(i));
+ }
+ }
}
diff --git a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestDelegatingContentLimitingAdapter.java b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestDelegatingContentLimitingAdapter.java
index d3e9791..4a59c04 100644
--- a/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestDelegatingContentLimitingAdapter.java
+++ b/car-ui-lib/car-ui-lib/src/androidTest/java/com/android/car/ui/recyclerview/TestDelegatingContentLimitingAdapter.java
@@ -62,6 +62,45 @@
return "Item " + i;
}
+ public void changeItemRange(int positionStart, int itemCount) {
+ for (int i = 0; i < itemCount; i++) {
+ mItems.set(i + positionStart, mItems.get(i + positionStart) + "-changed");
+ }
+ notifyItemRangeChanged(positionStart, itemCount);
+ }
+
+ public void insertItemRange(int position, String... items) {
+ for (int i = 0; i < items.length; i++) {
+ mItems.add(position, items[i]);
+ }
+ notifyItemRangeInserted(position, items.length);
+ }
+
+ public void removeItemRange(int positionStart, int itemCount) {
+ for (int i = 0; i < itemCount; i++) {
+ mItems.remove(positionStart + i);
+ }
+ notifyItemRangeRemoved(positionStart, itemCount);
+ }
+
+ public void moveItem(int fromPosition, int toPosition) {
+ String item = mItems.get(fromPosition);
+ if (fromPosition > toPosition) {
+ mItems.remove(fromPosition);
+ mItems.add(toPosition, item);
+ } else {
+ mItems.add(toPosition, item);
+ mItems.remove(fromPosition);
+ }
+ notifyItemMoved(fromPosition, toPosition);
+ }
+
+ public void changeList(List<String> newItems) {
+ mItems.clear();
+ mItems.addAll(newItems);
+ notifyDataSetChanged();
+ }
+
static class WithContentLimiting extends TestDelegatingContentLimitingAdapter
implements DelegatingContentLimitingAdapter.ContentLimiting {
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapter.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapter.java
index c865b75..62d9feb 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapter.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/recyclerview/DelegatingContentLimitingAdapter.java
@@ -41,6 +41,8 @@
private final int mScrollingLimitedMessagePositionOffset;
@IdRes
private final int mConfigId;
+ @NonNull
+ private final Observer mAdapterDataObserver;
/**
* Provides the abilities to delegate {@link ContentLimitingAdapter} callback functions.
@@ -102,7 +104,24 @@
mConfigId = configId;
mScrollingLimitedMessageViewType = viewType;
mScrollingLimitedMessagePositionOffset = offset;
- mDelegate.registerAdapterDataObserver(new Observer());
+ mAdapterDataObserver = new Observer();
+ }
+
+ @Override
+ public void registerAdapterDataObserver(@NonNull RecyclerView.AdapterDataObserver observer) {
+ if (!hasObservers()) {
+ mDelegate.registerAdapterDataObserver(mAdapterDataObserver);
+ }
+ super.registerAdapterDataObserver(observer);
+ }
+
+ @Override
+ public void unregisterAdapterDataObserver(@NonNull RecyclerView.AdapterDataObserver observer) {
+ super.unregisterAdapterDataObserver(observer);
+
+ if (!hasObservers()) {
+ mDelegate.unregisterAdapterDataObserver(mAdapterDataObserver);
+ }
}
private class Observer extends RecyclerView.AdapterDataObserver {