diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java index b7c87150fc2..8f66b67f4d9 100644 --- a/src/com/android/settings/dashboard/DashboardSummary.java +++ b/src/com/android/settings/dashboard/DashboardSummary.java @@ -24,6 +24,7 @@ import android.os.Bundle; import android.os.Handler; import android.service.settings.suggestions.Suggestion; import android.support.annotation.VisibleForTesting; +import android.support.annotation.WorkerThread; import android.support.v7.widget.LinearLayoutManager; import android.util.Log; import android.view.LayoutInflater; @@ -50,6 +51,7 @@ import com.android.settingslib.drawer.SettingsDrawerActivity.CategoryListener; import com.android.settingslib.drawer.Tile; import com.android.settingslib.suggestions.SuggestionList; import com.android.settingslib.suggestions.SuggestionParser; +import com.android.settingslib.utils.ThreadUtils; import java.util.ArrayList; import java.util.List; @@ -181,12 +183,6 @@ public class DashboardSummary extends InstrumentedFragment } } - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - return inflater.inflate(R.layout.dashboard, container, false); - } - @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -198,9 +194,10 @@ public class DashboardSummary extends InstrumentedFragment } @Override - public void onViewCreated(View view, Bundle bundle) { + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { long startTime = System.currentTimeMillis(); - mDashboard = view.findViewById(R.id.dashboard_container); + final View root = inflater.inflate(R.layout.dashboard, container, false); + mDashboard = root.findViewById(R.id.dashboard_container); mLayoutManager = new LinearLayoutManager(getContext()); mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); if (bundle != null) { @@ -218,19 +215,19 @@ public class DashboardSummary extends InstrumentedFragment mSummaryLoader.setSummaryConsumer(mAdapter); ActionBarShadowController.attachToRecyclerView( getActivity().findViewById(R.id.search_bar_container), getLifecycle(), mDashboard); - + rebuildUI(); if (DEBUG_TIMING) { - Log.d(TAG, "onViewCreated took " + Log.d(TAG, "onCreateView took " + (System.currentTimeMillis() - startTime) + " ms"); } - rebuildUI(); + return root; } @VisibleForTesting void rebuildUI() { if (!mSuggestionFeatureProvider.isSuggestionEnabled(getContext())) { Log.d(TAG, "Suggestion v1 feature is disabled, skipping suggestion v1"); - updateCategory(); + ThreadUtils.postOnBackgroundThread(() -> updateCategory()); } else { new SuggestionLoader().execute(); // Set categories on their own if loading suggestions takes too long. @@ -340,11 +337,12 @@ public class DashboardSummary extends InstrumentedFragment } } + @WorkerThread void updateCategory() { final DashboardCategory category = mDashboardFeatureProvider.getTilesForCategory( CategoryKey.CATEGORY_HOMEPAGE); mSummaryLoader.updateSummaryToCache(category); - mAdapter.setCategory(category); + ThreadUtils.postOnMainThread(() -> mAdapter.setCategory(category)); } /** diff --git a/src/com/android/settings/dashboard/SummaryLoader.java b/src/com/android/settings/dashboard/SummaryLoader.java index 5816bba8237..fe55be802a9 100644 --- a/src/com/android/settings/dashboard/SummaryLoader.java +++ b/src/com/android/settings/dashboard/SummaryLoader.java @@ -60,23 +60,6 @@ public class SummaryLoader { private boolean mWorkerListening; private ArraySet mReceivers = new ArraySet<>(); - public SummaryLoader(Activity activity, List categories) { - mDashboardFeatureProvider = FeatureFactory.getFactory(activity) - .getDashboardFeatureProvider(activity); - mCategoryKey = null; - mWorkerThread = new HandlerThread("SummaryLoader", Process.THREAD_PRIORITY_BACKGROUND); - mWorkerThread.start(); - mWorker = new Worker(mWorkerThread.getLooper()); - mActivity = activity; - for (int i = 0; i < categories.size(); i++) { - List tiles = categories.get(i).tiles; - for (int j = 0; j < tiles.size(); j++) { - Tile tile = tiles.get(j); - mWorker.obtainMessage(Worker.MSG_GET_PROVIDER, tile).sendToTarget(); - } - } - } - public SummaryLoader(Activity activity, String categoryKey) { mDashboardFeatureProvider = FeatureFactory.getFactory(activity) .getDashboardFeatureProvider(activity); @@ -85,17 +68,6 @@ public class SummaryLoader { mWorkerThread.start(); mWorker = new Worker(mWorkerThread.getLooper()); mActivity = activity; - - final DashboardCategory category = - mDashboardFeatureProvider.getTilesForCategory(categoryKey); - if (category == null || category.tiles == null) { - return; - } - - List tiles = category.tiles; - for (Tile tile : tiles) { - mWorker.obtainMessage(Worker.MSG_GET_PROVIDER, tile).sendToTarget(); - } } public void release() { @@ -153,15 +125,32 @@ public class SummaryLoader { * Only call from the main thread. */ public void setListening(boolean listening) { - if (mListening == listening) return; + if (mListening == listening) { + return; + } mListening = listening; // Unregister listeners immediately. for (int i = 0; i < mReceivers.size(); i++) { mActivity.unregisterReceiver(mReceivers.valueAt(i)); } mReceivers.clear(); + mWorker.removeMessages(Worker.MSG_SET_LISTENING); - mWorker.obtainMessage(Worker.MSG_SET_LISTENING, listening ? 1 : 0, 0).sendToTarget(); + if (!listening) { + // Stop listen + mWorker.obtainMessage(Worker.MSG_SET_LISTENING, 0 /* listening */).sendToTarget(); + } else { + // Start listen + if (mSummaryProviderMap.isEmpty()) { + // Category not initialized yet, init before starting to listen + if (!mWorker.hasMessages(Worker.MSG_GET_CATEGORY_TILES_AND_SET_LISTENING)) { + mWorker.sendEmptyMessage(Worker.MSG_GET_CATEGORY_TILES_AND_SET_LISTENING); + } + } else { + // Category already initialized, start listening immediately + mWorker.obtainMessage(Worker.MSG_SET_LISTENING, 1 /* listening */).sendToTarget(); + } + } } private SummaryProvider getSummaryProvider(Tile tile) { @@ -236,9 +225,13 @@ public class SummaryLoader { } private synchronized void setListeningW(boolean listening) { - if (mWorkerListening == listening) return; + if (mWorkerListening == listening) { + return; + } mWorkerListening = listening; - if (DEBUG) Log.d(TAG, "Listening " + listening); + if (DEBUG) { + Log.d(TAG, "Listening " + listening); + } for (SummaryProvider p : mSummaryProviderMap.keySet()) { try { p.setListening(listening); @@ -271,7 +264,6 @@ public class SummaryLoader { } - public interface SummaryProvider { void setListening(boolean listening); } @@ -285,8 +277,9 @@ public class SummaryLoader { } private class Worker extends Handler { - private static final int MSG_GET_PROVIDER = 1; - private static final int MSG_SET_LISTENING = 2; + private static final int MSG_GET_CATEGORY_TILES_AND_SET_LISTENING = 1; + private static final int MSG_GET_PROVIDER = 2; + private static final int MSG_SET_LISTENING = 3; public Worker(Looper looper) { super(looper); @@ -295,6 +288,18 @@ public class SummaryLoader { @Override public void handleMessage(Message msg) { switch (msg.what) { + case MSG_GET_CATEGORY_TILES_AND_SET_LISTENING: + final DashboardCategory category = + mDashboardFeatureProvider.getTilesForCategory(mCategoryKey); + if (category == null || category.tiles == null) { + return; + } + final List tiles = category.tiles; + for (Tile tile : tiles) { + makeProviderW(tile); + } + setListeningW(true); + break; case MSG_GET_PROVIDER: Tile tile = (Tile) msg.obj; makeProviderW(tile); diff --git a/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java b/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java index 146be9c7acb..44b61398b23 100644 --- a/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/SummaryLoaderTest.java @@ -16,6 +16,10 @@ package com.android.settings.dashboard; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -23,6 +27,7 @@ import android.content.Intent; import com.android.settings.TestConfig; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.Tile; @@ -35,12 +40,6 @@ import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; import org.robolectric.annotation.Config; -import java.util.ArrayList; -import java.util.List; - -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.when; - @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class SummaryLoaderTest { @@ -65,14 +64,14 @@ public class SummaryLoaderTest { mCallbackInvoked = false; final Activity activity = Robolectric.buildActivity(Activity.class).get(); - final List categories = new ArrayList<>(); - mSummaryLoader = new SummaryLoader(activity, categories); - mSummaryLoader.setSummaryConsumer(new SummaryLoader.SummaryConsumer() { - @Override - public void notifySummaryChanged(Tile tile) { - mCallbackInvoked = true; - } - }); + + mSummaryLoader = new SummaryLoader(activity, CategoryKey.CATEGORY_HOMEPAGE); + mSummaryLoader.setSummaryConsumer(tile -> mCallbackInvoked = true); + } + + @Test + public void newInstance_shouldNotLoadCategory() { + verifyZeroInteractions(mFeatureFactory.dashboardFeatureProvider); } @Test