Enable trim memory callbacks to the loader, background task preloading
- Also enable the high-res thumbnail loader
Bug: 73651529
Change-Id: Ic23997f10289ea10cb1f41104e07029c9102c
Signed-off-by: Winson Chung <winsonc@google.com>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 0956048..9b6c053 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -25,6 +25,9 @@
<dimen name="task_fade_length">20dp</dimen>
<dimen name="recents_page_spacing">10dp</dimen>
+ <!-- The speed in dp/s at which the user needs to be scrolling in recents such that we start
+ loading full resolution screenshots. -->
+ <dimen name="recents_fast_fling_velocity">600dp</dimen>
<dimen name="quickstep_fling_threshold_velocity">500dp</dimen>
<dimen name="quickstep_fling_min_velocity">250dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index 7bd4366..71cdd10 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -29,6 +29,7 @@
import com.android.launcher3.graphics.BitmapRenderer;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.OverviewInteractionState;
+import com.android.quickstep.RecentsModel;
import com.android.quickstep.RecentsView;
import com.android.systemui.shared.recents.view.RecentsTransition;
@@ -88,4 +89,18 @@
RecentsView recents = launcher.getOverviewPanel();
recents.reset();
}
+
+ public static void onStart(Launcher launcher) {
+ RecentsModel model = RecentsModel.getInstance(launcher);
+ if (model != null) {
+ model.onStart();
+ }
+ }
+
+ public static void onTrimMemory(Launcher launcher, int level) {
+ RecentsModel model = RecentsModel.getInstance(launcher);
+ if (model != null) {
+ model.onTrimMemory(level);
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 7fe7751..90e857c 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -16,6 +16,8 @@
package com.android.quickstep;
import android.annotation.TargetApi;
+import android.app.ActivityManager;
+import android.content.ComponentCallbacks2;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -29,6 +31,7 @@
import android.util.LruCache;
import android.util.SparseArray;
+import com.android.launcher3.Launcher;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.util.Preconditions;
@@ -51,7 +54,6 @@
*/
@TargetApi(Build.VERSION_CODES.O)
public class RecentsModel extends TaskStackChangeListener {
-
// We do not need any synchronization for this variable as its only written on UI thread.
private static RecentsModel INSTANCE;
@@ -83,10 +85,16 @@
private int mTaskChangeId;
private ISystemUiProxy mSystemUiProxy;
private boolean mClearAssistCacheOnStackChange = true;
+ private final boolean mPreloadTasksInBackground;
private RecentsModel(Context context) {
mContext = context;
+ ActivityManager activityManager =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ mPreloadTasksInBackground = !activityManager.isLowRamDevice();
+ mMainThreadExecutor = new MainThreadExecutor();
+
Resources res = context.getResources();
mRecentsTaskLoader = new RecentsTaskLoader(mContext,
res.getInteger(R.integer.config_recentsMaxThumbnailCacheSize),
@@ -100,8 +108,6 @@
}
};
mRecentsTaskLoader.startLoader(mContext);
-
- mMainThreadExecutor = new MainThreadExecutor();
ActivityManagerWrapper.getInstance().registerTaskStackListener(this);
mTaskChangeId = 1;
@@ -162,6 +168,31 @@
}
}
+ @Override
+ public void onTaskStackChangedBackground() {
+ int userId = UserHandle.myUserId();
+ if (!mPreloadTasksInBackground || !checkCurrentUserId(userId, false /* debug */)) {
+ // TODO: Only register this for the current user
+ return;
+ }
+
+ // Preload a fixed number of task icons/thumbnails in the background
+ ActivityManager.RunningTaskInfo runningTaskInfo =
+ ActivityManagerWrapper.getInstance().getRunningTask();
+ RecentsTaskLoadPlan plan = new RecentsTaskLoadPlan(mContext);
+ RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
+ launchOpts.runningTaskId = runningTaskInfo != null ? runningTaskInfo.id : -1;
+ launchOpts.numVisibleTasks = 2;
+ launchOpts.numVisibleTaskThumbnails = 2;
+ launchOpts.onlyLoadForCache = true;
+ launchOpts.onlyLoadPausedActivities = true;
+ launchOpts.loadThumbnails = true;
+ PreloadOptions preloadOpts = new PreloadOptions();
+ preloadOpts.loadTitles = false;
+ plan.preloadPlan(preloadOpts, mRecentsTaskLoader, -1, userId);
+ mRecentsTaskLoader.loadTasks(plan, launchOpts);
+ }
+
public boolean isLoadPlanValid(int resultId) {
return mTaskChangeId == resultId;
}
@@ -178,6 +209,19 @@
return mSystemUiProxy;
}
+ public void onStart() {
+ mRecentsTaskLoader.startLoader(mContext);
+ mRecentsTaskLoader.getHighResThumbnailLoader().setVisible(true);
+ }
+
+ public void onTrimMemory(int level) {
+ if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
+ // We already stop the loader in UI_HIDDEN, so stop the high res loader as well
+ mRecentsTaskLoader.getHighResThumbnailLoader().setVisible(false);
+ }
+ mRecentsTaskLoader.onTrimMemory(level);
+ }
+
@WorkerThread
public void preloadAssistData(int taskId, Bundle data) {
mMainThreadExecutor.execute(() -> {
diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java
index 991852a..42677c1 100644
--- a/quickstep/src/com/android/quickstep/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/RecentsView.java
@@ -26,6 +26,7 @@
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
@@ -85,6 +86,8 @@
private LayoutTransition mLayoutTransition;
private Runnable mNextPageSwitchRunnable;
+ private float mFastFlingVelocity;
+
/**
* TODO: Call reloadIdNeeded in onTaskStackChanged.
*/
@@ -199,7 +202,9 @@
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+ Resources res = getResources();
mFirstTaskIndex = getPageCount();
+ mFastFlingVelocity = res.getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
}
@Override
@@ -327,8 +332,10 @@
}
while (getChildCount() > requiredChildCount) {
final TaskView taskView = (TaskView) getChildAt(getChildCount() - 1);
+ final Task task = taskView.getTask();
removeView(taskView);
- loader.unloadTaskData(taskView.getTask());
+ loader.unloadTaskData(task);
+ loader.getHighResThumbnailLoader().onTaskInvisible(task);
}
setLayoutTransition(mLayoutTransition);
@@ -439,11 +446,21 @@
@Override
protected boolean computeScrollHelper() {
boolean scrolling = super.computeScrollHelper();
+ boolean isFlingingFast = false;
updateCurveProperties();
if (scrolling || (mTouchState == TOUCH_STATE_SCROLLING)) {
+ if (scrolling) {
+ // Check if we are flinging quickly to disable high res thumbnail loading
+ isFlingingFast = mScroller.getCurrVelocity() > mFastFlingVelocity;
+ }
+
// After scrolling, update the visible task's data
loadVisibleTaskData();
}
+
+ // Update the high res thumbnail loader
+ RecentsTaskLoader loader = mModel.getRecentsTaskLoader();
+ loader.getHighResThumbnailLoader().setFlingingFast(isFlingingFast);
return scrolling;
}
@@ -488,10 +505,12 @@
if (visible) {
if (!mPrevVisibleTasks.get(i)) {
loader.loadTaskData(task);
+ loader.getHighResThumbnailLoader().onTaskVisible(task);
}
} else {
if (mPrevVisibleTasks.get(i)) {
loader.unloadTaskData(task);
+ loader.getHighResThumbnailLoader().onTaskInvisible(task);
}
}
mPrevVisibleTasks.put(i, visible);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5ac53a8..38b0140 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -829,6 +829,7 @@
mScrimAnimator.start();
}
mShouldFadeInScrim = false;
+ UiFactory.onStart(this);
}
@Override
@@ -2171,6 +2172,7 @@
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onTrimMemory(level);
}
+ UiFactory.onTrimMemory(this, level);
}
@Override
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index ca8039c..6ec209a 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -552,7 +552,6 @@
// Notify the user when the page changes
announceForAccessibility(getCurrentPageDescription());
}
- return true;
}
return false;
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index 64a29ea..a16ae48 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -64,4 +64,8 @@
public static void resetOverview(Launcher launcher) { }
public static void onLauncherStateOrFocusChanged(Launcher launcher) { }
+
+ public static void onStart(Launcher launcher) { }
+
+ public static void onTrimMemory(Launcher launcher, int level) { }
}