diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 3cd72fc66abce..44e0fd1fdc62c 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -182,6 +182,8 @@
true
true
+
+ 0
true
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index e0c76b1dea026..43d9dc1403d5f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -38,6 +38,18 @@ public class RecentsConfiguration {
static RecentsConfiguration sInstance;
static int sPrevConfigurationHashCode;
+ /** Levels of svelte in increasing severity/austerity. */
+ // No svelting.
+ public static final int SVELTE_NONE = 0;
+ // Limit thumbnail cache to number of visible thumbnails when Recents was loaded, disable
+ // caching thumbnails as you scroll.
+ public static final int SVELTE_LIMIT_CACHE = 1;
+ // Disable the thumbnail cache, load thumbnails asynchronously when the activity loads and
+ // evict all thumbnails when hidden.
+ public static final int SVELTE_DISABLE_CACHE = 2;
+ // Disable all thumbnail loading.
+ public static final int SVELTE_DISABLE_LOADING = 3;
+
/** Animations */
public float animationPxMovementPerSecond;
@@ -128,6 +140,7 @@ public class RecentsConfiguration {
public boolean lockToAppEnabled;
public boolean developerOptionsEnabled;
public boolean debugModeEnabled;
+ public int svelteLevel;
/** Private constructor */
private RecentsConfiguration(Context context) {
@@ -277,6 +290,7 @@ public class RecentsConfiguration {
useHardwareLayers = res.getBoolean(R.bool.config_recents_use_hardware_layers);
altTabKeyDelay = res.getInteger(R.integer.recents_alt_tab_key_delay);
fakeShadows = res.getBoolean(R.bool.config_recents_fake_shadows);
+ svelteLevel = res.getInteger(R.integer.recents_svelte_level);
}
/** Updates the system insets */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 33c4b055c07d8..0011811f942ac 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -155,7 +155,8 @@ public class RecentsTaskLoadPlan {
/**
* Called to apply the actual loading based on the specified conditions.
*/
- synchronized void executePlan(Options opts, RecentsTaskLoader loader) {
+ synchronized void executePlan(Options opts, RecentsTaskLoader loader,
+ TaskResourceLoadQueue loadQueue) {
if (DEBUG) Log.d(TAG, "executePlan, # tasks: " + opts.numVisibleTasks +
", # thumbnails: " + opts.numVisibleTaskThumbnails +
", running task id: " + opts.runningTaskId);
@@ -195,8 +196,12 @@ public class RecentsTaskLoadPlan {
if (opts.loadThumbnails && (isRunningTask || isVisibleThumbnail)) {
if (task.thumbnail == null) {
if (DEBUG) Log.d(TAG, "\tLoading thumbnail: " + taskKey);
- task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy,
- true);
+ if (mConfig.svelteLevel <= RecentsConfiguration.SVELTE_LIMIT_CACHE) {
+ task.thumbnail = loader.getAndUpdateThumbnail(taskKey, mSystemServicesProxy,
+ true);
+ } else if (mConfig.svelteLevel == RecentsConfiguration.SVELTE_DISABLE_CACHE) {
+ loadQueue.addTask(task);
+ }
}
}
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 599d3cee38478..67a36b97eaa83 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -94,6 +94,9 @@ class TaskResourceLoadQueue {
/* Task resource loader */
class TaskResourceLoader implements Runnable {
+ static String TAG = "TaskResourceLoader";
+ static boolean DEBUG = false;
+
Context mContext;
HandlerThread mLoadThread;
Handler mLoadThreadHandler;
@@ -165,6 +168,7 @@ class TaskResourceLoader implements Runnable {
}
}
} else {
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
SystemServicesProxy ssp = mSystemServicesProxy;
// If we've stopped the loader, then fall thorugh to the above logic to wait on
// the load thread
@@ -185,6 +189,7 @@ class TaskResourceLoader implements Runnable {
ActivityInfo info = ssp.getActivityInfo(t.key.baseIntent.getComponent(),
t.key.userId);
if (info != null) {
+ if (DEBUG) Log.d(TAG, "Loading icon: " + t.key);
cachedIcon = ssp.getActivityIcon(info, t.key.userId);
}
}
@@ -199,11 +204,19 @@ class TaskResourceLoader implements Runnable {
}
// Load the thumbnail if it is stale or we haven't cached one yet
if (cachedThumbnail == null) {
- cachedThumbnail = ssp.getTaskThumbnail(t.key.id);
+ if (config.svelteLevel < RecentsConfiguration.SVELTE_DISABLE_LOADING) {
+ if (DEBUG) Log.d(TAG, "Loading thumbnail: " + t.key);
+ cachedThumbnail = ssp.getTaskThumbnail(t.key.id);
+ }
if (cachedThumbnail == null) {
cachedThumbnail = mDefaultThumbnail;
}
- mThumbnailCache.put(t.key, cachedThumbnail);
+ // When svelte, we trim the memory to just the visible thumbnails when
+ // leaving, so don't thrash the cache as the user scrolls (just load them
+ // from scratch each time)
+ if (config.svelteLevel < RecentsConfiguration.SVELTE_LIMIT_CACHE) {
+ mThumbnailCache.put(t.key, cachedThumbnail);
+ }
}
if (!mCancelled) {
// Notify that the task data has changed
@@ -267,6 +280,7 @@ public class RecentsTaskLoader {
int mMaxThumbnailCacheSize;
int mMaxIconCacheSize;
int mNumVisibleTasksLoaded;
+ int mNumVisibleThumbnailsLoaded;
BitmapDrawable mDefaultApplicationIcon;
Bitmap mDefaultThumbnail;
@@ -392,7 +406,8 @@ public class RecentsTaskLoader {
return thumbnail;
}
- if (loadIfNotCached) {
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
+ if (config.svelteLevel < RecentsConfiguration.SVELTE_DISABLE_LOADING && loadIfNotCached) {
// Load the thumbnail from the system
thumbnail = ssp.getTaskThumbnail(taskKey.id);
if (thumbnail != null) {
@@ -441,9 +456,10 @@ public class RecentsTaskLoader {
if (opts == null) {
throw new RuntimeException("Requires load options");
}
- plan.executePlan(opts, this);
+ plan.executePlan(opts, this, mLoadQueue);
if (!opts.onlyLoadForCache) {
mNumVisibleTasksLoaded = opts.numVisibleTasks;
+ mNumVisibleThumbnailsLoaded = opts.numVisibleTaskThumbnails;
// Start the loader
mLoader.start(context);
@@ -503,12 +519,19 @@ public class RecentsTaskLoader {
* out of memory.
*/
public void onTrimMemory(int level) {
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
switch (level) {
case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
// Stop the loader immediately when the UI is no longer visible
stopLoader();
- mThumbnailCache.trimToSize(Math.max(mNumVisibleTasksLoaded,
- mMaxThumbnailCacheSize / 2));
+ if (config.svelteLevel == RecentsConfiguration.SVELTE_NONE) {
+ mThumbnailCache.trimToSize(Math.max(mNumVisibleTasksLoaded,
+ mMaxThumbnailCacheSize / 2));
+ } else if (config.svelteLevel == RecentsConfiguration.SVELTE_LIMIT_CACHE) {
+ mThumbnailCache.trimToSize(mNumVisibleThumbnailsLoaded);
+ } else if (config.svelteLevel >= RecentsConfiguration.SVELTE_DISABLE_CACHE) {
+ mThumbnailCache.evictAll();
+ }
mApplicationIconCache.trimToSize(Math.max(mNumVisibleTasksLoaded,
mMaxIconCacheSize / 2));
break;