Adding outline cache for PagedViewIcons.

Change-Id: I258740a0323660edd73b5f40d61d509455ae195b
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java
index 378c248..a673304 100644
--- a/src/com/android/launcher2/AllAppsPagedView.java
+++ b/src/com/android/launcher2/AllAppsPagedView.java
@@ -211,6 +211,7 @@
         mApps = list;
         Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR);
         mFilteredApps = rebuildFilteredApps(mApps);
+        mPageViewIconCache.clear();
         invalidatePageData();
     }
 
@@ -236,9 +237,11 @@
         // loop through all the apps and remove apps that have the same component
         final int length = list.size();
         for (int i = 0; i < length; ++i) {
-            int removeIndex = findAppByComponent(mApps, list.get(i));
+            final ApplicationInfo info = list.get(i);
+            int removeIndex = findAppByComponent(mApps, info);
             if (removeIndex > -1) {
                 mApps.remove(removeIndex);
+                mPageViewIconCache.removeOutline(info);
             }
         }
         mFilteredApps = rebuildFilteredApps(mApps);
@@ -327,16 +330,13 @@
 
         // actually reapply to the existing text views
         for (int i = startIndex; i < endIndex; ++i) {
-            int index = i - startIndex;
-            ApplicationInfo info = mFilteredApps.get(i);
-            TextView text = (TextView) layout.getChildAt(index);
-            text.setCompoundDrawablesWithIntrinsicBounds(null,
-                new FastBitmapDrawable(info.iconBitmap), null, null);
-            text.setText(info.title);
-            text.setTag(info);
+            final int index = i - startIndex;
+            final ApplicationInfo info = mFilteredApps.get(i);
+            PagedViewIcon icon = (PagedViewIcon) layout.getChildAt(index);
+            icon.applyFromApplicationInfo(info, mPageViewIconCache);
 
             PagedViewCellLayout.LayoutParams params = 
-                (PagedViewCellLayout.LayoutParams) text.getLayoutParams();
+                (PagedViewCellLayout.LayoutParams) icon.getLayoutParams();
             params.cellX = index % mCellCountX;
             params.cellY = index / mCellCountX;
         }
diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java
index 4488497..786300b 100644
--- a/src/com/android/launcher2/CustomizePagedView.java
+++ b/src/com/android/launcher2/CustomizePagedView.java
@@ -136,6 +136,9 @@
         mShortcutList = mPackageManager.queryIntentActivities(shortcutsIntent, 0);
         Collections.sort(mShortcutList, resolveInfoComparator);
 
+        // reset the icon cache
+        mPageViewIconCache.clear();
+
         invalidatePageData();
     }
 
@@ -443,19 +446,15 @@
         layout.removeAllViews();
         for (int i = startIndex; i < endIndex; ++i) {
             ResolveInfo info = list.get(i);
-            Drawable image = info.loadIcon(mPackageManager);
-            TextView text = (TextView) mInflater.inflate(R.layout.customize_paged_view_item, 
-                    layout, false);
-            image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
-            text.setCompoundDrawablesWithIntrinsicBounds(null, image, null, null);
-            text.setText(info.loadLabel(mPackageManager));
-            text.setTag(info);
-            text.setOnLongClickListener(this);
+            PagedViewIcon icon = (PagedViewIcon) mInflater.inflate(
+                    R.layout.customize_paged_view_item, layout, false);
+            icon.applyFromResolveInfo(info, mPackageManager, mPageViewIconCache);
+            icon.setOnLongClickListener(this);
 
             final int index = i - startIndex;
             final int x = index % mCellCountX;
             final int y = index / mCellCountX;
-            layout.addViewToCellLayout(text, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1));
+            layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1));
         }
     }
 
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index d56e7ac..6154947 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -18,8 +18,10 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 
 import android.content.Context;
+import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.os.Parcel;
@@ -87,6 +89,30 @@
     private ArrayList<Boolean> mDirtyPageContent;
     private boolean mDirtyPageAlpha;
 
+    protected PagedViewIconCache mPageViewIconCache;
+
+    /**
+     * Simple cache mechanism for PagedViewIcon outlines.
+     */
+    class PagedViewIconCache {
+        private final HashMap<Object, Bitmap> iconOutlineCache = new HashMap<Object, Bitmap>();
+
+        public void clear() {
+            iconOutlineCache.clear();
+        }
+        public void addOutline(Object key, Bitmap b) {
+            iconOutlineCache.put(key, b);
+        }
+        public void removeOutline(Object key) {
+            if (iconOutlineCache.containsKey(key)) {
+                iconOutlineCache.remove(key);
+            }
+        }
+        public Bitmap getOutline(Object key) {
+            return iconOutlineCache.get(key);
+        }
+    }
+
     public interface PageSwitchListener {
         void onPageSwitch(View newPage, int newPageIndex);
     }
@@ -112,6 +138,7 @@
     private void initWorkspace() {
         mDirtyPageContent = new ArrayList<Boolean>();
         mDirtyPageContent.ensureCapacity(32);
+        mPageViewIconCache = new PagedViewIconCache();
         mScroller = new Scroller(getContext());
         mCurrentPage = 0;
 
diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java
index 598761e..e227569 100644
--- a/src/com/android/launcher2/PagedViewIcon.java
+++ b/src/com/android/launcher2/PagedViewIcon.java
@@ -17,6 +17,8 @@
 package com.android.launcher2;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BlurMaskFilter;
@@ -31,9 +33,12 @@
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.Log;
 import android.widget.Checkable;
 import android.widget.TextView;
 
+import com.android.launcher2.PagedView.PagedViewIconCache;
+
 class HolographicOutlineHelper {
     private final Paint mHolographicPaint = new Paint();
     private final Paint mBlurPaint = new Paint();
@@ -138,6 +143,9 @@
     private boolean mIsHolographicUpdatePass;
     private Rect mDrawableClipRect;
 
+    private Object mIconCacheKey;
+    private PagedViewIconCache mIconCache;
+
     private int mAlpha;
     private int mHolographicAlpha;
 
@@ -166,6 +174,30 @@
         setBackgroundDrawable(null);
     }
 
+    public void applyFromApplicationInfo(ApplicationInfo info, PagedViewIconCache cache) {
+        mIconCache = cache;
+        mIconCacheKey = info;
+        mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
+
+        setCompoundDrawablesWithIntrinsicBounds(null,
+                new FastBitmapDrawable(info.iconBitmap), null, null);
+        setText(info.title);
+        setTag(info);
+    }
+
+    public void applyFromResolveInfo(ResolveInfo info, PackageManager packageManager,
+            PagedViewIconCache cache) {
+        mIconCache = cache;
+        mIconCacheKey = info;
+        mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
+
+        Drawable image = info.loadIcon(packageManager);
+        image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
+        setCompoundDrawablesWithIntrinsicBounds(null, image, null, null);
+        setText(info.loadLabel(packageManager));
+        setTag(info);
+    }
+
     @Override
     public void setAlpha(float alpha) {
         final float viewAlpha = sHolographicOutlineHelper.viewAlphaInterpolator(alpha);
@@ -176,21 +208,6 @@
     }
 
     @Override
-    public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top,
-            Drawable right, Drawable bottom) {
-        invalidateHolographicImage();
-        super.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
-    }
-
-    public void invalidateHolographicImage() {
-        if (mHolographicOutline != null) {
-            mHolographicOutline.recycle();
-            mHolographicOutline = null;
-            mHolographicOutlineCanvas = null;
-        }
-    }
-
-    @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
 
@@ -215,6 +232,7 @@
                     offset);
             sHolographicOutlineHelper.applyBlur(mHolographicOutline, mHolographicOutlineCanvas);
             mIsHolographicUpdatePass = false;
+            mIconCache.addOutline(mIconCacheKey, mHolographicOutline);
         }
     }