Hack to wait for both suggestion/category to load
- This is unfortunately necessary to avoid a jank when category
load completes before suggestion load, in which case user has to
manually scroll up to see the suggestions.
- We could technically just add scrollTo(0), but that causes the list
scroll on its own within 0.5 second of settings start, and that's bad.
Change-Id: I8dc869a69a5bf11bbf7644b281cc1778dd1a90e8
Fixes: 69068691
Test: visual
Test: robotests
diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java
index 54a1eeb..3d473f0 100644
--- a/src/com/android/settings/dashboard/DashboardAdapter.java
+++ b/src/com/android/settings/dashboard/DashboardAdapter.java
@@ -161,7 +161,6 @@
}
public void setSuggestionsV2(List<Suggestion> data) {
- // TODO: Tint icon
final DashboardData prevData = mDashboardData;
mDashboardData = new DashboardData.Builder(prevData)
.setSuggestionsV2(data)
diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java
index 8f66b67..ff2a76a 100644
--- a/src/com/android/settings/dashboard/DashboardSummary.java
+++ b/src/com/android/settings/dashboard/DashboardSummary.java
@@ -81,6 +81,9 @@
private boolean isOnCategoriesChangedCalled;
private boolean mOnConditionsChangedCalled;
+ private DashboardCategory mStagingCategory;
+ private List<Suggestion> mStagingSuggestions;
+
@Override
public int getMetricsCategory() {
return MetricsEvent.DASHBOARD_SUMMARY;
@@ -291,7 +294,13 @@
@Override
public void onSuggestionReady(List<Suggestion> suggestions) {
+ mStagingSuggestions = suggestions;
mAdapter.setSuggestionsV2(suggestions);
+ if (mStagingCategory != null) {
+ Log.d(TAG, "Category has loaded, setting category from suggestionReady");
+ mHandler.removeCallbacksAndMessages(null);
+ mAdapter.setCategory(mStagingCategory);
+ }
}
/**
@@ -342,7 +351,19 @@
final DashboardCategory category = mDashboardFeatureProvider.getTilesForCategory(
CategoryKey.CATEGORY_HOMEPAGE);
mSummaryLoader.updateSummaryToCache(category);
- ThreadUtils.postOnMainThread(() -> mAdapter.setCategory(category));
+ mStagingCategory = category;
+ if (mSuggestionControllerMixin.isSuggestionLoaded()) {
+ Log.d(TAG, "Suggestion has loaded, setting suggestion/category");
+ ThreadUtils.postOnMainThread(() -> {
+ if (mStagingSuggestions != null) {
+ mAdapter.setSuggestionsV2(mStagingSuggestions);
+ }
+ mAdapter.setCategory(mStagingCategory);
+ });
+ } else {
+ Log.d(TAG, "Suggestion NOT loaded, delaying setCategory by " + MAX_WAIT_MILLIS + "ms");
+ mHandler.postDelayed(() -> mAdapter.setCategory(mStagingCategory), MAX_WAIT_MILLIS);
+ }
}
/**
diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java
index 71bf107..81496ee 100644
--- a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java
+++ b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java
@@ -59,6 +59,8 @@
private final SuggestionController mSuggestionController;
private final SuggestionControllerHost mHost;
+ private boolean mSuggestionLoaded;
+
public SuggestionControllerMixin(Context context, SuggestionControllerHost host,
Lifecycle lifecycle) {
mContext = context.getApplicationContext();
@@ -106,6 +108,7 @@
@Override
public Loader<List<Suggestion>> onCreateLoader(int id, Bundle args) {
if (id == SuggestionLoader.LOADER_ID_SUGGESTIONS) {
+ mSuggestionLoaded = false;
return new SuggestionLoader(mContext, mSuggestionController);
}
throw new IllegalArgumentException("This loader id is not supported " + id);
@@ -113,12 +116,17 @@
@Override
public void onLoadFinished(Loader<List<Suggestion>> loader, List<Suggestion> data) {
+ mSuggestionLoaded = true;
mHost.onSuggestionReady(data);
}
@Override
public void onLoaderReset(Loader<List<Suggestion>> loader) {
+ mSuggestionLoaded = false;
+ }
+ public boolean isSuggestionLoaded() {
+ return mSuggestionLoaded;
}
public void dismissSuggestion(Suggestion suggestion) {
diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
index ad97e18..790f166 100644
--- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixinTest.java
@@ -18,9 +18,7 @@
import static android.arch.lifecycle.Lifecycle.Event.ON_START;
import static android.arch.lifecycle.Lifecycle.Event.ON_STOP;
-
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -37,9 +35,9 @@
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;
@RunWith(SettingsRobolectricTestRunner.class)
@@ -49,19 +47,18 @@
})
public class SuggestionControllerMixinTest {
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
@Mock
private SuggestionControllerMixin.SuggestionControllerHost mHost;
+ private Context mContext;
private Lifecycle mLifecycle;
private SuggestionControllerMixin mMixin;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- FakeFeatureFactory.setupForTest(mContext);
+ mContext = RuntimeEnvironment.application;
+ FakeFeatureFactory.setupForTest();
mLifecycle = new Lifecycle(() -> mLifecycle);
- when(mContext.getApplicationContext()).thenReturn(mContext);
}
@After
@@ -111,4 +108,17 @@
verify(mHost).getLoaderManager();
}
+
+ @Test
+ public void doneLoadingg_shouldSetSuggestionLoaded() {
+ mMixin = new SuggestionControllerMixin(mContext, mHost, mLifecycle);
+
+ mMixin.onLoadFinished(mock(SuggestionLoader.class), null);
+
+ assertThat(mMixin.isSuggestionLoaded()).isTrue();
+
+ mMixin.onLoaderReset(mock(SuggestionLoader.class));
+
+ assertThat(mMixin.isSuggestionLoaded()).isFalse();
+ }
}