Card showing mechanism change in homepage
- update contextual card proto interface to fit the new SettingsIntelligence - show sticky cards at the tail of the card area Bug: 149274976 Test: robotest Change-Id: Icca167825c1c037ec12d8836d82c5fdff4331a8e
This commit is contained in:
@@ -19,6 +19,7 @@ message ContextualCard {
|
||||
POSSIBLE = 2;
|
||||
IMPORTANT = 3;
|
||||
DEFERRED_SETUP = 5;
|
||||
STICKY = 6;
|
||||
}
|
||||
|
||||
/** Slice uri of the contextual card */
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.homepage.contextualcards;
|
||||
|
||||
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_VALUE;
|
||||
import static com.android.settings.slices.CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI;
|
||||
import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_NOTIFICATION_CHANNEL_SLICE_URI;
|
||||
import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI;
|
||||
@@ -129,18 +130,34 @@ public class ContextualCardLoader extends AsyncLoaderCompat<List<ContextualCard>
|
||||
@VisibleForTesting
|
||||
List<ContextualCard> getDisplayableCards(List<ContextualCard> candidates) {
|
||||
final List<ContextualCard> eligibleCards = filterEligibleCards(candidates);
|
||||
final List<ContextualCard> stickyCards = new ArrayList<>();
|
||||
final List<ContextualCard> visibleCards = new ArrayList<>();
|
||||
final List<ContextualCard> hiddenCards = new ArrayList<>();
|
||||
|
||||
final int size = eligibleCards.size();
|
||||
final int cardCount = getCardCount();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i < cardCount) {
|
||||
visibleCards.add(eligibleCards.get(i));
|
||||
final int maxCardCount = getCardCount();
|
||||
eligibleCards.forEach(card -> {
|
||||
if (card.getCategory() != STICKY_VALUE) {
|
||||
return;
|
||||
}
|
||||
if (stickyCards.size() < maxCardCount) {
|
||||
stickyCards.add(card);
|
||||
} else {
|
||||
hiddenCards.add(eligibleCards.get(i));
|
||||
hiddenCards.add(card);
|
||||
}
|
||||
});
|
||||
|
||||
final int nonStickyCardCount = maxCardCount - stickyCards.size();
|
||||
eligibleCards.forEach(card -> {
|
||||
if (card.getCategory() == STICKY_VALUE) {
|
||||
return;
|
||||
}
|
||||
if (visibleCards.size() < nonStickyCardCount) {
|
||||
visibleCards.add(card);
|
||||
} else {
|
||||
hiddenCards.add(card);
|
||||
}
|
||||
});
|
||||
visibleCards.addAll(stickyCards);
|
||||
|
||||
if (!CardContentProvider.DELETE_CARD_URI.equals(mNotifyUri)) {
|
||||
final MetricsFeatureProvider metricsFeatureProvider =
|
||||
|
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.homepage.contextualcards;
|
||||
|
||||
import static com.android.settings.homepage.contextualcards.ContextualCardLoader.CARD_CONTENT_LOADER_ID;
|
||||
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_VALUE;
|
||||
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE;
|
||||
import static com.android.settings.slices.CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI;
|
||||
import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI;
|
||||
@@ -346,16 +347,23 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO(b/143055685):use category to determine whether they are sticky.
|
||||
private List<ContextualCard> getCardsWithStickyViewType(List<ContextualCard> cards) {
|
||||
final List<ContextualCard> result = new ArrayList<>(cards);
|
||||
int replaceCount = 0;
|
||||
for (int index = 0; index < result.size(); index++) {
|
||||
final ContextualCard card = cards.get(index);
|
||||
if (FeatureFlagUtils.isEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2)) {
|
||||
if (card.getCategory() == STICKY_VALUE) {
|
||||
result.set(index, card.mutate().setViewType(
|
||||
SliceContextualCardRenderer.VIEW_TYPE_STICKY).build());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (replaceCount > STICKY_CARDS.size() - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
final ContextualCard card = cards.get(index);
|
||||
if (card.getCardType() != ContextualCard.CardType.SLICE) {
|
||||
continue;
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.homepage.contextualcards;
|
||||
|
||||
import static com.android.settings.homepage.contextualcards.ContextualCardLoader.DEFAULT_CARD_COUNT;
|
||||
import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.STICKY_VALUE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -82,15 +83,40 @@ public class ContextualCardLoaderTest {
|
||||
|
||||
@Test
|
||||
public void getDisplayableCards_fourEligibleCards_shouldShowDefaultCardCount() {
|
||||
final List<ContextualCard> fourCards = getContextualCardList();
|
||||
doReturn(fourCards).when(mContextualCardLoader).filterEligibleCards(anyList());
|
||||
final List<ContextualCard> cards = getContextualCardList().stream().limit(4)
|
||||
.collect(Collectors.toList());
|
||||
doReturn(cards).when(mContextualCardLoader).filterEligibleCards(anyList());
|
||||
|
||||
final List<ContextualCard> result = mContextualCardLoader
|
||||
.getDisplayableCards(fourCards);
|
||||
final List<ContextualCard> result = mContextualCardLoader.getDisplayableCards(cards);
|
||||
|
||||
assertThat(result).hasSize(DEFAULT_CARD_COUNT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDisplayableCards_oneStickyCard_shouldShowOneStickyCardAtTheTail() {
|
||||
final List<ContextualCard> cards = getContextualCardList().stream().limit(5)
|
||||
.collect(Collectors.toList());
|
||||
doReturn(cards).when(mContextualCardLoader).filterEligibleCards(anyList());
|
||||
|
||||
final List<ContextualCard> result = mContextualCardLoader.getDisplayableCards(cards);
|
||||
|
||||
assertThat(result).hasSize(DEFAULT_CARD_COUNT);
|
||||
assertThat(result.get(DEFAULT_CARD_COUNT - 1).getCategory()).isEqualTo(STICKY_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDisplayableCards_threeStickyCards_shouldShowThreeStickyCardAtTheTail() {
|
||||
final List<ContextualCard> cards = getContextualCardList();
|
||||
doReturn(cards).when(mContextualCardLoader).filterEligibleCards(anyList());
|
||||
|
||||
final List<ContextualCard> result = mContextualCardLoader.getDisplayableCards(cards);
|
||||
|
||||
assertThat(result).hasSize(DEFAULT_CARD_COUNT);
|
||||
for (int i = 1; i <= Math.min(3, DEFAULT_CARD_COUNT); i++) {
|
||||
assertThat(result.get(DEFAULT_CARD_COUNT - i).getCategory()).isEqualTo(STICKY_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDisplayableCards_refreshCardUri_shouldLogContextualCard() {
|
||||
mContextualCardLoader.mNotifyUri = CardContentProvider.REFRESH_CARD_URI;
|
||||
@@ -128,20 +154,20 @@ public class ContextualCardLoaderTest {
|
||||
private List<ContextualCard> getContextualCardList() {
|
||||
final List<ContextualCard> cards = new ArrayList<>();
|
||||
cards.add(new ContextualCard.Builder()
|
||||
.setName("test_wifi")
|
||||
.setName("test_low_storage")
|
||||
.setCardType(ContextualCard.CardType.SLICE)
|
||||
.setSliceUri(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI)
|
||||
.setSliceUri(CustomSliceRegistry.LOW_STORAGE_SLICE_URI)
|
||||
.build());
|
||||
cards.add(new ContextualCard.Builder()
|
||||
.setName("test_flashlight")
|
||||
.setCardType(ContextualCard.CardType.SLICE)
|
||||
.setSliceUri(
|
||||
Uri.parse("content://com.android.settings.test.slices/action/flashlight"))
|
||||
.setSliceUri(Uri.parse(
|
||||
"content://com.android.settings.test.slices/action/flashlight"))
|
||||
.build());
|
||||
cards.add(new ContextualCard.Builder()
|
||||
.setName("test_connected")
|
||||
.setName("test_dark_theme")
|
||||
.setCardType(ContextualCard.CardType.SLICE)
|
||||
.setSliceUri(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI)
|
||||
.setSliceUri(CustomSliceRegistry.DARK_THEME_SLICE_URI)
|
||||
.build());
|
||||
cards.add(new ContextualCard.Builder()
|
||||
.setName("test_gesture")
|
||||
@@ -149,6 +175,24 @@ public class ContextualCardLoaderTest {
|
||||
.setSliceUri(Uri.parse(
|
||||
"content://com.android.settings.test.slices/action/gesture_pick_up"))
|
||||
.build());
|
||||
cards.add(new ContextualCard.Builder()
|
||||
.setName("test_wifi")
|
||||
.setCardType(ContextualCard.CardType.SLICE)
|
||||
.setSliceUri(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI)
|
||||
.setCategory(STICKY_VALUE)
|
||||
.build());
|
||||
cards.add(new ContextualCard.Builder()
|
||||
.setName("test_connected")
|
||||
.setCardType(ContextualCard.CardType.SLICE)
|
||||
.setSliceUri(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI)
|
||||
.setCategory(STICKY_VALUE)
|
||||
.build());
|
||||
cards.add(new ContextualCard.Builder()
|
||||
.setName("test_sticky")
|
||||
.setCardType(ContextualCard.CardType.SLICE)
|
||||
.setSliceUri(Uri.parse("content://com.android.settings.test.slices/action/sticky"))
|
||||
.setCategory(STICKY_VALUE)
|
||||
.build());
|
||||
return cards;
|
||||
}
|
||||
}
|
||||
|
@@ -564,8 +564,28 @@ public class ContextualCardManagerTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCardsWithViewType_hasOneStickySlice_shouldHaveOneStickyCard() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, true);
|
||||
final List<ContextualCard> cards = new ArrayList<>();
|
||||
cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString()));
|
||||
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
|
||||
final List<Integer> categories = Arrays.asList(
|
||||
ContextualCardProto.ContextualCard.Category.STICKY_VALUE,
|
||||
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
|
||||
);
|
||||
final List<ContextualCard> cardListWithWifi = buildCategoriedCards(cards, categories);
|
||||
|
||||
final List<ContextualCard> result = mManager.getCardsWithViewType(cardListWithWifi);
|
||||
|
||||
assertThat(result).hasSize(cards.size());
|
||||
assertThat(result.get(0).getViewType()).isEqualTo(VIEW_TYPE_STICKY);
|
||||
assertThat(result.get(1).getViewType()).isEqualTo(VIEW_TYPE_FULL_WIDTH);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCardsWithViewType_hasWifiSlice_shouldHaveOneStickyCard() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
|
||||
final List<ContextualCard> cards = new ArrayList<>();
|
||||
cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString()));
|
||||
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
|
||||
@@ -584,6 +604,7 @@ public class ContextualCardManagerTest {
|
||||
|
||||
@Test
|
||||
public void getCardsWithViewType_hasBluetoothDeviceSlice_shouldHaveOneStickyCard() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
|
||||
final List<ContextualCard> cards = new ArrayList<>();
|
||||
cards.add(buildContextualCard(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString()));
|
||||
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
|
||||
@@ -602,6 +623,7 @@ public class ContextualCardManagerTest {
|
||||
|
||||
@Test
|
||||
public void getCardsWithViewType_hasWifiAndBtDeviceSlice_shouldHaveTwoStickyCards() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
|
||||
final List<ContextualCard> cards = new ArrayList<>();
|
||||
cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString()));
|
||||
cards.add(buildContextualCard(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString()));
|
||||
@@ -624,6 +646,7 @@ public class ContextualCardManagerTest {
|
||||
|
||||
@Test
|
||||
public void getCardsWithViewType_noWifiOrBtDeviceSlice_shouldNotHaveStickyCard() {
|
||||
FeatureFlagUtils.setEnabled(mContext, FeatureFlags.CONTEXTUAL_HOME2, false);
|
||||
final List<Integer> categories = Arrays.asList(
|
||||
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
|
||||
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
|
||||
@@ -683,8 +706,8 @@ public class ContextualCardManagerTest {
|
||||
cards.add(new ContextualCard.Builder()
|
||||
.setName("test_flashlight")
|
||||
.setCardType(ContextualCard.CardType.SLICE)
|
||||
.setSliceUri(
|
||||
Uri.parse("content://com.android.settings.test.slices/action/flashlight"))
|
||||
.setSliceUri(Uri.parse(
|
||||
"content://com.android.settings.test.slices/action/flashlight"))
|
||||
.setViewType(VIEW_TYPE_FULL_WIDTH)
|
||||
.build());
|
||||
cards.add(new ContextualCard.Builder()
|
||||
|
Reference in New Issue
Block a user