Merge "Build a way to decide card width"

This commit is contained in:
Mill Chen
2019-01-07 08:17:47 +00:00
committed by Android (Google) Code Review
4 changed files with 206 additions and 15 deletions

View File

@@ -107,12 +107,12 @@ public class ContextualCardLoader extends AsyncLoaderCompat<List<ContextualCard>
}
}
}
return getFinalDisplayableCards(result);
return getDisplayableCards(result);
}
// Get final displayed cards and log what cards will be displayed/hidden
@VisibleForTesting
List<ContextualCard> getFinalDisplayableCards(List<ContextualCard> candidates) {
List<ContextualCard> getDisplayableCards(List<ContextualCard> candidates) {
final List<ContextualCard> eligibleCards = filterEligibleCards(candidates);
final List<ContextualCard> visibleCards = new ArrayList<>();
final List<ContextualCard> hiddenCards = new ArrayList<>();

View File

@@ -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.SUGGESTION_VALUE;
import static java.util.stream.Collectors.groupingBy;
@@ -172,7 +173,8 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
//replace with the new data
mContextualCards.clear();
mContextualCards.addAll(sortCards(allCards));
final List<ContextualCard> sortedCards = sortCards(allCards);
mContextualCards.addAll(assignCardWidth(sortedCards));
loadCardControllers();
@@ -224,6 +226,24 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
mListener = listener;
}
@VisibleForTesting
List<ContextualCard> assignCardWidth(List<ContextualCard> cards) {
final List<ContextualCard> result = new ArrayList<>(cards);
// Shows as half cards if 2 suggestion type of cards are next to each other.
// Shows as full card if 1 suggestion type of card lives alone.
for (int index = 1; index < result.size(); index++) {
final ContextualCard previous = result.get(index - 1);
final ContextualCard current = result.get(index);
if (current.getCategory() == SUGGESTION_VALUE
&& previous.getCategory() == SUGGESTION_VALUE) {
result.set(index - 1, previous.mutate().setIsHalfWidth(true).build());
result.set(index, current.mutate().setIsHalfWidth(true).build());
index++;
}
}
return result;
}
private List<ContextualCard> getCardsToKeep(List<ContextualCard> cards) {
if (mSavedCards != null) {
//screen rotate

View File

@@ -29,16 +29,16 @@ import android.net.Uri;
import com.android.settings.slices.CustomSliceRegistry;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@RunWith(RobolectricTestRunner.class)
public class ContextualCardLoaderTest {
@@ -82,29 +82,29 @@ public class ContextualCardLoaderTest {
}
@Test
public void getFinalDisplayableCards_twoEligibleCards_shouldShowAll() {
public void getDisplayableCards_twoEligibleCards_shouldShowAll() {
final List<ContextualCard> cards = getContextualCardList().stream().limit(2)
.collect(Collectors.toList());
doReturn(cards).when(mContextualCardLoader).filterEligibleCards(any(List.class));
final List<ContextualCard> result = mContextualCardLoader.getFinalDisplayableCards(cards);
final List<ContextualCard> result = mContextualCardLoader.getDisplayableCards(cards);
assertThat(result).hasSize(cards.size());
}
@Test
public void getFinalDisplayableCards_fiveEligibleCardsNoLarge_shouldShowDefaultCardCount() {
public void getDisplayableCards_fiveEligibleCardsNoLarge_shouldShowDefaultCardCount() {
final List<ContextualCard> fiveCards = getContextualCardListWithNoLargeCard();
doReturn(fiveCards).when(mContextualCardLoader).filterEligibleCards(any(List.class));
final List<ContextualCard> result = mContextualCardLoader.getFinalDisplayableCards(
final List<ContextualCard> result = mContextualCardLoader.getDisplayableCards(
fiveCards);
assertThat(result).hasSize(DEFAULT_CARD_COUNT);
}
@Test
public void getFinalDisplayableCards_threeEligibleCardsOneLarge_shouldShowThreeCards() {
public void getDisplayableCards_threeEligibleCardsOneLarge_shouldShowThreeCards() {
final List<ContextualCard> cards = getContextualCardList().stream().limit(2)
.collect(Collectors.toList());
cards.add(new ContextualCard.Builder()
@@ -115,18 +115,18 @@ public class ContextualCardLoaderTest {
.build());
doReturn(cards).when(mContextualCardLoader).filterEligibleCards(any(List.class));
final List<ContextualCard> result = mContextualCardLoader.getFinalDisplayableCards(cards);
final List<ContextualCard> result = mContextualCardLoader.getDisplayableCards(cards);
assertThat(result).hasSize(3);
}
@Test
public void getFinalDisplayableCards_threeEligibleCardsTwoLarge_shouldShowTwoCards() {
public void getDisplayableCards_threeEligibleCardsTwoLarge_shouldShowTwoCards() {
final List<ContextualCard> threeCards = getContextualCardList().stream().limit(3)
.collect(Collectors.toList());
doReturn(threeCards).when(mContextualCardLoader).filterEligibleCards(any(List.class));
final List<ContextualCard> result = mContextualCardLoader.getFinalDisplayableCards(
final List<ContextualCard> result = mContextualCardLoader.getDisplayableCards(
threeCards);
assertThat(result).hasSize(2);

View File

@@ -32,6 +32,8 @@ import android.util.ArrayMap;
import com.android.settings.homepage.contextualcards.conditional.ConditionFooterContextualCard;
import com.android.settings.homepage.contextualcards.conditional.ConditionHeaderContextualCard;
import com.android.settings.homepage.contextualcards.conditional.ConditionalContextualCard;
import com.android.settings.intelligence.ContextualCardProto;
import com.android.settings.slices.CustomSliceRegistry;
import org.junit.Before;
import org.junit.Test;
@@ -203,6 +205,134 @@ public class ContextualCardManagerTest {
assertThat(actualCards).containsExactlyElementsIn(expectedCards);
}
@Test
public void assignCardWidth_noSuggestionCards_shouldNotHaveHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE
);
final List<ContextualCard> noSuggestionCards = buildCategoriedCards(getContextualCardList(),
categories);
final List<ContextualCard> result = mManager.assignCardWidth(noSuggestionCards);
assertThat(result).hasSize(5);
for (ContextualCard card : result) {
assertThat(card.isHalfWidth()).isFalse();
}
}
@Test
public void assignCardWidth_oneSuggestionCards_shouldNotHaveHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
);
final List<ContextualCard> oneSuggestionCards = buildCategoriedCards(
getContextualCardList(), categories);
final List<ContextualCard> result = mManager.assignCardWidth(oneSuggestionCards);
assertThat(result).hasSize(5);
for (ContextualCard card : result) {
assertThat(card.isHalfWidth()).isFalse();
}
}
@Test
public void assignCardWidth_twoConsecutiveSuggestionCards_shouldHaveTwoHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE
);
final List<ContextualCard> twoConsecutiveSuggestionCards = buildCategoriedCards(
getContextualCardList(), categories);
final List<Boolean> expectedValues = Arrays.asList(false, false, true, true, false);
final List<ContextualCard> result = mManager.assignCardWidth(
twoConsecutiveSuggestionCards);
assertThat(result).hasSize(5);
for (int i = 0; i < result.size(); i++) {
assertThat(result.get(i).isHalfWidth()).isEqualTo(expectedValues.get(i));
}
}
@Test
public void assignCardWidth_twoNonConsecutiveSuggestionCards_shouldNotHaveHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
);
final List<ContextualCard> twoNonConsecutiveSuggestionCards = buildCategoriedCards(
getContextualCardList(), categories);
final List<ContextualCard> result = mManager.assignCardWidth(
twoNonConsecutiveSuggestionCards);
assertThat(result).hasSize(5);
for (ContextualCard card : result) {
assertThat(card.isHalfWidth()).isFalse();
}
}
@Test
public void assignCardWidth_threeConsecutiveSuggestionCards_shouldHaveTwoHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE
);
final List<ContextualCard> threeConsecutiveSuggestionCards = buildCategoriedCards(
getContextualCardList(), categories);
final List<Boolean> expectedValues = Arrays.asList(false, true, true, false, false);
final List<ContextualCard> result = mManager.assignCardWidth(
threeConsecutiveSuggestionCards);
assertThat(result).hasSize(5);
for (int i = 0; i < result.size(); i++) {
assertThat(result.get(i).isHalfWidth()).isEqualTo(expectedValues.get(i));
}
}
@Test
public void assignCardWidth_fourConsecutiveSuggestionCards_shouldHaveFourHalfCards() {
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
);
final List<ContextualCard> fourConsecutiveSuggestionCards = buildCategoriedCards(
getContextualCardList(), categories);
final List<Boolean> expectedValues = Arrays.asList(false, true, true, true, true);
final List<ContextualCard> result = mManager.assignCardWidth(
fourConsecutiveSuggestionCards);
assertThat(result).hasSize(5);
for (int i = 0; i < result.size(); i++) {
assertThat(result.get(i).isHalfWidth()).isEqualTo(expectedValues.get(i));
}
}
private ContextualCard buildContextualCard(String sliceUri) {
return new ContextualCard.Builder()
.setName(TEST_SLICE_NAME)
@@ -210,4 +340,45 @@ public class ContextualCardManagerTest {
.setSliceUri(Uri.parse(sliceUri))
.build();
}
private List<ContextualCard> buildCategoriedCards(List<ContextualCard> cards,
List<Integer> categories) {
final List<ContextualCard> result = new ArrayList<>();
for (int i = 0; i < cards.size(); i++) {
result.add(cards.get(i).mutate().setCategory(categories.get(i)).build());
}
return result;
}
private List<ContextualCard> getContextualCardList() {
final List<ContextualCard> cards = new ArrayList<>();
cards.add(new ContextualCard.Builder()
.setName("test_wifi")
.setCardType(ContextualCard.CardType.SLICE)
.setSliceUri(CustomSliceRegistry.CONTEXTUAL_WIFI_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"))
.build());
cards.add(new ContextualCard.Builder()
.setName("test_connected")
.setCardType(ContextualCard.CardType.SLICE)
.setSliceUri(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI)
.build());
cards.add(new ContextualCard.Builder()
.setName("test_gesture")
.setCardType(ContextualCard.CardType.SLICE)
.setSliceUri(Uri.parse(
"content://com.android.settings.test.slices/action/gesture_pick_up"))
.build());
cards.add(new ContextualCard.Builder()
.setName("test_battery")
.setCardType(ContextualCard.CardType.SLICE)
.setSliceUri(CustomSliceRegistry.BATTERY_INFO_SLICE_URI)
.build());
return cards;
}
}