diff options
| author | 2017-05-12 15:40:43 +0200 | |
|---|---|---|
| committer | 2017-05-13 12:33:59 +0200 | |
| commit | 44f4bcb80df76608d4db048aacc27760472d6a2d (patch) | |
| tree | 5032bfbb75e88f6bfa5a7f7b93770f38aafeb1ed | |
| parent | d70695ee34611bee420d901ac9e6470d8c211519 (diff) | |
Fix recents entry delay
- Start loading things after we drew our first frame.
- Don't load high res task until low res tasks have been loaded:
In case the snapshot is already in cache in system_server the
low-res task loader will load the full res snapshot, leading to
GC pressure due to registerNativeAlloc. Now, if both task loader
load the same snapshot at the same time we are very likely
to trigger a blocking GC alloc.
Test: Open recents, look at systrace
Change-Id: I10c263dc8929742611ad9fbb32f65bc8ac3100bd
Fixes: 36851903
Bug: 32668632
4 files changed, 45 insertions, 10 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index 7bc591f4832a..c0e4b99b856e 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -222,6 +222,10 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD getApplicationContext()).onActionEnd( LatencyTracker.ACTION_TOGGLE_RECENTS)); } + DejankUtils.postAfterTraversal(() -> { + Recents.getTaskLoader().startLoader(RecentsActivity.this); + Recents.getTaskLoader().getHighResThumbnailLoader().setVisible(true); + }); return true; } }; @@ -376,8 +380,6 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD // Notify of the next draw mRecentsView.getViewTreeObserver().addOnPreDrawListener(mRecentsDrawnEventListener); - - Recents.getTaskLoader().getHighResThumbnailLoader().setVisible(true); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/HighResThumbnailLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/HighResThumbnailLoader.java index be8da9f38478..974139ad8670 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/HighResThumbnailLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/HighResThumbnailLoader.java @@ -50,6 +50,7 @@ public class HighResThumbnailLoader implements TaskCallbacks { private boolean mLoading; private boolean mVisible; private boolean mFlingingFast; + private boolean mTaskLoadQueueIdle; public HighResThumbnailLoader(SystemServicesProxy ssp, Looper looper) { mMainThreadHandler = new Handler(looper); @@ -71,13 +72,22 @@ public class HighResThumbnailLoader implements TaskCallbacks { updateLoading(); } + /** + * Sets whether the other task load queue is idling. Avoid double-loading bitmaps by not + * starting this queue until the other queue is idling. + */ + public void setTaskLoadQueueIdle(boolean idle) { + mTaskLoadQueueIdle = idle; + updateLoading(); + } + @VisibleForTesting boolean isLoading() { return mLoading; } private void updateLoading() { - setLoading(mVisible && !mFlingingFast); + setLoading(mVisible && !mFlingingFast && mTaskLoadQueueIdle); } private void setLoading(boolean loading) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java index 802cb8315484..97a9659c70fb 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java @@ -48,6 +48,7 @@ import java.util.concurrent.ConcurrentLinkedQueue; * A Task load queue */ class TaskResourceLoadQueue { + ConcurrentLinkedQueue<Task> mQueue = new ConcurrentLinkedQueue<Task>(); /** Adds a new task to the load queue */ @@ -104,15 +105,18 @@ class BackgroundTaskLoader implements Runnable { boolean mCancelled; boolean mWaitingOnLoadQueue; + private final OnIdleChangedListener mOnIdleChangedListener; + /** Constructor, creates a new loading thread that loads task resources in the background */ public BackgroundTaskLoader(TaskResourceLoadQueue loadQueue, TaskKeyLruCache<Drawable> iconCache, Bitmap defaultThumbnail, - BitmapDrawable defaultIcon) { + BitmapDrawable defaultIcon, OnIdleChangedListener onIdleChangedListener) { mLoadQueue = loadQueue; mIconCache = iconCache; mDefaultThumbnail = defaultThumbnail; mDefaultIcon = defaultIcon; mMainThreadHandler = new Handler(); + mOnIdleChangedListener = onIdleChangedListener; mLoadThread = new HandlerThread("Recents-TaskResourceLoader", android.os.Process.THREAD_PRIORITY_BACKGROUND); mLoadThread.start(); @@ -169,7 +173,11 @@ class BackgroundTaskLoader implements Runnable { synchronized(mLoadQueue) { try { mWaitingOnLoadQueue = true; + mMainThreadHandler.post( + () -> mOnIdleChangedListener.onIdleChanged(true)); mLoadQueue.wait(); + mMainThreadHandler.post( + () -> mOnIdleChangedListener.onIdleChanged(false)); mWaitingOnLoadQueue = false; } catch (InterruptedException ie) { ie.printStackTrace(); @@ -230,6 +238,10 @@ class BackgroundTaskLoader implements Runnable { } } } + + interface OnIdleChangedListener { + void onIdleChanged(boolean idle); + } } /** @@ -298,15 +310,16 @@ public class RecentsTaskLoader { // Initialize the proxy, cache and loaders int numRecentTasks = ActivityManager.getMaxRecentTasksStatic(); + mHighResThumbnailLoader = new HighResThumbnailLoader(Recents.getSystemServices(), + Looper.getMainLooper()); mLoadQueue = new TaskResourceLoadQueue(); mIconCache = new TaskKeyLruCache<>(iconCacheSize, mClearActivityInfoOnEviction); mActivityLabelCache = new TaskKeyLruCache<>(numRecentTasks, mClearActivityInfoOnEviction); mContentDescriptionCache = new TaskKeyLruCache<>(numRecentTasks, mClearActivityInfoOnEviction); mActivityInfoCache = new LruCache(numRecentTasks); - mLoader = new BackgroundTaskLoader(mLoadQueue, mIconCache, mDefaultThumbnail, mDefaultIcon); - mHighResThumbnailLoader = new HighResThumbnailLoader(Recents.getSystemServices(), - Looper.getMainLooper()); + mLoader = new BackgroundTaskLoader(mLoadQueue, mIconCache, mDefaultThumbnail, mDefaultIcon, + mHighResThumbnailLoader::setTaskLoadQueueIdle); } /** Returns the size of the app icon cache. */ @@ -360,9 +373,6 @@ public class RecentsTaskLoader { mTempCache.evictAll(); if (!opts.onlyLoadForCache) { mNumVisibleTasksLoaded = opts.numVisibleTasks; - - // Start the loader - mLoader.start(context); } } @@ -608,6 +618,13 @@ public class RecentsTaskLoader { } /** + * Starts loading tasks. + */ + public void startLoader(Context ctx) { + mLoader.start(ctx); + } + + /** * Stops the task loader and clears all queued, pending task loads. */ private void stopLoader() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java b/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java index 4d632af4c935..f57b6b361467 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java @@ -62,6 +62,7 @@ public class HighResThumbnailLoaderTest extends SysuiTestCase { when(mMockSystemServicesProxy.getTaskThumbnail(anyInt(), anyBoolean())) .thenReturn(mThumbnailData); mLoader.setVisible(true); + mLoader.setTaskLoadQueueIdle(true); } @Test @@ -75,6 +76,11 @@ public class HighResThumbnailLoaderTest extends SysuiTestCase { assertFalse(mLoader.isLoading()); mLoader.setFlingingFast(false); assertTrue(mLoader.isLoading()); + mLoader.setFlingingFast(false); + mLoader.setTaskLoadQueueIdle(false); + assertFalse(mLoader.isLoading()); + mLoader.setTaskLoadQueueIdle(true); + assertTrue(mLoader.isLoading()); } @Test |