Loading res/layout/contextual_slice_sticky_tile.xml 0 → 100644 +32 −0 Original line number Original line Diff line number Diff line <?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> No newline at end of file src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -87,6 +87,10 @@ public class ContextualCardLookupTable { SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH, SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH, SliceContextualCardController.class, SliceContextualCardController.class, SliceContextualCardRenderer.class)); SliceContextualCardRenderer.class)); add(new ControllerRendererMapping(CardType.SLICE, SliceContextualCardRenderer.VIEW_TYPE_STICKY, SliceContextualCardController.class, SliceContextualCardRenderer.class)); add(new ControllerRendererMapping(CardType.CONDITIONAL_FOOTER, add(new ControllerRendererMapping(CardType.CONDITIONAL_FOOTER, ConditionFooterContextualCardRenderer.VIEW_TYPE, ConditionFooterContextualCardRenderer.VIEW_TYPE, ConditionContextualCardController.class, ConditionContextualCardController.class, Loading src/com/android/settings/homepage/contextualcards/ContextualCardManager.java +32 −1 Original line number Original line Diff line number Diff line Loading @@ -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.homepage.contextualcards.ContextualCardLoader.CARD_CONTENT_LOADER_ID; import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE; 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 static java.util.stream.Collectors.groupingBy; import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Context; import android.net.Uri; import android.os.Bundle; import android.os.Bundle; import android.provider.Settings; import android.provider.Settings; import android.text.format.DateUtils; import android.text.format.DateUtils; Loading Loading @@ -51,6 +54,7 @@ import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import com.android.settingslib.core.lifecycle.events.OnStop; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.List; import java.util.Map; import java.util.Map; import java.util.Set; import java.util.Set; Loading Loading @@ -80,6 +84,8 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo static final String KEY_CONTEXTUAL_CARDS = "key_contextual_cards"; static final String KEY_CONTEXTUAL_CARDS = "key_contextual_cards"; private static final String TAG = "ContextualCardManager"; 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 Context mContext; private final Lifecycle mLifecycle; private final Lifecycle mLifecycle; Loading Loading @@ -308,7 +314,9 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo if (cards.isEmpty()) { if (cards.isEmpty()) { return cards; return cards; } } return getCardsWithSuggestionViewType(cards); final List<ContextualCard> result = getCardsWithStickyViewType(cards); return getCardsWithSuggestionViewType(result); } } @VisibleForTesting @VisibleForTesting Loading Loading @@ -338,6 +346,29 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo return result; 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 @VisibleForTesting List<ContextualCard> getCardsToKeep(List<ContextualCard> cards) { List<ContextualCard> getCardsToKeep(List<ContextualCard> cards) { if (mSavedCards != null) { if (mSavedCards != null) { Loading src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -54,6 +54,7 @@ import java.util.Set; public class SliceContextualCardRenderer implements ContextualCardRenderer, LifecycleObserver { 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_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_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"; private static final String TAG = "SliceCardRenderer"; Loading Loading @@ -137,7 +138,9 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer, Life } } }); }); if (holder.getItemViewType() != VIEW_TYPE_STICKY) { initDismissalActions(holder, card); initDismissalActions(holder, card); } if (card.isPendingDismiss()) { if (card.isPendingDismiss()) { showDismissalView(holder); showDismissalView(holder); Loading tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java +96 −12 Original line number Original line Diff line number Diff line Loading @@ -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.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_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_HALF_WIDTH; import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_STICKY; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -109,8 +110,8 @@ public class ContextualCardManagerTest { mManager = new ContextualCardManager(mContext, mLifecycle, outState); mManager = new ContextualCardManager(mContext, mLifecycle, outState); final List<String> actualCards = mManager.mSavedCards.stream().collect(Collectors.toList()); final List<String> actualCards = mManager.mSavedCards.stream().collect(Collectors.toList()); final List<String> expectedCards = Arrays.asList("test_wifi", "test_flashlight", final List<String> expectedCards = Arrays.asList("test_low_storage", "test_flashlight", "test_connected", "test_gesture", "test_battery"); "test_dark_theme", "test_gesture", "test_battery"); assertThat(actualCards).containsExactlyElementsIn(expectedCards); assertThat(actualCards).containsExactlyElementsIn(expectedCards); } } Loading Loading @@ -348,7 +349,8 @@ public class ContextualCardManagerTest { pool.getController(mContext, pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); ContextualCard.CardType.CONDITIONAL); final OnStart controller = spy((OnStart) conditionController); final OnStart controller = spy((OnStart) conditionController); doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); manager.onWindowFocusChanged(true /* hasWindowFocus */); manager.onWindowFocusChanged(true /* hasWindowFocus */); Loading @@ -366,7 +368,8 @@ public class ContextualCardManagerTest { pool.getController(mContext, pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); ContextualCard.CardType.CONDITIONAL); final OnStart controller = spy((OnStart) conditionController); final OnStart controller = spy((OnStart) conditionController); doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); manager.onWindowFocusChanged(true /* hasWindowFocus */); manager.onWindowFocusChanged(true /* hasWindowFocus */); Loading @@ -384,7 +387,8 @@ public class ContextualCardManagerTest { pool.getController(mContext, pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); ContextualCard.CardType.CONDITIONAL); final OnStop controller = spy((OnStop) conditionController); 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 */); manager.onWindowFocusChanged(false /* hasWindowFocus */); Loading @@ -400,7 +404,8 @@ public class ContextualCardManagerTest { pool.getController(mContext, pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); ContextualCard.CardType.CONDITIONAL); final OnStop controller = spy((OnStop) conditionController); 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 */); manager.onWindowFocusChanged(false /* hasWindowFocus */); Loading Loading @@ -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 @Test public void getCardsToKeep_hasSavedCard_shouldResetSavedCards() { public void getCardsToKeep_hasSavedCard_shouldResetSavedCards() { final List<String> savedCardNames = new ArrayList<>(); final List<String> savedCardNames = new ArrayList<>(); Loading Loading @@ -572,9 +656,9 @@ public class ContextualCardManagerTest { private List<ContextualCard> getContextualCardList() { private List<ContextualCard> getContextualCardList() { final List<ContextualCard> cards = new ArrayList<>(); final List<ContextualCard> cards = new ArrayList<>(); cards.add(new ContextualCard.Builder() cards.add(new ContextualCard.Builder() .setName("test_wifi") .setName("test_low_storage") .setCardType(ContextualCard.CardType.SLICE) .setCardType(ContextualCard.CardType.SLICE) .setSliceUri(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI) .setSliceUri(CustomSliceRegistry.LOW_STORAGE_SLICE_URI) .setViewType(VIEW_TYPE_FULL_WIDTH) .setViewType(VIEW_TYPE_FULL_WIDTH) .build()); .build()); cards.add(new ContextualCard.Builder() cards.add(new ContextualCard.Builder() Loading @@ -585,9 +669,9 @@ public class ContextualCardManagerTest { .setViewType(VIEW_TYPE_FULL_WIDTH) .setViewType(VIEW_TYPE_FULL_WIDTH) .build()); .build()); cards.add(new ContextualCard.Builder() cards.add(new ContextualCard.Builder() .setName("test_connected") .setName("test_dark_theme") .setCardType(ContextualCard.CardType.SLICE) .setCardType(ContextualCard.CardType.SLICE) .setSliceUri(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI) .setSliceUri(CustomSliceRegistry.DARK_THEME_SLICE_URI) .setViewType(VIEW_TYPE_FULL_WIDTH) .setViewType(VIEW_TYPE_FULL_WIDTH) .build()); .build()); cards.add(new ContextualCard.Builder() cards.add(new ContextualCard.Builder() Loading Loading
res/layout/contextual_slice_sticky_tile.xml 0 → 100644 +32 −0 Original line number Original line Diff line number Diff line <?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> No newline at end of file
src/com/android/settings/homepage/contextualcards/ContextualCardLookupTable.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -87,6 +87,10 @@ public class ContextualCardLookupTable { SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH, SliceContextualCardRenderer.VIEW_TYPE_HALF_WIDTH, SliceContextualCardController.class, SliceContextualCardController.class, SliceContextualCardRenderer.class)); SliceContextualCardRenderer.class)); add(new ControllerRendererMapping(CardType.SLICE, SliceContextualCardRenderer.VIEW_TYPE_STICKY, SliceContextualCardController.class, SliceContextualCardRenderer.class)); add(new ControllerRendererMapping(CardType.CONDITIONAL_FOOTER, add(new ControllerRendererMapping(CardType.CONDITIONAL_FOOTER, ConditionFooterContextualCardRenderer.VIEW_TYPE, ConditionFooterContextualCardRenderer.VIEW_TYPE, ConditionContextualCardController.class, ConditionContextualCardController.class, Loading
src/com/android/settings/homepage/contextualcards/ContextualCardManager.java +32 −1 Original line number Original line Diff line number Diff line Loading @@ -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.homepage.contextualcards.ContextualCardLoader.CARD_CONTENT_LOADER_ID; import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.SUGGESTION_VALUE; 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 static java.util.stream.Collectors.groupingBy; import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Context; import android.net.Uri; import android.os.Bundle; import android.os.Bundle; import android.provider.Settings; import android.provider.Settings; import android.text.format.DateUtils; import android.text.format.DateUtils; Loading Loading @@ -51,6 +54,7 @@ import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import com.android.settingslib.core.lifecycle.events.OnStop; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.List; import java.util.Map; import java.util.Map; import java.util.Set; import java.util.Set; Loading Loading @@ -80,6 +84,8 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo static final String KEY_CONTEXTUAL_CARDS = "key_contextual_cards"; static final String KEY_CONTEXTUAL_CARDS = "key_contextual_cards"; private static final String TAG = "ContextualCardManager"; 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 Context mContext; private final Lifecycle mLifecycle; private final Lifecycle mLifecycle; Loading Loading @@ -308,7 +314,9 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo if (cards.isEmpty()) { if (cards.isEmpty()) { return cards; return cards; } } return getCardsWithSuggestionViewType(cards); final List<ContextualCard> result = getCardsWithStickyViewType(cards); return getCardsWithSuggestionViewType(result); } } @VisibleForTesting @VisibleForTesting Loading Loading @@ -338,6 +346,29 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo return result; 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 @VisibleForTesting List<ContextualCard> getCardsToKeep(List<ContextualCard> cards) { List<ContextualCard> getCardsToKeep(List<ContextualCard> cards) { if (mSavedCards != null) { if (mSavedCards != null) { Loading
src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRenderer.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -54,6 +54,7 @@ import java.util.Set; public class SliceContextualCardRenderer implements ContextualCardRenderer, LifecycleObserver { 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_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_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"; private static final String TAG = "SliceCardRenderer"; Loading Loading @@ -137,7 +138,9 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer, Life } } }); }); if (holder.getItemViewType() != VIEW_TYPE_STICKY) { initDismissalActions(holder, card); initDismissalActions(holder, card); } if (card.isPendingDismiss()) { if (card.isPendingDismiss()) { showDismissalView(holder); showDismissalView(holder); Loading
tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardManagerTest.java +96 −12 Original line number Original line Diff line number Diff line Loading @@ -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.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_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_HALF_WIDTH; import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_STICKY; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -109,8 +110,8 @@ public class ContextualCardManagerTest { mManager = new ContextualCardManager(mContext, mLifecycle, outState); mManager = new ContextualCardManager(mContext, mLifecycle, outState); final List<String> actualCards = mManager.mSavedCards.stream().collect(Collectors.toList()); final List<String> actualCards = mManager.mSavedCards.stream().collect(Collectors.toList()); final List<String> expectedCards = Arrays.asList("test_wifi", "test_flashlight", final List<String> expectedCards = Arrays.asList("test_low_storage", "test_flashlight", "test_connected", "test_gesture", "test_battery"); "test_dark_theme", "test_gesture", "test_battery"); assertThat(actualCards).containsExactlyElementsIn(expectedCards); assertThat(actualCards).containsExactlyElementsIn(expectedCards); } } Loading Loading @@ -348,7 +349,8 @@ public class ContextualCardManagerTest { pool.getController(mContext, pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); ContextualCard.CardType.CONDITIONAL); final OnStart controller = spy((OnStart) conditionController); final OnStart controller = spy((OnStart) conditionController); doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); manager.onWindowFocusChanged(true /* hasWindowFocus */); manager.onWindowFocusChanged(true /* hasWindowFocus */); Loading @@ -366,7 +368,8 @@ public class ContextualCardManagerTest { pool.getController(mContext, pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); ContextualCard.CardType.CONDITIONAL); final OnStart controller = spy((OnStart) conditionController); final OnStart controller = spy((OnStart) conditionController); doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); doReturn(controller).when(pool).getController(mContext, ContextualCard.CardType.CONDITIONAL); manager.onWindowFocusChanged(true /* hasWindowFocus */); manager.onWindowFocusChanged(true /* hasWindowFocus */); Loading @@ -384,7 +387,8 @@ public class ContextualCardManagerTest { pool.getController(mContext, pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); ContextualCard.CardType.CONDITIONAL); final OnStop controller = spy((OnStop) conditionController); 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 */); manager.onWindowFocusChanged(false /* hasWindowFocus */); Loading @@ -400,7 +404,8 @@ public class ContextualCardManagerTest { pool.getController(mContext, pool.getController(mContext, ContextualCard.CardType.CONDITIONAL); ContextualCard.CardType.CONDITIONAL); final OnStop controller = spy((OnStop) conditionController); 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 */); manager.onWindowFocusChanged(false /* hasWindowFocus */); Loading Loading @@ -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 @Test public void getCardsToKeep_hasSavedCard_shouldResetSavedCards() { public void getCardsToKeep_hasSavedCard_shouldResetSavedCards() { final List<String> savedCardNames = new ArrayList<>(); final List<String> savedCardNames = new ArrayList<>(); Loading Loading @@ -572,9 +656,9 @@ public class ContextualCardManagerTest { private List<ContextualCard> getContextualCardList() { private List<ContextualCard> getContextualCardList() { final List<ContextualCard> cards = new ArrayList<>(); final List<ContextualCard> cards = new ArrayList<>(); cards.add(new ContextualCard.Builder() cards.add(new ContextualCard.Builder() .setName("test_wifi") .setName("test_low_storage") .setCardType(ContextualCard.CardType.SLICE) .setCardType(ContextualCard.CardType.SLICE) .setSliceUri(CustomSliceRegistry.CONTEXTUAL_WIFI_SLICE_URI) .setSliceUri(CustomSliceRegistry.LOW_STORAGE_SLICE_URI) .setViewType(VIEW_TYPE_FULL_WIDTH) .setViewType(VIEW_TYPE_FULL_WIDTH) .build()); .build()); cards.add(new ContextualCard.Builder() cards.add(new ContextualCard.Builder() Loading @@ -585,9 +669,9 @@ public class ContextualCardManagerTest { .setViewType(VIEW_TYPE_FULL_WIDTH) .setViewType(VIEW_TYPE_FULL_WIDTH) .build()); .build()); cards.add(new ContextualCard.Builder() cards.add(new ContextualCard.Builder() .setName("test_connected") .setName("test_dark_theme") .setCardType(ContextualCard.CardType.SLICE) .setCardType(ContextualCard.CardType.SLICE) .setSliceUri(CustomSliceRegistry.BLUETOOTH_DEVICES_SLICE_URI) .setSliceUri(CustomSliceRegistry.DARK_THEME_SLICE_URI) .setViewType(VIEW_TYPE_FULL_WIDTH) .setViewType(VIEW_TYPE_FULL_WIDTH) .build()); .build()); cards.add(new ContextualCard.Builder() cards.add(new ContextualCard.Builder() Loading