From 0ce468965c27ebc10f35143c49bbfb7e9a50b046 Mon Sep 17 00:00:00 2001 From: Yi-Ling Chuang Date: Mon, 20 Jan 2020 18:43:08 +0800 Subject: [PATCH] Make Wifi and Bluetooth Slices not dismissable. Wifi and Bluetooth are sticky, so remove its dismiss-ability. Bug: 143055685 Test: robotests Change-Id: Iff7724fbb261299e2107ff3b89bd5d7abe507532 --- res/layout/contextual_slice_sticky_tile.xml | 32 ++++++ .../ContextualCardLookupTable.java | 4 + .../ContextualCardManager.java | 33 +++++- .../slices/SliceContextualCardRenderer.java | 5 +- .../ContextualCardManagerTest.java | 108 ++++++++++++++++-- 5 files changed, 168 insertions(+), 14 deletions(-) create mode 100644 res/layout/contextual_slice_sticky_tile.xml diff --git a/res/layout/contextual_slice_sticky_tile.xml b/res/layout/contextual_slice_sticky_tile.xml new file mode 100644 index 00000000000..8e82f5339a0 --- /dev/null +++ b/res/layout/contextual_slice_sticky_tile.xml @@ -0,0 +1,32 @@ + + + + + + + + \ No newline at end of file diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java index 1f2e89ba60b..4a02d91b5ef 100644 --- a/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java +++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java @@ -87,6 +87,10 @@ public class ContextualCardLookupTable { SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH, SliceContextualCardController.class, SliceContextualCardRenderer.class)); + add(new ControllerRendererMapping(CardType.SLICE, + SliceContextualCardRenderer.VIEW_TYPE_STICKY, + SliceContextualCardController.class, + SliceContextualCardRenderer.class)); add(new ControllerRendererMapping(CardType.CONDITIONAL_FOOTER, ConditionFooterContextualCardRenderer.VIEW_TYPE, ConditionContextualCardController.class, diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java index 662448cc070..9e9069fc5f7 100644 --- a/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java +++ b/src/com/android/settings/homepage/contextualcards/ContextualCardManager.java @@ -18,11 +18,14 @@ 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 com.android.settings.slices.CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI; +import static com.android.settings.slices.CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI; import static java.util.stream.Collectors.groupingBy; import android.app.settings.SettingsEnums; import android.content.Context; +import android.net.Uri; import android.os.Bundle; import android.provider.Settings; import android.text.format.DateUtils; @@ -51,6 +54,7 @@ import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; @@ -80,6 +84,8 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo static final String KEY_CONTEXTUAL_CARDS = "key_contextual_cards"; private static final String TAG = "ContextualCardManager"; + private static final List STICKY_CARDS = + Arrays.asList(CONTEXTUAL_WIFI_SLICE_URI, BLUETOOTH_DEVICES_SLICE_URI); private final Context mContext; private final Lifecycle mLifecycle; @@ -308,7 +314,9 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo if (cards.isEmpty()) { return cards; } - return getCardsWithSuggestionViewType(cards); + + final List result = getCardsWithStickyViewType(cards); + return getCardsWithSuggestionViewType(result); } @VisibleForTesting @@ -338,6 +346,29 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo return result; } + // TODO(b/143055685):use category to determine whether they are sticky. + private List getCardsWithStickyViewType(List cards) { + final List result = new ArrayList<>(cards); + int replaceCount = 0; + for (int index = 0; index < result.size(); index++) { + if (replaceCount > STICKY_CARDS.size() - 1) { + break; + } + + final ContextualCard card = cards.get(index); + if (card.getCardType() != ContextualCard.CardType.SLICE) { + continue; + } + + if (STICKY_CARDS.contains(card.getSliceUri())) { + result.set(index, card.mutate().setViewType( + SliceContextualCardRenderer.VIEW_TYPE_STICKY).build()); + replaceCount++; + } + } + return result; + } + @VisibleForTesting List getCardsToKeep(List cards) { if (mSavedCards != null) { diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java index 23008745d17..6f07d4712e1 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java +++ b/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java @@ -54,6 +54,7 @@ import java.util.Set; public class SliceContextualCardRenderer implements ContextualCardRenderer, LifecycleObserver { public static final int VIEW_TYPE_FULL_WIDTH = R.layout.contextual_slice_full_tile; public static final int VIEW_TYPE_HALF_WIDTH = R.layout.contextual_slice_half_tile; + public static final int VIEW_TYPE_STICKY = R.layout.contextual_slice_sticky_tile; private static final String TAG = "SliceCardRenderer"; @@ -137,7 +138,9 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer, Life } }); - initDismissalActions(holder, card); + if (holder.getItemViewType() != VIEW_TYPE_STICKY) { + initDismissalActions(holder, card); + } if (card.isPendingDismiss()) { showDismissalView(holder); diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java index 63294446581..be3c6855a26 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java @@ -19,6 +19,7 @@ package com.android.settings.homepage.contextualcards; import static com.android.settings.homepage.contextualcards.ContextualCardManager.KEY_CONTEXTUAL_CARDS; import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH; import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH; +import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_STICKY; import static com.google.common.truth.Truth.assertThat; @@ -109,8 +110,8 @@ public class ContextualCardManagerTest { mManager = new ContextualCardManager(mContext, mLifecycle, outState); final List actualCards = mManager.mSavedCards.stream().collect(Collectors.toList()); - final List expectedCards = Arrays.asList("test_wifi", "test_flashlight", - "test_connected", "test_gesture", "test_battery"); + final List expectedCards = Arrays.asList("test_low_storage", "test_flashlight", + "test_dark_theme", "test_gesture", "test_battery"); assertThat(actualCards).containsExactlyElementsIn(expectedCards); } @@ -347,8 +348,9 @@ public class ContextualCardManagerTest { final ConditionContextualCardController conditionController = pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); - final OnStart controller = spy((OnStart)conditionController); - doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); + final OnStart controller = spy((OnStart) conditionController); + doReturn(controller).when(pool).getController(mContext, + ContextualCard.CardType.CONDITIONAL); manager.onWindowFocusChanged(true /* hasWindowFocus */); @@ -365,8 +367,9 @@ public class ContextualCardManagerTest { final ConditionContextualCardController conditionController = pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); - final OnStart controller = spy((OnStart)conditionController); - doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); + final OnStart controller = spy((OnStart) conditionController); + doReturn(controller).when(pool).getController(mContext, + ContextualCard.CardType.CONDITIONAL); manager.onWindowFocusChanged(true /* hasWindowFocus */); @@ -384,7 +387,8 @@ public class ContextualCardManagerTest { pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); final OnStop controller = spy((OnStop) conditionController); - doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); + doReturn(controller).when(pool).getController(mContext, + ContextualCard.CardType.CONDITIONAL); manager.onWindowFocusChanged(false /* hasWindowFocus */); @@ -400,7 +404,8 @@ public class ContextualCardManagerTest { pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); final OnStop controller = spy((OnStop) conditionController); - doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); + doReturn(controller).when(pool).getController(mContext, + ContextualCard.CardType.CONDITIONAL); manager.onWindowFocusChanged(false /* hasWindowFocus */); @@ -540,6 +545,85 @@ public class ContextualCardManagerTest { } } + @Test + public void getCardsWithViewType_hasWifiSlice_shouldHaveOneStickyCard() { + final List cards = new ArrayList<>(); + cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString())); + cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString())); + final List categories = Arrays.asList( + ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE, + ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE + ); + final List cardListWithWifi = buildCategoriedCards(cards, categories); + + final List 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_hasBluetoothDeviceSlice_shouldHaveOneStickyCard() { + final List cards = new ArrayList<>(); + cards.add(buildContextualCard(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString())); + cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString())); + final List categories = Arrays.asList( + ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE, + ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE + ); + final List cardListWithBT = buildCategoriedCards(cards, categories); + + final List result = mManager.getCardsWithViewType(cardListWithBT); + + 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_hasWifiAndBtDeviceSlice_shouldHaveTwoStickyCards() { + final List cards = new ArrayList<>(); + cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString())); + cards.add(buildContextualCard(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString())); + cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString())); + final List categories = Arrays.asList( + ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE, + ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE, + ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE + ); + final List cardListWithWifiBT = buildCategoriedCards(cards, categories); + + final List result = mManager.getCardsWithViewType(cardListWithWifiBT); + + assertThat(result).hasSize(cards.size()); + assertThat(result.stream() + .filter(card -> card.getViewType() == VIEW_TYPE_STICKY) + .count()) + .isEqualTo(2); + } + + @Test + public void getCardsWithViewType_noWifiOrBtDeviceSlice_shouldNotHaveStickyCard() { + final List 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.SUGGESTION_VALUE + ); + final List cardListWithoutWifiBT = + buildCategoriedCards(getContextualCardList(), categories); + + final List result = mManager.getCardsWithViewType(cardListWithoutWifiBT); + + assertThat(result).hasSize(cardListWithoutWifiBT.size()); + assertThat(result.stream() + .filter(card -> card.getViewType() == VIEW_TYPE_STICKY) + .count()) + .isEqualTo(0); + } + @Test public void getCardsToKeep_hasSavedCard_shouldResetSavedCards() { final List savedCardNames = new ArrayList<>(); @@ -572,9 +656,9 @@ public class ContextualCardManagerTest { private List getContextualCardList() { final List 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) .setViewType(VIEW_TYPE_FULL_WIDTH) .build()); cards.add(new ContextualCard.Builder() @@ -585,9 +669,9 @@ public class ContextualCardManagerTest { .setViewType(VIEW_TYPE_FULL_WIDTH) .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) .setViewType(VIEW_TYPE_FULL_WIDTH) .build()); cards.add(new ContextualCard.Builder()