Merge "Build a way to decide card width"
This commit is contained in:
@@ -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<>();
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user