suggestions) {
- if (suggestions == null || mSuggestionConditionMode == HEADER_MODE_COLLAPSED) {
+ if (suggestions == null) {
return null;
}
- if (mSuggestionConditionMode != HEADER_MODE_DEFAULT
- || suggestions.size() <= DEFAULT_SUGGESTION_COUNT) {
+ if (suggestions.size() <= MAX_SUGGESTION_COUNT) {
return suggestions;
}
- return suggestions.subList(0, DEFAULT_SUGGESTION_COUNT);
+ return suggestions.subList(0, MAX_SUGGESTION_COUNT);
}
/**
* Builder used to build the ItemsData
- *
- * {@link #mSuggestionConditionMode} have default value while others are not.
*/
public static class Builder {
- @HeaderMode
- private int mSuggestionConditionMode = HEADER_MODE_DEFAULT;
-
private DashboardCategory mCategory;
private List mConditions;
- private List mSuggestionsV2;
+ private List mSuggestions;
+ private boolean mConditionExpanded;
public Builder() {
}
@@ -306,8 +264,8 @@ public class DashboardData {
public Builder(DashboardData dashboardData) {
mCategory = dashboardData.mCategory;
mConditions = dashboardData.mConditions;
- mSuggestionsV2 = dashboardData.mSuggestions;
- mSuggestionConditionMode = dashboardData.mSuggestionConditionMode;
+ mSuggestions = dashboardData.mSuggestions;
+ mConditionExpanded = dashboardData.mConditionExpanded;
}
public Builder setCategory(DashboardCategory category) {
@@ -321,12 +279,12 @@ public class DashboardData {
}
public Builder setSuggestions(List suggestions) {
- this.mSuggestionsV2 = suggestions;
+ this.mSuggestions = suggestions;
return this;
}
- public Builder setSuggestionConditionMode(@HeaderMode int mode) {
- this.mSuggestionConditionMode = mode;
+ public Builder setConditionExpanded(boolean expanded) {
+ this.mConditionExpanded = expanded;
return this;
}
@@ -376,17 +334,18 @@ public class DashboardData {
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 =
- R.layout.suggestion_condition_container;
- private static final int TYPE_SUGGESTION_CONDITION_HEADER =
- R.layout.suggestion_condition_header;
- private static final int TYPE_SUGGESTION_CONDITION_FOOTER =
- R.layout.suggestion_condition_footer;
- private static final int TYPE_DASHBOARD_SPACER = R.layout.dashboard_spacer;
+ private static final int TYPE_SUGGESTION_CONTAINER =
+ R.layout.suggestion_container;
+ private static final int TYPE_CONDITION_CONTAINER =
+ R.layout.condition_container;
+ private static final int TYPE_CONDITION_HEADER =
+ R.layout.condition_header;
+ private static final int TYPE_CONDITION_FOOTER =
+ R.layout.condition_footer;
+ private static final int TYPE_SUGGESTION_CONDITION_DIVIDER = R.layout.horizontal_divider;
- @IntDef({TYPE_DASHBOARD_TILE, TYPE_SUGGESTION_CONDITION_CONTAINER,
- TYPE_SUGGESTION_CONDITION_HEADER, TYPE_SUGGESTION_CONDITION_FOOTER,
- TYPE_DASHBOARD_SPACER})
+ @IntDef({TYPE_DASHBOARD_TILE, TYPE_SUGGESTION_CONTAINER, TYPE_CONDITION_CONTAINER,
+ TYPE_CONDITION_HEADER, TYPE_CONDITION_FOOTER, TYPE_SUGGESTION_CONDITION_DIVIDER})
@Retention(RetentionPolicy.SOURCE)
public @interface ItemTypes {
}
@@ -444,8 +403,9 @@ public class DashboardData {
// Only check title and summary for dashboard tile
return TextUtils.equals(localTile.title, targetTile.title)
- && TextUtils.equals(localTile.summary, targetTile.summary);
- case TYPE_SUGGESTION_CONDITION_CONTAINER:
+ && TextUtils.equals(localTile.summary, targetTile.summary);
+ case TYPE_SUGGESTION_CONTAINER:
+ case TYPE_CONDITION_CONTAINER:
// If entity is suggestion and contains remote view, force refresh
final List entities = (List) entity;
if (!entities.isEmpty()) {
@@ -467,16 +427,13 @@ public class DashboardData {
* This class contains the data needed to build the suggestion/condition header. The data can
* also be used to check the diff in DiffUtil.Callback
*/
- public static class SuggestionConditionHeaderData {
+ public static class ConditionHeaderData {
public final List conditionIcons;
public final CharSequence title;
public final int conditionCount;
- public final int hiddenSuggestionCount;
- public SuggestionConditionHeaderData(List conditions,
- int hiddenSuggestionCount) {
+ public ConditionHeaderData(List conditions) {
conditionCount = sizeOf(conditions);
- this.hiddenSuggestionCount = hiddenSuggestionCount;
title = conditionCount > 0 ? conditions.get(0).getTitle() : null;
conditionIcons = new ArrayList<>();
for (int i = 0; conditions != null && i < conditions.size(); i++) {
diff --git a/src/com/android/settings/dashboard/DashboardDataV2.java b/src/com/android/settings/dashboard/DashboardDataV2.java
deleted file mode 100644
index e25ee05c449..00000000000
--- a/src/com/android/settings/dashboard/DashboardDataV2.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-package com.android.settings.dashboard;
-
-import android.annotation.IntDef;
-import android.graphics.drawable.Icon;
-import android.service.settings.suggestions.Suggestion;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.util.DiffUtil;
-import android.text.TextUtils;
-
-import com.android.settings.R;
-import com.android.settings.dashboard.conditional.Condition;
-import com.android.settingslib.drawer.DashboardCategory;
-import com.android.settingslib.drawer.Tile;
-
-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
- * Condition, suggestion or category tile.
- *
- * ItemsData has inner class Item, which represents the Item in data list.
- */
-public class DashboardDataV2 {
- public static final int POSITION_NOT_FOUND = -1;
- public static final int MAX_SUGGESTION_COUNT = 4;
-
- // stable id for different type of items.
- @VisibleForTesting
- static final int STABLE_ID_SUGGESTION_CONTAINER = 0;
- static final int STABLE_ID_SUGGESTION_CONDITION_DIVIDER = 1;
- @VisibleForTesting
- static final int STABLE_ID_CONDITION_HEADER = 2;
- @VisibleForTesting
- static final int STABLE_ID_CONDITION_FOOTER = 3;
- @VisibleForTesting
- static final int STABLE_ID_CONDITION_CONTAINER = 4;
-
- private final List- mItems;
- private final DashboardCategory mCategory;
- private final List mConditions;
- private final List mSuggestions;
- private final boolean mConditionExpanded;
-
- private DashboardDataV2(Builder builder) {
- mCategory = builder.mCategory;
- mConditions = builder.mConditions;
- mSuggestions = builder.mSuggestions;
- mConditionExpanded = builder.mConditionExpanded;
- mItems = new ArrayList<>();
-
- buildItemsData();
- }
-
- public int getItemIdByPosition(int position) {
- return mItems.get(position).id;
- }
-
- public int getItemTypeByPosition(int position) {
- return mItems.get(position).type;
- }
-
- public Object getItemEntityByPosition(int position) {
- return mItems.get(position).entity;
- }
-
- public List
- getItemList() {
- return mItems;
- }
-
- public int size() {
- return mItems.size();
- }
-
- public Object getItemEntityById(long id) {
- for (final Item item : mItems) {
- if (item.id == id) {
- return item.entity;
- }
- }
- return null;
- }
-
- public DashboardCategory getCategory() {
- return mCategory;
- }
-
- public List getConditions() {
- return mConditions;
- }
-
- public List getSuggestions() {
- return mSuggestions;
- }
-
- public boolean hasSuggestion() {
- return sizeOf(mSuggestions) > 0;
- }
-
- public boolean isConditionExpanded() {
- return mConditionExpanded;
- }
-
- /**
- * Find the position of the object in mItems list, using the equals method to compare
- *
- * @param entity the object that need to be found in list
- * @return position of the object, return POSITION_NOT_FOUND if object isn't in the list
- */
- public int getPositionByEntity(Object entity) {
- if (entity == null) return POSITION_NOT_FOUND;
-
- final int size = mItems.size();
- for (int i = 0; i < size; i++) {
- final Object item = mItems.get(i).entity;
- if (entity.equals(item)) {
- return i;
- }
- }
-
- return POSITION_NOT_FOUND;
- }
-
- /**
- * Find the position of the Tile object.
- *
- * First, try to find the exact identical instance of the tile object, if not found,
- * then try to find a tile has the same title.
- *
- * @param tile tile that need to be found
- * @return position of the object, return INDEX_NOT_FOUND if object isn't in the list
- */
- public int getPositionByTile(Tile tile) {
- final int size = mItems.size();
- for (int i = 0; i < size; i++) {
- final Object entity = mItems.get(i).entity;
- if (entity == tile) {
- return i;
- } else if (entity instanceof Tile && tile.title.equals(((Tile) entity).title)) {
- return i;
- }
- }
-
- return POSITION_NOT_FOUND;
- }
-
- /**
- * Add item into list when {@paramref add} is true.
- *
- * @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
- */
- private void addToItemList(Object item, int type, int stableId, boolean add) {
- if (add) {
- mItems.add(new Item(item, type, stableId));
- }
- }
-
- /**
- * Build the mItems list using mConditions, mSuggestions, mCategories data
- * and mIsShowingAll, mConditionExpanded flag.
- */
- private void buildItemsData() {
- final List conditions = getConditionsToShow(mConditions);
- final boolean hasConditions = sizeOf(conditions) > 0;
-
- final List suggestions = getSuggestionsToShow(mSuggestions);
- final boolean hasSuggestions = sizeOf(suggestions) > 0;
-
- /* Suggestion container. This is the card view that contains the list of suggestions.
- * This will be added whenever the suggestion list is not empty */
- addToItemList(suggestions, R.layout.suggestion_container,
- STABLE_ID_SUGGESTION_CONTAINER, hasSuggestions);
-
- /* Divider between suggestion and conditions if both are present. */
- addToItemList(suggestions, R.layout.horizontal_divider,
- STABLE_ID_SUGGESTION_CONDITION_DIVIDER, hasSuggestions && hasConditions);
-
- /* Condition header. This will be present when there is condition and it is collapsed */
- addToItemList(new ConditionHeaderData(conditions),
- R.layout.suggestion_condition_header,
- STABLE_ID_CONDITION_HEADER, hasConditions && !mConditionExpanded);
-
- /* Condition container. This is the card view that contains the list of conditions.
- * This will be added whenever the condition list is not empty and expanded */
- addToItemList(conditions, R.layout.condition_container,
- STABLE_ID_CONDITION_CONTAINER, hasConditions && mConditionExpanded);
-
- /* Condition footer. This will be present when there is condition and it is expanded */
- addToItemList(null /* item */, R.layout.suggestion_condition_footer,
- STABLE_ID_CONDITION_FOOTER, hasConditions && mConditionExpanded);
-
- if (mCategory != null) {
- final List tiles = mCategory.getTiles();
- for (int i = 0; i < tiles.size(); i++) {
- final Tile tile = tiles.get(i);
- addToItemList(tile, R.layout.dashboard_tile, Objects.hash(tile.title),
- true /* add */);
- }
- }
- }
-
- private static int sizeOf(List> list) {
- return list == null ? 0 : list.size();
- }
-
- private List getConditionsToShow(List conditions) {
- if (conditions == null) {
- return null;
- }
- List result = new ArrayList<>();
- final int size = conditions == null ? 0 : conditions.size();
- for (int i = 0; i < size; i++) {
- final Condition condition = conditions.get(i);
- if (condition.shouldShow()) {
- result.add(condition);
- }
- }
- return result;
- }
-
- private List getSuggestionsToShow(List suggestions) {
- if (suggestions == null) {
- return null;
- }
- if (suggestions.size() <= MAX_SUGGESTION_COUNT) {
- return suggestions;
- }
- return suggestions.subList(0, MAX_SUGGESTION_COUNT);
- }
-
- /**
- * Builder used to build the ItemsData
- */
- public static class Builder {
- private DashboardCategory mCategory;
- private List mConditions;
- private List mSuggestions;
- private boolean mConditionExpanded;
-
- public Builder() {
- }
-
- public Builder(DashboardDataV2 dashboardData) {
- mCategory = dashboardData.mCategory;
- mConditions = dashboardData.mConditions;
- mSuggestions = dashboardData.mSuggestions;
- mConditionExpanded = dashboardData.mConditionExpanded;
- }
-
- public Builder setCategory(DashboardCategory category) {
- this.mCategory = category;
- return this;
- }
-
- public Builder setConditions(List conditions) {
- this.mConditions = conditions;
- return this;
- }
-
- public Builder setSuggestions(List suggestions) {
- this.mSuggestions = suggestions;
- return this;
- }
-
- public Builder setConditionExpanded(boolean expanded) {
- this.mConditionExpanded = expanded;
- return this;
- }
-
- public DashboardDataV2 build() {
- return new DashboardDataV2(this);
- }
- }
-
- /**
- * A DiffCallback to calculate the difference between old and new Item
- * List in DashboardDataV2
- */
- public static class ItemsDataDiffCallback extends DiffUtil.Callback {
- final private List- mOldItems;
- final private List
- mNewItems;
-
- public ItemsDataDiffCallback(List
- oldItems, List
- newItems) {
- mOldItems = oldItems;
- mNewItems = newItems;
- }
-
- @Override
- public int getOldListSize() {
- return mOldItems.size();
- }
-
- @Override
- public int getNewListSize() {
- return mNewItems.size();
- }
-
- @Override
- public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
- return mOldItems.get(oldItemPosition).id == mNewItems.get(newItemPosition).id;
- }
-
- @Override
- public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
- return mOldItems.get(oldItemPosition).equals(mNewItems.get(newItemPosition));
- }
-
- }
-
- /**
- * An item contains the data needed in the DashboardDataV2.
- */
- 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_CONTAINER =
- R.layout.suggestion_container;
- private static final int TYPE_CONDITION_CONTAINER =
- R.layout.condition_container;
- private static final int TYPE_CONDITION_HEADER =
- R.layout.suggestion_condition_header;
- private static final int TYPE_CONDITION_FOOTER =
- R.layout.suggestion_condition_footer;
- private static final int TYPE_SUGGESTION_CONDITION_DIVIDER = R.layout.horizontal_divider;
-
- @IntDef({TYPE_DASHBOARD_TILE, TYPE_SUGGESTION_CONTAINER, TYPE_CONDITION_CONTAINER,
- TYPE_CONDITION_HEADER, TYPE_CONDITION_FOOTER, TYPE_SUGGESTION_CONDITION_DIVIDER})
- @Retention(RetentionPolicy.SOURCE)
- public @interface ItemTypes {
- }
-
- /**
- * The main data object in item, usually is a {@link Tile}, {@link Condition}
- * object. This object can also be null when the
- * item is an divider line. Please refer to {@link #buildItemsData()} for
- * detail usage of the Item.
- */
- public final Object entity;
-
- /**
- * The type of item, value inside is the layout id(e.g. R.layout.dashboard_tile)
- */
- @ItemTypes
- public final int type;
-
- /**
- * Id of this item, used in the {@link ItemsDataDiffCallback} to identify the same item.
- */
- public final int id;
-
- public Item(Object entity, @ItemTypes int type, int id) {
- this.entity = entity;
- this.type = type;
- this.id = id;
- }
-
- /**
- * 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.
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (!(obj instanceof Item)) {
- return false;
- }
-
- final Item targetItem = (Item) obj;
- if (type != targetItem.type || id != targetItem.id) {
- return false;
- }
-
- switch (type) {
- case TYPE_DASHBOARD_TILE:
- final Tile localTile = (Tile) entity;
- final Tile targetTile = (Tile) targetItem.entity;
-
- // Only check title and summary for dashboard tile
- return TextUtils.equals(localTile.title, targetTile.title)
- && TextUtils.equals(localTile.summary, targetTile.summary);
- case TYPE_SUGGESTION_CONTAINER:
- case TYPE_CONDITION_CONTAINER:
- // If entity is suggestion and contains remote view, force refresh
- final List entities = (List) entity;
- if (!entities.isEmpty()) {
- Object firstEntity = entities.get(0);
- if (firstEntity instanceof Tile
- && ((Tile) firstEntity).remoteViews != null) {
- return false;
- }
- }
- // Otherwise Fall through to default
- default:
- return entity == null ? targetItem.entity == null
- : entity.equals(targetItem.entity);
- }
- }
- }
-
- /**
- * This class contains the data needed to build the suggestion/condition header. The data can
- * also be used to check the diff in DiffUtil.Callback
- */
- public static class ConditionHeaderData {
- public final List conditionIcons;
- public final CharSequence title;
- public final int conditionCount;
-
- public ConditionHeaderData(List conditions) {
- conditionCount = sizeOf(conditions);
- title = conditionCount > 0 ? conditions.get(0).getTitle() : null;
- conditionIcons = new ArrayList<>();
- for (int i = 0; conditions != null && i < conditions.size(); i++) {
- final Condition condition = conditions.get(i);
- conditionIcons.add(condition.getIcon());
- }
- }
- }
-
-}
\ No newline at end of file
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProvider.java b/src/com/android/settings/dashboard/DashboardFeatureProvider.java
index e0873f59a71..6c3f9cd219d 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProvider.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProvider.java
@@ -90,9 +90,4 @@ public interface DashboardFeatureProvider {
*/
void openTileIntent(Activity activity, Tile tile);
- /**
- * Whether or not we should use the v2 of suggestions UI.
- */
- boolean useSuggestionUiV2();
-
}
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index a14d9e9a76d..086a131a9c8 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -217,11 +217,6 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
launchIntentOrSelectProfile(activity, tile, intent, MetricsEvent.DASHBOARD_SUMMARY);
}
- @Override
- public boolean useSuggestionUiV2() {
- return FeatureFlagUtils.isEnabled(mContext, FeatureFlags.SUGGESTION_UI_V2);
- }
-
private void bindSummary(Preference preference, Tile tile) {
if (tile.summary != null) {
preference.setSummary(tile.summary);
diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java
index f86867b67de..4f045a28061 100644
--- a/src/com/android/settings/dashboard/DashboardSummary.java
+++ b/src/com/android/settings/dashboard/DashboardSummary.java
@@ -38,7 +38,6 @@ import com.android.settings.dashboard.conditional.ConditionManager;
import com.android.settings.dashboard.conditional.ConditionManager.ConditionListener;
import com.android.settings.dashboard.conditional.FocusRecyclerView;
import com.android.settings.dashboard.conditional.FocusRecyclerView.FocusListener;
-import com.android.settings.dashboard.suggestions.SuggestionDismissController;
import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.ActionBarShadowController;
@@ -53,8 +52,7 @@ import java.util.List;
public class DashboardSummary extends InstrumentedFragment
implements CategoryListener, ConditionListener,
- FocusListener, SuggestionDismissController.Callback,
- SuggestionControllerMixin.SuggestionControllerHost {
+ FocusListener, SuggestionControllerMixin.SuggestionControllerHost {
public static final boolean DEBUG = false;
private static final boolean DEBUG_TIMING = false;
private static final int MAX_WAIT_MILLIS = 700;
@@ -66,7 +64,6 @@ public class DashboardSummary extends InstrumentedFragment
private FocusRecyclerView mDashboard;
private DashboardAdapter mAdapter;
- private DashboardAdapterV2 mAdapterV2;
private SummaryLoader mSummaryLoader;
private ConditionManager mConditionManager;
private LinearLayoutManager mLayoutManager;
@@ -181,13 +178,10 @@ public class DashboardSummary extends InstrumentedFragment
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- if (mLayoutManager == null) return;
- outState.putInt(EXTRA_SCROLL_POSITION, mLayoutManager.findFirstVisibleItemPosition());
- if (!mDashboardFeatureProvider.useSuggestionUiV2()) {
- if (mAdapter != null) {
- mAdapter.onSaveInstanceState(outState);
- }
+ if (mLayoutManager == null) {
+ return;
}
+ outState.putInt(EXTRA_SCROLL_POSITION, mLayoutManager.findFirstVisibleItemPosition());
}
@Override
@@ -205,17 +199,10 @@ public class DashboardSummary extends InstrumentedFragment
mDashboard.setHasFixedSize(true);
mDashboard.setListener(this);
mDashboard.setItemAnimator(new DashboardItemAnimator());
- if (mDashboardFeatureProvider.useSuggestionUiV2()) {
- mAdapterV2 = new DashboardAdapterV2(getContext(), bundle,
- mConditionManager.getConditions(), mSuggestionControllerMixin, getLifecycle());
- mDashboard.setAdapter(mAdapterV2);
- mSummaryLoader.setSummaryConsumer(mAdapterV2);
- } else {
- mAdapter = new DashboardAdapter(getContext(), bundle, mConditionManager.getConditions(),
- mSuggestionControllerMixin, this /* SuggestionDismissController.Callback */);
- mDashboard.setAdapter(mAdapter);
- mSummaryLoader.setSummaryConsumer(mAdapter);
- }
+ mAdapter = new DashboardAdapter(getContext(), bundle,
+ mConditionManager.getConditions(), mSuggestionControllerMixin, getLifecycle());
+ mDashboard.setAdapter(mAdapter);
+ mSummaryLoader.setSummaryConsumer(mAdapter);
ActionBarShadowController.attachToRecyclerView(
getActivity().findViewById(R.id.search_bar_container), getLifecycle(), mDashboard);
rebuildUI();
@@ -254,11 +241,7 @@ public class DashboardSummary extends InstrumentedFragment
if (mOnConditionsChangedCalled) {
final boolean scrollToTop =
mLayoutManager.findFirstCompletelyVisibleItemPosition() <= 1;
- if (mDashboardFeatureProvider.useSuggestionUiV2()) {
- mAdapterV2.setConditions(mConditionManager.getConditions());
- } else {
- mAdapter.setConditions(mConditionManager.getConditions());
- }
+ mAdapter.setConditions(mConditionManager.getConditions());
if (scrollToTop) {
mDashboard.scrollToPosition(0);
}
@@ -267,37 +250,14 @@ public class DashboardSummary extends InstrumentedFragment
}
}
- @Override
- public Suggestion getSuggestionAt(int position) {
- if (mDashboardFeatureProvider.useSuggestionUiV2()) {
- return mAdapterV2.getSuggestion(position);
- } else {
- return mAdapter.getSuggestion(position);
- }
- }
-
- @Override
- public void onSuggestionDismissed(Suggestion suggestion) {
- mAdapter.onSuggestionDismissed(suggestion);
- }
-
@Override
public void onSuggestionReady(List suggestions) {
mStagingSuggestions = suggestions;
- if (mDashboardFeatureProvider.useSuggestionUiV2()) {
- mAdapterV2.setSuggestions(suggestions);
- if (mStagingCategory != null) {
- Log.d(TAG, "Category has loaded, setting category from suggestionReady");
- mHandler.removeCallbacksAndMessages(null);
- mAdapterV2.setCategory(mStagingCategory);
- }
- } else {
- mAdapter.setSuggestions(suggestions);
- if (mStagingCategory != null) {
- Log.d(TAG, "Category has loaded, setting category from suggestionReady");
- mHandler.removeCallbacksAndMessages(null);
- mAdapter.setCategory(mStagingCategory);
- }
+ mAdapter.setSuggestions(suggestions);
+ if (mStagingCategory != null) {
+ Log.d(TAG, "Category has loaded, setting category from suggestionReady");
+ mHandler.removeCallbacksAndMessages(null);
+ mAdapter.setCategory(mStagingCategory);
}
}
@@ -313,26 +273,14 @@ public class DashboardSummary extends InstrumentedFragment
if (mSuggestionControllerMixin.isSuggestionLoaded()) {
Log.d(TAG, "Suggestion has loaded, setting suggestion/category");
ThreadUtils.postOnMainThread(() -> {
- if (mDashboardFeatureProvider.useSuggestionUiV2()) {
- if (mStagingSuggestions != null) {
- mAdapterV2.setSuggestions(mStagingSuggestions);
- }
- mAdapterV2.setCategory(mStagingCategory);
- } else {
- if (mStagingSuggestions != null) {
- mAdapter.setSuggestions(mStagingSuggestions);
- }
- mAdapter.setCategory(mStagingCategory);
+ if (mStagingSuggestions != null) {
+ mAdapter.setSuggestions(mStagingSuggestions);
}
+ mAdapter.setCategory(mStagingCategory);
});
} else {
Log.d(TAG, "Suggestion NOT loaded, delaying setCategory by " + MAX_WAIT_MILLIS + "ms");
- if (mDashboardFeatureProvider.useSuggestionUiV2()) {
- mHandler.postDelayed(()
- -> mAdapterV2.setCategory(mStagingCategory), MAX_WAIT_MILLIS);
- } else {
- mHandler.postDelayed(() -> mAdapter.setCategory(mStagingCategory), MAX_WAIT_MILLIS);
- }
+ mHandler.postDelayed(() -> mAdapter.setCategory(mStagingCategory), MAX_WAIT_MILLIS);
}
}
}
diff --git a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
index d84aa7c9eac..a540b3f260a 100644
--- a/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
+++ b/src/com/android/settings/dashboard/conditional/ConditionAdapter.java
@@ -27,10 +27,7 @@ import android.widget.Button;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
-import com.android.settings.dashboard.DashboardAdapter;
import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
-import com.android.settings.dashboard.DashboardData;
-import com.android.settings.dashboard.DashboardData.HeaderMode;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.WirelessUtils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -44,7 +41,7 @@ public class ConditionAdapter extends RecyclerView.Adapter
private final Context mContext;
private final MetricsFeatureProvider mMetricsFeatureProvider;
private List mConditions;
- private @HeaderMode int mMode;
+ private boolean mExpanded;
private View.OnClickListener mConditionClickListener = new View.OnClickListener() {
@@ -84,10 +81,10 @@ public class ConditionAdapter extends RecyclerView.Adapter
}
};
- public ConditionAdapter(Context context, List conditions, @HeaderMode int mode) {
+ public ConditionAdapter(Context context, List conditions, boolean expanded) {
mContext = context;
mConditions = conditions;
- mMode = mode;
+ mExpanded = expanded;
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
setHasStableIds(true);
@@ -126,7 +123,7 @@ public class ConditionAdapter extends RecyclerView.Adapter
@Override
public int getItemCount() {
- if (mMode == DashboardData.HEADER_MODE_FULLY_EXPANDED) {
+ if (mExpanded) {
return mConditions.size();
}
return 0;
@@ -138,7 +135,7 @@ public class ConditionAdapter extends RecyclerView.Adapter
}
private void bindViews(final Condition condition,
- DashboardAdapter.DashboardItemHolder view, boolean isLastItem,
+ DashboardItemHolder view, boolean isLastItem,
View.OnClickListener onClickListener) {
if (condition instanceof AirplaneModeCondition) {
Log.d(TAG, "Airplane mode condition has been bound with "
diff --git a/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java b/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java
deleted file mode 100644
index 8db57f79678..00000000000
--- a/src/com/android/settings/dashboard/conditional/ConditionAdapterV2.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-package com.android.settings.dashboard.conditional;
-
-import android.content.Context;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.helper.ItemTouchHelper;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.WirelessUtils;
-import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-
-import java.util.List;
-import java.util.Objects;
-
-public class ConditionAdapterV2 extends RecyclerView.Adapter {
- public static final String TAG = "ConditionAdapter";
-
- private final Context mContext;
- private final MetricsFeatureProvider mMetricsFeatureProvider;
- private List mConditions;
- private boolean mExpanded;
-
- private View.OnClickListener mConditionClickListener = new View.OnClickListener() {
-
- @Override
- public void onClick(View v) {
- //TODO: get rid of setTag/getTag
- Condition condition = (Condition) v.getTag();
- mMetricsFeatureProvider.action(mContext,
- MetricsEvent.ACTION_SETTINGS_CONDITION_CLICK,
- condition.getMetricsConstant());
- condition.onPrimaryClick();
- }
- };
-
- @VisibleForTesting
- ItemTouchHelper.SimpleCallback mSwipeCallback = new ItemTouchHelper.SimpleCallback(0,
- ItemTouchHelper.START | ItemTouchHelper.END) {
- @Override
- public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
- RecyclerView.ViewHolder target) {
- return true;
- }
-
- @Override
- public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
- return viewHolder.getItemViewType() == R.layout.condition_tile
- ? super.getSwipeDirs(recyclerView, viewHolder) : 0;
- }
-
- @Override
- public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
- Object item = getItem(viewHolder.getItemId());
- // item can become null when running monkey
- if (item != null) {
- ((Condition) item).silence();
- }
- }
- };
-
- public ConditionAdapterV2(Context context, List conditions, boolean expanded) {
- mContext = context;
- mConditions = conditions;
- mExpanded = expanded;
- mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
-
- setHasStableIds(true);
- }
-
- public Object getItem(long itemId) {
- for (Condition condition : mConditions) {
- if (Objects.hash(condition.getTitle()) == itemId) {
- return condition;
- }
- }
- return null;
- }
-
- @Override
- public DashboardItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- return new DashboardItemHolder(LayoutInflater.from(parent.getContext()).inflate(
- viewType, parent, false));
- }
-
- @Override
- public void onBindViewHolder(DashboardItemHolder holder, int position) {
- bindViews(mConditions.get(position), holder,
- position == mConditions.size() - 1, mConditionClickListener);
- }
-
- @Override
- public long getItemId(int position) {
- return Objects.hash(mConditions.get(position).getTitle());
- }
-
- @Override
- public int getItemViewType(int position) {
- return R.layout.condition_tile;
- }
-
- @Override
- public int getItemCount() {
- if (mExpanded) {
- return mConditions.size();
- }
- return 0;
- }
-
- public void addDismissHandling(final RecyclerView recyclerView) {
- final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(mSwipeCallback);
- itemTouchHelper.attachToRecyclerView(recyclerView);
- }
-
- private void bindViews(final Condition condition,
- DashboardItemHolder view, boolean isLastItem,
- View.OnClickListener onClickListener) {
- if (condition instanceof AirplaneModeCondition) {
- Log.d(TAG, "Airplane mode condition has been bound with "
- + "isActive=" + condition.isActive() + ". Airplane mode is currently " +
- WirelessUtils.isAirplaneModeOn(condition.mManager.getContext()));
- }
- View card = view.itemView.findViewById(R.id.content);
- card.setTag(condition);
- card.setOnClickListener(onClickListener);
- view.icon.setImageIcon(condition.getIcon());
- view.title.setText(condition.getTitle());
-
- CharSequence[] actions = condition.getActions();
- final boolean hasButtons = actions.length > 0;
- setViewVisibility(view.itemView, R.id.buttonBar, hasButtons);
-
- view.summary.setText(condition.getSummary());
- for (int i = 0; i < 2; i++) {
- Button button = (Button) view.itemView.findViewById(i == 0
- ? R.id.first_action : R.id.second_action);
- if (actions.length > i) {
- button.setVisibility(View.VISIBLE);
- button.setText(actions[i]);
- final int index = i;
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Context context = v.getContext();
- FeatureFactory.getFactory(context).getMetricsFeatureProvider()
- .action(context, MetricsEvent.ACTION_SETTINGS_CONDITION_BUTTON,
- condition.getMetricsConstant());
- condition.onActionClick(index);
- }
- });
- } else {
- button.setVisibility(View.GONE);
- }
- }
- setViewVisibility(view.itemView, R.id.divider, !isLastItem);
- }
-
- private void setViewVisibility(View containerView, int viewId, boolean visible) {
- View view = containerView.findViewById(viewId);
- if (view != null) {
- view.setVisibility(visible ? View.VISIBLE : View.GONE);
- }
- }
-}
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
index d1d7db2107a..070e758e111 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java
@@ -17,6 +17,10 @@ package com.android.settings.dashboard.suggestions;
import android.app.PendingIntent;
import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
import android.service.settings.suggestions.Suggestion;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
@@ -24,37 +28,71 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder;
import com.android.settings.dashboard.DashboardAdapter.IconCache;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.Utils;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
import com.android.settingslib.suggestions.SuggestionControllerMixin;
+import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
-public class SuggestionAdapter extends RecyclerView.Adapter {
+public class SuggestionAdapter extends RecyclerView.Adapter implements
+ LifecycleObserver, OnSaveInstanceState {
public static final String TAG = "SuggestionAdapter";
+ private static final String STATE_SUGGESTIONS_SHOWN_LOGGED = "suggestions_shown_logged";
+ private static final String STATE_SUGGESTION_LIST = "suggestion_list";
+
private final Context mContext;
private final MetricsFeatureProvider mMetricsFeatureProvider;
- private final List mSuggestions;
private final IconCache mCache;
- private final List mSuggestionsShownLogged;
+ private final ArrayList mSuggestionsShownLogged;
+ private final SuggestionFeatureProvider mSuggestionFeatureProvider;
private final SuggestionControllerMixin mSuggestionControllerMixin;
+ private final Callback mCallback;
+ private final CardConfig mConfig;
+
+ private List mSuggestions;
+
+ public interface Callback {
+ /**
+ * Called when the close button of the suggestion card is clicked.
+ */
+ void onSuggestionClosed(Suggestion suggestion);
+ }
public SuggestionAdapter(Context context, SuggestionControllerMixin suggestionControllerMixin,
- List suggestions, List suggestionsShownLogged) {
+ Bundle savedInstanceState, Callback callback, Lifecycle lifecycle) {
mContext = context;
mSuggestionControllerMixin = suggestionControllerMixin;
- mSuggestions = suggestions;
- mSuggestionsShownLogged = suggestionsShownLogged;
mCache = new IconCache(context);
final FeatureFactory factory = FeatureFactory.getFactory(context);
mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
+ mSuggestionFeatureProvider = factory.getSuggestionFeatureProvider(context);
+ mCallback = callback;
+ if (savedInstanceState != null) {
+ mSuggestions = savedInstanceState.getParcelableArrayList(STATE_SUGGESTION_LIST);
+ mSuggestionsShownLogged = savedInstanceState.getStringArrayList(
+ STATE_SUGGESTIONS_SHOWN_LOGGED);
+ } else {
+ mSuggestionsShownLogged = new ArrayList<>();
+ }
+
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ mConfig = CardConfig.get(context);
setHasStableIds(true);
}
@@ -67,31 +105,49 @@ public class SuggestionAdapter extends RecyclerView.Adapter
@Override
public void onBindViewHolder(DashboardItemHolder holder, int position) {
- bindSuggestion(holder, position);
- }
-
- private void bindSuggestion(DashboardItemHolder holder, int position) {
final Suggestion suggestion = mSuggestions.get(position);
final String id = suggestion.getId();
+ final int suggestionCount = mSuggestions.size();
if (!mSuggestionsShownLogged.contains(id)) {
mMetricsFeatureProvider.action(
mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, id);
mSuggestionsShownLogged.add(id);
}
-
- holder.icon.setImageDrawable(mCache.getIcon(suggestion.getIcon()));
+ mConfig.setCardLayout(holder, suggestionCount, position);
+ final Icon icon = suggestion.getIcon();
+ final Drawable drawable = mCache.getIcon(icon);
+ if (drawable != null && TextUtils.equals(icon.getResPackage(), mContext.getPackageName())) {
+ drawable.setTint(Utils.getColorAccent(mContext));
+ }
+ holder.icon.setImageDrawable(drawable);
holder.title.setText(suggestion.getTitle());
- final CharSequence summary = suggestion.getSummary();
- if (!TextUtils.isEmpty(summary)) {
- holder.summary.setText(summary);
- holder.summary.setVisibility(View.VISIBLE);
+ holder.title.setSingleLine(suggestionCount == 1);
+
+ if (suggestionCount == 1) {
+ final CharSequence summary = suggestion.getSummary();
+ if (!TextUtils.isEmpty(summary)) {
+ holder.summary.setText(summary);
+ holder.summary.setVisibility(View.VISIBLE);
+ } else {
+ holder.summary.setVisibility(View.GONE);
+ }
} else {
+ // Do not show summary if there are more than 1 suggestions
holder.summary.setVisibility(View.GONE);
+ holder.title.setMaxLines(3);
}
- final View divider = holder.itemView.findViewById(R.id.divider);
- if (divider != null) {
- divider.setVisibility(position < mSuggestions.size() - 1 ? View.VISIBLE : View.GONE);
+
+ final ImageView closeButton = holder.itemView.findViewById(R.id.close_button);
+ if (closeButton != null) {
+ closeButton.setOnClickListener(v -> {
+ mSuggestionFeatureProvider.dismissSuggestion(
+ mContext, mSuggestionControllerMixin, suggestion);
+ if (mCallback != null) {
+ mCallback.onSuggestionClosed(suggestion);
+ }
+ });
}
+
View clickHandler = holder.itemView;
// If a view with @android:id/primary is defined, use that as the click handler
// instead.
@@ -144,7 +200,83 @@ public class SuggestionAdapter extends RecyclerView.Adapter
}
public void removeSuggestion(Suggestion suggestion) {
+ final int position = mSuggestions.indexOf(suggestion);
mSuggestions.remove(suggestion);
- notifyDataSetChanged();
+ notifyItemRemoved(position);
}
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ if (mSuggestions != null) {
+ outState.putParcelableArrayList(STATE_SUGGESTION_LIST,
+ new ArrayList<>(mSuggestions));
+ }
+ outState.putStringArrayList(STATE_SUGGESTIONS_SHOWN_LOGGED, mSuggestionsShownLogged);
+ }
+
+ public void setSuggestions(List suggestions) {
+ mSuggestions = suggestions;
+ }
+
+ public List getSuggestions() {
+ return mSuggestions;
+ }
+
+ private static class CardConfig {
+ // Card start/end margin
+ private final int mMarginInner;
+ private final int mMarginOuter;
+ // Card width for different numbers of cards
+ private final int mWidthSingleCard;
+ private final int mWidthTwoCards;
+ private final int mWidthMultipleCards;
+ // padding between icon and title
+ private final int mPaddingTitleTopSingleCard;
+ private final int mPaddingTitleTopMultipleCards;
+
+ private static CardConfig sConfig;
+
+ private CardConfig(Context context) {
+ final Resources res = context.getResources();
+ mMarginInner =
+ res.getDimensionPixelOffset(R.dimen.suggestion_card_inner_margin);
+ mMarginOuter =
+ res.getDimensionPixelOffset(R.dimen.suggestion_card_outer_margin);
+ mWidthSingleCard = res.getDimensionPixelOffset(R.dimen.suggestion_card_width_one_card);
+ mWidthTwoCards = res.getDimensionPixelOffset(R.dimen.suggestion_card_width_two_cards);
+ mWidthMultipleCards =
+ res.getDimensionPixelOffset(R.dimen.suggestion_card_width_multiple_cards);
+ mPaddingTitleTopSingleCard =
+ res.getDimensionPixelOffset(R.dimen.suggestion_card_title_padding_bottom_one_card);
+ mPaddingTitleTopMultipleCards = res.getDimensionPixelOffset(
+ R.dimen.suggestion_card_title_padding_bottom_multiple_cards);
+ }
+
+ public static CardConfig get(Context context) {
+ if (sConfig == null) {
+ sConfig = new CardConfig(context);
+ }
+ return sConfig;
+ }
+
+ private void setCardLayout(DashboardItemHolder holder, int suggestionCount,
+ int position) {
+ final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
+ suggestionCount == 1
+ ? mWidthSingleCard : suggestionCount == 2
+ ? mWidthTwoCards : mWidthMultipleCards,
+ LinearLayout.LayoutParams.WRAP_CONTENT);
+ if (suggestionCount == 1) {
+ params.setMarginStart(mMarginOuter);
+ params.setMarginEnd(mMarginOuter);
+ } else {
+ params.setMarginStart(
+ position == 0 ? mMarginOuter : mMarginInner);
+ params.setMarginEnd(position == suggestionCount - 1 ? mMarginOuter : 0);
+ }
+ holder.itemView.setLayoutParams(params);
+ }
+
+ }
+
}
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
deleted file mode 100644
index e29ca5fdac4..00000000000
--- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-package com.android.settings.dashboard.suggestions;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
-import android.os.Bundle;
-import android.service.settings.suggestions.Suggestion;
-import android.support.v7.widget.RecyclerView;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.dashboard.DashboardAdapterV2.DashboardItemHolder;
-import com.android.settings.dashboard.DashboardAdapterV2.IconCache;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.Utils;
-import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
-import com.android.settingslib.suggestions.SuggestionControllerMixin;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-public class SuggestionAdapterV2 extends RecyclerView.Adapter implements
- LifecycleObserver, OnSaveInstanceState {
- public static final String TAG = "SuggestionAdapterV2";
-
- private static final String STATE_SUGGESTIONS_SHOWN_LOGGED = "suggestions_shown_logged";
- private static final String STATE_SUGGESTION_LIST = "suggestion_list";
-
- private final Context mContext;
- private final MetricsFeatureProvider mMetricsFeatureProvider;
- private final IconCache mCache;
- private final ArrayList mSuggestionsShownLogged;
- private final SuggestionFeatureProvider mSuggestionFeatureProvider;
- private final SuggestionControllerMixin mSuggestionControllerMixin;
- private final Callback mCallback;
- private final CardConfig mConfig;
-
- private List mSuggestions;
-
- public interface Callback {
- /**
- * Called when the close button of the suggestion card is clicked.
- */
- void onSuggestionClosed(Suggestion suggestion);
- }
-
- public SuggestionAdapterV2(Context context, SuggestionControllerMixin suggestionControllerMixin,
- Bundle savedInstanceState, Callback callback, Lifecycle lifecycle) {
- mContext = context;
- mSuggestionControllerMixin = suggestionControllerMixin;
- mCache = new IconCache(context);
- final FeatureFactory factory = FeatureFactory.getFactory(context);
- mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
- mSuggestionFeatureProvider = factory.getSuggestionFeatureProvider(context);
- mCallback = callback;
- if (savedInstanceState != null) {
- mSuggestions = savedInstanceState.getParcelableArrayList(STATE_SUGGESTION_LIST);
- mSuggestionsShownLogged = savedInstanceState.getStringArrayList(
- STATE_SUGGESTIONS_SHOWN_LOGGED);
- } else {
- mSuggestionsShownLogged = new ArrayList<>();
- }
-
- if (lifecycle != null) {
- lifecycle.addObserver(this);
- }
- mConfig = CardConfig.get(context);
-
- setHasStableIds(true);
- }
-
- @Override
- public DashboardItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- return new DashboardItemHolder(LayoutInflater.from(parent.getContext()).inflate(
- viewType, parent, false));
- }
-
- @Override
- public void onBindViewHolder(DashboardItemHolder holder, int position) {
- final Suggestion suggestion = mSuggestions.get(position);
- final String id = suggestion.getId();
- final int suggestionCount = mSuggestions.size();
- if (!mSuggestionsShownLogged.contains(id)) {
- mMetricsFeatureProvider.action(
- mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, id);
- mSuggestionsShownLogged.add(id);
- }
- mConfig.setCardLayout(holder, suggestionCount, position);
- final Icon icon = suggestion.getIcon();
- final Drawable drawable = mCache.getIcon(icon);
- if (drawable != null && TextUtils.equals(icon.getResPackage(), mContext.getPackageName())) {
- drawable.setTint(Utils.getColorAccent(mContext));
- }
- holder.icon.setImageDrawable(drawable);
- holder.title.setText(suggestion.getTitle());
- holder.title.setSingleLine(suggestionCount == 1);
-
- if (suggestionCount == 1) {
- final CharSequence summary = suggestion.getSummary();
- if (!TextUtils.isEmpty(summary)) {
- holder.summary.setText(summary);
- holder.summary.setVisibility(View.VISIBLE);
- } else {
- holder.summary.setVisibility(View.GONE);
- }
- } else {
- // Do not show summary if there are more than 1 suggestions
- holder.summary.setVisibility(View.GONE);
- holder.title.setMaxLines(3);
- }
-
- final ImageView closeButton = holder.itemView.findViewById(R.id.close_button);
- if (closeButton != null) {
- closeButton.setOnClickListener(v -> {
- mSuggestionFeatureProvider.dismissSuggestion(
- mContext, mSuggestionControllerMixin, suggestion);
- if (mCallback != null) {
- mCallback.onSuggestionClosed(suggestion);
- }
- });
- }
-
- View clickHandler = holder.itemView;
- // If a view with @android:id/primary is defined, use that as the click handler
- // instead.
- final View primaryAction = holder.itemView.findViewById(android.R.id.primary);
- if (primaryAction != null) {
- clickHandler = primaryAction;
- }
- clickHandler.setOnClickListener(v -> {
- mMetricsFeatureProvider.action(mContext, MetricsEvent.ACTION_SETTINGS_SUGGESTION, id);
- try {
- suggestion.getPendingIntent().send();
- mSuggestionControllerMixin.launchSuggestion(suggestion);
- } catch (PendingIntent.CanceledException e) {
- Log.w(TAG, "Failed to start suggestion " + suggestion.getTitle());
- }
- });
- }
-
- @Override
- public long getItemId(int position) {
- return Objects.hash(mSuggestions.get(position).getId());
- }
-
- @Override
- public int getItemViewType(int position) {
- final Suggestion suggestion = getSuggestion(position);
- if ((suggestion.getFlags() & Suggestion.FLAG_HAS_BUTTON) != 0) {
- return R.layout.suggestion_tile_with_button_v2;
- } else {
- return R.layout.suggestion_tile_v2;
- }
- }
-
- @Override
- public int getItemCount() {
- return mSuggestions.size();
- }
-
- public Suggestion getSuggestion(int position) {
- final long itemId = getItemId(position);
- if (mSuggestions == null) {
- return null;
- }
- for (Suggestion suggestion : mSuggestions) {
- if (Objects.hash(suggestion.getId()) == itemId) {
- return suggestion;
- }
- }
- return null;
- }
-
- public void removeSuggestion(Suggestion suggestion) {
- final int position = mSuggestions.indexOf(suggestion);
- mSuggestions.remove(suggestion);
- notifyItemRemoved(position);
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- if (mSuggestions != null) {
- outState.putParcelableArrayList(STATE_SUGGESTION_LIST,
- new ArrayList<>(mSuggestions));
- }
- outState.putStringArrayList(STATE_SUGGESTIONS_SHOWN_LOGGED, mSuggestionsShownLogged);
- }
-
- public void setSuggestions(List suggestions) {
- mSuggestions = suggestions;
- }
-
- public List getSuggestions() {
- return mSuggestions;
- }
-
- private static class CardConfig {
- // Card start/end margin
- private final int mMarginInner;
- private final int mMarginOuter;
- // Card width for different numbers of cards
- private final int mWidthSingleCard;
- private final int mWidthTwoCards;
- private final int mWidthMultipleCards;
- // padding between icon and title
- private final int mPaddingTitleTopSingleCard;
- private final int mPaddingTitleTopMultipleCards;
-
- private static CardConfig sConfig;
-
- private CardConfig(Context context) {
- final Resources res = context.getResources();
- mMarginInner =
- res.getDimensionPixelOffset(R.dimen.suggestion_card_inner_margin);
- mMarginOuter =
- res.getDimensionPixelOffset(R.dimen.suggestion_card_outer_margin);
- mWidthSingleCard = res.getDimensionPixelOffset(R.dimen.suggestion_card_width_one_card);
- mWidthTwoCards = res.getDimensionPixelOffset(R.dimen.suggestion_card_width_two_cards);
- mWidthMultipleCards =
- res.getDimensionPixelOffset(R.dimen.suggestion_card_width_multiple_cards);
- mPaddingTitleTopSingleCard =
- res.getDimensionPixelOffset(R.dimen.suggestion_card_title_padding_bottom_one_card);
- mPaddingTitleTopMultipleCards = res.getDimensionPixelOffset(
- R.dimen.suggestion_card_title_padding_bottom_multiple_cards);
- }
-
- public static CardConfig get(Context context) {
- if (sConfig == null) {
- sConfig = new CardConfig(context);
- }
- return sConfig;
- }
-
- private void setCardLayout(DashboardItemHolder holder, int suggestionCount,
- int position) {
- final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
- suggestionCount == 1
- ? mWidthSingleCard : suggestionCount == 2
- ? mWidthTwoCards : mWidthMultipleCards,
- LinearLayout.LayoutParams.WRAP_CONTENT);
- if (suggestionCount == 1) {
- params.setMarginStart(mMarginOuter);
- params.setMarginEnd(mMarginOuter);
- } else {
- params.setMarginStart(
- position == 0 ? mMarginOuter : mMarginInner);
- params.setMarginEnd(position == suggestionCount - 1 ? mMarginOuter : 0);
- }
- holder.itemView.setLayoutParams(params);
- }
-
- }
-
-}
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java b/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java
deleted file mode 100644
index 6a8db892992..00000000000
--- a/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package com.android.settings.dashboard.suggestions;
-
-import android.content.Context;
-import android.service.settings.suggestions.Suggestion;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.helper.ItemTouchHelper;
-
-import com.android.settings.R;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.suggestions.SuggestionControllerMixin;
-
-/**
- * Deprecated as a close button is provided to dismiss the suggestion.
- */
-@Deprecated
-public class SuggestionDismissController extends ItemTouchHelper.SimpleCallback {
-
- public interface Callback {
- /**
- * Returns suggestion tile data from the callback
- */
- Suggestion getSuggestionAt(int position);
-
- /**
- * Called when a suggestion is dismissed.
- */
- void onSuggestionDismissed(Suggestion suggestion);
- }
-
- private final Context mContext;
- private final SuggestionFeatureProvider mSuggestionFeatureProvider;
- private final SuggestionControllerMixin mSuggestionMixin;
- private final Callback mCallback;
-
- public SuggestionDismissController(Context context, RecyclerView recyclerView,
- SuggestionControllerMixin suggestionMixin, Callback callback) {
- super(0, ItemTouchHelper.START | ItemTouchHelper.END);
- mSuggestionMixin = suggestionMixin;
- mContext = context;
- mSuggestionFeatureProvider = FeatureFactory.getFactory(context)
- .getSuggestionFeatureProvider(context);
- mCallback = callback;
- final ItemTouchHelper itemTouchHelper = new ItemTouchHelper(this);
- itemTouchHelper.attachToRecyclerView(recyclerView);
- }
-
- @Override
- public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
- RecyclerView.ViewHolder target) {
- return true;
- }
-
- @Override
- public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
- final int layoutId = viewHolder.getItemViewType();
- if (layoutId == R.layout.suggestion_tile
- || layoutId == R.layout.suggestion_tile_with_button) {
- // Only return swipe direction for suggestion tiles. All other types are not swipeable.
- return super.getSwipeDirs(recyclerView, viewHolder);
- }
- return 0;
- }
-
- @Override
- public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
- if (mCallback == null) {
- return;
- }
- final int position = viewHolder.getAdapterPosition();
- final Suggestion suggestionV2 = mCallback.getSuggestionAt(position);
- mSuggestionFeatureProvider.dismissSuggestion(mContext, mSuggestionMixin, suggestionV2);
- mCallback.onSuggestionDismissed(suggestionV2);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
index f9ef424e335..2d22e04fd51 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -16,10 +16,8 @@
package com.android.settings.dashboard;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -30,14 +28,14 @@ import static org.mockito.Mockito.when;
import android.app.PendingIntent;
import android.content.Context;
import android.content.res.Resources;
-import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.service.settings.suggestions.Suggestion;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
-import android.widget.RelativeLayout;
+import android.widget.TextView;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
@@ -47,7 +45,6 @@ import com.android.settings.dashboard.suggestions.SuggestionAdapter;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
import org.junit.Before;
@@ -58,6 +55,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
@@ -81,8 +79,6 @@ public class DashboardAdapterTest {
private Resources mResources;
private FakeFeatureFactory mFactory;
private DashboardAdapter mDashboardAdapter;
- private DashboardAdapter.SuggestionAndConditionHeaderHolder mSuggestionHolder;
- private DashboardData.SuggestionConditionHeaderData mSuggestionHeaderData;
private List mConditionList;
@Before
@@ -98,30 +94,17 @@ public class DashboardAdapterTest {
mConditionList = new ArrayList<>();
mConditionList.add(mCondition);
when(mCondition.shouldShow()).thenReturn(true);
- mDashboardAdapter = new DashboardAdapter(mContext, null, mConditionList, null, null);
- mSuggestionHeaderData = new DashboardData.SuggestionConditionHeaderData(mConditionList, 1);
+ mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
+ mConditionList, null /* suggestionControllerMixin */, null /* lifecycle */);
when(mView.getTag()).thenReturn(mCondition);
}
- @Test
- public void testSuggestionsLogs_nullSuggestionsList_shouldNotCrash() {
- setupSuggestions(makeSuggestionsV2("pkg1", "pkg2", "pkg3", "pkg4", "pkg5"));
- mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData);
-
- // set suggestions to null
- final DashboardData prevData = mDashboardAdapter.mDashboardData;
- mDashboardAdapter.mDashboardData = new DashboardData.Builder(prevData)
- .setSuggestions(null)
- .build();
-
- mSuggestionHolder.itemView.callOnClick();
- // no crash
- }
-
@Test
public void testSuggestionDismissed_notOnlySuggestion_updateSuggestionOnly() {
final DashboardAdapter adapter =
- spy(new DashboardAdapter(mContext, null, null, null, null));
+ spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
+ null /* conditions */, null /* suggestionControllerMixin */, null /*
+ lifecycle */));
final List suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3");
adapter.setSuggestions(suggestions);
@@ -130,18 +113,18 @@ public class DashboardAdapterTest {
when(data.getContext()).thenReturn(mContext);
when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
final View itemView = mock(View.class);
- when(itemView.findViewById(R.id.data)).thenReturn(data);
- final DashboardAdapter.SuggestionAndConditionContainerHolder holder =
- new DashboardAdapter.SuggestionAndConditionContainerHolder(itemView);
+ when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
+ when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
+ final DashboardAdapter.SuggestionContainerHolder holder =
+ new DashboardAdapter.SuggestionContainerHolder(itemView);
- adapter.onBindConditionAndSuggestion(
- holder, DashboardAdapter.SUGGESTION_CONDITION_HEADER_POSITION);
+ adapter.onBindSuggestion(holder, 0);
final DashboardData dashboardData = adapter.mDashboardData;
reset(adapter); // clear interactions tracking
final Suggestion suggestionToRemove = suggestions.get(1);
- adapter.onSuggestionDismissed(suggestionToRemove);
+ adapter.onSuggestionClosed(suggestionToRemove);
assertThat(adapter.mDashboardData).isEqualTo(dashboardData);
assertThat(suggestions.size()).isEqualTo(2);
@@ -150,25 +133,25 @@ public class DashboardAdapterTest {
}
@Test
- public void testSuggestionDismissed_moreThanTwoSuggestions_defaultMode_shouldNotCrash() {
+ public void testSuggestionDismissed_moreThanTwoSuggestions_shouldNotCrash() {
final RecyclerView data = new RecyclerView(RuntimeEnvironment.application);
final View itemView = mock(View.class);
- when(itemView.findViewById(R.id.data)).thenReturn(data);
- final DashboardAdapter.SuggestionAndConditionContainerHolder holder =
- new DashboardAdapter.SuggestionAndConditionContainerHolder(itemView);
+ when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
+ when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
+ final DashboardAdapter.SuggestionContainerHolder holder =
+ new DashboardAdapter.SuggestionContainerHolder(itemView);
final List suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3", "pkg4");
- final DashboardAdapter adapter = spy(new DashboardAdapter(mContext, null /*savedInstance */,
- null /* conditions */,
- null /* suggestionControllerMixin */, null /* callback */));
+ final DashboardAdapter adapter = spy(new DashboardAdapter(mContext,
+ null /*savedInstance */, null /* conditions */,
+ null /* suggestionControllerMixin */,
+ null /* lifecycle */));
adapter.setSuggestions(suggestions);
- adapter.onBindConditionAndSuggestion(
- holder, DashboardAdapter.SUGGESTION_CONDITION_HEADER_POSITION);
- // default mode, only displaying 2 suggestions
+ adapter.onBindSuggestion(holder, 0);
- adapter.onSuggestionDismissed(suggestions.get(1));
+ adapter.onSuggestionClosed(suggestions.get(1));
// verify operations that access the lists will not cause ConcurrentModificationException
- assertThat(holder.data.getAdapter().getItemCount()).isEqualTo(1);
+ assertThat(holder.data.getAdapter().getItemCount()).isEqualTo(3);
adapter.setSuggestions(suggestions);
// should not crash
}
@@ -176,42 +159,25 @@ public class DashboardAdapterTest {
@Test
public void testSuggestionDismissed_onlySuggestion_updateDashboardData() {
DashboardAdapter adapter =
- spy(new DashboardAdapter(mContext, null, null, null, null));
+ spy(new DashboardAdapter(mContext, null /* savedInstanceState */,
+ null /* conditions */, null /* suggestionControllerMixin */, null /*
+ lifecycle */));
final List suggestions = makeSuggestionsV2("pkg1");
adapter.setSuggestions(suggestions);
final DashboardData dashboardData = adapter.mDashboardData;
reset(adapter); // clear interactions tracking
- adapter.onSuggestionDismissed(suggestions.get(0));
+ adapter.onSuggestionClosed(suggestions.get(0));
assertThat(adapter.mDashboardData).isNotEqualTo(dashboardData);
verify(adapter).notifyDashboardDataChanged(any());
}
@Test
- public void testSetCategories_iconTinted() {
- TypedArray mockTypedArray = mock(TypedArray.class);
- doReturn(mockTypedArray).when(mContext).obtainStyledAttributes(any(int[].class));
- doReturn(0x89000000).when(mockTypedArray).getColor(anyInt(), anyInt());
-
- final DashboardCategory category = new DashboardCategory();
- final Icon mockIcon = mock(Icon.class);
- final Tile tile = new Tile();
- tile.isIconTintable = true;
- tile.icon = mockIcon;
- category.addTile(tile);
-
- mDashboardAdapter.setCategory(category);
-
- verify(mockIcon).setTint(eq(0x89000000));
- }
-
- @Test
- public void testBindConditionAndSuggestion_v2_shouldSetSuggestionAdapterAndNoCrash() {
- mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null);
+ public void testBindSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
+ mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
+ null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
final List suggestions = makeSuggestionsV2("pkg1");
- final DashboardCategory category = new DashboardCategory();
- category.addTile(mock(Tile.class));
mDashboardAdapter.setSuggestions(suggestions);
@@ -220,17 +186,88 @@ public class DashboardAdapterTest {
when(data.getContext()).thenReturn(mContext);
when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
final View itemView = mock(View.class);
- when(itemView.findViewById(R.id.data)).thenReturn(data);
- final DashboardAdapter.SuggestionAndConditionContainerHolder holder =
- new DashboardAdapter.SuggestionAndConditionContainerHolder(itemView);
+ when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
+ when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
+ final DashboardAdapter.SuggestionContainerHolder holder =
+ new DashboardAdapter.SuggestionContainerHolder(itemView);
- mDashboardAdapter.onBindConditionAndSuggestion(
- holder, DashboardAdapter.SUGGESTION_CONDITION_HEADER_POSITION);
+ mDashboardAdapter.onBindSuggestion(holder, 0);
verify(data).setAdapter(any(SuggestionAdapter.class));
// should not crash
}
+ @Test
+ public void testBindSuggestion_shouldSetSummary() {
+ mDashboardAdapter = new DashboardAdapter(mContext, null /* savedInstanceState */,
+ null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
+ final List suggestions = makeSuggestionsV2("pkg1");
+
+ mDashboardAdapter.setSuggestions(suggestions);
+
+ final RecyclerView data = mock(RecyclerView.class);
+ when(data.getResources()).thenReturn(mResources);
+ when(data.getContext()).thenReturn(mContext);
+ when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
+ final View itemView = mock(View.class);
+ when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
+ final TextView summary = mock(TextView.class);
+ when(itemView.findViewById(android.R.id.summary)).thenReturn(summary);
+ final DashboardAdapter.SuggestionContainerHolder holder =
+ new DashboardAdapter.SuggestionContainerHolder(itemView);
+
+ mDashboardAdapter.onBindSuggestion(holder, 0);
+
+ verify(summary).setText("1");
+
+ suggestions.addAll(makeSuggestionsV2("pkg2", "pkg3", "pkg4"));
+ mDashboardAdapter.setSuggestions(suggestions);
+
+ mDashboardAdapter.onBindSuggestion(holder, 0);
+
+ verify(summary).setText("4");
+ }
+
+ @Test
+ public void onBindTile_internalTile_shouldNotUseGenericBackgroundIcon() {
+ final Context context = RuntimeEnvironment.application;
+ final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
+ final DashboardAdapter.DashboardItemHolder holder =
+ new DashboardAdapter.DashboardItemHolder(view);
+ final Tile tile = new Tile();
+ tile.icon = Icon.createWithResource(context, R.drawable.ic_settings);
+ final DashboardAdapter.IconCache iconCache = mock(DashboardAdapter.IconCache.class);
+ when(iconCache.getIcon(tile.icon)).thenReturn(context.getDrawable(R.drawable.ic_settings));
+
+ mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
+ null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
+ ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
+ mDashboardAdapter.onBindTile(holder, tile);
+
+ verify(iconCache, never()).updateIcon(any(Icon.class), any(Drawable.class));
+ }
+
+ @Test
+ public void onBindTile_externalTile_shouldNotUseGenericBackgroundIcon() {
+ final Context context = RuntimeEnvironment.application;
+ final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
+ final DashboardAdapter.DashboardItemHolder holder =
+ new DashboardAdapter.DashboardItemHolder(view);
+ final Tile tile = new Tile();
+ tile.icon = mock(Icon.class);
+ when(tile.icon.getResPackage()).thenReturn("another.package");
+
+ final DashboardAdapter.IconCache iconCache = mock(DashboardAdapter.IconCache.class);
+ when(iconCache.getIcon(tile.icon)).thenReturn(context.getDrawable(R.drawable.ic_settings));
+
+ mDashboardAdapter = new DashboardAdapter(context, null /* savedInstanceState */,
+ null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
+ ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
+ mDashboardAdapter.onBindTile(holder, tile);
+
+ verify(iconCache).updateIcon(eq(tile.icon), any(RoundedHomepageIcon.class));
+ }
+
private List makeSuggestionsV2(String... pkgNames) {
final List suggestions = new ArrayList<>();
for (String pkgName : pkgNames) {
@@ -245,8 +282,5 @@ public class DashboardAdapterTest {
private void setupSuggestions(List suggestions) {
final Context context = RuntimeEnvironment.application;
mDashboardAdapter.setSuggestions(suggestions);
- mSuggestionHolder = new DashboardAdapter.SuggestionAndConditionHeaderHolder(
- LayoutInflater.from(context).inflate(
- R.layout.suggestion_condition_header, new RelativeLayout(context), true));
}
}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterV2Test.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterV2Test.java
deleted file mode 100644
index 40150cbffc0..00000000000
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterV2Test.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-package com.android.settings.dashboard;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
-import android.service.settings.suggestions.Suggestion;
-import android.support.v7.widget.RecyclerView;
-import android.util.DisplayMetrics;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextView;
-
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.TestConfig;
-import com.android.settings.dashboard.conditional.Condition;
-import com.android.settings.dashboard.suggestions.SuggestionAdapterV2;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settingslib.drawer.Tile;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.util.ReflectionHelpers;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH,
- sdk = TestConfig.SDK_VERSION,
- shadows = {
- SettingsShadowResources.class,
- SettingsShadowResources.SettingsShadowTheme.class,
- })
-public class DashboardAdapterV2Test {
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private SettingsActivity mContext;
- @Mock
- private View mView;
- @Mock
- private Condition mCondition;
- @Mock
- private Resources mResources;
- private FakeFeatureFactory mFactory;
- private DashboardAdapterV2 mDashboardAdapter;
- private List mConditionList;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mFactory = FakeFeatureFactory.setupForTest();
- when(mFactory.dashboardFeatureProvider.shouldTintIcon()).thenReturn(true);
-
- when(mContext.getResources()).thenReturn(mResources);
- when(mResources.getQuantityString(any(int.class), any(int.class), any()))
- .thenReturn("");
-
- mConditionList = new ArrayList<>();
- mConditionList.add(mCondition);
- when(mCondition.shouldShow()).thenReturn(true);
- mDashboardAdapter = new DashboardAdapterV2(mContext, null /* savedInstanceState */,
- mConditionList, null /* suggestionControllerMixin */, null /* lifecycle */);
- when(mView.getTag()).thenReturn(mCondition);
- }
-
- @Test
- public void testSuggestionDismissed_notOnlySuggestion_updateSuggestionOnly() {
- final DashboardAdapterV2 adapter =
- spy(new DashboardAdapterV2(mContext, null /* savedInstanceState */,
- null /* conditions */, null /* suggestionControllerMixin */, null /*
- lifecycle */));
- final List suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3");
- adapter.setSuggestions(suggestions);
-
- final RecyclerView data = mock(RecyclerView.class);
- when(data.getResources()).thenReturn(mResources);
- when(data.getContext()).thenReturn(mContext);
- when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
- final View itemView = mock(View.class);
- when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
- when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
- final DashboardAdapterV2.SuggestionContainerHolder holder =
- new DashboardAdapterV2.SuggestionContainerHolder(itemView);
-
- adapter.onBindSuggestion(holder, 0);
-
- final DashboardDataV2 dashboardData = adapter.mDashboardData;
- reset(adapter); // clear interactions tracking
-
- final Suggestion suggestionToRemove = suggestions.get(1);
- adapter.onSuggestionClosed(suggestionToRemove);
-
- assertThat(adapter.mDashboardData).isEqualTo(dashboardData);
- assertThat(suggestions.size()).isEqualTo(2);
- assertThat(suggestions.contains(suggestionToRemove)).isFalse();
- verify(adapter, never()).notifyDashboardDataChanged(any());
- }
-
- @Test
- public void testSuggestionDismissed_moreThanTwoSuggestions_shouldNotCrash() {
- final RecyclerView data = new RecyclerView(RuntimeEnvironment.application);
- final View itemView = mock(View.class);
- when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
- when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
- final DashboardAdapterV2.SuggestionContainerHolder holder =
- new DashboardAdapterV2.SuggestionContainerHolder(itemView);
- final List suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3", "pkg4");
- final DashboardAdapterV2 adapter = spy(new DashboardAdapterV2(mContext,
- null /*savedInstance */, null /* conditions */,
- null /* suggestionControllerMixin */,
- null /* lifecycle */));
- adapter.setSuggestions(suggestions);
- adapter.onBindSuggestion(holder, 0);
-
- adapter.onSuggestionClosed(suggestions.get(1));
-
- // verify operations that access the lists will not cause ConcurrentModificationException
- assertThat(holder.data.getAdapter().getItemCount()).isEqualTo(3);
- adapter.setSuggestions(suggestions);
- // should not crash
- }
-
- @Test
- public void testSuggestionDismissed_onlySuggestion_updateDashboardData() {
- DashboardAdapterV2 adapter =
- spy(new DashboardAdapterV2(mContext, null /* savedInstanceState */,
- null /* conditions */, null /* suggestionControllerMixin */, null /*
- lifecycle */));
- final List suggestions = makeSuggestionsV2("pkg1");
- adapter.setSuggestions(suggestions);
- final DashboardDataV2 dashboardData = adapter.mDashboardData;
- reset(adapter); // clear interactions tracking
-
- adapter.onSuggestionClosed(suggestions.get(0));
-
- assertThat(adapter.mDashboardData).isNotEqualTo(dashboardData);
- verify(adapter).notifyDashboardDataChanged(any());
- }
-
- @Test
- public void testBindSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
- mDashboardAdapter = new DashboardAdapterV2(mContext, null /* savedInstanceState */,
- null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
- final List suggestions = makeSuggestionsV2("pkg1");
-
- mDashboardAdapter.setSuggestions(suggestions);
-
- final RecyclerView data = mock(RecyclerView.class);
- when(data.getResources()).thenReturn(mResources);
- when(data.getContext()).thenReturn(mContext);
- when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
- final View itemView = mock(View.class);
- when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
- when(itemView.findViewById(android.R.id.summary)).thenReturn(mock(TextView.class));
- final DashboardAdapterV2.SuggestionContainerHolder holder =
- new DashboardAdapterV2.SuggestionContainerHolder(itemView);
-
- mDashboardAdapter.onBindSuggestion(holder, 0);
-
- verify(data).setAdapter(any(SuggestionAdapterV2.class));
- // should not crash
- }
-
- @Test
- public void testBindSuggestion_shouldSetSummary() {
- mDashboardAdapter = new DashboardAdapterV2(mContext, null /* savedInstanceState */,
- null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
- final List suggestions = makeSuggestionsV2("pkg1");
-
- mDashboardAdapter.setSuggestions(suggestions);
-
- final RecyclerView data = mock(RecyclerView.class);
- when(data.getResources()).thenReturn(mResources);
- when(data.getContext()).thenReturn(mContext);
- when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
- final View itemView = mock(View.class);
- when(itemView.findViewById(R.id.suggestion_list)).thenReturn(data);
- final TextView summary = mock(TextView.class);
- when(itemView.findViewById(android.R.id.summary)).thenReturn(summary);
- final DashboardAdapterV2.SuggestionContainerHolder holder =
- new DashboardAdapterV2.SuggestionContainerHolder(itemView);
-
- mDashboardAdapter.onBindSuggestion(holder, 0);
-
- verify(summary).setText("1");
-
- suggestions.addAll(makeSuggestionsV2("pkg2", "pkg3", "pkg4"));
- mDashboardAdapter.setSuggestions(suggestions);
-
- mDashboardAdapter.onBindSuggestion(holder, 0);
-
- verify(summary).setText("4");
- }
-
- @Test
- public void onBindTile_internalTile_shouldNotUseGenericBackgroundIcon() {
- final Context context = RuntimeEnvironment.application;
- final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
- final DashboardAdapterV2.DashboardItemHolder holder =
- new DashboardAdapterV2.DashboardItemHolder(view);
- final Tile tile = new Tile();
- tile.icon = Icon.createWithResource(context, R.drawable.ic_settings);
- final DashboardAdapterV2.IconCache iconCache = mock(DashboardAdapterV2.IconCache.class);
- when(iconCache.getIcon(tile.icon)).thenReturn(context.getDrawable(R.drawable.ic_settings));
-
- mDashboardAdapter = new DashboardAdapterV2(context, null /* savedInstanceState */,
- null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
- ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
- mDashboardAdapter.onBindTile(holder, tile);
-
- verify(iconCache, never()).updateIcon(any(Icon.class), any(Drawable.class));
- }
-
- @Test
- public void onBindTile_externalTile_shouldNotUseGenericBackgroundIcon() {
- final Context context = RuntimeEnvironment.application;
- final View view = LayoutInflater.from(context).inflate(R.layout.dashboard_tile, null);
- final DashboardAdapterV2.DashboardItemHolder holder =
- new DashboardAdapterV2.DashboardItemHolder(view);
- final Tile tile = new Tile();
- tile.icon = mock(Icon.class);
- when(tile.icon.getResPackage()).thenReturn("another.package");
-
- final DashboardAdapterV2.IconCache iconCache = mock(DashboardAdapterV2.IconCache.class);
- when(iconCache.getIcon(tile.icon)).thenReturn(context.getDrawable(R.drawable.ic_settings));
-
- mDashboardAdapter = new DashboardAdapterV2(context, null /* savedInstanceState */,
- null /* conditions */, null /* suggestionControllerMixin */, null /* lifecycle */);
- ReflectionHelpers.setField(mDashboardAdapter, "mCache", iconCache);
- mDashboardAdapter.onBindTile(holder, tile);
-
- verify(iconCache).updateIcon(eq(tile.icon), any(RoundedHomepageIcon.class));
- }
-
- private List makeSuggestionsV2(String... pkgNames) {
- final List suggestions = new ArrayList<>();
- for (String pkgName : pkgNames) {
- final Suggestion suggestion = new Suggestion.Builder(pkgName)
- .setPendingIntent(mock(PendingIntent.class))
- .build();
- suggestions.add(suggestion);
- }
- return suggestions;
- }
-
- private void setupSuggestions(List suggestions) {
- final Context context = RuntimeEnvironment.application;
- mDashboardAdapter.setSuggestions(suggestions);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
index 1116d7d8d47..35f525e7214 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java
@@ -17,8 +17,9 @@
package com.android.settings.dashboard;
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_CONDITION_FOOTER;
import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONTAINER;
+import static com.android.settings.dashboard.DashboardData.STABLE_ID_SUGGESTION_CONDITION_DIVIDER;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -103,14 +104,14 @@ public class DashboardDataTest {
.setConditions(oneItemConditions)
.setCategory(mDashboardCategory)
.setSuggestions(suggestions)
- .setSuggestionConditionMode(DashboardData.HEADER_MODE_FULLY_EXPANDED)
+ .setConditionExpanded(true)
.build();
mDashboardDataWithTwoConditions = new DashboardData.Builder()
.setConditions(twoItemsConditions)
.setCategory(mDashboardCategory)
.setSuggestions(suggestions)
- .setSuggestionConditionMode(DashboardData.HEADER_MODE_FULLY_EXPANDED)
+ .setConditionExpanded(true)
.build();
mDashboardDataWithNoItems = new DashboardData.Builder()
@@ -124,21 +125,23 @@ public class DashboardDataTest {
public void testBuildItemsData_shouldSetstableId() {
final List items = mDashboardDataWithOneConditions.getItemList();
- // Header, suggestion, condition, footer, 1 tile
- assertThat(items).hasSize(4);
+ // suggestion, seperator, condition, footer, 1 tile
+ assertThat(items).hasSize(5);
assertThat(items.get(0).id).isEqualTo(STABLE_ID_SUGGESTION_CONTAINER);
- assertThat(items.get(1).id).isEqualTo(STABLE_ID_CONDITION_CONTAINER);
- assertThat(items.get(2).id).isEqualTo(STABLE_ID_SUGGESTION_CONDITION_FOOTER);
- assertThat(items.get(3).id).isEqualTo(Objects.hash(mTestCategoryTile.title));
+ assertThat(items.get(1).id).isEqualTo(STABLE_ID_SUGGESTION_CONDITION_DIVIDER);
+ assertThat(items.get(2).id).isEqualTo(STABLE_ID_CONDITION_CONTAINER);
+ assertThat(items.get(3).id).isEqualTo(STABLE_ID_CONDITION_FOOTER);
+ assertThat(items.get(4).id).isEqualTo(Objects.hash(mTestCategoryTile.title));
}
@Test
public void testBuildItemsData_containsAllData() {
final Object[] expectedObjects = {
mDashboardDataWithOneConditions.getSuggestions(),
+ null /* divider */,
mDashboardDataWithOneConditions.getConditions(),
- null, mTestCategoryTile};
+ null /* footer */, mTestCategoryTile};
final int expectedSize = expectedObjects.length;
assertThat(mDashboardDataWithOneConditions.getItemList()).hasSize(expectedSize);
@@ -147,14 +150,13 @@ public class DashboardDataTest {
final Object item = mDashboardDataWithOneConditions.getItemEntityByPosition(i);
if (item instanceof List) {
assertThat(item).isEqualTo(expectedObjects[i]);
- } else if (item instanceof DashboardData.SuggestionConditionHeaderData) {
- DashboardData.SuggestionConditionHeaderData i1 =
- (DashboardData.SuggestionConditionHeaderData) item;
- DashboardData.SuggestionConditionHeaderData i2 =
- (DashboardData.SuggestionConditionHeaderData) expectedObjects[i];
+ } else if (item instanceof DashboardData.ConditionHeaderData) {
+ DashboardData.ConditionHeaderData i1 =
+ (DashboardData.ConditionHeaderData) item;
+ DashboardData.ConditionHeaderData i2 =
+ (DashboardData.ConditionHeaderData) expectedObjects[i];
assertThat(i1.title).isEqualTo(i2.title);
assertThat(i1.conditionCount).isEqualTo(i2.conditionCount);
- assertThat(i1.hiddenSuggestionCount).isEqualTo(i2.hiddenSuggestionCount);
} else {
assertThat(item).isSameAs(expectedObjects[i]);
}
@@ -209,10 +211,10 @@ public class DashboardDataTest {
public void testDiffUtil_InsertOneCondition_ResultDataOneChanged() {
//Build testResultData
final List testResultData = new ArrayList<>();
- // Item in position 2 is the condition container containing the list of conditions, which
+ // Item in position 3 is the condition container containing the list of conditions, which
// gets 1 more item
testResultData.add(new ListUpdateResult.ResultData(
- ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 1, 1));
+ ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 2, 1));
testDiffUtil(mDashboardDataWithOneConditions,
mDashboardDataWithTwoConditions, testResultData);
@@ -222,10 +224,11 @@ public class DashboardDataTest {
public void testDiffUtil_RemoveOneSuggestion_causeItemRemoveAndChange() {
//Build testResultData
final List testResultData = new ArrayList<>();
+ // removed suggestion and the divider
testResultData.add(new ListUpdateResult.ResultData(
- ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 0, 1));
+ ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 0, 2));
testResultData.add(new ListUpdateResult.ResultData(
- ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 1, 1));
+ ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 2, 1));
// Build DashboardData
final List oneItemConditions = new ArrayList<>();
when(mTestCondition.shouldShow()).thenReturn(true);
@@ -237,13 +240,13 @@ public class DashboardDataTest {
.setConditions(oneItemConditions)
.setCategory(mDashboardCategory)
.setSuggestions(suggestions)
- .setSuggestionConditionMode(DashboardData.HEADER_MODE_DEFAULT)
+ .setConditionExpanded(false)
.build();
final DashboardData newData = new DashboardData.Builder()
.setConditions(oneItemConditions)
.setSuggestions(null)
.setCategory(mDashboardCategory)
- .setSuggestionConditionMode(DashboardData.HEADER_MODE_DEFAULT)
+ .setConditionExpanded(false)
.build();
testDiffUtil(oldData, newData, testResultData);
@@ -254,7 +257,7 @@ public class DashboardDataTest {
//Build testResultData
final List testResultData = new ArrayList<>();
testResultData.add(new ListUpdateResult.ResultData(
- ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 0, 4));
+ ListUpdateResult.ResultData.TYPE_OPERATION_REMOVE, 0, 5));
testDiffUtil(mDashboardDataWithOneConditions, mDashboardDataWithNoItems, testResultData);
}
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java
index 2a7b829c17e..a1c8d67e034 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java
@@ -164,10 +164,4 @@ public class DashboardSummaryTest {
mSummary.onCategoriesChanged();
verify(mSummary).rebuildUI();
}
-
- @Test
- public void onSuggestionDismissed_shouldNotRebuildUI() {
- mSummary.onSuggestionDismissed(mock(Suggestion.class));
- verify(mSummary, never()).rebuildUI();
- }
}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionAdapterTest.java
index d943fe3ec74..e33db6e3132 100644
--- a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionAdapterTest.java
@@ -15,6 +15,11 @@
*/
package com.android.settings.dashboard.conditional;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@@ -22,13 +27,9 @@ import android.view.View;
import android.widget.LinearLayout;
import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.dashboard.DashboardAdapter;
-import com.android.settings.dashboard.DashboardData;
-
-import java.util.ArrayList;
-import java.util.List;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
@@ -38,9 +39,8 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import java.util.ArrayList;
+import java.util.List;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@@ -70,35 +70,23 @@ public class ConditionAdapterTest {
}
@Test
- public void getItemCount_notFullyExpanded_shouldReturn0() {
- mConditionAdapter = new ConditionAdapter(
- mContext, mOneCondition, DashboardData.HEADER_MODE_DEFAULT);
- assertThat(mConditionAdapter.getItemCount()).isEqualTo(0);
-
- mConditionAdapter = new ConditionAdapter(
- mContext, mOneCondition, DashboardData.HEADER_MODE_SUGGESTION_EXPANDED);
- assertThat(mConditionAdapter.getItemCount()).isEqualTo(0);
-
- mConditionAdapter = new ConditionAdapter(
- mContext, mOneCondition, DashboardData.HEADER_MODE_COLLAPSED);
+ public void getItemCount_notExpanded_shouldReturn0() {
+ mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, false);
assertThat(mConditionAdapter.getItemCount()).isEqualTo(0);
}
@Test
- public void getItemCount_fullyExpanded_shouldReturnListSize() {
- mConditionAdapter = new ConditionAdapter(
- mContext, mOneCondition, DashboardData.HEADER_MODE_FULLY_EXPANDED);
+ public void getItemCount_expanded_shouldReturnListSize() {
+ mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
assertThat(mConditionAdapter.getItemCount()).isEqualTo(1);
- mConditionAdapter = new ConditionAdapter(
- mContext, mTwoConditions, DashboardData.HEADER_MODE_FULLY_EXPANDED);
+ mConditionAdapter = new ConditionAdapter(mContext, mTwoConditions, true);
assertThat(mConditionAdapter.getItemCount()).isEqualTo(2);
}
@Test
public void getItemViewType_shouldReturnConditionTile() {
- mConditionAdapter = new ConditionAdapter(
- mContext, mTwoConditions, DashboardData.HEADER_MODE_FULLY_EXPANDED);
+ mConditionAdapter = new ConditionAdapter(mContext, mTwoConditions, true);
assertThat(mConditionAdapter.getItemViewType(0)).isEqualTo(R.layout.condition_tile);
}
@@ -108,8 +96,7 @@ public class ConditionAdapterTest {
R.layout.condition_tile, new LinearLayout(mContext), true);
final DashboardAdapter.DashboardItemHolder viewHolder =
new DashboardAdapter.DashboardItemHolder(view);
- mConditionAdapter = new ConditionAdapter(
- mContext, mOneCondition, DashboardData.HEADER_MODE_SUGGESTION_EXPANDED);
+ mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
mConditionAdapter.onBindViewHolder(viewHolder, 0);
final View card = view.findViewById(R.id.content);
@@ -122,8 +109,7 @@ public class ConditionAdapterTest {
R.layout.condition_tile, new LinearLayout(mContext), true);
final DashboardAdapter.DashboardItemHolder viewHolder =
new DashboardAdapter.DashboardItemHolder(view);
- mConditionAdapter = new ConditionAdapter(
- mContext, mOneCondition, DashboardData.HEADER_MODE_SUGGESTION_EXPANDED);
+ mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
mConditionAdapter.onBindViewHolder(viewHolder, 0);
final View card = view.findViewById(R.id.content);
@@ -137,9 +123,8 @@ public class ConditionAdapterTest {
final View view = LayoutInflater.from(mContext).inflate(
R.layout.condition_tile, new LinearLayout(mContext), true);
final DashboardAdapter.DashboardItemHolder viewHolder =
- new DashboardAdapter.DashboardItemHolder(view);
- mConditionAdapter = new ConditionAdapter(
- mContext, mOneCondition, DashboardData.HEADER_MODE_SUGGESTION_EXPANDED);
+ new DashboardAdapter.DashboardItemHolder(view);
+ mConditionAdapter = new ConditionAdapter(mContext, mOneCondition, true);
mConditionAdapter.addDismissHandling(recyclerView);
// do not bind viewholder to simulate the null condition scenario
diff --git a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionAdapterV2Test.java b/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionAdapterV2Test.java
deleted file mode 100644
index 5e0ecec037d..00000000000
--- a/tests/robotests/src/com/android/settings/dashboard/conditional/ConditionAdapterV2Test.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-package com.android.settings.dashboard.conditional;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.settings.R;
-import com.android.settings.TestConfig;
-import com.android.settings.dashboard.DashboardAdapterV2;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class ConditionAdapterV2Test {
- @Mock
- private Condition mCondition1;
- @Mock
- private Condition mCondition2;
-
- private Context mContext;
- private ConditionAdapterV2 mConditionAdapter;
- private List mOneCondition;
- private List mTwoConditions;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- final CharSequence[] actions = new CharSequence[2];
- when(mCondition1.getActions()).thenReturn(actions);
- when(mCondition1.shouldShow()).thenReturn(true);
- mOneCondition = new ArrayList<>();
- mOneCondition.add(mCondition1);
- mTwoConditions = new ArrayList<>();
- mTwoConditions.add(mCondition1);
- mTwoConditions.add(mCondition2);
- }
-
- @Test
- public void getItemCount_notExpanded_shouldReturn0() {
- mConditionAdapter = new ConditionAdapterV2(mContext, mOneCondition, false);
- assertThat(mConditionAdapter.getItemCount()).isEqualTo(0);
- }
-
- @Test
- public void getItemCount_expanded_shouldReturnListSize() {
- mConditionAdapter = new ConditionAdapterV2(mContext, mOneCondition, true);
- assertThat(mConditionAdapter.getItemCount()).isEqualTo(1);
-
- mConditionAdapter = new ConditionAdapterV2(mContext, mTwoConditions, true);
- assertThat(mConditionAdapter.getItemCount()).isEqualTo(2);
- }
-
- @Test
- public void getItemViewType_shouldReturnConditionTile() {
- mConditionAdapter = new ConditionAdapterV2(mContext, mTwoConditions, true);
- assertThat(mConditionAdapter.getItemViewType(0)).isEqualTo(R.layout.condition_tile);
- }
-
- @Test
- public void onBindViewHolder_shouldSetListener() {
- final View view = LayoutInflater.from(mContext).inflate(
- R.layout.condition_tile, new LinearLayout(mContext), true);
- final DashboardAdapterV2.DashboardItemHolder viewHolder =
- new DashboardAdapterV2.DashboardItemHolder(view);
- mConditionAdapter = new ConditionAdapterV2(mContext, mOneCondition, true);
-
- mConditionAdapter.onBindViewHolder(viewHolder, 0);
- final View card = view.findViewById(R.id.content);
- assertThat(card.hasOnClickListeners()).isTrue();
- }
-
- @Test
- public void viewClick_shouldInvokeConditionPrimaryClick() {
- final View view = LayoutInflater.from(mContext).inflate(
- R.layout.condition_tile, new LinearLayout(mContext), true);
- final DashboardAdapterV2.DashboardItemHolder viewHolder =
- new DashboardAdapterV2.DashboardItemHolder(view);
- mConditionAdapter = new ConditionAdapterV2(mContext, mOneCondition, true);
-
- mConditionAdapter.onBindViewHolder(viewHolder, 0);
- final View card = view.findViewById(R.id.content);
- card.performClick();
- verify(mCondition1).onPrimaryClick();
- }
-
- @Test
- public void onSwiped_nullCondition_shouldNotCrash() {
- final RecyclerView recyclerView = new RecyclerView(mContext);
- final View view = LayoutInflater.from(mContext).inflate(
- R.layout.condition_tile, new LinearLayout(mContext), true);
- final DashboardAdapterV2.DashboardItemHolder viewHolder =
- new DashboardAdapterV2.DashboardItemHolder(view);
- mConditionAdapter = new ConditionAdapterV2(mContext, mOneCondition, true);
- mConditionAdapter.addDismissHandling(recyclerView);
-
- // do not bind viewholder to simulate the null condition scenario
- mConditionAdapter.mSwipeCallback.onSwiped(viewHolder, 0);
- // no crash
- }
-
-}
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
index 49e82e42f85..ebf3dc70fcd 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java
@@ -16,12 +16,19 @@
package com.android.settings.dashboard.suggestions;
import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.app.PendingIntent;
import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.service.settings.suggestions.Suggestion;
import android.view.LayoutInflater;
@@ -46,6 +53,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
@@ -87,20 +95,21 @@ public class SuggestionAdapterTest {
@Test
public void getItemCount_shouldReturnListSize() {
mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
- mOneSuggestion, new ArrayList<>());
+ null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
+ mSuggestionAdapter.setSuggestions(mOneSuggestion);
assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(1);
- mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
- mTwoSuggestions, new ArrayList<>());
+ mSuggestionAdapter.setSuggestions(mTwoSuggestions);
assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(2);
}
@Test
public void getItemViewType_shouldReturnSuggestionTile() {
mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
- mOneSuggestion, new ArrayList<>());
+ null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
+ mSuggestionAdapter.setSuggestions(mOneSuggestion);
assertThat(mSuggestionAdapter.getItemViewType(0))
- .isEqualTo(R.layout.suggestion_tile);
+ .isEqualTo(R.layout.suggestion_tile);
}
@Test
@@ -112,19 +121,21 @@ public class SuggestionAdapterTest {
.setSummary("456")
.build());
mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
- suggestions, new ArrayList<>());
+ null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
+ mSuggestionAdapter.setSuggestions(suggestions);
assertThat(mSuggestionAdapter.getItemViewType(0))
- .isEqualTo(R.layout.suggestion_tile_with_button);
+ .isEqualTo(R.layout.suggestion_tile_with_button);
}
@Test
public void onBindViewHolder_shouldLog() {
final View view = spy(LayoutInflater.from(mContext).inflate(
- R.layout.suggestion_tile, new LinearLayout(mContext), true));
+ R.layout.suggestion_tile, new LinearLayout(mContext), true));
mSuggestionHolder = new DashboardAdapter.DashboardItemHolder(view);
mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
- mOneSuggestion, new ArrayList<>());
+ null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
+ mSuggestionAdapter.setSuggestions(mOneSuggestion);
// Bind twice
mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
@@ -149,6 +160,31 @@ public class SuggestionAdapterTest {
verify(suggestions.get(0).getPendingIntent()).send();
}
+ @Test
+ public void onBindViewHolder_hasButton_buttonShouldHandleClick()
+ throws PendingIntent.CanceledException {
+ final List suggestions = new ArrayList<>();
+ final PendingIntent pendingIntent = mock(PendingIntent.class);
+ suggestions.add(new Suggestion.Builder("id")
+ .setFlags(Suggestion.FLAG_HAS_BUTTON)
+ .setTitle("123")
+ .setSummary("456")
+ .setPendingIntent(pendingIntent)
+ .build());
+ mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin,
+ null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
+ mSuggestionAdapter.setSuggestions(suggestions);
+ mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
+ new FrameLayout(RuntimeEnvironment.application),
+ mSuggestionAdapter.getItemViewType(0));
+
+ mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
+ mSuggestionHolder.itemView.findViewById(android.R.id.primary).performClick();
+
+ verify(mSuggestionControllerMixin).launchSuggestion(suggestions.get(0));
+ verify(pendingIntent).send();
+ }
+
@Test
public void getSuggestions_shouldReturnSuggestionWhenMatch() {
final List suggestions = makeSuggestions("pkg1");
@@ -157,9 +193,92 @@ public class SuggestionAdapterTest {
assertThat(mSuggestionAdapter.getSuggestion(0)).isNotNull();
}
+ @Test
+ public void onBindViewHolder_closeButtonShouldHandleClick()
+ throws PendingIntent.CanceledException {
+ final List suggestions = makeSuggestions("pkg1");
+ final SuggestionAdapter.Callback callback = mock(SuggestionAdapter.Callback.class);
+ mSuggestionAdapter = new SuggestionAdapter(mActivity, mSuggestionControllerMixin,
+ null /* savedInstanceState */, callback, null /* lifecycle */);
+ mSuggestionAdapter.setSuggestions(suggestions);
+ mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
+ new FrameLayout(RuntimeEnvironment.application),
+ mSuggestionAdapter.getItemViewType(0));
+
+ mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
+ mSuggestionHolder.itemView.findViewById(R.id.close_button).performClick();
+
+ final Suggestion suggestion = suggestions.get(0);
+ verify(mFeatureFactory.suggestionsFeatureProvider).dismissSuggestion(
+ mActivity, mSuggestionControllerMixin, suggestion);
+ verify(callback).onSuggestionClosed(suggestion);
+ }
+
+ @Test
+ public void onBindViewHolder_differentPackage_shouldNotTintIcon()
+ throws PendingIntent.CanceledException {
+ final Icon icon = mock(Icon.class);
+ when(icon.getResPackage()).thenReturn("pkg1");
+ when(mActivity.getPackageName()).thenReturn("pkg2");
+ final Suggestion suggestion = new Suggestion.Builder("pkg1")
+ .setPendingIntent(mock(PendingIntent.class))
+ .setIcon(icon)
+ .build();
+ final List suggestions = new ArrayList<>();
+ suggestions.add(suggestion);
+ mSuggestionAdapter = new SuggestionAdapter(mActivity, mSuggestionControllerMixin,
+ null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
+ mSuggestionAdapter.setSuggestions(suggestions);
+ mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
+ new FrameLayout(RuntimeEnvironment.application),
+ mSuggestionAdapter.getItemViewType(0));
+ DashboardAdapter.IconCache cache = mock(DashboardAdapter.IconCache.class);
+ final Drawable drawable = mock(Drawable.class);
+ when(cache.getIcon(icon)).thenReturn(drawable);
+ ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
+
+ mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
+
+ verify(drawable, never()).setTint(anyInt());
+ }
+
+ @Test
+ public void onBindViewHolder_samePackage_shouldTintIcon()
+ throws PendingIntent.CanceledException {
+ final Icon icon = mock(Icon.class);
+ final String packageName = "pkg1";
+ when(icon.getResPackage()).thenReturn(packageName);
+ when(mActivity.getPackageName()).thenReturn(packageName);
+ final Suggestion suggestion = new Suggestion.Builder(packageName)
+ .setPendingIntent(mock(PendingIntent.class))
+ .setIcon(icon)
+ .build();
+ final List suggestions = new ArrayList<>();
+ suggestions.add(suggestion);
+ mSuggestionAdapter = new SuggestionAdapter(mActivity, mSuggestionControllerMixin,
+ null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
+ mSuggestionAdapter.setSuggestions(suggestions);
+ mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
+ new FrameLayout(RuntimeEnvironment.application),
+ mSuggestionAdapter.getItemViewType(0));
+ DashboardAdapter.IconCache cache = mock(DashboardAdapter.IconCache.class);
+ final Drawable drawable = mock(Drawable.class);
+ when(cache.getIcon(icon)).thenReturn(drawable);
+ ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
+ TypedArray typedArray = mock(TypedArray.class);
+ final int colorAccent = 1234;
+ when(mActivity.obtainStyledAttributes(any())).thenReturn(typedArray);
+ when(typedArray.getColor(anyInt(), anyInt())).thenReturn(colorAccent);
+
+ mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
+
+ verify(drawable).setTint(colorAccent);
+ }
+
private void setupSuggestions(Context context, List suggestions) {
mSuggestionAdapter = new SuggestionAdapter(context, mSuggestionControllerMixin,
- suggestions, new ArrayList<>());
+ null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
+ mSuggestionAdapter.setSuggestions(suggestions);
mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
new FrameLayout(RuntimeEnvironment.application),
mSuggestionAdapter.getItemViewType(0));
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2Test.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2Test.java
deleted file mode 100644
index 181c8781491..00000000000
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterV2Test.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-package com.android.settings.dashboard.suggestions;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
-import android.service.settings.suggestions.Suggestion;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.R;
-import com.android.settings.SettingsActivity;
-import com.android.settings.TestConfig;
-import com.android.settings.dashboard.DashboardAdapterV2;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settingslib.suggestions.SuggestionControllerMixin;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.util.ReflectionHelpers;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class SuggestionAdapterV2Test {
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private SettingsActivity mActivity;
- @Mock
- private SuggestionControllerMixin mSuggestionControllerMixin;
- private FakeFeatureFactory mFeatureFactory;
- private Context mContext;
- private SuggestionAdapterV2 mSuggestionAdapter;
- private DashboardAdapterV2.DashboardItemHolder mSuggestionHolder;
- private List mOneSuggestion;
- private List mTwoSuggestions;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- mFeatureFactory = FakeFeatureFactory.setupForTest();
-
- final Suggestion suggestion1 = new Suggestion.Builder("id1")
- .setTitle("Test suggestion 1")
- .build();
- final Suggestion suggestion2 = new Suggestion.Builder("id2")
- .setTitle("Test suggestion 2")
- .build();
- mOneSuggestion = new ArrayList<>();
- mOneSuggestion.add(suggestion1);
- mTwoSuggestions = new ArrayList<>();
- mTwoSuggestions.add(suggestion1);
- mTwoSuggestions.add(suggestion2);
- }
-
- @Test
- public void getItemCount_shouldReturnListSize() {
- mSuggestionAdapter = new SuggestionAdapterV2(mContext, mSuggestionControllerMixin,
- null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
- mSuggestionAdapter.setSuggestions(mOneSuggestion);
- assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(1);
-
- mSuggestionAdapter.setSuggestions(mTwoSuggestions);
- assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(2);
- }
-
- @Test
- public void getItemViewType_shouldReturnSuggestionTile() {
- mSuggestionAdapter = new SuggestionAdapterV2(mContext, mSuggestionControllerMixin,
- null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
- mSuggestionAdapter.setSuggestions(mOneSuggestion);
- assertThat(mSuggestionAdapter.getItemViewType(0))
- .isEqualTo(R.layout.suggestion_tile_v2);
- }
-
- @Test
- public void getItemType_hasButton_shouldReturnSuggestionWithButton() {
- final List suggestions = new ArrayList<>();
- suggestions.add(new Suggestion.Builder("id")
- .setFlags(Suggestion.FLAG_HAS_BUTTON)
- .setTitle("123")
- .setSummary("456")
- .build());
- mSuggestionAdapter = new SuggestionAdapterV2(mContext, mSuggestionControllerMixin,
- null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
- mSuggestionAdapter.setSuggestions(suggestions);
-
- assertThat(mSuggestionAdapter.getItemViewType(0))
- .isEqualTo(R.layout.suggestion_tile_with_button_v2);
- }
-
- @Test
- public void onBindViewHolder_shouldLog() {
- final View view = spy(LayoutInflater.from(mContext).inflate(
- R.layout.suggestion_tile, new LinearLayout(mContext), true));
- mSuggestionHolder = new DashboardAdapterV2.DashboardItemHolder(view);
- mSuggestionAdapter = new SuggestionAdapterV2(mContext, mSuggestionControllerMixin,
- null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
- mSuggestionAdapter.setSuggestions(mOneSuggestion);
-
- // Bind twice
- mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
- mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
-
- // Log once
- verify(mFeatureFactory.metricsFeatureProvider).action(
- mContext, MetricsProto.MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION,
- mOneSuggestion.get(0).getId());
- }
-
- @Test
- public void onBindViewHolder_itemViewShouldHandleClick()
- throws PendingIntent.CanceledException {
- final List suggestions = makeSuggestions("pkg1");
- setupSuggestions(mActivity, suggestions);
-
- mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
- mSuggestionHolder.itemView.performClick();
-
- verify(mSuggestionControllerMixin).launchSuggestion(suggestions.get(0));
- verify(suggestions.get(0).getPendingIntent()).send();
- }
-
- @Test
- public void onBindViewHolder_hasButton_buttonShouldHandleClick()
- throws PendingIntent.CanceledException {
- final List suggestions = new ArrayList<>();
- final PendingIntent pendingIntent = mock(PendingIntent.class);
- suggestions.add(new Suggestion.Builder("id")
- .setFlags(Suggestion.FLAG_HAS_BUTTON)
- .setTitle("123")
- .setSummary("456")
- .setPendingIntent(pendingIntent)
- .build());
- mSuggestionAdapter = new SuggestionAdapterV2(mContext, mSuggestionControllerMixin,
- null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
- mSuggestionAdapter.setSuggestions(suggestions);
- mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
- new FrameLayout(RuntimeEnvironment.application),
- mSuggestionAdapter.getItemViewType(0));
-
- mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
- mSuggestionHolder.itemView.findViewById(android.R.id.primary).performClick();
-
- verify(mSuggestionControllerMixin).launchSuggestion(suggestions.get(0));
- verify(pendingIntent).send();
- }
-
- @Test
- public void getSuggestions_shouldReturnSuggestionWhenMatch() {
- final List suggestions = makeSuggestions("pkg1");
- setupSuggestions(mActivity, suggestions);
-
- assertThat(mSuggestionAdapter.getSuggestion(0)).isNotNull();
- }
-
- @Test
- public void onBindViewHolder_closeButtonShouldHandleClick()
- throws PendingIntent.CanceledException {
- final List suggestions = makeSuggestions("pkg1");
- final SuggestionAdapterV2.Callback callback = mock(SuggestionAdapterV2.Callback.class);
- mSuggestionAdapter = new SuggestionAdapterV2(mActivity, mSuggestionControllerMixin,
- null /* savedInstanceState */, callback, null /* lifecycle */);
- mSuggestionAdapter.setSuggestions(suggestions);
- mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
- new FrameLayout(RuntimeEnvironment.application),
- mSuggestionAdapter.getItemViewType(0));
-
- mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
- mSuggestionHolder.itemView.findViewById(R.id.close_button).performClick();
-
- final Suggestion suggestion = suggestions.get(0);
- verify(mFeatureFactory.suggestionsFeatureProvider).dismissSuggestion(
- mActivity, mSuggestionControllerMixin, suggestion);
- verify(callback).onSuggestionClosed(suggestion);
- }
-
- @Test
- public void onBindViewHolder_differentPackage_shouldNotTintIcon()
- throws PendingIntent.CanceledException {
- final Icon icon = mock(Icon.class);
- when(icon.getResPackage()).thenReturn("pkg1");
- when(mActivity.getPackageName()).thenReturn("pkg2");
- final Suggestion suggestion = new Suggestion.Builder("pkg1")
- .setPendingIntent(mock(PendingIntent.class))
- .setIcon(icon)
- .build();
- final List suggestions = new ArrayList<>();
- suggestions.add(suggestion);
- mSuggestionAdapter = new SuggestionAdapterV2(mActivity, mSuggestionControllerMixin,
- null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
- mSuggestionAdapter.setSuggestions(suggestions);
- mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
- new FrameLayout(RuntimeEnvironment.application),
- mSuggestionAdapter.getItemViewType(0));
- DashboardAdapterV2.IconCache cache = mock(DashboardAdapterV2.IconCache.class);
- final Drawable drawable = mock(Drawable.class);
- when(cache.getIcon(icon)).thenReturn(drawable);
- ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
-
- mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
-
- verify(drawable, never()).setTint(anyInt());
- }
-
- @Test
- public void onBindViewHolder_samePackage_shouldTintIcon()
- throws PendingIntent.CanceledException {
- final Icon icon = mock(Icon.class);
- final String packageName = "pkg1";
- when(icon.getResPackage()).thenReturn(packageName);
- when(mActivity.getPackageName()).thenReturn(packageName);
- final Suggestion suggestion = new Suggestion.Builder(packageName)
- .setPendingIntent(mock(PendingIntent.class))
- .setIcon(icon)
- .build();
- final List suggestions = new ArrayList<>();
- suggestions.add(suggestion);
- mSuggestionAdapter = new SuggestionAdapterV2(mActivity, mSuggestionControllerMixin,
- null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
- mSuggestionAdapter.setSuggestions(suggestions);
- mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
- new FrameLayout(RuntimeEnvironment.application),
- mSuggestionAdapter.getItemViewType(0));
- DashboardAdapterV2.IconCache cache = mock(DashboardAdapterV2.IconCache.class);
- final Drawable drawable = mock(Drawable.class);
- when(cache.getIcon(icon)).thenReturn(drawable);
- ReflectionHelpers.setField(mSuggestionAdapter, "mCache", cache);
- TypedArray typedArray = mock(TypedArray.class);
- final int colorAccent = 1234;
- when(mActivity.obtainStyledAttributes(any())).thenReturn(typedArray);
- when(typedArray.getColor(anyInt(), anyInt())).thenReturn(colorAccent);
-
- mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0);
-
- verify(drawable).setTint(colorAccent);
- }
-
- private void setupSuggestions(Context context, List suggestions) {
- mSuggestionAdapter = new SuggestionAdapterV2(context, mSuggestionControllerMixin,
- null /* savedInstanceState */, null /* callback */, null /* lifecycle */);
- mSuggestionAdapter.setSuggestions(suggestions);
- mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder(
- new FrameLayout(RuntimeEnvironment.application),
- mSuggestionAdapter.getItemViewType(0));
- }
-
- private List makeSuggestions(String... pkgNames) {
- final List suggestions = new ArrayList<>();
- for (String pkgName : pkgNames) {
- final Suggestion suggestion = new Suggestion.Builder(pkgName)
- .setPendingIntent(mock(PendingIntent.class))
- .build();
- suggestions.add(suggestion);
- }
- return suggestions;
- }
-}
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java
deleted file mode 100644
index f10f5ec916b..00000000000
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package com.android.settings.dashboard.suggestions;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.service.settings.suggestions.Suggestion;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.helper.ItemTouchHelper;
-
-import com.android.settings.R;
-import com.android.settings.TestConfig;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settingslib.suggestions.SuggestionControllerMixin;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.annotation.Config;
-
-@RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
-public class SuggestionDismissControllerTest {
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private RecyclerView mRecyclerView;
- @Mock
- private SuggestionControllerMixin mSuggestionControllerMixin;
- @Mock
- private SuggestionDismissController.Callback mCallback;
-
- private FakeFeatureFactory mFactory;
- private SuggestionDismissController mController;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mFactory = FakeFeatureFactory.setupForTest();
-
- when(mRecyclerView.getResources().getDimension(anyInt())).thenReturn(50F);
-
- mController = new SuggestionDismissController(mContext, mRecyclerView,
- mSuggestionControllerMixin, mCallback);
- }
-
- @Test
- public void onMove_alwaysReturnTrue() {
- assertThat(mController.onMove(null, null, null)).isTrue();
- }
-
- @Test
- public void getSwipeDirs_isSuggestionTile_shouldReturnDirection() {
- final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
- when(vh.getItemViewType()).thenReturn(R.layout.suggestion_tile);
-
- assertThat(mController.getSwipeDirs(mRecyclerView, vh))
- .isEqualTo(ItemTouchHelper.START | ItemTouchHelper.END);
- }
-
- @Test
- public void getSwipeDirs_isSuggestionTileCard_shouldReturnDirection() {
- final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
- when(vh.getItemViewType()).thenReturn(R.layout.suggestion_tile_with_button);
-
- assertThat(mController.getSwipeDirs(mRecyclerView, vh))
- .isEqualTo(ItemTouchHelper.START | ItemTouchHelper.END);
- }
-
- @Test
- public void getSwipeDirs_isNotSuggestionTile_shouldReturn0() {
- final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
- when(vh.getItemViewType()).thenReturn(R.layout.condition_tile);
-
- assertThat(mController.getSwipeDirs(mRecyclerView, vh))
- .isEqualTo(0);
- }
-
- @Test
- public void onSwiped_shouldTriggerDismissSuggestion() {
- final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class);
- when(mCallback.getSuggestionAt(anyInt())).thenReturn(
- new Suggestion.Builder("id").build());
-
- mController.onSwiped(vh, ItemTouchHelper.START);
-
- verify(mFactory.suggestionsFeatureProvider).dismissSuggestion(
- eq(mContext), eq(mSuggestionControllerMixin), nullable(Suggestion.class));
- verify(mCallback).onSuggestionDismissed(nullable(Suggestion.class));
- }
-}