Add missing animations when dragging from customize.

- Fix 3453751: Moon landing on canceled drag from customize
- Fix 3453595: Use home screen "consume" animation when dragging and dropping

Change-Id: Ia6a83c2d7a8f24c3ce02811547a35a7022d245f6
diff --git a/src/com/android/launcher2/AllApps2D.java b/src/com/android/launcher2/AllApps2D.java
index 66d9395..a9423be 100644
--- a/src/com/android/launcher2/AllApps2D.java
+++ b/src/com/android/launcher2/AllApps2D.java
@@ -211,7 +211,7 @@
     }
 
     @Override
-    public void onDropCompleted(View target, boolean success) {
+    public void onDropCompleted(View target, Object dragInfo, boolean success) {
     }
 
     /**
diff --git a/src/com/android/launcher2/AllApps3D.java b/src/com/android/launcher2/AllApps3D.java
index 2ecf761..29f49af 100644
--- a/src/com/android/launcher2/AllApps3D.java
+++ b/src/com/android/launcher2/AllApps3D.java
@@ -685,16 +685,14 @@
                 && mCurrentIconIndex >= 0 && mCurrentIconIndex < mAllAppsList.size()) {
             ApplicationInfo app = mAllAppsList.get(mCurrentIconIndex);
 
-            Bitmap bmp = app.iconBitmap;
-            final int w = bmp.getWidth();
-            final int h = bmp.getHeight();
+            final Bitmap bmp = app.iconBitmap;
 
             // We don't really have an accurate location to use.  This will do.
-            int screenX = mMotionDownRawX - (w / 2);
-            int screenY = mMotionDownRawY - h;
+            int screenX = mMotionDownRawX - (bmp.getWidth() / 2);
+            int screenY = mMotionDownRawY - bmp.getHeight();
 
-            mDragController.startDrag(bmp, screenX, screenY,
-                    0, 0, w, h, this, app, DragController.DRAG_ACTION_COPY);
+            mDragController.startDrag(
+                    bmp, screenX, screenY, this, app, DragController.DRAG_ACTION_COPY);
 
             mLauncher.closeAllApps(true);
         }
@@ -748,7 +746,7 @@
     }
 
     @Override
-    public void onDropCompleted(View target, boolean success) {
+    public void onDropCompleted(View target, Object dragInfo, boolean success) {
     }
 
     /**
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java
index 1e4821a..e926974 100644
--- a/src/com/android/launcher2/AllAppsPagedView.java
+++ b/src/com/android/launcher2/AllAppsPagedView.java
@@ -282,7 +282,7 @@
     }
 
     @Override
-    public void onDropCompleted(View target, boolean success) {
+    public void onDropCompleted(View target, Object dragInfo, boolean success) {
         // close the choice action mode if we have a proper drop
         if (target != this) {
             endChoiceMode();
diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java
index 93e1394..b997275 100644
--- a/src/com/android/launcher2/CustomizePagedView.java
+++ b/src/com/android/launcher2/CustomizePagedView.java
@@ -38,8 +38,9 @@
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
 import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.Bitmap.Config;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -53,7 +54,7 @@
 import android.view.MenuItem;
 import android.view.View;
 import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
 import android.widget.Checkable;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -120,9 +121,19 @@
 
     private final float mTmpFloatPos[] = new float[2];
     private final float ANIMATION_SCALE = 0.5f;
-    private final int ANIMATION_DURATION = 400;
+
+    // The duration of the translation animation that occurs during you drag and drop
+    private final int TRANSLATE_ANIM_DURATION = 400;
+
+    // The duration of the scale & alpha animation that occurs during drag and drop
+    private final int DROP_ANIM_DURATION = 200;
+
     private TimeInterpolator mQuintEaseOutInterpolator = new DecelerateInterpolator(2.5f);
-    private ScaleAlphaInterpolator mScaleAlphaInterpolator = new ScaleAlphaInterpolator();
+
+    // The Bitmap used to generate the drag view
+    private Bitmap mDragBitmap;
+
+    private int[] mDragViewOrigin = new int[2];
 
     public CustomizePagedView(Context context) {
         this(context, null, 0);
@@ -324,38 +335,60 @@
         return mCustomizationType;
     }
 
-    @Override
-    public void onDropCompleted(View target, boolean success) {
-        resetCheckedGrandchildren();
+    /**
+     * Similar to resetCheckedGrandchildren, but allows us to specify that it's not animated.
+     * NOTE: This assumes that only a single item can be checked.
+     */
+    private void resetCheckedItem(boolean animated) {
+        Checkable checkable = getCheckedGrandchildren().get(0);
+        if (checkable instanceof PagedViewWidget) {
+            ((PagedViewWidget) checkable).setChecked(false, animated);
+        } else {
+            ((PagedViewIcon) checkable).setChecked(false, animated);
+        }
+    }
+
+    public void onDropCompleted(View target, Object dragInfo, boolean success) {
+        final DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer);
+
+        // Create a view, identical to the drag view, that is only used for animating the
+        // item onto the home screen (or back to its original position, if the drop failed).
+        final int[] pos = new int[2];
+        mDragController.getDragView().getLocationOnScreen(pos);
+        final View animView = dragLayer.createDragView(mDragBitmap, pos[0], pos[1]);
+        animView.setVisibility(View.VISIBLE);
+
+        if (success) {
+            resetCheckedItem(true);
+            animateDropOntoScreen(animView, (ItemInfo) dragInfo, DROP_ANIM_DURATION, 0);
+        } else {
+            // Animate the icon/widget back to its original position
+            animateIntoPosition(animView, mDragViewOrigin[0], mDragViewOrigin[1], new Runnable() {
+                public void run() {
+                   resetCheckedItem(false);
+                   dragLayer.removeView(animView);
+                }
+            });
+        }
         mLauncher.getWorkspace().onDragStopped(success);
         mLauncher.unlockScreenOrientation();
+        mDragBitmap = null;
     }
 
     @Override
     public void onDragViewVisible() {
     }
 
-    class ScaleAlphaInterpolator implements Interpolator {
-        public float getInterpolation(float input) {
-            float pivot = 0.5f;
-            if (input < pivot) {
-                return 0;
-            } else {
-                return (input - pivot)/(1 - pivot);
-            }
-        }
-    }
-
+    /**
+     * Animates the given item onto the center of a home screen, and then scales the item to
+     * look as though it's disappearing onto that screen.
+     */
     private void animateItemOntoScreen(View dragView,
             final CellLayout layout, final ItemInfo info) {
         mTmpFloatPos[0] = layout.getWidth() / 2;
         mTmpFloatPos[1] = layout.getHeight() / 2;
         mLauncher.getWorkspace().mapPointFromChildToSelf(layout, mTmpFloatPos);
 
-        final DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer);
-        final View dragCopy = dragLayer.createDragView(dragView);
-        dragCopy.setAlpha(1.0f);
-
         int dragViewWidth = dragView.getMeasuredWidth();
         int dragViewHeight = dragView.getMeasuredHeight();
         float heightOffset = 0;
@@ -374,37 +407,69 @@
                 widthOffset = ANIMATION_SCALE * (dragViewWidth - f * width) / 2;
             }
         }
+        final float toX = mTmpFloatPos[0] - dragView.getMeasuredWidth() / 2 + widthOffset;
+        final float toY = mTmpFloatPos[1] - dragView.getMeasuredHeight() / 2 + heightOffset;
 
-        float toX = mTmpFloatPos[0] - dragView.getMeasuredWidth() / 2 + widthOffset;
-        float toY = mTmpFloatPos[1] - dragView.getMeasuredHeight() / 2 + heightOffset;
+        final DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer);
+        final View dragCopy = dragLayer.createDragView(dragView);
+        dragCopy.setAlpha(1.0f);
 
-        ObjectAnimator posAnim = ObjectAnimator.ofPropertyValuesHolder(dragCopy,
-                PropertyValuesHolder.ofFloat("x", toX),
-                PropertyValuesHolder.ofFloat("y", toY));
-        posAnim.setInterpolator(mQuintEaseOutInterpolator);
-        posAnim.setDuration(ANIMATION_DURATION);
+        // Translate the item to the center of the appropriate home screen
+        animateIntoPosition(dragCopy, toX, toY, null);
 
-        posAnim.addListener(new AnimatorListenerAdapter() {
-            public void onAnimationEnd(Animator animation) {
-                dragLayer.removeView(dragCopy);
-                mLauncher.addExternalItemToScreen(info, layout);
-                post(new Runnable() {
-                    public void run() {
-                        layout.animateDrop();
-                    }
-                });
-            }
-        });
+        // The drop-onto-screen animation begins a bit later, but ends at the same time.
+        final int startDelay = TRANSLATE_ANIM_DURATION - DROP_ANIM_DURATION;
+        
+        // Scale down the icon and fade out the alpha
+        animateDropOntoScreen(dragCopy, info, DROP_ANIM_DURATION, startDelay);
+    }
 
-        ObjectAnimator scaleAlphaAnim = ObjectAnimator.ofPropertyValuesHolder(dragCopy,
+    /**
+     * Animation which scales the view down and animates its alpha, making it appear to disappear
+     * onto a home screen.
+     */
+    private void animateDropOntoScreen(
+            final View view, final ItemInfo info, int duration, int delay) {
+        final DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer);
+        final CellLayout layout = mLauncher.getWorkspace().getCurrentDropLayout();
+
+        ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view,
                 PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.0f),
                 PropertyValuesHolder.ofFloat("scaleX", ANIMATION_SCALE),
                 PropertyValuesHolder.ofFloat("scaleY", ANIMATION_SCALE));
-        scaleAlphaAnim.setInterpolator(mScaleAlphaInterpolator);
-        scaleAlphaAnim.setDuration(ANIMATION_DURATION);
+        anim.setInterpolator(new LinearInterpolator());
+        if (delay > 0) {
+            anim.setStartDelay(delay);
+        }
+        anim.setDuration(duration);
+        anim.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator animation) {
+                dragLayer.removeView(view);
+                mLauncher.addExternalItemToScreen(info, layout);
+            }
+        });
+        anim.start();
+    }
 
-        posAnim.start();
-        scaleAlphaAnim.start();
+    /**
+     * Animates the x,y position of the view, and optionally execute a Runnable on animation end.
+     */
+    private void animateIntoPosition(
+            View view, float toX, float toY, final Runnable endRunnable) {
+        ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view,
+                PropertyValuesHolder.ofFloat("x", toX),
+                PropertyValuesHolder.ofFloat("y", toY));
+        anim.setInterpolator(mQuintEaseOutInterpolator);
+        anim.setDuration(TRANSLATE_ANIM_DURATION);
+        if (endRunnable != null) {
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    endRunnable.run();
+                }
+            });
+        }
+        anim.start();
     }
 
     @Override
@@ -479,9 +544,10 @@
         }
     }
 
-    Bitmap drawableToBitmap(Drawable d) {
-        int w = d.getIntrinsicWidth();
-        int h = d.getIntrinsicHeight();
+    private Bitmap drawableToBitmap(Drawable d) {
+        final Rect bounds = d.getBounds();
+        final int w = bounds.width();
+        final int h = bounds.height();
         Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
         renderDrawableToBitmap(d, b, 0, 0, w, h);
         return b;
@@ -500,6 +566,7 @@
         if (isChoiceMode(CHOICE_MODE_SINGLE)) {
             endChoiceMode();
         }
+        final Workspace workspace = mLauncher.getWorkspace();
         boolean result = false;
         mLauncher.lockScreenOrientation();
         switch (mCustomizationType) {
@@ -508,50 +575,44 @@
                 // Get the widget preview as the drag representation
                 final LinearLayout l = (LinearLayout) v;
                 final ImageView i = (ImageView) l.findViewById(R.id.widget_preview);
-                Bitmap b = drawableToBitmap(i.getDrawable());
+                mDragBitmap = drawableToBitmap(i.getDrawable());
+                i.getLocationOnScreen(mDragViewOrigin);
                 PendingAddWidgetInfo createWidgetInfo = (PendingAddWidgetInfo) v.getTag();
 
-                int[] spanXY = CellLayout.rectToCell(
-                        getResources(), createWidgetInfo.minWidth, createWidgetInfo.minHeight, null);
+                int[] spanXY = CellLayout.rectToCell(getResources(),
+                        createWidgetInfo.minWidth, createWidgetInfo.minHeight, null);
                 createWidgetInfo.spanX = spanXY[0];
                 createWidgetInfo.spanY = spanXY[1];
-                mLauncher.getWorkspace().onDragStartedWithItemSpans(spanXY[0], spanXY[1], b);
-                mDragController.startDrag(
-                        i, b, this, createWidgetInfo, DragController.DRAG_ACTION_COPY, null);
-                b.recycle();
+                workspace.onDragStartedWithItemSpans(spanXY[0], spanXY[1], mDragBitmap);
+                mDragController.startDrag(i, mDragBitmap, this, createWidgetInfo,
+                        DragController.DRAG_ACTION_COPY, null);
                 result = true;
             }
             break;
         }
-        case ShortcutCustomization: {
-            if (v instanceof PagedViewIcon) {
-                // get icon (top compound drawable, index is 1)
-                final TextView tv = (TextView) v;
-                final Drawable icon = tv.getCompoundDrawables()[1];
-                Bitmap b = drawableToBitmap(icon);
-                PendingAddItemInfo createItemInfo = (PendingAddItemInfo) v.getTag();
-
-                mLauncher.getWorkspace().onDragStartedWithItemSpans(1, 1, b);
-                mDragController.startDrag(v, b, this, createItemInfo, DragController.DRAG_ACTION_COPY,
-                        null);
-                b.recycle();
-                result = true;
-            }
-            break;
-        }
+        case ShortcutCustomization:
         case ApplicationCustomization: {
             if (v instanceof PagedViewIcon) {
-                // Pick up the application for dropping
                 // get icon (top compound drawable, index is 1)
                 final TextView tv = (TextView) v;
                 final Drawable icon = tv.getCompoundDrawables()[1];
-                Bitmap b = drawableToBitmap(icon);
-                ApplicationInfo app = (ApplicationInfo) v.getTag();
-                app = new ApplicationInfo(app);
+                mDragBitmap = drawableToBitmap(icon);
 
-                mLauncher.getWorkspace().onDragStartedWithItemSpans(1, 1, b);
-                mDragController.startDrag(v, b, this, app, DragController.DRAG_ACTION_COPY, null);
-                b.recycle();
+                Object dragInfo = v.getTag();
+                if (mCustomizationType == CustomizationType.ApplicationCustomization) {
+                    // TODO: Not sure why we have to copy this
+                    dragInfo = new ApplicationInfo((ApplicationInfo) dragInfo);
+                }
+                workspace.onDragStartedWithItemSpans(1, 1, mDragBitmap);
+
+                // Calculate where to place the drag view in order to align the icon pixels with
+                // the original view.
+                v.getLocationOnScreen(mDragViewOrigin);
+                mDragViewOrigin[0] += (v.getWidth() - icon.getIntrinsicWidth()) / 2;
+                mDragViewOrigin[1] += v.getPaddingTop();
+
+                mDragController.startDrag(mDragBitmap, mDragViewOrigin[0], mDragViewOrigin[1],
+                        this, dragInfo, DragController.DRAG_ACTION_COPY);
                 result = true;
             }
             break;
@@ -621,8 +682,10 @@
     private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h) {
         if (bitmap != null) mCanvas.setBitmap(bitmap);
         mCanvas.save();
-        d.setBounds(x, y, x+w, y+h);
+        final Rect oldBounds = d.copyBounds();
+        d.setBounds(x, y, x + w, y + h);
         d.draw(mCanvas);
+        d.setBounds(oldBounds); // Restore the bounds
         mCanvas.restore();
     }
 
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index 45b359d..e546697 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -205,9 +205,7 @@
         int screenX = loc[0];
         int screenY = loc[1];
 
-        startDrag(b, screenX, screenY, 0, 0, b.getWidth(), b.getHeight(),
-                source, dragInfo, dragAction, dragRegion);
-
+        startDrag(b, screenX, screenY, source, dragInfo, dragAction, dragRegion);
         b.recycle();
 
         if (dragAction == DRAG_ACTION_MOVE) {
@@ -236,8 +234,7 @@
         int screenX = loc[0];
         int screenY = loc[1];
 
-        startDrag(bmp, screenX, screenY, 0, 0, bmp.getWidth(), bmp.getHeight(),
-                source, dragInfo, dragAction, dragRegion);
+        startDrag(bmp, screenX, screenY, source, dragInfo, dragAction, dragRegion);
 
         if (dragAction == DRAG_ACTION_MOVE) {
             v.setVisibility(View.GONE);
@@ -251,20 +248,14 @@
      *          enlarged size.
      * @param screenX The x position on screen of the left-top of the bitmap.
      * @param screenY The y position on screen of the left-top of the bitmap.
-     * @param textureLeft The left edge of the region inside b to use.
-     * @param textureTop The top edge of the region inside b to use.
-     * @param textureWidth The width of the region inside b to use.
-     * @param textureHeight The height of the region inside b to use.
      * @param source An object representing where the drag originated
      * @param dragInfo The data associated with the object that is being dragged
      * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or
      *        {@link #DRAG_ACTION_COPY}
      */
     public void startDrag(Bitmap b, int screenX, int screenY,
-            int textureLeft, int textureTop, int textureWidth, int textureHeight,
             DragSource source, Object dragInfo, int dragAction) {
-        startDrag(b, screenX, screenY, textureLeft, textureTop, textureWidth, textureHeight,
-                source, dragInfo, dragAction, null);
+        startDrag(b, screenX, screenY, source, dragInfo, dragAction, null);
     }
 
     /**
@@ -274,10 +265,6 @@
      *          enlarged size.
      * @param screenX The x position on screen of the left-top of the bitmap.
      * @param screenY The y position on screen of the left-top of the bitmap.
-     * @param textureLeft The left edge of the region inside b to use.
-     * @param textureTop The top edge of the region inside b to use.
-     * @param textureWidth The width of the region inside b to use.
-     * @param textureHeight The height of the region inside b to use.
      * @param source An object representing where the drag originated
      * @param dragInfo The data associated with the object that is being dragged
      * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or
@@ -286,7 +273,6 @@
      *          Makes dragging feel more precise, e.g. you can clip out a transparent border
      */
     public void startDrag(Bitmap b, int screenX, int screenY,
-            int textureLeft, int textureTop, int textureWidth, int textureHeight,
             DragSource source, Object dragInfo, int dragAction, Rect dragRegion) {
         if (PROFILE_DRAWING_DURING_DRAG) {
             android.os.Debug.startMethodTracing("Launcher");
@@ -318,7 +304,7 @@
         mVibrator.vibrate(VIBRATE_DURATION);
 
         DragView dragView = mDragView = new DragView(mContext, b, registrationX, registrationY,
-                textureLeft, textureTop, textureWidth, textureHeight);
+                0, 0, b.getWidth(), b.getHeight());
 
         final DragSource dragSource = source;
         dragView.setOnDrawRunnable(new Runnable() {
@@ -400,7 +386,7 @@
     public void cancelDrag() {
         if (mDragging) {
             // Should we also be calling onDragExit() here?
-            mDragSource.onDropCompleted(null, false);
+            mDragSource.onDropCompleted(null, mDragInfo, false);
         }
         endDrag();
     }
@@ -596,14 +582,14 @@
                     (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo)) {
                 dropTarget.onDrop(mDragSource, coordinates[0], coordinates[1],
                         (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
-                mDragSource.onDropCompleted((View) dropTarget, true);
+                mDragSource.onDropCompleted((View) dropTarget, mDragInfo, true);
                 return true;
             } else {
-                mDragSource.onDropCompleted((View) dropTarget, false);
+                mDragSource.onDropCompleted((View) dropTarget, mDragInfo, false);
                 return true;
             }
         } else {
-            mDragSource.onDropCompleted(null, false);
+            mDragSource.onDropCompleted(null, mDragInfo, false);
         }
         return false;
     }
@@ -716,6 +702,10 @@
         mDeleteRegion = region;
     }
 
+    DragView getDragView() {
+        return mDragView;
+    }
+
     private class ScrollRunnable implements Runnable {
         private int mDirection;
 
diff --git a/src/com/android/launcher2/DragSource.java b/src/com/android/launcher2/DragSource.java
index 11cdcc9..4dbdaf7 100644
--- a/src/com/android/launcher2/DragSource.java
+++ b/src/com/android/launcher2/DragSource.java
@@ -31,5 +31,5 @@
      */
     void onDragViewVisible();
 
-    void onDropCompleted(View target, boolean success);
+    void onDropCompleted(View target, Object dragInfo, boolean success);
 }
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index cb450b9..059e73d 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -114,7 +114,7 @@
     }
 
     @Override
-    public void onDropCompleted(View target, boolean success) {
+    public void onDropCompleted(View target, Object dragInfo, boolean success) {
     }
 
     @Override
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 57148d2..59ca9b3 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -3057,9 +3057,15 @@
         }
     }
 
-    void addExternalItemToScreen(ItemInfo itemInfo, CellLayout layout) {
+    /**
+     * Add an item from all apps or customize onto the given workspace screen.
+     * If layout is null, add to the current screen.
+     */
+    void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {
         if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {
             showOutOfSpaceMessage();
+        } else {
+            layout.animateDrop();
         }
     }
 
diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java
index 1366619..9c5d126 100644
--- a/src/com/android/launcher2/PagedViewIcon.java
+++ b/src/com/android/launcher2/PagedViewIcon.java
@@ -243,8 +243,7 @@
         return mIsChecked;
     }
 
-    @Override
-    public void setChecked(boolean checked) {
+    void setChecked(boolean checked, boolean animate) {
         if (mIsChecked != checked) {
             mIsChecked = checked;
 
@@ -262,15 +261,24 @@
             if (mCheckedAlphaAnimator != null) {
                 mCheckedAlphaAnimator.cancel();
             }
-            mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha);
-            mCheckedAlphaAnimator.setDuration(duration);
-            mCheckedAlphaAnimator.start();
+            if (animate) {
+                mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha);
+                mCheckedAlphaAnimator.setDuration(duration);
+                mCheckedAlphaAnimator.start();
+            } else {
+                setAlpha(alpha);
+            }
 
             invalidate();
         }
     }
 
     @Override
+    public void setChecked(boolean checked) {
+        setChecked(checked, true);
+    }
+
+    @Override
     public void toggle() {
         setChecked(!mIsChecked);
     }
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 9b83f48..07b215d 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -257,8 +257,7 @@
         sWorker.removeMessages(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE, this);
     }
 
-    @Override
-    public void setChecked(boolean checked) {
+    void setChecked(boolean checked, boolean animate) {
         if (mIsChecked != checked) {
             mIsChecked = checked;
 
@@ -276,15 +275,24 @@
             if (mCheckedAlphaAnimator != null) {
                 mCheckedAlphaAnimator.cancel();
             }
-            mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha);
-            mCheckedAlphaAnimator.setDuration(duration);
-            mCheckedAlphaAnimator.start();
+            if (animate) {
+                mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha);
+                mCheckedAlphaAnimator.setDuration(duration);
+                mCheckedAlphaAnimator.start();
+            } else {
+                setAlpha(alpha);
+            }
 
             invalidate();
         }
     }
 
     @Override
+    public void setChecked(boolean checked) {
+        setChecked(checked, true);
+    }
+
+    @Override
     public boolean isChecked() {
         return mIsChecked;
     }
diff --git a/src/com/android/launcher2/UserFolder.java b/src/com/android/launcher2/UserFolder.java
index b362fbd..251b3f9 100644
--- a/src/com/android/launcher2/UserFolder.java
+++ b/src/com/android/launcher2/UserFolder.java
@@ -64,7 +64,7 @@
     }
 
     @Override
-    public void onDropCompleted(View target, boolean success) {
+    public void onDropCompleted(View target, Object dragInfo, boolean success) {
         if (success) {
             ShortcutsAdapter adapter = (ShortcutsAdapter)mContent.getAdapter();
             adapter.remove(mDragItem);
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index e7735be..c2063ab 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -2070,8 +2070,8 @@
         final int screenX = (int) mTempXY[0] + (child.getWidth() - bmpWidth) / 2;
         final int screenY = (int) mTempXY[1] + (child.getHeight() - bmpHeight) / 2;
         mLauncher.lockScreenOrientation();
-        mDragController.startDrag(b, screenX, screenY, 0, 0, bmpWidth, bmpHeight, this,
-                child.getTag(), DragController.DRAG_ACTION_MOVE, null);
+        mDragController.startDrag(
+                b, screenX, screenY, this, child.getTag(), DragController.DRAG_ACTION_MOVE);
         b.recycle();
     }
 
@@ -2226,6 +2226,11 @@
         }
 
         if (source != this) {
+            if ((mIsSmall || mIsInUnshrinkAnimation) && !mLauncher.isAllAppsVisible()) {
+                // When the workspace is shrunk and the drop comes from customize, don't actually
+                // add the item to the screen -- customize will do this itself
+                return;
+            }
             onDropExternal(new int[] { originX, originY }, dragInfo, mDragTargetLayout, false);
         } else if (mDragInfo != null) {
             final View cell = mDragInfo.cell;
@@ -2821,11 +2826,8 @@
      * Return the current {@link CellLayout}, correctly picking the destination
      * screen while a scroll is in progress.
      */
-    private CellLayout getCurrentDropLayout() {
-        // if we're currently small, use findMatchingPageForDragOver instead
-        if (mIsSmall) return null;
-        int index = mScroller.isFinished() ? mCurrentPage : mNextPage;
-        return (CellLayout) getChildAt(index);
+    public CellLayout getCurrentDropLayout() {
+        return (CellLayout) getChildAt(mNextPage == INVALID_PAGE ? mCurrentPage : mNextPage);
     }
 
     /**
@@ -2870,7 +2872,7 @@
     /**
      * Called at the end of a drag which originated on the workspace.
      */
-    public void onDropCompleted(View target, boolean success) {
+    public void onDropCompleted(View target, Object dragInfo, boolean success) {
         if (success) {
             if (target != this && mDragInfo != null) {
                 final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen);