Force the adapter to rebind cards with a toggle.

A card dismissal and scheduled card collection trigger a reload. During
card reloading, we perform slices pre check. The pre check goes through
the whole slice binding process, which means slices will be pinned and unpinned.
Hence, the on screen slices will gets unpinned resulting to the
unresponsive toggling.

As we have DiffCallbck implmented, if the card list are the same, then
bindView in the renderer will be ignored, which means the unpinned slice
will have no chance to re-register slice callback. So here we force it
to rebind the views.

Fixes: 123174237
Test: robotests
Change-Id: Id98bc16632bf024cbb611b40890e4d2629f08d7b
This commit is contained in:
Yi-Ling Chuang
2019-04-18 16:29:45 +08:00
parent 37db031aa1
commit acb50f2c6a
5 changed files with 236 additions and 2 deletions

View File

@@ -72,6 +72,7 @@ public class ContextualCard {
@LayoutRes
private final int mViewType;
private final boolean mIsPendingDismiss;
private final boolean mHasInlineAction;
public String getName() {
return mName;
@@ -161,6 +162,10 @@ public class ContextualCard {
return mIsPendingDismiss;
}
public boolean hasInlineAction() {
return mHasInlineAction;
}
public Builder mutate() {
return mBuilder;
}
@@ -187,6 +192,7 @@ public class ContextualCard {
mIsLargeCard = builder.mIsLargeCard;
mViewType = builder.mViewType;
mIsPendingDismiss = builder.mIsPendingDismiss;
mHasInlineAction = builder.mHasInlineAction;
}
ContextualCard(Cursor c) {
@@ -234,6 +240,8 @@ public class ContextualCard {
mBuilder.setViewType(mViewType);
mIsPendingDismiss = false;
mBuilder.setIsPendingDismiss(mIsPendingDismiss);
mHasInlineAction = false;
mBuilder.setHasInlineAction(mHasInlineAction);
}
@Override
@@ -286,6 +294,7 @@ public class ContextualCard {
@LayoutRes
private int mViewType;
private boolean mIsPendingDismiss;
private boolean mHasInlineAction;
public Builder setName(String name) {
mName = name;
@@ -387,6 +396,11 @@ public class ContextualCard {
return this;
}
public Builder setHasInlineAction(boolean hasInlineAction) {
mHasInlineAction = hasInlineAction;
return this;
}
public ContextualCard build() {
return new ContextualCard(this);
}

View File

@@ -20,7 +20,6 @@ import androidx.recyclerview.widget.DiffUtil;
import java.util.List;
//TODO(b/117816826): add test cases for DiffUtil.
/**
* A DiffCallback to calculate the difference between old and new {@link ContextualCard} List.
*/
@@ -53,6 +52,11 @@ public class ContextualCardsDiffCallback extends DiffUtil.Callback {
@Override
public boolean areContentsTheSame(int oldCardPosition, int newCardPosition) {
// Slices with toggles needs to be updated continuously, which means their contents may
// change. So here we assume the content will always be different to force view rebinding.
if (mNewCards.get(newCardPosition).hasInlineAction()) {
return false;
}
return mOldCards.get(oldCardPosition).equals(mNewCards.get(newCardPosition));
}
}

View File

@@ -26,11 +26,14 @@ import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.slice.Slice;
import androidx.slice.SliceMetadata;
import androidx.slice.SliceViewManager;
import androidx.slice.core.SliceAction;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -41,7 +44,9 @@ public class EligibleCardChecker implements Callable<ContextualCard> {
private static final long LATCH_TIMEOUT_MS = 200;
private final Context mContext;
private final ContextualCard mCard;
@VisibleForTesting
ContextualCard mCard;
EligibleCardChecker(Context context, ContextualCard card) {
mContext = context;
@@ -93,6 +98,11 @@ public class EligibleCardChecker implements Callable<ContextualCard> {
}
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;
@@ -133,4 +143,12 @@ public class EligibleCardChecker implements Callable<ContextualCard> {
}
return returnSlice[0];
}
@VisibleForTesting
boolean isSliceToggleable(Slice slice) {
final SliceMetadata metadata = SliceMetadata.from(mContext, slice);
final List<SliceAction> toggles = metadata.getToggles();
return !toggles.isEmpty();
}
}