Merge "Adding RTL paging."
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index a9f7faf..3f8360f 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -75,7 +75,7 @@
     }
 
     AsyncTaskPageData(int p, ArrayList<Object> l, int cw, int ch, AsyncTaskCallback bgR,
-            AsyncTaskCallback postR) {
+            AsyncTaskCallback postR, WidgetPreviewLoader w) {
         page = p;
         items = l;
         generatedImages = new ArrayList<Bitmap>();
@@ -83,13 +83,14 @@
         maxImageHeight = ch;
         doInBackgroundCallback = bgR;
         postExecuteCallback = postR;
+        widgetPreviewLoader = w;
     }
     void cleanup(boolean cancelled) {
         // Clean up any references to source/generated bitmaps
         if (generatedImages != null) {
             if (cancelled) {
                 for (int i = 0; i < generatedImages.size(); i++) {
-                    WidgetPreviewLoader.releaseBitmap(items.get(i), generatedImages.get(i));
+                    widgetPreviewLoader.releaseBitmap(items.get(i), generatedImages.get(i));
                 }
             }
             generatedImages.clear();
@@ -103,6 +104,7 @@
     int maxImageHeight;
     AsyncTaskCallback doInBackgroundCallback;
     AsyncTaskCallback postExecuteCallback;
+    WidgetPreviewLoader widgetPreviewLoader;
 }
 
 /**
@@ -346,6 +348,10 @@
     }
 
     protected void onDataReady(int width, int height) {
+        if (mWidgetPreviewLoader == null) {
+            mWidgetPreviewLoader = new WidgetPreviewLoader(mLauncher);
+        }
+
         // Note that we transpose the counts in portrait so that we get a similar layout
         boolean isLandscape = getResources().getConfiguration().orientation ==
             Configuration.ORIENTATION_LANDSCAPE;
@@ -1110,7 +1116,7 @@
                     // do cleanup inside onSyncWidgetPageItems
                     onSyncWidgetPageItems(data);
                 }
-            });
+            }, mWidgetPreviewLoader);
 
         // Ensure that the task is appropriately prioritized and runs in parallel
         AppsCustomizeAsyncTask t = new AppsCustomizeAsyncTask(page,
@@ -1174,7 +1180,7 @@
                 createItemInfo.minSpanX = minSpanXY[0];
                 createItemInfo.minSpanY = minSpanXY[1];
 
-                widget.applyFromAppWidgetProviderInfo(info, -1, spanXY);
+                widget.applyFromAppWidgetProviderInfo(info, -1, spanXY, mWidgetPreviewLoader);
                 widget.setTag(createItemInfo);
                 widget.setShortPressListener(this);
             } else if (rawInfo instanceof ResolveInfo) {
@@ -1184,7 +1190,7 @@
                 createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
                 createItemInfo.componentName = new ComponentName(info.activityInfo.packageName,
                         info.activityInfo.name);
-                widget.applyFromResolveInfo(mPackageManager, info);
+                widget.applyFromResolveInfo(mPackageManager, info, mWidgetPreviewLoader);
                 widget.setTag(createItemInfo);
             }
             widget.setOnClickListener(this);
@@ -1221,13 +1227,11 @@
                     maxPreviewHeight = maxSize[1];
                 }
 
-                if (mWidgetPreviewLoader == null) {
-                    mWidgetPreviewLoader = new WidgetPreviewLoader(
-                            maxPreviewWidth, maxPreviewHeight, mLauncher, mWidgetSpacingLayout);
-                }
+                mWidgetPreviewLoader.setPreviewSize(
+                        maxPreviewWidth, maxPreviewHeight, mWidgetSpacingLayout);
                 if (immediate) {
                     AsyncTaskPageData data = new AsyncTaskPageData(page, items,
-                            maxPreviewWidth, maxPreviewHeight, null, null);
+                            maxPreviewWidth, maxPreviewHeight, null, null, mWidgetPreviewLoader);
                     loadWidgetPreviewsInBackground(null, data);
                     onSyncWidgetPageItems(data);
                 } else {
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 1ee1c4a..aece398 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -47,6 +47,7 @@
     boolean mIsAppWidget;
     private final Rect mOriginalImagePadding = new Rect();
     private Object mInfo;
+    private WidgetPreviewLoader mWidgetPreviewLoader;
 
     public PagedViewWidget(Context context) {
         this(context, null);
@@ -90,7 +91,7 @@
             if (image != null) {
                 FastBitmapDrawable preview = (FastBitmapDrawable) image.getDrawable();
                 if (mInfo != null && preview != null && preview.getBitmap() != null) {
-                    WidgetPreviewLoader.releaseBitmap(mInfo, preview.getBitmap());
+                    mWidgetPreviewLoader.releaseBitmap(mInfo, preview.getBitmap());
                 }
                 image.setImageDrawable(null);
             }
@@ -98,7 +99,7 @@
     }
 
     public void applyFromAppWidgetProviderInfo(AppWidgetProviderInfo info,
-            int maxWidth, int[] cellSpan) {
+            int maxWidth, int[] cellSpan, WidgetPreviewLoader loader) {
         mIsAppWidget = true;
         mInfo = info;
         final ImageView image = (ImageView) findViewById(R.id.widget_preview);
@@ -114,9 +115,11 @@
             int vSpan = Math.min(cellSpan[1], LauncherModel.getCellCountY());
             dims.setText(String.format(mDimensionsFormatString, hSpan, vSpan));
         }
+        mWidgetPreviewLoader = loader;
     }
 
-    public void applyFromResolveInfo(PackageManager pm, ResolveInfo info) {
+    public void applyFromResolveInfo(
+            PackageManager pm, ResolveInfo info, WidgetPreviewLoader loader) {
         mIsAppWidget = false;
         mInfo = info;
         CharSequence label = info.loadLabel(pm);
@@ -128,6 +131,7 @@
         if (dims != null) {
             dims.setText(String.format(mDimensionsFormatString, 1, 1));
         }
+        mWidgetPreviewLoader = loader;
     }
 
     public int[] getPreviewSize() {
diff --git a/src/com/android/launcher2/WidgetPreviewLoader.java b/src/com/android/launcher2/WidgetPreviewLoader.java
index 2d10967..052151c 100644
--- a/src/com/android/launcher2/WidgetPreviewLoader.java
+++ b/src/com/android/launcher2/WidgetPreviewLoader.java
@@ -103,8 +103,8 @@
 public class WidgetPreviewLoader {
     static final String TAG = "WidgetPreviewLoader";
 
-    private int mPreviewBitmapMaxWidth;
-    private int mPreviewBitmapMaxHeight;
+    private int mPreviewBitmapWidth;
+    private int mPreviewBitmapHeight;
     private String mSize;
     private Context mContext;
     private Launcher mLauncher;
@@ -131,27 +131,30 @@
 
     private WidgetPreviewCacheDb mDb;
 
-    private static HashMap<String, WeakReference<Bitmap>> sLoadedPreviews;
-    private static ArrayList<SoftReference<Bitmap>> sUnusedBitmaps;
+    private HashMap<String, WeakReference<Bitmap>> mLoadedPreviews;
+    private ArrayList<SoftReference<Bitmap>> mUnusedBitmaps;
     private static HashSet<String> sInvalidPackages;
 
     static {
-        sLoadedPreviews = new HashMap<String, WeakReference<Bitmap>>();
-        sUnusedBitmaps = new ArrayList<SoftReference<Bitmap>>();
         sInvalidPackages = new HashSet<String>();
     }
 
-    public WidgetPreviewLoader(int previewWidth, int previewHeight,
-            Launcher launcher, PagedViewCellLayout widgetSpacingLayout) {
-        mPreviewBitmapMaxWidth = previewWidth;
-        mPreviewBitmapMaxHeight = previewHeight;
-        mSize = previewWidth + "x" + previewHeight;
+    public WidgetPreviewLoader(Launcher launcher) {
         mContext = mLauncher = launcher;
         mPackageManager = mContext.getPackageManager();
         mAppIconSize = mContext.getResources().getDimensionPixelSize(R.dimen.app_icon_size);
         mIconCache = ((LauncherApplication) launcher.getApplicationContext()).getIconCache();
-        mWidgetSpacingLayout = widgetSpacingLayout;
         mDb = new WidgetPreviewCacheDb(mContext);
+        mLoadedPreviews = new HashMap<String, WeakReference<Bitmap>>();
+        mUnusedBitmaps = new ArrayList<SoftReference<Bitmap>>();
+    }
+
+    public void setPreviewSize(int previewWidth, int previewHeight,
+            PagedViewCellLayout widgetSpacingLayout) {
+        mPreviewBitmapWidth = previewWidth;
+        mPreviewBitmapHeight = previewHeight;
+        mSize = previewWidth + "x" + previewHeight;
+        mWidgetSpacingLayout = widgetSpacingLayout;
     }
 
     public Bitmap getPreview(final Object o) {
@@ -165,20 +168,22 @@
             return null;
         }
         if (packageValid) {
-            synchronized(sLoadedPreviews) {
+            synchronized(mLoadedPreviews) {
                 // check if it exists in our existing cache
-                if (sLoadedPreviews.containsKey(name) && sLoadedPreviews.get(name).get() != null) {
-                    return sLoadedPreviews.get(name).get();
+                if (mLoadedPreviews.containsKey(name) && mLoadedPreviews.get(name).get() != null) {
+                    return mLoadedPreviews.get(name).get();
                 }
             }
         }
 
         Bitmap unusedBitmap = null;
-        synchronized(sUnusedBitmaps) {
+        synchronized(mUnusedBitmaps) {
             // not in cache; we need to load it from the db
-            while ((unusedBitmap == null || !unusedBitmap.isMutable())
-                    && sUnusedBitmaps.size() > 0) {
-                unusedBitmap = sUnusedBitmaps.remove(0).get();
+            while ((unusedBitmap == null || !unusedBitmap.isMutable() ||
+                    unusedBitmap.getWidth() != mPreviewBitmapWidth ||
+                    unusedBitmap.getHeight() != mPreviewBitmapHeight)
+                    && mUnusedBitmaps.size() > 0) {
+                unusedBitmap = mUnusedBitmaps.remove(0).get();
             }
             if (unusedBitmap != null) {
                 final Canvas c = mCachedAppWidgetPreviewCanvas.get();
@@ -189,7 +194,7 @@
         }
 
         if (unusedBitmap == null) {
-            unusedBitmap = Bitmap.createBitmap(mPreviewBitmapMaxWidth, mPreviewBitmapMaxHeight,
+            unusedBitmap = Bitmap.createBitmap(mPreviewBitmapWidth, mPreviewBitmapHeight,
                     Bitmap.Config.ARGB_8888);
         }
 
@@ -200,8 +205,8 @@
         }
 
         if (preview != null) {
-            synchronized(sLoadedPreviews) {
-                sLoadedPreviews.put(name, new WeakReference<Bitmap>(preview));
+            synchronized(mLoadedPreviews) {
+                mLoadedPreviews.put(name, new WeakReference<Bitmap>(preview));
             }
             return preview;
         } else {
@@ -212,8 +217,8 @@
                 throw new RuntimeException("generatePreview is not recycling the bitmap " + o);
             }
 
-            synchronized(sLoadedPreviews) {
-                sLoadedPreviews.put(name, new WeakReference<Bitmap>(preview));
+            synchronized(mLoadedPreviews) {
+                mLoadedPreviews.put(name, new WeakReference<Bitmap>(preview));
             }
 
             // write to db on a thread pool... this can be done lazily and improves the performance
@@ -229,16 +234,16 @@
         }
     }
 
-    public static void releaseBitmap(Object o, Bitmap bitmapToFree) {
+    public void releaseBitmap(Object o, Bitmap bitmapToFree) {
         // enable this code when doDecode doesn't force Bitmaps to become immutable
         String name = getObjectName(o);
-        synchronized(sLoadedPreviews) {
-            synchronized(sUnusedBitmaps) {
-                Bitmap b = sLoadedPreviews.get(name).get();
+        synchronized(mLoadedPreviews) {
+            synchronized(mUnusedBitmaps) {
+                Bitmap b = mLoadedPreviews.get(name).get();
                 if (b == bitmapToFree) {
-                    sLoadedPreviews.remove(name);
+                    mLoadedPreviews.remove(name);
                     if (bitmapToFree.isMutable()) {
-                        sUnusedBitmaps.add(new SoftReference<Bitmap>(b));
+                        mUnusedBitmaps.add(new SoftReference<Bitmap>(b));
                     }
                 } else {
                     throw new RuntimeException("Bitmap passed in doesn't match up");
@@ -378,15 +383,15 @@
 
     public Bitmap generatePreview(Object info, Bitmap preview) {
         if (preview != null &&
-                (preview.getWidth() != mPreviewBitmapMaxWidth ||
-                preview.getHeight() != mPreviewBitmapMaxHeight)) {
+                (preview.getWidth() != mPreviewBitmapWidth ||
+                preview.getHeight() != mPreviewBitmapHeight)) {
             throw new RuntimeException("Improperly sized bitmap passed as argument");
         }
         if (info instanceof AppWidgetProviderInfo) {
             return generateWidgetPreview((AppWidgetProviderInfo) info, preview);
         } else {
             return generateShortcutPreview(
-                    (ResolveInfo) info, mPreviewBitmapMaxWidth, mPreviewBitmapMaxHeight, preview);
+                    (ResolveInfo) info, mPreviewBitmapWidth, mPreviewBitmapHeight, preview);
         }
     }
 
@@ -404,12 +409,12 @@
     }
 
     public int maxWidthForWidgetPreview(int spanX) {
-        return Math.min(mPreviewBitmapMaxWidth,
+        return Math.min(mPreviewBitmapWidth,
                 mWidgetSpacingLayout.estimateCellWidth(spanX));
     }
 
     public int maxHeightForWidgetPreview(int spanY) {
-        return Math.min(mPreviewBitmapMaxHeight,
+        return Math.min(mPreviewBitmapHeight,
                 mWidgetSpacingLayout.estimateCellHeight(spanY));
     }