Merge "Fix scaling on widget previews that have width / height set to wrap_content" into sc-v2-dev
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 6bd6261..92ed18a 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -192,15 +192,15 @@
             float appWidgetHostViewScale = mWidgetCell.getAppWidgetHostViewScale();
             int xOffset =
                     appWidgetHostView.getLeft() - (int) (mLastTouchPos.x * appWidgetHostViewScale);
-            int yOffset = appWidgetHostView.getTop()
-                    - (int) (mLastTouchPos.y * mWidgetCell.getAppWidgetHostViewScale());
+            int yOffset =
+                    appWidgetHostView.getTop() - (int) (mLastTouchPos.y * appWidgetHostViewScale);
             bounds.offset(xOffset, yOffset);
             listener = new PinItemDragListener(
                     mRequest,
                     bounds,
                     appWidgetHostView.getMeasuredWidth(),
                     appWidgetHostView.getMeasuredWidth(),
-                    appWidgetHostView.getScaleX());
+                    appWidgetHostViewScale);
         } else {
             bounds = img.getBitmapBounds();
             bounds.offset(img.getLeft() - (int) mLastTouchPos.x,
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index ee44174..8e9769c 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -188,11 +188,11 @@
             dragHelper.startDrag(image.getBitmapBounds(), image.getDrawable().getIntrinsicWidth(),
                     image.getWidth(), new Point(loc[0], loc[1]), this, new DragOptions());
         } else {
-            View preview = v.getAppWidgetHostViewPreview();
+            NavigableAppWidgetHostView preview = v.getAppWidgetHostViewPreview();
             int[] loc = new int[2];
             getPopupContainer().getLocationInDragLayer(preview, loc);
-
-            Rect r = new Rect(0, 0, preview.getWidth(), preview.getHeight());
+            Rect r = new Rect();
+            preview.getWorkspaceVisualDragBounds(r);
             dragHelper.startDrag(r, preview.getMeasuredWidth(), preview.getMeasuredWidth(),
                     new Point(loc[0], loc[1]), this, new DragOptions());
         }
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index fb6de9f..0313e68 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -84,10 +84,8 @@
     private boolean mIsScrollable;
     private boolean mIsAttachedToWindow;
     private boolean mIsAutoAdvanceRegistered;
-    private boolean mIsInDragMode = false;
     private Runnable mAutoAdvanceRunnable;
     private RectF mLastLocationRegistered = null;
-    @Nullable private AppWidgetHostViewDragListener mDragListener;
 
     // Used to store the widget sizes in drag layer coordinates.
     private final Rect mCurrentWidgetSize = new Rect();
@@ -102,6 +100,14 @@
     private @Nullable SparseIntArray mDeferredColorChange = null;
     private boolean mEnableColorExtraction = true;
 
+    // The following member variables are only used during drag-n-drop.
+    private boolean mIsInDragMode = false;
+    @Nullable private AppWidgetHostViewDragListener mDragListener;
+    /** The drag content width which is only set when the drag content scale is not 1f. */
+    private int mDragContentWidth = 0;
+    /** The drag content height which is only set when the drag content scale is not 1f. */
+    private int mDragContentHeight = 0;
+
     public LauncherAppWidgetHostView(Context context) {
         super(context);
         mLauncher = Launcher.getLauncher(context);
@@ -310,10 +316,28 @@
         updateColorExtraction();
     }
 
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        if (mIsInDragMode && mDragContentWidth > 0 && mDragContentHeight > 0
+                && getChildCount() == 1) {
+            measureChild(getChildAt(0), MeasureSpec.getSize(mDragContentWidth),
+                    MeasureSpec.getSize(mDragContentHeight));
+        }
+    }
+
     /** Starts the drag mode. */
     public void startDrag(AppWidgetHostViewDragListener dragListener) {
         mIsInDragMode = true;
         mDragListener = dragListener;
+        // In the case of dragging a scaled preview from widgets picker, we should reuse the
+        // previously measured dimension from WidgetCell#measureAndComputeWidgetPreviewScale, which
+        // measures the dimension of a widget preview without its parent's bound before scaling
+        // down.
+        if ((getScaleX() != 1f || getScaleY() != 1f) && getChildCount() == 1) {
+            mDragContentWidth = getChildAt(0).getMeasuredWidth();
+            mDragContentHeight = getChildAt(0).getMeasuredHeight();
+        }
     }
 
     /** Handles a drag event occurred on a workspace page, {@code pageId}. */
@@ -326,6 +350,8 @@
     public void endDrag() {
         mIsInDragMode = false;
         mDragListener = null;
+        mDragContentWidth = 0;
+        mDragContentHeight = 0;
         mWidgetSizeAtDrag.setEmpty();
     }
 
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index d3f4528..167eb09 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -18,6 +18,7 @@
 
 import static android.view.View.MeasureSpec.makeMeasureSpec;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY;
 import static com.android.launcher3.Utilities.ATLEAST_S;
@@ -372,7 +373,7 @@
                 if (shouldScale) {
                     setNoClip(mWidgetImageContainer);
                     setNoClip(mAppWidgetHostViewPreview);
-                    mAppWidgetHostViewScale = computeWidgetPreviewScale();
+                    mAppWidgetHostViewScale = measureAndComputeWidgetPreviewScale();
                     mAppWidgetHostViewPreview.setScaleToFit(mAppWidgetHostViewScale);
                 }
             }
@@ -473,7 +474,7 @@
         view.setClipToPadding(false);
     }
 
-    private float computeWidgetPreviewScale() {
+    private float measureAndComputeWidgetPreviewScale() {
         if (mAppWidgetHostViewPreview.getChildCount() != 1) {
             return 1f;
         }
@@ -482,12 +483,25 @@
         mAppWidgetHostViewPreview.measure(
                 makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED),
                 makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED));
-        int appWidgetContentWidth = mAppWidgetHostViewPreview.getChildAt(0).getMeasuredWidth();
-        int appWidgetContentHeight = mAppWidgetHostViewPreview.getChildAt(0).getMeasuredHeight();
+        View widgetContent = mAppWidgetHostViewPreview.getChildAt(0);
+        int appWidgetContentWidth = widgetContent.getMeasuredWidth();
+        int appWidgetContentHeight = widgetContent.getMeasuredHeight();
         if (appWidgetContentWidth == 0 || appWidgetContentHeight == 0) {
             return 1f;
         }
 
+        // If the width / height of the widget content is set to wrap content, overrides the width /
+        // height with the measured dimension. This avoids incorrect measurement after scaling.
+        FrameLayout.LayoutParams layoutParam =
+                (FrameLayout.LayoutParams) widgetContent.getLayoutParams();
+        if (layoutParam.width == WRAP_CONTENT) {
+            layoutParam.width = widgetContent.getMeasuredWidth();
+        }
+        if (layoutParam.height == WRAP_CONTENT) {
+            layoutParam.height = widgetContent.getMeasuredHeight();
+        }
+        widgetContent.setLayoutParams(layoutParam);
+
         int horizontalPadding = mAppWidgetHostViewPreview.getPaddingStart()
                 + mAppWidgetHostViewPreview.getPaddingEnd();
         int verticalPadding = mAppWidgetHostViewPreview.getPaddingTop()