Make dashboard tile refresh more effcient.
Instead of removing and re-adding all dashboard tiles, figure out a diff and rebind/add/remove as necessary. Bug: 32255863 Test: RunSettingsRoboTests Change-Id: I9d87ba30ab746257d0ea71282951348ebc4e8965
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.dashboard;
|
package com.android.settings.dashboard;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
|
|
||||||
import com.android.settingslib.drawer.DashboardCategory;
|
import com.android.settingslib.drawer.DashboardCategory;
|
||||||
@@ -53,4 +54,10 @@ public interface DashboardFeatureProvider {
|
|||||||
* Returns an unique string key for the tile.
|
* Returns an unique string key for the tile.
|
||||||
*/
|
*/
|
||||||
String getDashboardKeyForTile(Tile tile);
|
String getDashboardKeyForTile(Tile tile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link ProgressiveDisclosureMixin} for specified fragment.
|
||||||
|
*/
|
||||||
|
ProgressiveDisclosureMixin getProgressiveDisclosureMixin(Context context,
|
||||||
|
DashboardFragment fragment);
|
||||||
}
|
}
|
||||||
|
@@ -72,4 +72,10 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
|
|||||||
sb.append(component.getClassName());
|
sb.append(component.getClassName());
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProgressiveDisclosureMixin getProgressiveDisclosureMixin(Context context,
|
||||||
|
DashboardFragment fragment) {
|
||||||
|
return new ProgressiveDisclosureMixin(context, this, fragment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,9 @@ import android.graphics.Color;
|
|||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.VisibleForTesting;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.support.v7.preference.PreferenceManager;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
@@ -41,6 +43,7 @@ import com.android.settingslib.drawer.DashboardCategory;
|
|||||||
import com.android.settingslib.drawer.SettingsDrawerActivity;
|
import com.android.settingslib.drawer.SettingsDrawerActivity;
|
||||||
import com.android.settingslib.drawer.Tile;
|
import com.android.settingslib.drawer.Tile;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -69,7 +72,8 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
|||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
mDashboardFeatureProvider =
|
mDashboardFeatureProvider =
|
||||||
FeatureFactory.getFactory(context).getDashboardFeatureProvider(context);
|
FeatureFactory.getFactory(context).getDashboardFeatureProvider(context);
|
||||||
mProgressiveDisclosureMixin = new ProgressiveDisclosureMixin(context, this);
|
mProgressiveDisclosureMixin = mDashboardFeatureProvider
|
||||||
|
.getProgressiveDisclosureMixin(context, this);
|
||||||
getLifecycle().addObserver(mProgressiveDisclosureMixin);
|
getLifecycle().addObserver(mProgressiveDisclosureMixin);
|
||||||
|
|
||||||
final List<PreferenceController> controllers = getPreferenceControllers(context);
|
final List<PreferenceController> controllers = getPreferenceControllers(context);
|
||||||
@@ -81,6 +85,24 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle icicle) {
|
||||||
|
super.onCreate(icicle);
|
||||||
|
// Set ComparisonCallback so we get better animation when list changes.
|
||||||
|
getPreferenceManager().setPreferenceComparisonCallback(
|
||||||
|
new PreferenceManager.SimplePreferenceComparisonCallback());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
final View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||||
|
if (mDashboardFeatureProvider.isEnabled()) {
|
||||||
|
getListView().addItemDecoration(mDividerDecoration);
|
||||||
|
}
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCategoriesChanged() {
|
public void onCategoriesChanged() {
|
||||||
final DashboardCategory category =
|
final DashboardCategory category =
|
||||||
@@ -98,6 +120,18 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
|||||||
refreshAllPreferences(getLogTag());
|
refreshAllPreferences(getLogTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDivider(Drawable divider) {
|
||||||
|
if (mDashboardFeatureProvider.isEnabled()) {
|
||||||
|
// Intercept divider and set it transparent so system divider decoration is disabled.
|
||||||
|
// We will use our decoration to draw divider more intelligently.
|
||||||
|
mDividerDecoration.setDivider(divider);
|
||||||
|
super.setDivider(new ColorDrawable(Color.TRANSPARENT));
|
||||||
|
} else {
|
||||||
|
super.setDivider(divider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
@@ -210,16 +244,6 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
|
||||||
Bundle savedInstanceState) {
|
|
||||||
final View view = super.onCreateView(inflater, container, savedInstanceState);
|
|
||||||
if (mDashboardFeatureProvider.isEnabled()) {
|
|
||||||
getListView().addItemDecoration(mDividerDecoration);
|
|
||||||
}
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update state of each preference managed by PreferenceController.
|
* Update state of each preference managed by PreferenceController.
|
||||||
*/
|
*/
|
||||||
@@ -238,18 +262,6 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDivider(Drawable divider) {
|
|
||||||
if (mDashboardFeatureProvider.isEnabled()) {
|
|
||||||
// Intercept divider and set it transparent so system divider decoration is disabled.
|
|
||||||
// We will use our decoration to draw divider more intelligently.
|
|
||||||
mDividerDecoration.setDivider(divider);
|
|
||||||
super.setDivider(new ColorDrawable(Color.TRANSPARENT));
|
|
||||||
} else {
|
|
||||||
super.setDivider(divider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh all preference items, including both static prefs from xml, and dynamic items from
|
* Refresh all preference items, including both static prefs from xml, and dynamic items from
|
||||||
* DashboardCategory.
|
* DashboardCategory.
|
||||||
@@ -275,18 +287,15 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
|||||||
/**
|
/**
|
||||||
* Refresh preference items backed by DashboardCategory.
|
* Refresh preference items backed by DashboardCategory.
|
||||||
*/
|
*/
|
||||||
private void refreshDashboardTiles(final String TAG) {
|
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||||
|
void refreshDashboardTiles(final String TAG) {
|
||||||
final PreferenceScreen screen = getPreferenceScreen();
|
final PreferenceScreen screen = getPreferenceScreen();
|
||||||
for (String key : mDashboardTilePrefKeys) {
|
|
||||||
// Remove tiles from screen
|
|
||||||
mProgressiveDisclosureMixin.removePreference(screen, key);
|
|
||||||
}
|
|
||||||
mDashboardTilePrefKeys.clear();
|
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
final DashboardCategory category =
|
final DashboardCategory category =
|
||||||
mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
|
mDashboardFeatureProvider.getTilesForCategory(getCategoryKey());
|
||||||
if (category == null) {
|
if (category == null) {
|
||||||
Log.d(TAG, "NO dynamic tiles for " + TAG);
|
Log.d(TAG, "NO dashboard tiles for " + TAG);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
List<Tile> tiles = category.tiles;
|
List<Tile> tiles = category.tiles;
|
||||||
@@ -294,6 +303,9 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
|||||||
Log.d(TAG, "tile list is empty, skipping category " + category.title);
|
Log.d(TAG, "tile list is empty, skipping category " + category.title);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Create a list to track which tiles are to be removed.
|
||||||
|
final List<String> remove = new ArrayList<>(mDashboardTilePrefKeys);
|
||||||
|
|
||||||
// There are dashboard tiles, so we need to install SummaryLoader.
|
// There are dashboard tiles, so we need to install SummaryLoader.
|
||||||
if (mSummaryLoader != null) {
|
if (mSummaryLoader != null) {
|
||||||
mSummaryLoader.release();
|
mSummaryLoader.release();
|
||||||
@@ -307,32 +319,51 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
|||||||
Log.d(TAG, "tile does not contain a key, skipping " + tile);
|
Log.d(TAG, "tile does not contain a key, skipping " + tile);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mDashboardTilePrefKeys.add(key);
|
if (mDashboardTilePrefKeys.contains(key)) {
|
||||||
final Preference pref = new DashboardTilePreference(context);
|
// Have the key already, will rebind.
|
||||||
pref.setTitle(tile.title);
|
final Preference preference = mProgressiveDisclosureMixin.findPreference(
|
||||||
pref.setKey(key);
|
screen, key);
|
||||||
pref.setSummary(tile.summary);
|
bindPreferenceToTile(context, preference, tile, key);
|
||||||
if (tile.icon != null) {
|
} else {
|
||||||
pref.setIcon(tile.icon.loadDrawable(context));
|
// Don't have this key, add it.
|
||||||
|
final Preference pref = new DashboardTilePreference(context);
|
||||||
|
bindPreferenceToTile(context, pref, tile, key);
|
||||||
|
mProgressiveDisclosureMixin.addPreference(screen, pref);
|
||||||
|
mDashboardTilePrefKeys.add(key);
|
||||||
}
|
}
|
||||||
final Bundle metadata = tile.metaData;
|
remove.remove(key);
|
||||||
if (metadata != null) {
|
}
|
||||||
String clsName = metadata.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS);
|
// Finally remove tiles that are gone.
|
||||||
if (!TextUtils.isEmpty(clsName)) {
|
for (String key : remove) {
|
||||||
pref.setFragment(clsName);
|
mDashboardTilePrefKeys.remove(key);
|
||||||
}
|
mProgressiveDisclosureMixin.removePreference(screen, key);
|
||||||
} else if (tile.intent != null) {
|
|
||||||
final Intent intent = new Intent(tile.intent);
|
|
||||||
pref.setOnPreferenceClickListener(preference -> {
|
|
||||||
getActivity().startActivityForResult(intent, 0);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Use negated priority for order, because tile priority is based on intent-filter
|
|
||||||
// (larger value has higher priority). However pref order defines smaller value has
|
|
||||||
// higher priority.
|
|
||||||
pref.setOrder(-tile.priority);
|
|
||||||
mProgressiveDisclosureMixin.addPreference(screen, pref);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||||
|
void bindPreferenceToTile(Context context, Preference pref, Tile tile, String key) {
|
||||||
|
pref.setTitle(tile.title);
|
||||||
|
pref.setKey(key);
|
||||||
|
pref.setSummary(tile.summary);
|
||||||
|
if (tile.icon != null) {
|
||||||
|
pref.setIcon(tile.icon.loadDrawable(context));
|
||||||
|
}
|
||||||
|
final Bundle metadata = tile.metaData;
|
||||||
|
if (metadata != null) {
|
||||||
|
String clsName = metadata.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS);
|
||||||
|
if (!TextUtils.isEmpty(clsName)) {
|
||||||
|
pref.setFragment(clsName);
|
||||||
|
}
|
||||||
|
} else if (tile.intent != null) {
|
||||||
|
final Intent intent = new Intent(tile.intent);
|
||||||
|
pref.setOnPreferenceClickListener(preference -> {
|
||||||
|
getActivity().startActivityForResult(intent, 0);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Use negated priority for order, because tile priority is based on intent-filter
|
||||||
|
// (larger value has higher priority). However pref order defines smaller value has
|
||||||
|
// higher priority.
|
||||||
|
pref.setOrder(-tile.priority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,9 +28,9 @@ import android.util.Log;
|
|||||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||||
import com.android.settings.core.lifecycle.events.OnCreate;
|
import com.android.settings.core.lifecycle.events.OnCreate;
|
||||||
import com.android.settings.core.lifecycle.events.OnSaveInstanceState;
|
import com.android.settings.core.lifecycle.events.OnSaveInstanceState;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickListener,
|
public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickListener,
|
||||||
@@ -43,18 +43,19 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL
|
|||||||
private int mTileLimit = DEFAULT_TILE_LIMIT;
|
private int mTileLimit = DEFAULT_TILE_LIMIT;
|
||||||
|
|
||||||
private final DashboardFeatureProvider mDashboardFeatureProvider;
|
private final DashboardFeatureProvider mDashboardFeatureProvider;
|
||||||
private final List<Preference> collapsedPrefs = new ArrayList<>();
|
// Collapsed preference sorted by order.
|
||||||
|
private final List<Preference> mCollapsedPrefs = new ArrayList<>();
|
||||||
private final ExpandPreference mExpandButton;
|
private final ExpandPreference mExpandButton;
|
||||||
private final PreferenceFragment mFragment;
|
private final PreferenceFragment mFragment;
|
||||||
|
|
||||||
private boolean mUserExpanded;
|
private boolean mUserExpanded;
|
||||||
|
|
||||||
public ProgressiveDisclosureMixin(Context context, PreferenceFragment fragment) {
|
public ProgressiveDisclosureMixin(Context context,
|
||||||
|
DashboardFeatureProvider dashboardFeatureProvider, PreferenceFragment fragment) {
|
||||||
mFragment = fragment;
|
mFragment = fragment;
|
||||||
mExpandButton = new ExpandPreference(context);
|
mExpandButton = new ExpandPreference(context);
|
||||||
mExpandButton.setOnPreferenceClickListener(this);
|
mExpandButton.setOnPreferenceClickListener(this);
|
||||||
mDashboardFeatureProvider = FeatureFactory.getFactory(context)
|
mDashboardFeatureProvider = dashboardFeatureProvider;
|
||||||
.getDashboardFeatureProvider(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -75,10 +76,10 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL
|
|||||||
final PreferenceScreen screen = mFragment.getPreferenceScreen();
|
final PreferenceScreen screen = mFragment.getPreferenceScreen();
|
||||||
if (screen != null) {
|
if (screen != null) {
|
||||||
screen.removePreference(preference);
|
screen.removePreference(preference);
|
||||||
for (Preference pref : collapsedPrefs) {
|
for (Preference pref : mCollapsedPrefs) {
|
||||||
screen.addPreference(pref);
|
screen.addPreference(pref);
|
||||||
}
|
}
|
||||||
collapsedPrefs.clear();
|
mCollapsedPrefs.clear();
|
||||||
mUserExpanded = true;
|
mUserExpanded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,7 +97,7 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL
|
|||||||
* Whether the controller is in collapsed state.
|
* Whether the controller is in collapsed state.
|
||||||
*/
|
*/
|
||||||
public boolean isCollapsed() {
|
public boolean isCollapsed() {
|
||||||
return !collapsedPrefs.isEmpty();
|
return !mCollapsedPrefs.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,7 +116,7 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL
|
|||||||
if (!shouldCollapse(screen)) {
|
if (!shouldCollapse(screen)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!collapsedPrefs.isEmpty()) {
|
if (!mCollapsedPrefs.isEmpty()) {
|
||||||
Log.w(TAG, "collapsed list should ALWAYS BE EMPTY before collapsing!");
|
Log.w(TAG, "collapsed list should ALWAYS BE EMPTY before collapsing!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,12 +135,27 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL
|
|||||||
public void addPreference(PreferenceScreen screen, Preference pref) {
|
public void addPreference(PreferenceScreen screen, Preference pref) {
|
||||||
// Either add to screen, or to collapsed list.
|
// Either add to screen, or to collapsed list.
|
||||||
if (isCollapsed()) {
|
if (isCollapsed()) {
|
||||||
// Already collapsed, add to collapsed list.
|
// insert the preference to right position.
|
||||||
addToCollapsedList(pref);
|
final int lastPreferenceIndex = screen.getPreferenceCount() - 2;
|
||||||
|
if (lastPreferenceIndex >= 0) {
|
||||||
|
final Preference lastPreference = screen.getPreference(lastPreferenceIndex);
|
||||||
|
if (lastPreference.getOrder() > pref.getOrder()) {
|
||||||
|
// insert to screen and move the last pref to collapsed list.
|
||||||
|
screen.removePreference(lastPreference);
|
||||||
|
screen.addPreference(pref);
|
||||||
|
addToCollapsedList(lastPreference);
|
||||||
|
} else {
|
||||||
|
// Insert to collapsed list.
|
||||||
|
addToCollapsedList(pref);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Couldn't find last preference on screen, just add to collapsed list.
|
||||||
|
addToCollapsedList(pref);
|
||||||
|
}
|
||||||
} else if (shouldCollapse(screen)) {
|
} else if (shouldCollapse(screen)) {
|
||||||
// About to have too many tiles on scree, collapse and add pref to collapsed list.
|
// About to have too many tiles on scree, collapse and add pref to collapsed list.
|
||||||
|
screen.addPreference(pref);
|
||||||
collapse(screen);
|
collapse(screen);
|
||||||
addToCollapsedList(pref);
|
|
||||||
} else {
|
} else {
|
||||||
// No need to collapse, add to screen directly.
|
// No need to collapse, add to screen directly.
|
||||||
screen.addPreference(pref);
|
screen.addPreference(pref);
|
||||||
@@ -158,11 +174,11 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Didn't find on screen, try removing from collapsed list.
|
// Didn't find on screen, try removing from collapsed list.
|
||||||
for (int i = 0; i < collapsedPrefs.size(); i++) {
|
for (int i = 0; i < mCollapsedPrefs.size(); i++) {
|
||||||
final Preference pref = collapsedPrefs.get(i);
|
final Preference pref = mCollapsedPrefs.get(i);
|
||||||
if (TextUtils.equals(key, pref.getKey())) {
|
if (TextUtils.equals(key, pref.getKey())) {
|
||||||
collapsedPrefs.remove(pref);
|
mCollapsedPrefs.remove(pref);
|
||||||
if (collapsedPrefs.isEmpty()) {
|
if (mCollapsedPrefs.isEmpty()) {
|
||||||
// Removed last element, remove expand button too.
|
// Removed last element, remove expand button too.
|
||||||
screen.removePreference(mExpandButton);
|
screen.removePreference(mExpandButton);
|
||||||
}
|
}
|
||||||
@@ -179,8 +195,8 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL
|
|||||||
if (preference != null) {
|
if (preference != null) {
|
||||||
return preference;
|
return preference;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < collapsedPrefs.size(); i++) {
|
for (int i = 0; i < mCollapsedPrefs.size(); i++) {
|
||||||
final Preference pref = collapsedPrefs.get(i);
|
final Preference pref = mCollapsedPrefs.get(i);
|
||||||
if (TextUtils.equals(key, pref.getKey())) {
|
if (TextUtils.equals(key, pref.getKey())) {
|
||||||
return pref;
|
return pref;
|
||||||
}
|
}
|
||||||
@@ -192,9 +208,18 @@ public class ProgressiveDisclosureMixin implements Preference.OnPreferenceClickL
|
|||||||
/**
|
/**
|
||||||
* Add preference to collapsed list.
|
* Add preference to collapsed list.
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||||
void addToCollapsedList(Preference preference) {
|
void addToCollapsedList(Preference preference) {
|
||||||
collapsedPrefs.add(preference);
|
// Insert preference based on it's order.
|
||||||
|
int insertionIndex = Collections.binarySearch(mCollapsedPrefs, preference);
|
||||||
|
if (insertionIndex < 0) {
|
||||||
|
insertionIndex = insertionIndex * -1 - 1;
|
||||||
|
}
|
||||||
|
mCollapsedPrefs.add(insertionIndex, preference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||||
|
List<Preference> getCollapsedPrefs() {
|
||||||
|
return mCollapsedPrefs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,10 +16,13 @@
|
|||||||
package com.android.settings.dashboard;
|
package com.android.settings.dashboard;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.Icon;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.core.PreferenceController;
|
import com.android.settings.core.PreferenceController;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
@@ -44,6 +47,7 @@ import java.util.List;
|
|||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Matchers.anyString;
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -59,6 +63,8 @@ public class DashboardFragmentTest {
|
|||||||
private DashboardCategory mDashboardCategory;
|
private DashboardCategory mDashboardCategory;
|
||||||
@Mock
|
@Mock
|
||||||
private FakeFeatureFactory mFakeFeatureFactory;
|
private FakeFeatureFactory mFakeFeatureFactory;
|
||||||
|
@Mock
|
||||||
|
private ProgressiveDisclosureMixin mDisclosureMixin;
|
||||||
private TestFragment mTestFragment;
|
private TestFragment mTestFragment;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -69,9 +75,12 @@ public class DashboardFragmentTest {
|
|||||||
mDashboardCategory.tiles = new ArrayList<>();
|
mDashboardCategory.tiles = new ArrayList<>();
|
||||||
mDashboardCategory.tiles.add(new Tile());
|
mDashboardCategory.tiles.add(new Tile());
|
||||||
mTestFragment = new TestFragment(ShadowApplication.getInstance().getApplicationContext());
|
mTestFragment = new TestFragment(ShadowApplication.getInstance().getApplicationContext());
|
||||||
mTestFragment.onAttach(ShadowApplication.getInstance().getApplicationContext());
|
when(mFakeFeatureFactory.dashboardFeatureProvider
|
||||||
|
.getProgressiveDisclosureMixin(any(Context.class), eq(mTestFragment)))
|
||||||
|
.thenReturn(mDisclosureMixin);
|
||||||
when(mFakeFeatureFactory.dashboardFeatureProvider.getTilesForCategory(anyString()))
|
when(mFakeFeatureFactory.dashboardFeatureProvider.getTilesForCategory(anyString()))
|
||||||
.thenReturn(mDashboardCategory);
|
.thenReturn(mDashboardCategory);
|
||||||
|
mTestFragment.onAttach(ShadowApplication.getInstance().getApplicationContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -87,11 +96,14 @@ public class DashboardFragmentTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void displayTilesAsPreference_shouldAddTilesWithIntent() {
|
public void displayTilesAsPreference_shouldAddTilesWithIntent() {
|
||||||
|
when(mFakeFeatureFactory.dashboardFeatureProvider.getTilesForCategory(anyString()))
|
||||||
|
.thenReturn(mDashboardCategory);
|
||||||
when(mFakeFeatureFactory.dashboardFeatureProvider.getDashboardKeyForTile(any(Tile.class)))
|
when(mFakeFeatureFactory.dashboardFeatureProvider.getDashboardKeyForTile(any(Tile.class)))
|
||||||
.thenReturn("test_key");
|
.thenReturn("test_key");
|
||||||
mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
|
mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
|
||||||
|
|
||||||
verify(mTestFragment.mScreen).addPreference(any(DashboardTilePreference.class));
|
verify(mDisclosureMixin).addPreference(any(PreferenceScreen.class),
|
||||||
|
any(DashboardTilePreference.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -109,6 +121,27 @@ public class DashboardFragmentTest {
|
|||||||
verify(mTestFragment.mScreen, never()).addPreference(any(DashboardTilePreference.class));
|
verify(mTestFragment.mScreen, never()).addPreference(any(DashboardTilePreference.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindPreference_shouldBindAllData() {
|
||||||
|
final Preference preference = new Preference(
|
||||||
|
ShadowApplication.getInstance().getApplicationContext());
|
||||||
|
final Tile tile = new Tile();
|
||||||
|
tile.title = "title";
|
||||||
|
tile.summary = "summary";
|
||||||
|
tile.icon = Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565));
|
||||||
|
tile.metaData = new Bundle();
|
||||||
|
tile.metaData.putString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS, "HI");
|
||||||
|
tile.priority = 10;
|
||||||
|
mTestFragment.bindPreferenceToTile(mContext, preference, tile, "123");
|
||||||
|
|
||||||
|
assertThat(preference.getTitle()).isEqualTo(tile.title);
|
||||||
|
assertThat(preference.getSummary()).isEqualTo(tile.summary);
|
||||||
|
assertThat(preference.getIcon()).isNotNull();
|
||||||
|
assertThat(preference.getFragment())
|
||||||
|
.isEqualTo(tile.metaData.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS));
|
||||||
|
assertThat(preference.getOrder()).isEqualTo(-tile.priority);
|
||||||
|
}
|
||||||
|
|
||||||
public static class TestPreferenceController extends PreferenceController {
|
public static class TestPreferenceController extends PreferenceController {
|
||||||
|
|
||||||
public TestPreferenceController(Context context) {
|
public TestPreferenceController(Context context) {
|
||||||
@@ -139,7 +172,6 @@ public class DashboardFragmentTest {
|
|||||||
public static class TestFragment extends DashboardFragment {
|
public static class TestFragment extends DashboardFragment {
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
@Mock
|
|
||||||
public PreferenceScreen mScreen;
|
public PreferenceScreen mScreen;
|
||||||
|
|
||||||
public TestFragment(Context context) {
|
public TestFragment(Context context) {
|
||||||
|
@@ -35,6 +35,8 @@ import org.robolectric.RobolectricTestRunner;
|
|||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.shadows.ShadowApplication;
|
import org.robolectric.shadows.ShadowApplication;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Matchers.anyInt;
|
import static org.mockito.Matchers.anyInt;
|
||||||
@@ -67,7 +69,8 @@ public class ProgressiveDisclosureTest {
|
|||||||
mScreen = mPreferenceFragment.getPreferenceScreen();
|
mScreen = mPreferenceFragment.getPreferenceScreen();
|
||||||
mAppContext = ShadowApplication.getInstance().getApplicationContext();
|
mAppContext = ShadowApplication.getInstance().getApplicationContext();
|
||||||
mFakeFeatureFactory = (FakeFeatureFactory) FeatureFactory.getFactory(mContext);
|
mFakeFeatureFactory = (FakeFeatureFactory) FeatureFactory.getFactory(mContext);
|
||||||
mMixin = new ProgressiveDisclosureMixin(mAppContext, mPreferenceFragment);
|
mMixin = new ProgressiveDisclosureMixin(mAppContext,
|
||||||
|
mFakeFeatureFactory.dashboardFeatureProvider, mPreferenceFragment);
|
||||||
mPreference = new Preference(mAppContext);
|
mPreference = new Preference(mAppContext);
|
||||||
mPreference.setKey("test");
|
mPreference.setKey("test");
|
||||||
when(mFakeFeatureFactory.dashboardFeatureProvider.isEnabled()).thenReturn(true);
|
when(mFakeFeatureFactory.dashboardFeatureProvider.isEnabled()).thenReturn(true);
|
||||||
@@ -180,4 +183,77 @@ public class ProgressiveDisclosureTest {
|
|||||||
verify(screen, times(3)).removePreference(any(Preference.class));
|
verify(screen, times(3)).removePreference(any(Preference.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addToCollapsedList_shouldAddInOrder() {
|
||||||
|
final Preference pref1 = new Preference(mAppContext);
|
||||||
|
final Preference pref2 = new Preference(mAppContext);
|
||||||
|
pref1.setOrder(10);
|
||||||
|
pref2.setOrder(20);
|
||||||
|
|
||||||
|
// Pref1 has lower order than pref2, but add pref2 first. The collapsed list should maintain
|
||||||
|
// items in increasing order.
|
||||||
|
mMixin.addToCollapsedList(pref2);
|
||||||
|
mMixin.addToCollapsedList(pref1);
|
||||||
|
|
||||||
|
List<Preference> collapsedList = mMixin.getCollapsedPrefs();
|
||||||
|
assertThat(collapsedList.get(0)).isSameAs(pref1);
|
||||||
|
assertThat(collapsedList.get(1)).isSameAs(pref2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addPreferenceWhenCollapsed_noPrefOnScreen_shouldAddToList() {
|
||||||
|
// Add something to collapsed list so we are in collapsed state.
|
||||||
|
mMixin.addToCollapsedList(new Preference(mAppContext));
|
||||||
|
assertThat(mMixin.getCollapsedPrefs().size()).isEqualTo(1);
|
||||||
|
|
||||||
|
// Just 1 preference on screen: the more button
|
||||||
|
when(mScreen.getPreferenceCount()).thenReturn(1);
|
||||||
|
final Preference toBeAdded = new Preference(mAppContext);
|
||||||
|
toBeAdded.setOrder(100);
|
||||||
|
mMixin.addPreference(mScreen, toBeAdded);
|
||||||
|
|
||||||
|
// Should have 2 prefs in collapsed list now
|
||||||
|
assertThat(mMixin.getCollapsedPrefs().size()).isEqualTo(2);
|
||||||
|
assertThat(mMixin.getCollapsedPrefs().get(0)).isSameAs(toBeAdded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addPreferenceWhenCollapsed_prefOrderLessThanLastOnScreen_shouldAddToScreen() {
|
||||||
|
final Preference lastPref = new Preference(mAppContext);
|
||||||
|
lastPref.setOrder(100);
|
||||||
|
// Add something to collapsed list so we are in collapsed state.
|
||||||
|
mMixin.addToCollapsedList(new Preference(mAppContext));
|
||||||
|
assertThat(mMixin.getCollapsedPrefs().size()).isEqualTo(1);
|
||||||
|
// 3 prefs on screen, 2 are real and the last one is more button.
|
||||||
|
when(mScreen.getPreferenceCount()).thenReturn(3);
|
||||||
|
when(mScreen.getPreference(1)).thenReturn(lastPref);
|
||||||
|
|
||||||
|
final Preference toBeAdded = new Preference(mAppContext);
|
||||||
|
toBeAdded.setOrder(50);
|
||||||
|
mMixin.addPreference(mScreen, toBeAdded);
|
||||||
|
|
||||||
|
verify(mScreen).removePreference(lastPref);
|
||||||
|
verify(mScreen).addPreference(toBeAdded);
|
||||||
|
assertThat(mMixin.getCollapsedPrefs().get(0)).isSameAs(lastPref);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addPreferenceWhenCollapsed_prefOrderMoreThanLastOnScreen_shouldAddToList() {
|
||||||
|
final Preference lastPref = new Preference(mAppContext);
|
||||||
|
lastPref.setOrder(100);
|
||||||
|
// Add something to collapsed list so we are in collapsed state.
|
||||||
|
mMixin.addToCollapsedList(new Preference(mAppContext));
|
||||||
|
assertThat(mMixin.getCollapsedPrefs().size()).isEqualTo(1);
|
||||||
|
// 3 prefs on screen, 2 are real and the last one is more button.
|
||||||
|
when(mScreen.getPreferenceCount()).thenReturn(3);
|
||||||
|
when(mScreen.getPreference(1)).thenReturn(lastPref);
|
||||||
|
|
||||||
|
final Preference toBeAdded = new Preference(mAppContext);
|
||||||
|
toBeAdded.setOrder(200);
|
||||||
|
mMixin.addPreference(mScreen, toBeAdded);
|
||||||
|
|
||||||
|
verify(mScreen, never()).removePreference(any(Preference.class));
|
||||||
|
verify(mScreen, never()).addPreference(any(Preference.class));
|
||||||
|
assertThat(mMixin.getCollapsedPrefs().get(0)).isSameAs(toBeAdded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user