Make Wifi and Bluetooth Slices not dismissable.

Wifi and Bluetooth are sticky, so remove its dismiss-ability.

Bug: 143055685
Test: robotests
Change-Id: Iff7724fbb261299e2107ff3b89bd5d7abe507532
This commit is contained in:
Yi-Ling Chuang
2020-01-20 18:43:08 +08:00
parent 9d1b873c69
commit 0ce468965c
5 changed files with 168 additions and 14 deletions

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/ContextualCardStyle">
<androidx.slice.widget.SliceView
android:id="@+id/slice_view"
style="@style/ContextualCardSliceViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:importantForAccessibility="no"/>
</com.google.android.material.card.MaterialCardView>

View File

@@ -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,

View File

@@ -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<Uri> 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<ContextualCard> 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<ContextualCard> getCardsWithStickyViewType(List<ContextualCard> cards) {
final List<ContextualCard> 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<ContextualCard> getCardsToKeep(List<ContextualCard> cards) {
if (mSavedCards != null) {

View File

@@ -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
}
});
if (holder.getItemViewType() != VIEW_TYPE_STICKY) {
initDismissalActions(holder, card);
}
if (card.isPendingDismiss()) {
showDismissalView(holder);

View File

@@ -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<String> actualCards = mManager.mSavedCards.stream().collect(Collectors.toList());
final List<String> expectedCards = Arrays.asList("test_wifi", "test_flashlight",
"test_connected", "test_gesture", "test_battery");
final List<String> 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<ContextualCard> cards = new ArrayList<>();
cards.add(buildContextualCard(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI.toString()));
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
);
final List<ContextualCard> cardListWithWifi = buildCategoriedCards(cards, categories);
final List<ContextualCard> 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<ContextualCard> cards = new ArrayList<>();
cards.add(buildContextualCard(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI.toString()));
cards.add(buildContextualCard(CustomSliceRegistry.LOW_STORAGE_SLICE_URI.toString()));
final List<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
);
final List<ContextualCard> cardListWithBT = buildCategoriedCards(cards, categories);
final List<ContextualCard> 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<ContextualCard> 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<Integer> categories = Arrays.asList(
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE,
ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE
);
final List<ContextualCard> cardListWithWifiBT = buildCategoriedCards(cards, categories);
final List<ContextualCard> 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<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.SUGGESTION_VALUE
);
final List<ContextualCard> cardListWithoutWifiBT =
buildCategoriedCards(getContextualCardList(), categories);
final List<ContextualCard> 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<String> savedCardNames = new ArrayList<>();
@@ -572,9 +656,9 @@ public class ContextualCardManagerTest {
private List<ContextualCard> getContextualCardList() {
final List<ContextualCard> 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()