Fix issues with drag and drop from All Apps in non-default grids

=> Also fix the widget tray in these non-default grids, and the external shortcut addition flow. The layout was broken as it was scaling with the icon size. Instead keep it fixed which looks much better, similar to how we maintain all apps.
=> This also fixes a small jump when dragging shortcuts external to Launcher.

issue 154169001

Change-Id: Iad1e3859dd6fedccce9b5c6633e64426a4630c31
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index d7d4a27..79ed2b8 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -722,11 +722,27 @@
     }
 
     @Override
-    public void getVisualDragBounds(Rect bounds) {
+    public void getWorkspaceVisualDragBounds(Rect bounds) {
         DeviceProfile grid = mActivity.getDeviceProfile();
         BubbleTextView.getIconBounds(this, bounds, grid.iconSizePx);
     }
 
+    private int getIconSizeForDisplay(int display) {
+        DeviceProfile grid = mActivity.getDeviceProfile();
+        switch (display) {
+            case DISPLAY_ALL_APPS:
+                return grid.allAppsIconSizePx;
+            case DISPLAY_WORKSPACE:
+            case DISPLAY_FOLDER:
+            default:
+                return grid.iconSizePx;
+        }
+    }
+
+    public void getSourceVisualDragBounds(Rect bounds) {
+        BubbleTextView.getIconBounds(this, bounds, getIconSizeForDisplay(mDisplay));
+    }
+
     @Override
     public void prepareDrawDragView() {
         if (getIcon() instanceof FastBitmapDrawable) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 412eef1..8dab818 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1441,6 +1441,10 @@
 
         mOutlineProvider = previewProvider;
 
+        if (draggableView == null && child instanceof DraggableView) {
+            draggableView = (DraggableView) child;
+        }
+
         // The drag bitmap follows the touch point around on the screen
         final Bitmap b = previewProvider.createDragBitmap();
         int halfPadding = previewProvider.previewPadding / 2;
@@ -1451,12 +1455,8 @@
         Point dragVisualizeOffset = null;
         Rect dragRect = new Rect();
 
-        if (draggableView == null && child instanceof DraggableView) {
-            draggableView = (DraggableView) child;
-        }
-
         if (draggableView != null) {
-            draggableView.getVisualDragBounds(dragRect);
+            draggableView.getSourceVisualDragBounds(dragRect);
             dragLayerY += dragRect.top;
             dragVisualizeOffset = new Point(- halfPadding, halfPadding);
         }
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 970c5a0..ddf44ca 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -274,19 +274,29 @@
         scale *= childScale;
         int toX = Math.round(coord[0]);
         int toY = Math.round(coord[1]);
+
         float toScale = scale;
 
         if (child instanceof DraggableView) {
+            // This code is fairly subtle. Please verify drag and drop is pixel-perfect in a number
+            // of scenarios before modifying (from all apps, from workspace, different grid-sizes,
+            // shortcuts from in and out of Launcher etc).
             DraggableView d = (DraggableView) child;
-            d.getVisualDragBounds(dragViewBounds);
+            Rect destRect = new Rect();
+            d.getWorkspaceVisualDragBounds(destRect);
+
+            // In most cases this additional scale factor should be a no-op (1). It mainly accounts
+            // for alternate grids where the source and destination icon sizes are different
+            toScale *= ((1f * destRect.width())
+                    / (dragView.getMeasuredWidth() - dragView.getBlurSizeOutline()));
 
             // This accounts for the offset of the DragView created by scaling it about its
             // center as it animates into place.
-            float scaleShiftX = dragView.getMeasuredWidth() * (1 - scale) / 2;
-            float scaleShiftY = dragView.getMeasuredHeight() * (1 - scale) / 2;
+            float scaleShiftX = dragView.getMeasuredWidth() * (1 - toScale) / 2;
+            float scaleShiftY = dragView.getMeasuredHeight() * (1 - toScale) / 2;
 
-            toX += scale * (dragViewBounds.left - dragView.getBlurSizeOutline() / 2) - scaleShiftX;
-            toY += scale * (dragViewBounds.top - dragView.getBlurSizeOutline() / 2) - scaleShiftY;
+            toX += scale * destRect.left - toScale * dragView.getBlurSizeOutline() / 2 - scaleShiftX;
+            toY += scale * destRect.top - toScale * dragView.getBlurSizeOutline() / 2 - scaleShiftY;
         }
 
         child.setVisibility(INVISIBLE);
diff --git a/src/com/android/launcher3/dragndrop/DraggableView.java b/src/com/android/launcher3/dragndrop/DraggableView.java
index df99902..287c781 100644
--- a/src/com/android/launcher3/dragndrop/DraggableView.java
+++ b/src/com/android/launcher3/dragndrop/DraggableView.java
@@ -53,5 +53,14 @@
      *
      * @param bounds Visual bounds in the views coordinates will be written here.
      */
-    default void getVisualDragBounds(Rect bounds) { }
+    default void getWorkspaceVisualDragBounds(Rect bounds) { }
+
+    /**
+     * Same as above, but accounts for differing icon sizes between source and destination
+     *
+     * @param bounds Visual bounds in the views coordinates will be written here.
+     */
+    default void getSourceVisualDragBounds(Rect bounds) {
+        getWorkspaceVisualDragBounds(bounds);
+    }
 }
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index e2963d7..9a3b0a6 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -758,7 +758,7 @@
     }
 
     @Override
-    public void getVisualDragBounds(Rect bounds) {
+    public void getWorkspaceVisualDragBounds(Rect bounds) {
         getPreviewBounds(bounds);
     }
 }
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index 848c04a..634d07e 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -77,7 +77,7 @@
         if (mView instanceof DraggableView) {
             DraggableView dv = (DraggableView) mView;
             dv.prepareDrawDragView();
-            dv.getVisualDragBounds(mTempRect);
+            dv.getSourceVisualDragBounds(mTempRect);
             destCanvas.translate(blurSizeOutline / 2 - mTempRect.left,
                     blurSizeOutline / 2 - mTempRect.top);
             mView.draw(destCanvas);
@@ -95,7 +95,7 @@
         // Assume scaleX == scaleY, which is always the case for workspace items.
         float scale = mView.getScaleX();
         if (mView instanceof DraggableView) {
-            ((DraggableView) mView).getVisualDragBounds(mTempRect);
+            ((DraggableView) mView).getSourceVisualDragBounds(mTempRect);
             width = mTempRect.width();
             height = mTempRect.height();
         } else {
diff --git a/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java b/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
index a4e7daa..ed42bc4 100644
--- a/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
@@ -218,7 +218,7 @@
     }
 
     @Override
-    public void getVisualDragBounds(Rect bounds) {
+    public void getWorkspaceVisualDragBounds(Rect bounds) {
         int width = (int) (getMeasuredWidth() * mScaleToFit);
         int height = (int) (getMeasuredHeight() * mScaleToFit);
 
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 4a0b4ef..bef91d2 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -55,7 +55,7 @@
     private static final int FADE_IN_DURATION_MS = 90;
 
     /** Widget cell width is calculated by multiplying this factor to grid cell width. */
-    private static final float WIDTH_SCALE = 2.6f;
+    private static final float WIDTH_SCALE = 3f;
 
     /** Widget preview width is calculated by multiplying this factor to the widget cell width. */
     private static final float PREVIEW_SCALE = 0.8f;
@@ -104,7 +104,7 @@
     }
 
     private void setContainerWidth() {
-        mCellSize = (int) (mDeviceProfile.cellWidthPx * WIDTH_SCALE);
+        mCellSize = (int) (mDeviceProfile.allAppsIconSizePx * WIDTH_SCALE);
         mPresetPreviewSize = (int) (mCellSize * PREVIEW_SCALE);
     }