Loading src/com/android/settings/dashboard/DashboardData.java +69 −70 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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; Loading @@ -69,7 +79,6 @@ public class DashboardData { mSuggestionConditionMode = builder.mSuggestionConditionMode; mItems = new ArrayList<>(); mId = 0; buildItemsData(); } Loading Loading @@ -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++; } /** Loading @@ -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 */); } } } Loading Loading @@ -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; Loading Loading @@ -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 = Loading @@ -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} Loading @@ -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. Loading @@ -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. */ Loading tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 = Loading Loading
src/com/android/settings/dashboard/DashboardData.java +69 −70 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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; Loading @@ -69,7 +79,6 @@ public class DashboardData { mSuggestionConditionMode = builder.mSuggestionConditionMode; mItems = new ArrayList<>(); mId = 0; buildItemsData(); } Loading Loading @@ -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++; } /** Loading @@ -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 */); } } } Loading Loading @@ -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; Loading Loading @@ -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 = Loading @@ -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} Loading @@ -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. Loading @@ -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. */ Loading
tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 = Loading