Merge "Remove intrinsic padding from widget previews" into sc-dev
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 8b7a750..c7323d0 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -385,27 +385,29 @@
             previewHeight = Math.max((int)(scale * previewHeight), 1);
         }
 
-        // If a bitmap is passed in, we use it; otherwise, we create a bitmap of the right size
         final Canvas c = new Canvas();
         if (preview == null) {
+            // If no bitmap was provided, then allocate a new one with the right size.
             preview = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
             c.setBitmap(preview);
         } else {
-            // We use the preview bitmap height to determine where the badge will be drawn in the
-            // UI. If its larger than what we need, resize the preview bitmap so that there are
-            // no transparent pixels between the preview and the badge.
-            if (preview.getHeight() > previewHeight) {
-                preview.reconfigure(preview.getWidth(), previewHeight, preview.getConfig());
+            // If a bitmap was passed in, attempt to reconfigure the bitmap to the same dimensions
+            // as the preview.
+            try {
+                preview.reconfigure(previewWidth, previewHeight, preview.getConfig());
+            } catch (IllegalArgumentException e) {
+                // This occurs if the preview can't be reconfigured for any reason. In this case,
+                // allocate a new bitmap with the right size.
+                preview = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
             }
-            // Reusing bitmap. Clear it.
+
             c.setBitmap(preview);
             c.drawColor(0, PorterDuff.Mode.CLEAR);
         }
 
         // Draw the scaled preview into the final bitmap
-        int x = (preview.getWidth() - previewWidth) / 2;
         if (widgetPreviewExists) {
-            drawable.setBounds(x, 0, x + previewWidth, previewHeight);
+            drawable.setBounds(0, 0, previewWidth, previewHeight);
             drawable.draw(c);
         } else {
             RectF boxRect;
@@ -565,6 +567,7 @@
         @Thunk long[] mVersions;
         @Thunk Bitmap mBitmapToRecycle;
 
+        @Nullable private Bitmap mUnusedPreviewBitmap;
         private boolean mSaveToDB = false;
 
         PreviewLoadTask(WidgetCacheKey key, WidgetItem info, int previewWidth,
@@ -625,6 +628,11 @@
                 Pair<Bitmap, Boolean> pair = generatePreview(mActivity, mInfo, unusedBitmap,
                         mPreviewWidth, mPreviewHeight);
                 preview = pair.first;
+
+                if (preview != unusedBitmap) {
+                    mUnusedPreviewBitmap = unusedBitmap;
+                }
+
                 this.mSaveToDB = pair.second;
             }
             return preview;
@@ -639,6 +647,14 @@
                 MODEL_EXECUTOR.post(new Runnable() {
                     @Override
                     public void run() {
+                        if (mUnusedPreviewBitmap != null) {
+                            // If we didn't end up using the bitmap, it can be added back into the
+                            // recycled set.
+                            synchronized (mUnusedBitmaps) {
+                                mUnusedBitmaps.add(mUnusedPreviewBitmap);
+                            }
+                        }
+
                         if (!isCancelled() && mSaveToDB) {
                             // If we are still using this preview, then write it to the DB and then
                             // let the normal clear mechanism recycle the bitmap
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index f7993dc..7d04d7b 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -95,6 +95,7 @@
     protected final BaseActivity mActivity;
     private final CheckLongPressHelper mLongPressHelper;
     private final float mEnforcedCornerRadius;
+    private final int mPreviewPadding;
 
     private RemoteViews mRemoteViewsPreview;
     private NavigableAppWidgetHostView mAppWidgetHostViewPreview;
@@ -119,6 +120,8 @@
         setClipToPadding(false);
         setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
         mEnforcedCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(context);
+        mPreviewPadding =
+                2 * getResources().getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
     }
 
     private void setContainerWidth() {
@@ -281,7 +284,16 @@
             return;
         }
         if (drawable != null) {
-            setContainerSize(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+            float scale = 1f;
+            if (getWidth() > 0 && getHeight() > 0) {
+                // Scale down the preview size if it's wider than the cell.
+                float maxWidth = getWidth() - mPreviewPadding;
+                float previewWidth = drawable.getIntrinsicWidth() * mPreviewScale;
+                scale = Math.min(maxWidth / previewWidth, 1);
+            }
+            setContainerSize(
+                    Math.round(drawable.getIntrinsicWidth() * scale),
+                    Math.round(drawable.getIntrinsicHeight() * scale));
             mWidgetImage.setDrawable(drawable);
             mWidgetImage.setVisibility(View.VISIBLE);
             if (mAppWidgetHostViewPreview != null) {
@@ -330,11 +342,9 @@
 
     /** Sets the widget preview image size, in number of cells, and preview scale. */
     public void setPreviewSize(int spanX, int spanY, float previewScale) {
-        int padding = 2 * getResources()
-                .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
         DeviceProfile deviceProfile = mActivity.getDeviceProfile();
-        mPreviewWidth = deviceProfile.cellWidthPx * spanX + padding;
-        mPreviewHeight = deviceProfile.cellHeightPx * spanY + padding;
+        mPreviewWidth = deviceProfile.cellWidthPx * spanX + mPreviewPadding;
+        mPreviewHeight = deviceProfile.cellHeightPx * spanY + mPreviewPadding;
         mPreviewScale = previewScale;
     }