Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbc97bc7 authored by Fan Zhang's avatar Fan Zhang
Browse files

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
parent d786fc5b
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -161,7 +161,6 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
    }

    public void setSuggestionsV2(List<Suggestion> data) {
        // TODO: Tint icon
        final DashboardData prevData = mDashboardData;
        mDashboardData = new DashboardData.Builder(prevData)
                .setSuggestionsV2(data)
+22 −1
Original line number Diff line number Diff line
@@ -81,6 +81,9 @@ public class DashboardSummary extends InstrumentedFragment
    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 @@ public class DashboardSummary extends InstrumentedFragment

    @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 @@ public class DashboardSummary extends InstrumentedFragment
        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);
        }
    }

    /**
+8 −0
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ public class SuggestionControllerMixin implements SuggestionController.ServiceCo
    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 @@ public class SuggestionControllerMixin implements SuggestionController.ServiceCo
    @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 @@ public class SuggestionControllerMixin implements SuggestionController.ServiceCo

    @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) {
+17 −7
Original line number Diff line number Diff line
@@ -18,9 +18,7 @@ package com.android.settings.dashboard.suggestions;

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.After;
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 @@ import org.robolectric.annotation.Config;
        })
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 @@ public class SuggestionControllerMixinTest {

        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();
    }
}