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:
Fan Zhang
2016-10-19 14:15:34 -07:00
parent 8b5bca5937
commit a1a84e6530
6 changed files with 256 additions and 79 deletions

View File

@@ -16,10 +16,13 @@
package com.android.settings.dashboard;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import com.android.settings.SettingsActivity;
import com.android.settings.TestConfig;
import com.android.settings.core.PreferenceController;
import com.android.settings.overlay.FeatureFactory;
@@ -44,6 +47,7 @@ import java.util.List;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -59,6 +63,8 @@ public class DashboardFragmentTest {
private DashboardCategory mDashboardCategory;
@Mock
private FakeFeatureFactory mFakeFeatureFactory;
@Mock
private ProgressiveDisclosureMixin mDisclosureMixin;
private TestFragment mTestFragment;
@Before
@@ -69,9 +75,12 @@ public class DashboardFragmentTest {
mDashboardCategory.tiles = new ArrayList<>();
mDashboardCategory.tiles.add(new Tile());
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()))
.thenReturn(mDashboardCategory);
mTestFragment.onAttach(ShadowApplication.getInstance().getApplicationContext());
}
@Test
@@ -87,11 +96,14 @@ public class DashboardFragmentTest {
@Test
public void displayTilesAsPreference_shouldAddTilesWithIntent() {
when(mFakeFeatureFactory.dashboardFeatureProvider.getTilesForCategory(anyString()))
.thenReturn(mDashboardCategory);
when(mFakeFeatureFactory.dashboardFeatureProvider.getDashboardKeyForTile(any(Tile.class)))
.thenReturn("test_key");
mTestFragment.onCreatePreferences(new Bundle(), "rootKey");
verify(mTestFragment.mScreen).addPreference(any(DashboardTilePreference.class));
verify(mDisclosureMixin).addPreference(any(PreferenceScreen.class),
any(DashboardTilePreference.class));
}
@Test
@@ -109,6 +121,27 @@ public class DashboardFragmentTest {
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 TestPreferenceController(Context context) {
@@ -139,7 +172,6 @@ public class DashboardFragmentTest {
public static class TestFragment extends DashboardFragment {
private final Context mContext;
@Mock
public PreferenceScreen mScreen;
public TestFragment(Context context) {

View File

@@ -35,6 +35,8 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import java.util.List;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
@@ -67,7 +69,8 @@ public class ProgressiveDisclosureTest {
mScreen = mPreferenceFragment.getPreferenceScreen();
mAppContext = ShadowApplication.getInstance().getApplicationContext();
mFakeFeatureFactory = (FakeFeatureFactory) FeatureFactory.getFactory(mContext);
mMixin = new ProgressiveDisclosureMixin(mAppContext, mPreferenceFragment);
mMixin = new ProgressiveDisclosureMixin(mAppContext,
mFakeFeatureFactory.dashboardFeatureProvider, mPreferenceFragment);
mPreference = new Preference(mAppContext);
mPreference.setKey("test");
when(mFakeFeatureFactory.dashboardFeatureProvider.isEnabled()).thenReturn(true);
@@ -180,4 +183,77 @@ public class ProgressiveDisclosureTest {
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);
}
}