Make UI refresh when there is only one contextual card left.
After having card dismissal mechanism implemented, it is possible that the card list loaded from the card loader will be empty (users may dismiss all cards). When there is only one card remaining on the screen and user dismiss it, the card should go away. Fixes: 119580732 Test: robotest Change-Id: I7ae3b03f16a0b8b009d8aa77811b5a6d39c359e7
This commit is contained in:
@@ -62,10 +62,12 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
|||||||
private static final int[] SETTINGS_CARDS =
|
private static final int[] SETTINGS_CARDS =
|
||||||
{ContextualCard.CardType.CONDITIONAL, ContextualCard.CardType.LEGACY_SUGGESTION};
|
{ContextualCard.CardType.CONDITIONAL, ContextualCard.CardType.LEGACY_SUGGESTION};
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
final List<ContextualCard> mContextualCards;
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final ControllerRendererPool mControllerRendererPool;
|
private final ControllerRendererPool mControllerRendererPool;
|
||||||
private final Lifecycle mLifecycle;
|
private final Lifecycle mLifecycle;
|
||||||
private final List<ContextualCard> mContextualCards;
|
|
||||||
private final List<LifecycleObserver> mLifecycleObservers;
|
private final List<LifecycleObserver> mLifecycleObservers;
|
||||||
|
|
||||||
private ContextualCardUpdateListener mListener;
|
private ContextualCardUpdateListener mListener;
|
||||||
@@ -122,10 +124,23 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
|||||||
public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> updateList) {
|
public void onContextualCardUpdated(Map<Integer, List<ContextualCard>> updateList) {
|
||||||
final Set<Integer> cardTypes = updateList.keySet();
|
final Set<Integer> cardTypes = updateList.keySet();
|
||||||
//Remove the existing data that matches the certain cardType before inserting new data.
|
//Remove the existing data that matches the certain cardType before inserting new data.
|
||||||
final List<ContextualCard> cardsToKeep = mContextualCards
|
List<ContextualCard> cardsToKeep;
|
||||||
.stream()
|
|
||||||
|
// We are not sure how many card types will be in the database, so when the list coming
|
||||||
|
// from the database is empty (e.g. no eligible cards/cards are dismissed), we cannot
|
||||||
|
// assign a specific card type for its map which is sending here. Thus, we assume that
|
||||||
|
// except Conditional cards, all other cards are from the database. So when the map sent
|
||||||
|
// here is empty, we only keep Conditional cards.
|
||||||
|
if (cardTypes.isEmpty()) {
|
||||||
|
cardsToKeep = mContextualCards.stream()
|
||||||
|
.filter(card -> card.getCardType() == ContextualCard.CardType.CONDITIONAL)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
cardsToKeep = mContextualCards.stream()
|
||||||
.filter(card -> !cardTypes.contains(card.getCardType()))
|
.filter(card -> !cardTypes.contains(card.getCardType()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
final List<ContextualCard> allCards = new ArrayList<>();
|
final List<ContextualCard> allCards = new ArrayList<>();
|
||||||
allCards.addAll(cardsToKeep);
|
allCards.addAll(cardsToKeep);
|
||||||
allCards.addAll(
|
allCards.addAll(
|
||||||
|
@@ -18,8 +18,12 @@ package com.android.settings.homepage.contextualcards;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.anyMap;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.util.ArrayMap;
|
||||||
|
|
||||||
import com.android.settings.homepage.contextualcards.conditional.ConditionalContextualCard;
|
import com.android.settings.homepage.contextualcards.conditional.ConditionalContextualCard;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
@@ -27,6 +31,8 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -35,11 +41,17 @@ import java.util.List;
|
|||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
public class ContextualCardManagerTest {
|
public class ContextualCardManagerTest {
|
||||||
|
|
||||||
|
private static final String TEST_SLICE_URI = "context://test/test";
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ContextualCardUpdateListener mListener;
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private ContextualCardManager mManager;
|
private ContextualCardManager mManager;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = RuntimeEnvironment.application;
|
mContext = RuntimeEnvironment.application;
|
||||||
final ContextualCardsFragment fragment = new ContextualCardsFragment();
|
final ContextualCardsFragment fragment = new ContextualCardsFragment();
|
||||||
mManager = new ContextualCardManager(mContext, fragment.getSettingsLifecycle());
|
mManager = new ContextualCardManager(mContext, fragment.getSettingsLifecycle());
|
||||||
@@ -47,10 +59,9 @@ public class ContextualCardManagerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void sortCards_hasConditionalAndSliceCards_conditionalShouldAlwaysBeTheLast() {
|
public void sortCards_hasConditionalAndSliceCards_conditionalShouldAlwaysBeTheLast() {
|
||||||
final String sliceUri = "content://com.android.settings.slices/action/flashlight";
|
|
||||||
final List<ContextualCard> cards = new ArrayList<>();
|
final List<ContextualCard> cards = new ArrayList<>();
|
||||||
cards.add(new ConditionalContextualCard.Builder().build());
|
cards.add(new ConditionalContextualCard.Builder().build());
|
||||||
cards.add(buildContextualCard(sliceUri));
|
cards.add(buildContextualCard(TEST_SLICE_URI));
|
||||||
|
|
||||||
final List<ContextualCard> sortedCards = mManager.sortCards(cards);
|
final List<ContextualCard> sortedCards = mManager.sortCards(cards);
|
||||||
|
|
||||||
@@ -58,6 +69,21 @@ public class ContextualCardManagerTest {
|
|||||||
.isEqualTo(ContextualCard.CardType.CONDITIONAL);
|
.isEqualTo(ContextualCard.CardType.CONDITIONAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onContextualCardUpdated_emtpyMapWithExistingCards_shouldOnlyKeepConditionalCard() {
|
||||||
|
mManager.mContextualCards.add(new ConditionalContextualCard.Builder().build());
|
||||||
|
mManager.mContextualCards.add(
|
||||||
|
buildContextualCard(TEST_SLICE_URI));
|
||||||
|
mManager.setListener(mListener);
|
||||||
|
|
||||||
|
//Simulate database returns no contents.
|
||||||
|
mManager.onContextualCardUpdated(new ArrayMap<>());
|
||||||
|
|
||||||
|
assertThat(mManager.mContextualCards).hasSize(1);
|
||||||
|
assertThat(mManager.mContextualCards.get(0).getCardType())
|
||||||
|
.isEqualTo(ContextualCard.CardType.CONDITIONAL);
|
||||||
|
}
|
||||||
|
|
||||||
private ContextualCard buildContextualCard(String sliceUri) {
|
private ContextualCard buildContextualCard(String sliceUri) {
|
||||||
return new ContextualCard.Builder()
|
return new ContextualCard.Builder()
|
||||||
.setName("test_name")
|
.setName("test_name")
|
||||||
|
Reference in New Issue
Block a user