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:
@@ -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);
|
||||
}
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user