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

Commit 2b3ce727 authored by Fan Zhang's avatar Fan Zhang Committed by Android (Google) Code Review
Browse files

Merge "Change the way we generate stable id for DashboardSummary"

parents 6f19d968 a29346ba
Loading
Loading
Loading
Loading
+69 −70
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@ package com.android.settings.dashboard;

import android.annotation.IntDef;
import android.graphics.drawable.Icon;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.support.v7.util.DiffUtil;
import android.text.TextUtils;

@@ -30,6 +30,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Description about data list used in the DashboardAdapter. In the data list each item can be
@@ -42,25 +43,34 @@ public class DashboardData {
    public static final int HEADER_MODE_SUGGESTION_EXPANDED = 1;
    public static final int HEADER_MODE_FULLY_EXPANDED = 2;
    public static final int HEADER_MODE_COLLAPSED = 3;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({HEADER_MODE_DEFAULT, HEADER_MODE_SUGGESTION_EXPANDED, HEADER_MODE_FULLY_EXPANDED,
            HEADER_MODE_COLLAPSED})
    public @interface HeaderMode{}
    public @interface HeaderMode {
    }

    public static final int POSITION_NOT_FOUND = -1;
    public static final int DEFAULT_SUGGESTION_COUNT = 2;

    // id namespace for different type of items.
    private static final int NS_SPACER = 0;
    private static final int NS_ITEMS = 2000;
    private static final int NS_SUGGESTION_CONDITION = 3000;
    // stable id for different type of items.
    @VisibleForTesting
    static final int STABLE_ID_SUGGESTION_CONDITION_TOP_HEADER = 0;
    @VisibleForTesting
    static final int STABLE_ID_SUGGESTION_CONDITION_MIDDLE_HEADER = 1;
    @VisibleForTesting
    static final int STABLE_ID_SUGGESTION_CONDITION_FOOTER = 2;
    @VisibleForTesting
    static final int STABLE_ID_SUGGESTION_CONTAINER = 3;
    @VisibleForTesting
    static final int STABLE_ID_CONDITION_CONTAINER = 4;

    private final List<Item> mItems;
    private final List<DashboardCategory> mCategories;
    private final List<Condition> mConditions;
    private final List<Tile> mSuggestions;
    private final @HeaderMode int mSuggestionConditionMode;
    private int mId;
    @HeaderMode
    private final int mSuggestionConditionMode;

    private DashboardData(Builder builder) {
        mCategories = builder.mCategories;
@@ -69,7 +79,6 @@ public class DashboardData {
        mSuggestionConditionMode = builder.mSuggestionConditionMode;

        mItems = new ArrayList<>();
        mId = 0;

        buildItemsData();
    }
@@ -186,33 +195,18 @@ public class DashboardData {
        return suggestionSize;
    }

    public boolean hasMoreSuggestions() {
        return mSuggestionConditionMode == HEADER_MODE_COLLAPSED && mSuggestions.size() > 0
                || mSuggestionConditionMode == HEADER_MODE_DEFAULT
                && mSuggestions.size() > DEFAULT_SUGGESTION_COUNT;
    }

    private void resetCount() {
        mId = 0;
    }

    /**
     * Count the item and add it into list when {@paramref add} is true.
     *
     * Note that {@link #mId} will increment automatically and the real
     * id stored in {@link Item} is shifted by {@paramref nameSpace}. This is a
     * simple way to keep the id stable.
     * Add item into list when {@paramref add} is true.
     *
     * @param object    maybe {@link Condition}, {@link Tile}, {@link DashboardCategory} or null
     * @param item     maybe {@link Condition}, {@link Tile}, {@link DashboardCategory} or null
     * @param type     type of the item, and value is the layout id
     * @param stableId The stable id for this item
     * @param add      flag about whether to add item into list
     * @param nameSpace namespace based on the type
     */
    private void countItem(Object object, int type, boolean add, int nameSpace) {
    private void addToItemList(Object item, int type, int stableId, boolean add) {
        if (add) {
            mItems.add(new Item(object, type, mId + nameSpace));
            mItems.add(new Item(item, type, stableId));
        }
        mId++;
    }

    /**
@@ -228,51 +222,52 @@ public class DashboardData {
        final int hiddenSuggestion =
                hasSuggestions ? sizeOf(mSuggestions) - sizeOf(suggestions) : 0;

        resetCount();
        /* Top suggestion/condition header. This will be present when there is any suggestion or
         * condition to show, except in the case that there is only conditions to show and the
         * mode is fully expanded. */
        countItem(new SuggestionConditionHeaderData(conditions, hiddenSuggestion),
                R.layout.suggestion_condition_header, hasSuggestions
                        || hasConditions && mSuggestionConditionMode != HEADER_MODE_FULLY_EXPANDED,
                NS_SUGGESTION_CONDITION);
        addToItemList(new SuggestionConditionHeaderData(conditions, hiddenSuggestion),
                R.layout.suggestion_condition_header,
                STABLE_ID_SUGGESTION_CONDITION_TOP_HEADER,
                hasSuggestions
                        || hasConditions && mSuggestionConditionMode != HEADER_MODE_FULLY_EXPANDED);

        /* Suggestion container. This is the card view that contains the list of suggestions.
         * This will be added whenever the suggestion list is not empty */
        countItem(suggestions, R.layout.suggestion_condition_container, sizeOf(suggestions) > 0,
                NS_SUGGESTION_CONDITION);
        addToItemList(suggestions, R.layout.suggestion_condition_container,
                STABLE_ID_SUGGESTION_CONTAINER, sizeOf(suggestions) > 0);

        /* Second suggestion/condition header. This will be added when there is at least one
         * suggestion or condition that is not currently displayed, and the user can expand the
         * section to view more items. */
        countItem(new SuggestionConditionHeaderData(conditions, hiddenSuggestion),
        addToItemList(new SuggestionConditionHeaderData(conditions, hiddenSuggestion),
                R.layout.suggestion_condition_header,
                STABLE_ID_SUGGESTION_CONDITION_MIDDLE_HEADER,
                mSuggestionConditionMode != HEADER_MODE_COLLAPSED
                        && mSuggestionConditionMode != HEADER_MODE_FULLY_EXPANDED
                        && (hiddenSuggestion > 0
                        || hasConditions && hasSuggestions),
                NS_SUGGESTION_CONDITION);
                        && (hiddenSuggestion > 0 || hasConditions && hasSuggestions));

            /* Condition container. This is the card view that contains the list of conditions.
             * This will be added whenever the condition list is not empty */
        countItem(conditions, R.layout.suggestion_condition_container,
                hasConditions && mSuggestionConditionMode == HEADER_MODE_FULLY_EXPANDED,
                NS_SUGGESTION_CONDITION);
        addToItemList(conditions, R.layout.suggestion_condition_container,
                STABLE_ID_CONDITION_CONTAINER,
                hasConditions && mSuggestionConditionMode == HEADER_MODE_FULLY_EXPANDED);

            /* Suggestion/condition footer. This will be present when the section is fully expanded
             * or when there is no conditions and no hidden suggestions */
        countItem(null, R.layout.suggestion_condition_footer,
                (hasConditions || hasSuggestions) &&
                        mSuggestionConditionMode == HEADER_MODE_FULLY_EXPANDED
                        || hasSuggestions && !hasConditions && hiddenSuggestion == 0,
                NS_SUGGESTION_CONDITION);
        addToItemList(null /* item */, R.layout.suggestion_condition_footer,
                STABLE_ID_SUGGESTION_CONDITION_FOOTER,
                (hasConditions || hasSuggestions)
                        && mSuggestionConditionMode == HEADER_MODE_FULLY_EXPANDED
                        || hasSuggestions
                        && !hasConditions
                        && hiddenSuggestion == 0);

        resetCount();
        for (int i = 0; mCategories != null && i < mCategories.size(); i++) {
            DashboardCategory category = mCategories.get(i);
            for (int j = 0; j < category.tiles.size(); j++) {
                Tile tile = category.tiles.get(j);
                countItem(tile, R.layout.dashboard_tile, true, NS_ITEMS);
                final Tile tile = category.tiles.get(j);
                addToItemList(tile, R.layout.dashboard_tile, Objects.hash(tile.title),
                        true /* add */);
            }
        }
    }
@@ -313,7 +308,8 @@ public class DashboardData {
     * {@link #mSuggestionConditionMode} have default value while others are not.
     */
    public static class Builder {
        private @HeaderMode int mSuggestionConditionMode = HEADER_MODE_DEFAULT;
        @HeaderMode
        private int mSuggestionConditionMode = HEADER_MODE_DEFAULT;

        private List<DashboardCategory> mCategories;
        private List<Condition> mConditions;
@@ -392,7 +388,7 @@ public class DashboardData {
    /**
     * An item contains the data needed in the DashboardData.
     */
    private static class Item {
    static class Item {
        // valid types in field type
        private static final int TYPE_DASHBOARD_TILE = R.layout.dashboard_tile;
        private static final int TYPE_SUGGESTION_CONDITION_CONTAINER =
@@ -407,7 +403,8 @@ public class DashboardData {
                TYPE_SUGGESTION_CONDITION_HEADER, TYPE_SUGGESTION_CONDITION_FOOTER,
                TYPE_DASHBOARD_SPACER})
        @Retention(RetentionPolicy.SOURCE)
        public @interface ItemTypes{}
        public @interface ItemTypes {
        }

        /**
         * The main data object in item, usually is a {@link Tile}, {@link Condition}
@@ -420,7 +417,8 @@ public class DashboardData {
        /**
         * The type of item, value inside is the layout id(e.g. R.layout.dashboard_tile)
         */
        public final @ItemTypes int type;
        @ItemTypes
        public final int type;

        /**
         * Id of this item, used in the {@link ItemsDataDiffCallback} to identify the same item.
@@ -435,6 +433,7 @@ public class DashboardData {

        /**
         * Override it to make comparision in the {@link ItemsDataDiffCallback}
         *
         * @param obj object to compared with
         * @return true if the same object or has equal value.
         */
+20 −0
Original line number Diff line number Diff line
@@ -37,7 +37,13 @@ import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import static com.android.settings.dashboard.DashboardData.STABLE_ID_CONDITION_CONTAINER;
import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONDITION_FOOTER;
import static com.android.settings.dashboard.DashboardData
        .STABLE_ID_SUGGESTION_CONDITION_TOP_HEADER;
import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONTAINER;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -112,6 +118,20 @@ public class DashboardDataTest {
                .build();
    }

    @Test
    public void testBuildItemsData_shouldSetstableId() {
        final List<DashboardData.Item> items = mDashboardDataWithOneConditions.getItemList();

        // Header, suggestion, condition, footer, 1 tile
        assertThat(items).hasSize(5);

        assertThat(items.get(0).id).isEqualTo(STABLE_ID_SUGGESTION_CONDITION_TOP_HEADER);
        assertThat(items.get(1).id).isEqualTo(STABLE_ID_SUGGESTION_CONTAINER);
        assertThat(items.get(2).id).isEqualTo(STABLE_ID_CONDITION_CONTAINER);
        assertThat(items.get(3).id).isEqualTo(STABLE_ID_SUGGESTION_CONDITION_FOOTER);
        assertThat(items.get(4).id).isEqualTo(Objects.hash(mTestCategoryTile.title));
    }

    @Test
    public void testBuildItemsData_containsAllData() {
        final DashboardData.SuggestionConditionHeaderData data =