diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java index dabc88c67f6..a4a84199c98 100644 --- a/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java +++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java @@ -24,10 +24,14 @@ import androidx.annotation.VisibleForTesting; import com.android.settings.homepage.contextualcards.ContextualCard.CardType; import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardController; import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer; +import com.android.settings.homepage.contextualcards.conditional + .ConditionHeaderContextualCardRenderer; import com.android.settings.homepage.contextualcards.legacysuggestion .LegacySuggestionContextualCardController; import com.android.settings.homepage.contextualcards.legacysuggestion .LegacySuggestionContextualCardRenderer; +import com.android.settings.homepage.contextualcards.conditional + .ConditionFooterContextualCardRenderer; import com.android.settings.homepage.contextualcards.slices.SliceContextualCardController; import com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer; @@ -83,6 +87,14 @@ public class ContextualCardLookupTable { SliceContextualCardRenderer.VIEW_TYPE, SliceContextualCardController.class, SliceContextualCardRenderer.class)); + add(new ControllerRendererMapping(CardType.CONDITIONAL_FOOTER, + ConditionFooterContextualCardRenderer.VIEW_TYPE, + ConditionContextualCardController.class, + ConditionFooterContextualCardRenderer.class)); + add(new ControllerRendererMapping(CardType.CONDITIONAL_HEADER, + ConditionHeaderContextualCardRenderer.VIEW_TYPE, + ConditionContextualCardController.class, + ConditionHeaderContextualCardRenderer.class)); }}; public static Class getCardControllerClass( diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java b/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java index 0a8749d37d4..10bed90d601 100644 --- a/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java +++ b/src/com/android/settings/homepage/contextualcards/ContextualCardsAdapter.java @@ -129,5 +129,7 @@ public class ContextualCardsAdapter extends RecyclerView.Adapter conditionCards = mConditionManager.getDisplayableCards(); + final Map> conditionalCards = + buildConditionalCardsWithFooterOrHeader(conditionCards); + mListener.onContextualCardUpdated(conditionalCards); - final boolean isOddNumber = conditionCards.size() % 2 == 1; + } + + /** + * According to conditional cards, build a map that includes conditional cards, header card and + * footer card. + * + * Rules: + * - The last one of conditional cards will be displayed as a full-width card if the size of + * conditional cards is odd number. The rest will be displayed as a half-width card. + * - By default conditional cards will be collapsed if there are more than TWO cards. + * + * For examples: + * - Only one conditional card: Returns a map that contains a full-width conditional card, + * no header card and no footer card. + *

Map{(CONDITIONAL, conditionCards), (CONDITIONAL_FOOTER, EMPTY_LIST), (CONDITIONAL_HEADER, + * EMPTY_LIST)}

+ * - Two conditional cards: Returns a map that contains two half-width conditional cards, + * no header card and no footer card. + *

Map{(CONDITIONAL, conditionCards), (CONDITIONAL_FOOTER, EMPTY_LIST), (CONDITIONAL_HEADER, + * EMPTY_LIST)}

+ * - Three conditional cards or above: By default, returns a map that contains no conditional + * card, one header card and no footer card. If conditional cards are expanded, will returns a + * map that contains three conditional cards, no header card and one footer card. + * If expanding conditional cards: + *

Map{(CONDITIONAL, conditionCards), (CONDITIONAL_FOOTER, footerCards), (CONDITIONAL_HEADER, + * EMPTY_LIST)}

+ * If collapsing conditional cards: + *

Map{(CONDITIONAL, EMPTY_LIST), (CONDITIONAL_FOOTER, EMPTY_LIST), (CONDITIONAL_HEADER, + * headerCards)}

+ * + * @param conditionCards A list of conditional cards that are from {@link + * ConditionManager#getDisplayableCards} + * @return A map contained three types of lists + */ + @VisibleForTesting + Map> buildConditionalCardsWithFooterOrHeader( + List conditionCards) { + final Map> conditionalCards = new ArrayMap<>(); + conditionalCards.put(ContextualCard.CardType.CONDITIONAL, + getExpandedConditionalCards(conditionCards)); + conditionalCards.put(ContextualCard.CardType.CONDITIONAL_FOOTER, + getConditionalFooterCard(conditionCards)); + conditionalCards.put(ContextualCard.CardType.CONDITIONAL_HEADER, + getConditionalHeaderCard(conditionCards)); + return conditionalCards; + } + + private List getExpandedConditionalCards(List conditionCards) { + if (conditionCards.isEmpty() || (conditionCards.size() > EXPANDING_THRESHOLD + && !mIsExpanded)) { + return Collections.EMPTY_LIST; + } + final List expandedCards = conditionCards.stream().collect( + Collectors.toList()); + final boolean isOddNumber = expandedCards.size() % 2 == 1; if (isOddNumber) { - final int lastIndex = conditionCards.size() - 1; - final ConditionalContextualCard card = (ConditionalContextualCard) conditionCards - .get(lastIndex); - conditionCards.set(lastIndex, card.mutate().setIsHalfWidth(false).build()); + final int lastIndex = expandedCards.size() - 1; + final ConditionalContextualCard card = + (ConditionalContextualCard) expandedCards.get(lastIndex); + expandedCards.set(lastIndex, card.mutate().setIsHalfWidth(false).build()); } + return expandedCards; + } - if (mListener != null) { - final Map> conditionalCards = new ArrayMap<>(); - conditionalCards.put(ContextualCard.CardType.CONDITIONAL, conditionCards); - mListener.onContextualCardUpdated(conditionalCards); + private List getConditionalFooterCard(List conditionCards) { + if (!conditionCards.isEmpty() && mIsExpanded + && conditionCards.size() > EXPANDING_THRESHOLD) { + final List footerCards = new ArrayList<>(); + footerCards.add(new ConditionFooterContextualCard.Builder() + .setName(CONDITION_FOOTER) + .setRankingScore(UNSUPPORTED_RANKING) + .build()); + return footerCards; } + return Collections.EMPTY_LIST; + } + + private List getConditionalHeaderCard(List conditionCards) { + if (!conditionCards.isEmpty() && !mIsExpanded + && conditionCards.size() > EXPANDING_THRESHOLD) { + final List headerCards = new ArrayList<>(); + headerCards.add(new ConditionHeaderContextualCard.Builder() + .setConditionalCards(conditionCards) + .setName(CONDITION_HEADER) + .setRankingScore(UNSUPPORTED_RANKING) + .build()); + return headerCards; + } + return Collections.EMPTY_LIST; } } diff --git a/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCard.java b/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCard.java index f1a0fede469..b72f9f7e6af 100644 --- a/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCard.java +++ b/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCard.java @@ -16,9 +16,12 @@ package com.android.settings.homepage.contextualcards.conditional; +import android.text.TextUtils; + import com.android.settings.homepage.contextualcards.ContextualCard; import java.util.List; +import java.util.Objects; /** * Data class representing a condition header {@link ContextualCard}. @@ -44,6 +47,25 @@ public class ConditionHeaderContextualCard extends ContextualCard { return mConditionalCards; } + @Override + public int hashCode() { + return Objects.hash(getName(), mConditionalCards); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ConditionHeaderContextualCard)) { + return false; + } + final ConditionHeaderContextualCard that = (ConditionHeaderContextualCard) obj; + + return TextUtils.equals(getName(), that.getName()) && mConditionalCards.equals( + that.mConditionalCards); + } + public static class Builder extends ContextualCard.Builder { private List mConditionalCards;