Merge "Fix the janky transition of contextual cards." into rvc-dev
diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCard.java b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
index 262cd2f..510c36d 100644
--- a/src/com/android/settings/homepage/contextualcards/ContextualCard.java
+++ b/src/com/android/settings/homepage/contextualcards/ContextualCard.java
@@ -23,6 +23,7 @@
import android.text.TextUtils;
import androidx.annotation.LayoutRes;
+import androidx.slice.Slice;
import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer;
@@ -66,6 +67,7 @@
private final int mViewType;
private final boolean mIsPendingDismiss;
private final boolean mHasInlineAction;
+ private final Slice mSlice;
public String getName() {
return mName;
@@ -127,6 +129,10 @@
return mHasInlineAction;
}
+ public Slice getSlice() {
+ return mSlice;
+ }
+
public Builder mutate() {
return mBuilder;
}
@@ -147,6 +153,7 @@
mViewType = builder.mViewType;
mIsPendingDismiss = builder.mIsPendingDismiss;
mHasInlineAction = builder.mHasInlineAction;
+ mSlice = builder.mSlice;
}
ContextualCard(Cursor c) {
@@ -179,6 +186,8 @@
mBuilder.setIsPendingDismiss(mIsPendingDismiss);
mHasInlineAction = false;
mBuilder.setHasInlineAction(mHasInlineAction);
+ mSlice = null;
+ mBuilder.setSlice(mSlice);
}
@Override
@@ -225,6 +234,7 @@
private int mViewType;
private boolean mIsPendingDismiss;
private boolean mHasInlineAction;
+ private Slice mSlice;
public Builder setName(String name) {
mName = name;
@@ -296,6 +306,14 @@
return this;
}
+ /**
+ * Cache a slice created at pre-check time for later usage.
+ */
+ public Builder setSlice(Slice slice) {
+ mSlice = slice;
+ return this;
+ }
+
public ContextualCard build() {
return new ContextualCard(this);
}
diff --git a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
index 90b7f36..4e8c61f 100644
--- a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
+++ b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java
@@ -96,14 +96,17 @@
final Slice slice = bindSlice(uri);
- if (isSliceToggleable(slice)) {
- mCard = card.mutate().setHasInlineAction(true).build();
- }
-
if (slice == null || slice.hasHint(HINT_ERROR)) {
Log.w(TAG, "Failed to bind slice, not eligible for display " + uri);
return false;
}
+
+ mCard = card.mutate().setSlice(slice).build();
+
+ if (isSliceToggleable(slice)) {
+ mCard = card.mutate().setHasInlineAction(true).build();
+ }
+
return true;
}
diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
index 6538cac..c9ec5cf 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java
@@ -47,6 +47,7 @@
import com.android.settings.homepage.contextualcards.ContextualCard;
import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
import com.android.settings.homepage.contextualcards.ControllerRendererPool;
+import com.android.settings.homepage.contextualcards.slices.SliceFullCardRendererHelper.SliceViewHolder;
import com.android.settingslib.utils.ThreadUtils;
import java.util.Map;
@@ -102,6 +103,11 @@
return;
}
+ // Show cached slice first before slice binding completed to avoid jank.
+ if (holder.getItemViewType() != VIEW_TYPE_HALF_WIDTH) {
+ ((SliceViewHolder) holder).sliceView.setSlice(card.getSlice());
+ }
+
LiveData<Slice> sliceLiveData = mSliceLiveDataMap.get(uri);
if (sliceLiveData == null) {
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
index 23ae2f3..613062f 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/EligibleCardCheckerTest.java
@@ -114,6 +114,17 @@
.isFalse();
}
+ @Test
+ public void isCardEligibleToDisplay_sliceNotNull_cacheSliceToCard() {
+ final ContextualWifiSlice wifiSlice = new ContextualWifiSlice(mContext);
+ final Slice slice = wifiSlice.getSlice();
+ doReturn(slice).when(mEligibleCardChecker).bindSlice(any(Uri.class));
+
+ mEligibleCardChecker.isCardEligibleToDisplay(getContextualCard(TEST_SLICE_URI));
+
+ assertThat(mEligibleCardChecker.mCard.getSlice()).isNotNull();
+ }
+
private ContextualCard getContextualCard(Uri sliceUri) {
return new ContextualCard.Builder()
.setName("test_card")
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
index 70761cf..154d106 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java
@@ -17,10 +17,12 @@
package com.android.settings.homepage.contextualcards.slices;
import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH;
+import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_STICKY;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.app.Activity;
@@ -39,6 +41,7 @@
import com.android.settings.homepage.contextualcards.ContextualCard;
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
import com.android.settings.homepage.contextualcards.ControllerRendererPool;
+import com.android.settings.wifi.slice.ContextualWifiSlice;
import org.junit.Before;
import org.junit.Test;
@@ -81,7 +84,7 @@
@Test
public void bindView_invalidScheme_sliceShouldBeNull() {
final Uri sliceUri = Uri.parse("contet://com.android.settings.slices/action/flashlight");
- RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+ final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
mRenderer.bindView(viewHolder, buildContextualCard(sliceUri));
@@ -91,6 +94,29 @@
}
@Test
+ public void bindView_viewTypeFullWidth_shouldSetCachedSlice() {
+ final RecyclerView.ViewHolder viewHolder = getSliceViewHolder();
+
+ mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
+
+ assertThat(
+ ((SliceFullCardRendererHelper.SliceViewHolder) viewHolder).sliceView.getSlice())
+ .isNotNull();
+ }
+
+ @Test
+ public void bindView_viewTypeSticky_shouldSetCachedSlice() {
+ final RecyclerView.ViewHolder viewHolder = spy(getStickyViewHolder());
+ doReturn(VIEW_TYPE_STICKY).when(viewHolder).getItemViewType();
+
+ mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI));
+
+ assertThat(
+ ((SliceFullCardRendererHelper.SliceViewHolder) viewHolder).sliceView.getSlice())
+ .isNotNull();
+ }
+
+ @Test
public void bindView_newSliceLiveData_shouldAddDataToMap() {
mRenderer.bindView(getSliceViewHolder(), buildContextualCard(TEST_SLICE_URI));
@@ -246,12 +272,23 @@
return mRenderer.createViewHolder(view, VIEW_TYPE_FULL_WIDTH);
}
+ private RecyclerView.ViewHolder getStickyViewHolder() {
+ final RecyclerView recyclerView = new RecyclerView(mActivity);
+ recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
+ final View view = LayoutInflater.from(mActivity).inflate(VIEW_TYPE_STICKY, recyclerView,
+ false);
+
+ return mRenderer.createViewHolder(view, VIEW_TYPE_STICKY);
+ }
+
private ContextualCard buildContextualCard(Uri sliceUri) {
+ final Slice slice = new ContextualWifiSlice(mActivity).getSlice();
return new ContextualCard.Builder()
.setName("test_name")
.setCardType(ContextualCard.CardType.SLICE)
.setSliceUri(sliceUri)
.setViewType(VIEW_TYPE_FULL_WIDTH)
+ .setSlice(slice)
.build();
}
}