Aggressive tuning of recents memory usage

Limit the thumbnail count to a maximum of 10 thumbnails and the app
icon count to a maximum of 20 thumbnails, instead of using a
byte-size based limit.

Also prune entries immediately when leaving recents.

Bug: 16513124
Change-Id: Id9a32f87ca3f9f19e5cad5f115d54b19b26f4f93
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index cc77aaa..e22d78a 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -29,6 +29,12 @@
      ImageView -->
     <bool name="config_recents_thumbnail_image_fits_to_xy">false</bool>
 
+    <!-- The number of app thumbnails we keep in memory -->
+    <integer name="config_recents_max_thumbnail_count">10</integer>
+
+    <!-- The number of app icons we keep in memory -->
+    <integer name="config_recents_max_icon_count">20</integer>
+
     <!-- Control whether status bar should distinguish HSPA data icon form UMTS
     data icon on devices -->
     <bool name="config_hspa_data_distinguishable">false</bool>
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index 6f4cf6b..52ec54b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -68,7 +68,7 @@
 
         public static class RecentsTaskLoader {
             // XXX: This should be calculated on the first load
-            public static final int PreloadFirstTasksCount = 5;
+            public static final int PreloadFirstTasksCount = 6;
         }
 
         public static class TaskStackView {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java
index 757c07f..624a8ff 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/BitmapLruCache.java
@@ -25,10 +25,4 @@
     public BitmapLruCache(int cacheSize) {
         super(cacheSize);
     }
-
-    @Override
-    protected int computeSize(Bitmap b) {
-        // The cache size will be measured in kilobytes rather than number of items
-        return b.getAllocationByteCount();
-    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java
index 5b50358..01a515b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/DrawableLruCache.java
@@ -25,12 +25,4 @@
     public DrawableLruCache(int cacheSize) {
         super(cacheSize);
     }
-
-    @Override
-    protected int computeSize(Drawable d) {
-        // The cache size will be measured in kilobytes rather than number of items
-        // NOTE: this isn't actually correct, as the icon may be smaller
-        int maxBytes = (d.getIntrinsicWidth() * d.getIntrinsicHeight() * 4);
-        return maxBytes;
-    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java
index bb4dc76..7ccefc6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java
@@ -34,10 +34,6 @@
 
     public KeyStoreLruCache(int cacheSize) {
         mCache = new LruCache<Integer, V>(cacheSize) {
-            @Override
-            protected int sizeOf(Integer taskId, V v) {
-                return computeSize(v);
-            }
 
             @Override
             protected void entryRemoved(boolean evicted, Integer taskId, V oldV, V newV) {
@@ -46,11 +42,6 @@
         };
     }
 
-    /** Computes the size of a value. */
-    protected int computeSize(V value) {
-        return 0;
-    }
-
     /** Gets a specific entry in the cache. */
     final V get(Task.TaskKey key) {
         return mCache.get(key.id);
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 f7ad35b..5d7baab 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -29,6 +29,7 @@
 import android.os.UserHandle;
 import android.util.Log;
 
+import com.android.systemui.R;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -123,8 +124,8 @@
         mDefaultThumbnail = defaultThumbnail;
         mDefaultApplicationIcon = defaultApplicationIcon;
         mMainThreadHandler = new Handler();
-        mLoadThread = new HandlerThread("Recents-TaskResourceLoader");
-        mLoadThread.setPriority(Thread.NORM_PRIORITY - 1);
+        mLoadThread = new HandlerThread("Recents-TaskResourceLoader",
+                android.os.Process.THREAD_PRIORITY_DEFAULT - 1);
         mLoadThread.start();
         mLoadThreadHandler = new Handler(mLoadThread.getLooper());
         mLoadThreadHandler.post(this);
@@ -255,12 +256,10 @@
 
     /** Private Constructor */
     private RecentsTaskLoader(Context context) {
-        // Calculate the cache sizes, we just use a reasonable number here similar to those
-        // suggested in the Android docs, 1/6th for the thumbnail cache and 1/30 of the max memory
-        // for icons.
-        int maxMemory = (int) Runtime.getRuntime().maxMemory();
-        mMaxThumbnailCacheSize = maxMemory / 6;
-        mMaxIconCacheSize = mMaxThumbnailCacheSize / 5;
+        mMaxThumbnailCacheSize = context.getResources().getInteger(
+                R.integer.config_recents_max_thumbnail_count);
+        mMaxIconCacheSize = context.getResources().getInteger(
+                R.integer.config_recents_max_icon_count);
         int iconCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 :
                 mMaxIconCacheSize;
         int thumbnailCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 :
@@ -550,6 +549,12 @@
             case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
                 // Stop the loader immediately when the UI is no longer visible
                 stopLoader();
+                mThumbnailCache.trimToSize(Math.max(
+                        Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount,
+                        mMaxThumbnailCacheSize / 2));
+                mApplicationIconCache.trimToSize(Math.max(
+                        Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount,
+                        mMaxIconCacheSize / 2));
                 break;
             case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
             case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/StringLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/StringLruCache.java
index b06c454..6769716 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/StringLruCache.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/StringLruCache.java
@@ -23,10 +23,4 @@
     public StringLruCache(int cacheSize) {
         super(cacheSize);
     }
-
-    @Override
-    protected int computeSize(String s) {
-        // The cache size is measured in number of strings
-        return 1;
-    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 4563597..51adc28 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -41,6 +41,7 @@
 /* A task view */
 public class TaskView extends FrameLayout implements Task.TaskCallbacks,
         TaskViewFooter.TaskFooterViewCallbacks, View.OnClickListener, View.OnLongClickListener {
+
     /** The TaskView callbacks */
     interface TaskViewCallbacks {
         public void onTaskViewAppIconClicked(TaskView tv);