Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 814e65ad authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Make Wifi and Bluetooth Slices not dismissable."

parents 8003ea4c 0ce46896
Loading
Loading
Loading
Loading
+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
+4 −0
Original line number Original line Diff line number Diff line
@@ -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,
+32 −1
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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
@@ -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) {
+4 −1
Original line number Original line Diff line number Diff line
@@ -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";


@@ -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);
+96 −12
Original line number Original line Diff line number Diff line
@@ -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;


@@ -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);
    }
    }


@@ -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 */);


@@ -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 */);


@@ -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 */);


@@ -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 */);


@@ -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<>();
@@ -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()
@@ -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()