Fix crash when dragging a contact to searchbox

Also fix drag handling so that dropping outside the listview will
also complete the drag animation.

Bug: 11017468
Change-Id: I968cc8463e9d567b0a8c62f851c067d589571c6d
diff --git a/src/com/android/dialer/list/PhoneFavoriteListView.java b/src/com/android/dialer/list/PhoneFavoriteListView.java
index b685e82..99979dd 100644
--- a/src/com/android/dialer/list/PhoneFavoriteListView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteListView.java
@@ -80,8 +80,6 @@
 
     private int mDragShadowLeft;
     private int mDragShadowTop;
-    private int mDragShadowWidth;
-    private int mDragShadowHeight;
 
     private final float DRAG_SHADOW_ALPHA = 0.7f;
 
@@ -268,9 +266,8 @@
                 ensureScrollHandler();
                 mScrollHandler.removeCallbacks(mDragScroller);
                 mIsDragScrollerRunning = false;
-                // Either it's been a successful drop or it's ended with out drop.
-                if (action == DragEvent.ACTION_DROP ||
-                        (action == DragEvent.ACTION_DRAG_ENDED && !event.getResult())) {
+                // Either a successful drop or it's ended with out drop.
+                if (action == DragEvent.ACTION_DROP || action == DragEvent.ACTION_DRAG_ENDED) {
                     handleDragFinished(eX, eY);
                 }
                 break;
@@ -346,9 +343,6 @@
                 mDragShadowTop = tileView.getTop() + tileView.getParentRow().getTop();
             }
 
-            mDragShadowWidth = tileView.getWidth();
-            mDragShadowHeight = tileView.getHeight();
-
             mDragShadowOverlay.setImageBitmap(mDragShadowBitmap);
             mDragShadowOverlay.setVisibility(VISIBLE);
             mDragShadowOverlay.setAlpha(DRAG_SHADOW_ALPHA);
@@ -372,22 +366,21 @@
     }
 
     private void handleDragHovered(int x, int y) {
-        final View child = getViewAtPosition(x, y);
-        if (!(child instanceof ContactTileRow)) {
-            // Bail early.
-            return;
-        }
-
         // Update the drag shadow location.
         mDragShadowLeft = x - mTouchOffsetToChildLeft;
         mDragShadowTop = y - mTouchOffsetToChildTop;
-
         // Draw the drag shadow at its last known location if the drag shadow exists.
         if (mDragShadowOverlay != null) {
             mDragShadowOverlay.setX(mDragShadowLeft);
             mDragShadowOverlay.setY(mDragShadowTop);
         }
 
+        final View child = getViewAtPosition(x, y);
+        if (!(child instanceof ContactTileRow)) {
+            // Bail early.
+            return;
+        }
+
         final ContactTileRow tile = (ContactTileRow) child;
         final int itemIndex = tile.getItemIndex(x, y);
         if (itemIndex != -1 && mOnDragDropListener != null) {
diff --git a/src/com/android/dialer/list/PhoneFavoriteTileView.java b/src/com/android/dialer/list/PhoneFavoriteTileView.java
index ac89fd6..371c805 100644
--- a/src/com/android/dialer/list/PhoneFavoriteTileView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteTileView.java
@@ -20,6 +20,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
+import android.content.ClipData;
 import android.content.Context;
 import android.text.TextUtils;
 import android.util.AttributeSet;
@@ -68,6 +69,10 @@
     /** Custom gesture detector.*/
     protected GestureDetector mGestureDetector;
 
+    // Dummy clip data object that is attached to drag shadows so that text views
+    // don't crash with an NPE if the drag shadow is released in their bounds
+    private static final ClipData EMPTY_CLIP_DATA = ClipData.newPlainText("", "");
+
     public PhoneFavoriteTileView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mAnimationDuration = context.getResources().getInteger(R.integer.fade_duration);
@@ -99,15 +104,15 @@
                 final PhoneFavoriteTileView view = (PhoneFavoriteTileView) v;
                 // NOTE The drag shadow is handled in the ListView.
                 if (view instanceof PhoneFavoriteRegularRowView) {
-                    final ContactTileRow parent = (ContactTileRow) view.getParentRow();
+                    final ContactTileRow parent = view.getParentRow();
                     // If the view is regular row, start drag the row view.
                     // Drag is not available for the item exceeds the PIN_LIMIT.
                     if (parent.getRegularRowItemIndex() < PhoneFavoritesTileAdapter.PIN_LIMIT) {
-                        parent.startDrag(null, new View.DragShadowBuilder(), null, 0);
+                        parent.startDrag(EMPTY_CLIP_DATA, new View.DragShadowBuilder(), null, 0);
                     }
                 } else {
                     // If the view is a tile view, start drag the tile.
-                    view.startDrag(null, new View.DragShadowBuilder(), null, 0);
+                    view.startDrag(EMPTY_CLIP_DATA, new View.DragShadowBuilder(), null, 0);
                 }
                 return true;
             }