Fix bug drag viz & hover state

Change-Id: I6b40d4dd43a2ee0c127df938375870347faeb5f6
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 57953c0..018a966 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -216,7 +216,6 @@
                             Log.d(TAG, "anim " + thisIndex + " update: " + val +
                                      ", isStopped " + anim.isStopped());
                         }
-
                         // Try to prevent it from continuing to run
                         animation.cancel();
                     } else {
@@ -837,10 +836,12 @@
     void visualizeDropLocation(
             View v, Bitmap dragOutline, int originX, int originY, int spanX, int spanY) {
 
+        final int oldDragCellX = mDragCell[0];
+        final int oldDragCellY = mDragCell[1];
         final int[] nearest = findNearestVacantArea(originX, originY, spanX, spanY, v, mDragCell);
         mDragCenter.set(originX + (v.getWidth() / 2), originY + (v.getHeight() / 2));
 
-        if (nearest != null) {
+        if (nearest != null && (nearest[0] != oldDragCellX || nearest[1] != oldDragCellY)) {
             // Find the top left corner of the rect the object will occupy
             final int[] topLeft = mTmpPoint;
             cellToPoint(nearest[0], nearest[1], topLeft);
@@ -859,16 +860,12 @@
             top += (v.getHeight() - dragOutline.getHeight()) / 2;
 
             final int oldIndex = mDragOutlineCurrent;
-            final Point lastPoint = mDragOutlines[oldIndex];
-            if (lastPoint.x != left || lastPoint.y != top) {
-                mDragOutlineCurrent = (oldIndex + 1) % mDragOutlines.length;
+            mDragOutlineAnims[oldIndex].animateOut();
+            mDragOutlineCurrent = (oldIndex + 1) % mDragOutlines.length;
 
-                mDragOutlines[mDragOutlineCurrent].set(left, top);
-
-                mDragOutlineAnims[oldIndex].animateOut();
-                mDragOutlineAnims[mDragOutlineCurrent].setTag(dragOutline);
-                mDragOutlineAnims[mDragOutlineCurrent].animateIn();
-            }
+            mDragOutlines[mDragOutlineCurrent].set(left, top);
+            mDragOutlineAnims[mDragOutlineCurrent].setTag(dragOutline);
+            mDragOutlineAnims[mDragOutlineCurrent].animateIn();
         }
 
         // If we are drawing crosshairs, the entire CellLayout needs to be invalidated
@@ -1084,21 +1081,19 @@
         if (mDragging) {
             mDragging = false;
 
-            // Invalidate the drag data
-            mDragCell[0] = -1;
-            mDragCell[1] = -1;
-
             // Fade out the drag indicators
             if (mCrosshairsAnimator != null) {
                 mCrosshairsAnimator.animateOut();
             }
-
-            final int prev = mDragOutlineCurrent;
-            mDragOutlineAnims[prev].animateOut();
-            mDragOutlineCurrent = (prev + 1) % mDragOutlines.length;
-            mDragOutlines[mDragOutlineCurrent].set(-1, -1);
-            mDragOutlineAlphas[mDragOutlineCurrent] = 0;
         }
+
+        // Invalidate the drag data
+        mDragCell[0] = -1;
+        mDragCell[1] = -1;
+        mDragOutlineAnims[mDragOutlineCurrent].animateOut();
+        mDragOutlineCurrent = (mDragOutlineCurrent + 1) % mDragOutlineAnims.length;
+
+        setHover(false);
     }
 
     /**
@@ -1115,14 +1110,12 @@
             lp.dropped = true;
             child.requestLayout();
         }
-        onDragExit();
     }
 
     void onDropAborted(View child) {
         if (child != null) {
             ((LayoutParams) child.getLayoutParams()).isDragging = false;
         }
-        onDragExit();
     }
 
     /**
@@ -1142,7 +1135,6 @@
      */
     void onDragEnter(View dragView) {
         if (!mDragging) {
-//            Log.d(TAG, "Received onDragEnter while drag still active");
             // Fade in the drag indicators
             if (mCrosshairsAnimator != null) {
                 mCrosshairsAnimator.animateIn();
diff --git a/src/com/android/launcher2/InterruptibleInOutAnimator.java b/src/com/android/launcher2/InterruptibleInOutAnimator.java
index bed7e6b..5ebe605 100644
--- a/src/com/android/launcher2/InterruptibleInOutAnimator.java
+++ b/src/com/android/launcher2/InterruptibleInOutAnimator.java
@@ -43,7 +43,7 @@
     private static final int IN = 1;
     private static final int OUT = 2;
 
-
+    // TODO: This isn't really necessary, but is here to help diagnose a bug in the drag viz
     private int mDirection = STOPPED;
 
     public InterruptibleInOutAnimator(long duration, float fromValue, float toValue) {
@@ -51,6 +51,12 @@
         mOriginalDuration = duration;
         mOriginalFromValue = fromValue;
         mOriginalToValue = toValue;
+
+        mAnimator.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator animation) {
+                mDirection = STOPPED;
+            }
+        });
     }
 
     private void animate(int direction) {
@@ -62,13 +68,17 @@
         // Make sure it's stopped before we modify any values
         cancel();
 
-        if (startValue != toValue) {
-            mDirection = direction;
-            mAnimator.setDuration(mOriginalDuration - currentPlayTime);
-            mAnimator.setFloatValues(startValue, toValue);
-            mAnimator.start();
-            mFirstRun = false;
-        }
+        // TODO: We don't really need to do the animation if startValue == toValue, but
+        // somehow that doesn't seem to work, possibly a quirk of the animation framework
+        mDirection = direction;
+
+        // Ensure we don't calculate a non-sensical duration
+        long duration = mOriginalDuration - currentPlayTime;
+        mAnimator.setDuration(Math.max(0, Math.min(duration, mOriginalDuration)));
+
+        mAnimator.setFloatValues(startValue, toValue);
+        mAnimator.start();
+        mFirstRun = false;
     }
 
     public void cancel() {
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 1b6b139..051ac65 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -1004,7 +1004,7 @@
         mDragInfo = cellInfo;
         mDragInfo.screen = mCurrentPage;
 
-        CellLayout current = ((CellLayout) getChildAt(mCurrentPage));
+        CellLayout current = getCurrentDropLayout();
 
         current.onDragChild(child);
 
@@ -1028,7 +1028,6 @@
                 child.getTag(), DragController.DRAG_ACTION_MOVE, null);
         b.recycle();
 
-        current.onDragEnter(child);
         child.setVisibility(View.GONE);
     }
 
@@ -1102,8 +1101,11 @@
 
     public void onDragEnter(DragSource source, int x, int y, int xOffset,
             int yOffset, DragView dragView, Object dragInfo) {
+        mDragTargetLayout = null; // Reset the drag state
+
         if (!mIsSmall) {
-            getCurrentDropLayout().onDragEnter(dragView);
+            mDragTargetLayout = getCurrentDropLayout();
+            mDragTargetLayout.onDragEnter(dragView);
             showOutlines();
         }
     }
@@ -1371,11 +1373,11 @@
             int yOffset, DragView dragView, Object dragInfo) {
         if (mDragTargetLayout != null) {
             mDragTargetLayout.onDragExit();
-            mDragTargetLayout = null;
         }
         if (!mIsPageMoving) {
             hideOutlines();
         }
+        clearAllHovers();
     }
 
     private void onDropExternal(int x, int y, Object dragInfo,
@@ -1496,9 +1498,6 @@
      */
     public boolean acceptDrop(DragSource source, int x, int y,
             int xOffset, int yOffset, DragView dragView, Object dragInfo) {
-        // call onDragOver one more time, in case the current layout has changed
-        onDragOver(source, x, y, xOffset, yOffset, dragView, dragInfo);
-
         if (mDragTargetLayout == null) {
             // cancel the drag if we're not over a screen at time of drop
             return false;
@@ -1611,14 +1610,18 @@
         }
     }
 
+    private void clearAllHovers() {
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            ((CellLayout) getChildAt(i)).setHover(false);
+        }
+    }
+
     @Override
     public void onExitScrollArea() {
         if (mInScrollArea) {
             mInScrollArea = false;
-            final int childCount = getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                ((CellLayout) getChildAt(i)).setHover(false);
-            }
+            clearAllHovers();
         }
     }