Use PhoneFavoritesTileAdapter directly in GridView

This CL moves the adapter that contains the speed dial contacts into
its own GridView that lives in PhoneFavoritesFragment. This is the
first step to splitting up PhoneFavoritesMergedAdapter into
a list of shortcuts and a grid of contacts, and also get rid of the
convoluted ContactTileRow logic within PhoneFavoritesTileAdapter, to
facilitate a future transition to RecyclerView.

* PhoneFavoritesTileAdapter now directly returns PhoneFavoriteTileViews
rather than ContactTileRows.
* Deleted a lot of unnecessary complicated logic within
PhoneFavoritesTileAdapter that had to do with ContactTileRows.
* Simplified and rewrote animation logic so that animations now perform
as expected within the GridView. In the future this may not be necessary
if RecyclerView is used.
* Rewrote layout/measurement logic for PhoneFavoriteTileView. It now
determines its height directly based on what its measured width is.
* Replaced PhoneFavoritesListView in PhoneFavoriteFragment with a
standard GridView
* Delete stale PhoneFavoriteTileAdapter tests

Notes:
Call shortcut cards are now temporarily missing due to this change

Bug: 13963734
Bug: 13933092
Bug: 13419223

Change-Id: I71e8970667589e4024d00e9af2c8b45c843c5db1
diff --git a/res/layout/phone_favorite_tile_view.xml b/res/layout/phone_favorite_tile_view.xml
index 8a94844..0050cef 100644
--- a/res/layout/phone_favorite_tile_view.xml
+++ b/res/layout/phone_favorite_tile_view.xml
@@ -16,7 +16,8 @@
 <view
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/contact_tile"
-    class="com.android.dialer.list.PhoneFavoriteSquareTileView" >
+    class="com.android.dialer.list.PhoneFavoriteSquareTileView"
+    android:paddingEnd="@dimen/contact_tile_divider_width">
 
     <RelativeLayout
         android:id="@+id/contact_favorite_card"
diff --git a/res/layout/phone_favorites_fragment.xml b/res/layout/phone_favorites_fragment.xml
index 7a1f05a..5e9e3bb 100644
--- a/res/layout/phone_favorites_fragment.xml
+++ b/res/layout/phone_favorites_fragment.xml
@@ -29,12 +29,13 @@
         android:layout_height="match_parent"
         android:layout_alignParentTop="true"
         android:layout_alignParentLeft="true"
-        >
-
+        android:paddingStart="@dimen/favorites_row_start_padding"
+        android:paddingEnd="@dimen/favorites_row_end_padding" >
         <com.android.dialer.list.PhoneFavoriteListView
             android:id="@+id/contact_tile_list"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
+            android:numColumns="@integer/contact_tile_column_count_in_favorites"
             android:clipToPadding="false"
             android:fadingEdge="none"
             android:divider="@null" />
@@ -43,7 +44,8 @@
             android:id="@+id/contact_tile_drag_shadow_overlay"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:visibility="gone"/>
+            android:visibility="gone"
+            android:importantForAccessibility="no" />
     </FrameLayout>
 
     <include
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index f113ac0..496eb43 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -64,7 +64,7 @@
     <dimen name="call_button_height">74dp</dimen>
 
     <dimen name="fake_action_bar_height">60dp</dimen>
-    <!-- Min with of fake menu buttons, which should be same as ActionBar's one -->
+    <!-- Min width of fake menu buttons, which should be same as ActionBar's one -->
     <dimen name="fake_menu_button_min_width">56dp</dimen>
 
     <!--  Favorites tile and recent call log padding -->
@@ -76,7 +76,8 @@
     <dimen name="favorites_row_top_padding">1dp</dimen>
     <dimen name="favorites_row_bottom_padding">0dp</dimen>
     <dimen name="favorites_row_start_padding">1dp</dimen>
-    <dimen name="favorites_row_end_padding">1dp</dimen>
+    <!-- Padding from the last contact tile will provide the end padding. -->
+    <dimen name="favorites_row_end_padding">0dp</dimen>
     <dimen name="favorites_row_undo_text_side_padding">32dp</dimen>
     <dimen name="recent_call_log_item_padding">8dp</dimen>
     <!-- Size of the star icon on the favorites tile. -->
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index db4ff35..2d5df2b 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -76,6 +76,7 @@
 import com.android.dialer.list.OnListFragmentScrolledListener;
 import com.android.dialer.list.PhoneFavoriteFragment;
 import com.android.dialer.list.PhoneFavoriteTileView;
+import com.android.dialer.list.PhoneFavoriteSquareTileView;
 import com.android.dialer.list.RegularSearchFragment;
 import com.android.dialer.list.RemoveView;
 import com.android.dialer.list.SearchFragment;
@@ -915,13 +916,13 @@
      * Called when the user has long-pressed a contact tile to start a drag operation.
      */
     @Override
-    public void onDragStarted(int itemIndex, int x, int y, PhoneFavoriteTileView view) {
+    public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view) {
         getActionBar().hide();
         mSearchAndRemoveViewContainer.setVisibility(View.VISIBLE);
     }
 
     @Override
-    public void onDragHovered(int itemIndex, int x, int y) {}
+    public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView view) {}
 
     /**
      * Called when the user has released a contact tile after long-pressing it.
diff --git a/src/com/android/dialer/list/DragDropController.java b/src/com/android/dialer/list/DragDropController.java
index 399cd09..db4dd59 100644
--- a/src/com/android/dialer/list/DragDropController.java
+++ b/src/com/android/dialer/list/DragDropController.java
@@ -1,9 +1,5 @@
 package com.android.dialer.list;
 
-import android.view.View;
-
-import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow;
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -17,30 +13,22 @@
     /**
      * @return True if the drag is started, false if the drag is cancelled for some reason.
      */
-    boolean handleDragStarted(int x, int y, ContactTileRow tileRow) {
-        final PhoneFavoriteTileView tileView =
-                (PhoneFavoriteTileView) tileRow.getViewAtPosition(x, y);
-
-        final int itemIndex = tileRow.getItemIndex(x, y);
-        if (itemIndex != -1 && !mOnDragDropListeners.isEmpty()) {
+    boolean handleDragStarted(int x, int y, PhoneFavoriteSquareTileView tileView) {
+        if (tileView == null) {
+            return false;
+        }
+        if (tileView != null && !mOnDragDropListeners.isEmpty()) {
             for (int i = 0; i < mOnDragDropListeners.size(); i++) {
-                mOnDragDropListeners.get(i).onDragStarted(itemIndex, x, y, tileView);
+                mOnDragDropListeners.get(i).onDragStarted(x, y, tileView);
             }
         }
 
         return true;
     }
 
-    public void handleDragHovered(int x, int y, View view) {
-        int itemIndex;
-        if (!(view instanceof ContactTileRow)) {
-            itemIndex = -1;
-        } else {
-            final ContactTileRow tile = (ContactTileRow) view;
-            itemIndex = tile.getItemIndex(x, y);
-        }
+    public void handleDragHovered(int x, int y, PhoneFavoriteSquareTileView view) {
         for (int i = 0; i < mOnDragDropListeners.size(); i++) {
-            mOnDragDropListeners.get(i).onDragHovered(itemIndex, x, y);
+            mOnDragDropListeners.get(i).onDragHovered(x, y, view);
         }
     }
 
diff --git a/src/com/android/dialer/list/OnDragDropListener.java b/src/com/android/dialer/list/OnDragDropListener.java
index 7f6d179..c9ef50b 100644
--- a/src/com/android/dialer/list/OnDragDropListener.java
+++ b/src/com/android/dialer/list/OnDragDropListener.java
@@ -8,22 +8,22 @@
 public interface OnDragDropListener {
     /**
      * Called when a drag is started.
-     * @param itemIndex Index of the contact on which the drag was triggered
      * @param x X-coordinate of the drag event
      * @param y Y-coordinate of the drag event
      * @param view The contact tile which the drag was started on
      */
-    public void onDragStarted(int itemIndex, int x, int y, PhoneFavoriteTileView view);
+    public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view);
 
     /**
      * Called when a drag is in progress and the user moves the dragged contact to a
      * location.
-     * @param itemIndex Index of the contact in the ListView which is currently being displaced
-     * by the dragged contact
+     *
      * @param x X-coordinate of the drag event
      * @param y Y-coordinate of the drag event
+     * @param view Contact tile in the ListView which is currently being displaced
+     * by the dragged contact
      */
-    public void onDragHovered(int itemIndex, int x, int y);
+    public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView view);
 
     /**
      * Called when a drag is completed (whether by dropping it somewhere or simply by dragging
diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java
index f3787e5..ed6b5c8 100644
--- a/src/com/android/dialer/list/PhoneFavoriteFragment.java
+++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java
@@ -49,7 +49,6 @@
 import com.android.contacts.common.ContactTileLoaderFactory;
 import com.android.contacts.common.GeoUtil;
 import com.android.contacts.common.list.ContactEntry;
-import com.android.contacts.common.list.ContactListItemView;
 import com.android.contacts.common.list.ContactTileView;
 import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
 import com.android.dialer.DialtactsActivity;
@@ -58,7 +57,6 @@
 import com.android.dialer.calllog.CallLogQuery;
 import com.android.dialer.calllog.CallLogQueryHandler;
 import com.android.dialer.calllog.ContactInfoHelper;
-import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow;
 import com.android.dialerbind.ObjectFactory;
 
 import java.util.ArrayList;
@@ -161,7 +159,7 @@
 
         @Override
         public int getApproximateTileWidth() {
-            return getView().getWidth() / mContactTileAdapter.getColumnCount();
+            return getView().getWidth();
         }
     }
 
@@ -233,9 +231,7 @@
         // We don't construct the resultant adapter at this moment since it requires LayoutInflater
         // that will be available on onCreateView().
         mContactTileAdapter = new PhoneFavoritesTileAdapter(activity, mContactTileAdapterListener,
-                this,
-                getResources().getInteger(R.integer.contact_tile_column_count_in_favorites),
-                PhoneFavoritesTileAdapter.NO_ROW_LIMIT);
+                this);
         mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
     }
 
@@ -271,7 +267,6 @@
         mParentView = inflater.inflate(R.layout.phone_favorites_fragment, container, false);
 
         mListView = (PhoneFavoriteListView) mParentView.findViewById(R.id.contact_tile_list);
-        mListView.setItemsCanFocus(true);
         mListView.setOnItemClickListener(this);
         mListView.setVerticalScrollBarEnabled(false);
         mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT);
@@ -294,9 +289,10 @@
         mAdapter = new PhoneFavoriteMergedAdapter(getActivity(), this, mContactTileAdapter,
                 mCallLogAdapter, mPhoneFavoritesMenu, mTileInteractionTeaserView);
 
+
         mTileInteractionTeaserView.setAdapter(mAdapter);
 
-        mListView.setAdapter(mAdapter);
+        mListView.setAdapter(mContactTileAdapter);
 
         mListView.setOnScrollListener(mScrollListener);
         mListView.setFastScrollEnabled(false);
@@ -381,7 +377,6 @@
 
     @Override
     public void onCallsFetched(Cursor cursor) {
-        animateListView();
         mCallLogAdapter.setLoading(false);
 
         // Save the date of the most recent call log item
@@ -412,7 +407,6 @@
      * that slide views from their previous positions to their new ones, to give the appearance
      * that the views are sliding into their new positions.
      */
-    @SuppressWarnings("unchecked")
     private void saveOffsets(int removedItemHeight) {
         final int firstVisiblePosition = mListView.getFirstVisiblePosition();
         if (DEBUG) {
@@ -421,114 +415,22 @@
         for (int i = 0; i < mListView.getChildCount(); i++) {
             final View child = mListView.getChildAt(i);
             final int position = firstVisiblePosition + i;
-            final long itemId = mAdapter.getItemId(position);
-            final int itemViewType = mAdapter.getItemViewType(position);
-            if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP &&
-                    child instanceof ContactTileRow) {
-                // This is a tiled row, so save horizontal offsets instead
-                saveHorizontalOffsets((ContactTileRow) child, (ArrayList<ContactEntry>)
-                        mAdapter.getItem(position),
-                        mAdapter.getAdjustedPositionInContactTileAdapter(position));
-            }
+            final long itemId = mContactTileAdapter.getItemId(position);
             if (DEBUG) {
                 Log.d(TAG, "Saving itemId: " + itemId + " for listview child " + i + " Top: "
                         + child.getTop());
             }
             mItemIdTopMap.put(itemId, child.getTop());
+            mItemIdLeftMap.put(itemId, child.getLeft());
         }
 
         mItemIdTopMap.put(KEY_REMOVED_ITEM_HEIGHT, removedItemHeight);
     }
 
-    /**
-     * Saves the horizontal offsets for contacts that are displayed as tiles in a row. Saving
-     * these offsets allow us to animate tiles sliding left and right within the same row.
-     * See {@link #saveOffsets(int removedItemHeight)}
-     */
-    private void saveHorizontalOffsets(ContactTileRow row, ArrayList<ContactEntry> list,
-            int currentRowIndex) {
-        for (int i = 0; i < list.size() && i < row.getChildCount(); i++) {
-            final View child = row.getChildAt(i);
-            if (child == null) {
-                continue;
-            }
-            final ContactEntry entry = list.get(i);
-            final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id);
-            if (DEBUG) {
-                Log.d(TAG, "Saving itemId: " + itemId + " for tileview child " + i + " Left: "
-                        + child.getTop());
-            }
-            mItemIdTopMap.put(itemId, currentRowIndex);
-            mItemIdLeftMap.put(itemId, child.getLeft());
-        }
-    }
-
     /*
-     * Performs a animations for a row of tiles
+     * Performs animations for the gridView
      */
-    private void performHorizontalAnimations(ContactTileRow row, ArrayList<ContactEntry> list,
-            long[] idsInPlace, int currentRow) {
-        if (mItemIdLeftMap.isEmpty()) {
-            return;
-        }
-        final AnimatorSet animSet = new AnimatorSet();
-        final ArrayList<Animator> animators = new ArrayList<Animator>();
-        for (int i = 0; i < list.size(); i++) {
-            final View child = row.getChildAt(i);
-            final ContactEntry entry = list.get(i);
-            final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id);
-
-            if (containsId(idsInPlace, itemId)) {
-                animators.add(ObjectAnimator.ofFloat(
-                        child, "alpha", 0.0f, 1.0f));
-                break;
-            } else {
-                Integer startLeft = mItemIdLeftMap.get(itemId);
-                int left = child.getLeft();
-
-                Integer startRow = mItemIdTopMap.get(itemId);
-                if (startRow != null) {
-                    if (startRow > currentRow) {
-                        // Item has shifted upwards to the previous row.
-                        // It should now animate in from right to left.
-                        startLeft = left + child.getWidth();
-                    } else if (startRow < currentRow) {
-                        // Item has shifted downwards to the next row.
-                        // It should now animate in from left to right.
-                        startLeft = left - child.getWidth();
-                    }
-
-                    // If the item hasn't shifted rows (startRow == currentRow), it either remains
-                    // in the same position or has shifted left or right within its current row.
-                    // Either way, startLeft has already been correctly saved and retrieved from
-                    // mItemIdTopMap.
-                }
-
-                if (startLeft != null) {
-                    if (startLeft != left) {
-                        int delta = startLeft - left;
-                        if (DEBUG) {
-                            Log.d(TAG, "Found itemId: " + itemId + " for tileview child " + i +
-                                    " Left: " + left +
-                                    " Delta: " + delta);
-                        }
-                        animators.add(ObjectAnimator.ofFloat(
-                                child, "translationX", delta, 0.0f));
-                    }
-                }
-            }
-        }
-        if (animators.size() > 0) {
-            animSet.setDuration(mAnimationDuration).playTogether(animators);
-            animSet.start();
-        }
-    }
-
-    /*
-     * Performs animations for the list view. If the list item is a row of tiles, horizontal
-     * animations will be performed instead.
-     */
-    private void animateListView(final long... idsInPlace) {
+    private void animateGridView(final long... idsInPlace) {
         if (mItemIdTopMap.isEmpty()) {
             // Don't do animations if the database is being queried for the first time and
             // the previous item offsets have not been cached, or the user hasn't done anything
@@ -536,8 +438,6 @@
             return;
         }
 
-        final int removedItemHeight = mItemIdTopMap.get(KEY_REMOVED_ITEM_HEIGHT);
-
         final ViewTreeObserver observer = mListView.getViewTreeObserver();
         observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
             @SuppressWarnings("unchecked")
@@ -550,16 +450,8 @@
                 for (int i = 0; i < mListView.getChildCount(); i++) {
                     final View child = mListView.getChildAt(i);
                     int position = firstVisiblePosition + i;
-                    final int itemViewType = mAdapter.getItemViewType(position);
-                    if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP &&
-                            child instanceof ContactTileRow) {
-                        // This is a tiled row, so perform horizontal animations instead
-                        performHorizontalAnimations((ContactTileRow) child, (
-                                ArrayList<ContactEntry>) mAdapter.getItem(position), idsInPlace,
-                                mAdapter.getAdjustedPositionInContactTileAdapter(position));
-                    }
 
-                    final long itemId = mAdapter.getItemId(position);
+                    final long itemId = mContactTileAdapter.getItemId(position);
 
                     if (containsId(idsInPlace, itemId)) {
                         animators.add(ObjectAnimator.ofFloat(
@@ -567,35 +459,32 @@
                         break;
                     } else {
                         Integer startTop = mItemIdTopMap.get(itemId);
+                        Integer startLeft = mItemIdLeftMap.get(itemId);
                         final int top = child.getTop();
-                        int delta = 0;
+                        final int left = child.getLeft();
+                        int deltaX = 0;
+                        int deltaY = 0;
+
+                        if (startLeft != null) {
+                            if (startLeft != left) {
+                                deltaX = startLeft - left;
+                                animators.add(ObjectAnimator.ofFloat(
+                                        child, "translationX", deltaX, 0.0f));
+                            }
+                        }
+
                         if (startTop != null) {
                             if (startTop != top) {
-                                delta = startTop - top;
+                                deltaY = startTop - top;
+                                animators.add(ObjectAnimator.ofFloat(
+                                        child, "translationY", deltaY, 0.0f));
                             }
-                        } else if (!mItemIdLeftMap.containsKey(itemId)) {
-                            // Animate new views along with the others. The catch is that they did
-                            // not exist in the start state, so we must calculate their starting
-                            // position based on neighboring views.
-
-                            final int itemHeight;
-                            if (removedItemHeight == 0) {
-                                itemHeight = child.getHeight() + mListView.getDividerHeight();
-                            } else {
-                                itemHeight = removedItemHeight;
-                            }
-                            startTop = top + (i > 0 ? itemHeight : -itemHeight);
-                            delta = startTop - top;
                         }
+
                         if (DEBUG) {
                             Log.d(TAG, "Found itemId: " + itemId + " for listview child " + i +
                                     " Top: " + top +
-                                    " Delta: " + delta);
-                        }
-
-                        if (delta != 0) {
-                            animators.add(ObjectAnimator.ofFloat(
-                                    child, "translationY", delta, 0.0f));
+                                    " Delta: " + deltaY);
                         }
                     }
                 }
@@ -624,7 +513,7 @@
 
     @Override
     public void onDataSetChangedForAnimation(long... idsInPlace) {
-        animateListView(idsInPlace);
+        animateGridView(idsInPlace);
     }
 
     @Override
diff --git a/src/com/android/dialer/list/PhoneFavoriteListView.java b/src/com/android/dialer/list/PhoneFavoriteListView.java
index 67dbf2d..6c3d62a 100644
--- a/src/com/android/dialer/list/PhoneFavoriteListView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteListView.java
@@ -29,17 +29,15 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.widget.GridView;
 import android.widget.ImageView;
-import android.widget.ListView;
 
 import com.android.dialer.R;
-import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow;
 
 /**
- * The ListView used to present a combined list of shortcut cards and contact speed-dial
- * tiles.
+ * Viewgroup that presents the user's speed dial contacts in a grid.
  */
-public class PhoneFavoriteListView extends ListView implements OnDragDropListener {
+public class PhoneFavoriteListView extends GridView implements OnDragDropListener {
 
     public static final String LOG_TAG = PhoneFavoriteListView.class.getSimpleName();
 
@@ -116,7 +114,6 @@
         super(context, attrs, defStyle);
         mAnimationDuration = context.getResources().getInteger(R.integer.fade_duration);
         mTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
-        setItemsCanFocus(true);
         mDragDropController.addOnDragDropListener(this);
     }
 
@@ -146,7 +143,7 @@
         final int eX = (int) event.getX();
         final int eY = (int) event.getY();
         switch (action) {
-            case DragEvent.ACTION_DRAG_STARTED:
+            case DragEvent.ACTION_DRAG_STARTED: {
                 final int[] coordinates = new int[2];
                 getLocationOnScreen(coordinates);
                 // Calculate the X and Y coordinates of the drag event relative to the view
@@ -154,21 +151,26 @@
                 final int viewY = eY - coordinates[1];
                 final View child = getViewAtPosition(viewX, viewY);
 
-                if (!(child instanceof ContactTileRow)) {
+                if (!(child instanceof PhoneFavoriteSquareTileView)) {
                     // Bail early.
                     return false;
                 }
 
-                final ContactTileRow tile = (ContactTileRow) child;
-
+                final PhoneFavoriteSquareTileView tile = (PhoneFavoriteSquareTileView) child;
                 if (!mDragDropController.handleDragStarted(viewX, viewY, tile)) {
                     return false;
                 }
                 break;
+            }
             case DragEvent.ACTION_DRAG_LOCATION:
                 mLastDragY = eY;
-                final View view = getViewAtPosition(eX, eY);
-                mDragDropController.handleDragHovered(eX, eY, view);
+                final View child = getViewAtPosition(eX, eY);
+
+                PhoneFavoriteSquareTileView tile = null;
+                if (child instanceof PhoneFavoriteSquareTileView) {
+                    tile = (PhoneFavoriteSquareTileView) child;
+                }
+                mDragDropController.handleDragHovered(eX, eY, tile);
                 // Kick off {@link #mScrollHandler} if it's not started yet.
                 if (!mIsDragScrollerRunning &&
                         // And if the distance traveled while dragging exceeds the touch slop
@@ -213,7 +215,8 @@
         View child;
         for (int childIdx = 0; childIdx < count; childIdx++) {
             child = getChildAt(childIdx);
-            if (y >= child.getTop() && y <= child.getBottom()) {
+            if (y >= child.getTop() && y <= child.getBottom() && x >= child.getLeft()
+                    && x <= child.getRight()) {
                 return child;
             }
         }
@@ -231,7 +234,7 @@
     }
 
     @Override
-    public void onDragStarted(int itemIndex, int x, int y, PhoneFavoriteTileView tileView) {
+    public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView tileView) {
         if (mDragShadowOverlay == null) {
             return;
         }
@@ -244,8 +247,8 @@
 
         // Square tile is relative to the contact tile,
         // and contact tile is relative to this list view.
-        mDragShadowLeft = tileView.getLeft() + tileView.getParentRow().getLeft();
-        mDragShadowTop = tileView.getTop() + tileView.getParentRow().getTop();
+        mDragShadowLeft = tileView.getLeft();
+        mDragShadowTop = tileView.getTop();
 
         mDragShadowOverlay.setImageBitmap(mDragShadowBitmap);
         mDragShadowOverlay.setVisibility(VISIBLE);
@@ -262,7 +265,7 @@
     }
 
     @Override
-    public void onDragHovered(int itemIndex, int x, int y) {
+    public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView tileView) {
         // Update the drag shadow location.
         mDragShadowLeft = x - mTouchOffsetToChildLeft;
         mDragShadowTop = y - mTouchOffsetToChildTop;
diff --git a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
index 849d651..e2b9bb2 100644
--- a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
+++ b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
@@ -276,14 +276,6 @@
 
         // Favorites section
         final View view = mContactTileAdapter.getView(position, convertView, parent);
-        if (position >= mContactTileAdapter.getMaxTiledRows()) {
-            final FrameLayout frameLayout = (FrameLayout) view;
-            final View child = frameLayout.getChildAt(0);
-            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
-                    FrameLayout.LayoutParams.WRAP_CONTENT,
-                    FrameLayout.LayoutParams.WRAP_CONTENT);
-            child.setLayoutParams(params);
-        }
         return view;
     }
 
@@ -331,7 +323,6 @@
 
     /**
      * The swipeable call log row.
-     * See also {@link PhoneFavoritesTileAdapter.ContactTileRow}.
      */
     private class SwipeableCallLogRow extends FrameLayout implements SwipeHelperCallback {
         private SwipeHelper mSwipeHelper;
diff --git a/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java b/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
index 181d602..0520ab4 100644
--- a/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.provider.ContactsContract.QuickContact;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.ImageButton;
@@ -26,18 +25,23 @@
 import com.android.contacts.common.R;
 import com.android.contacts.common.list.ContactEntry;
 
-import java.util.regex.Pattern;
-
 /**
- * Displays the contact's picture overlayed with their name
- * in a perfect square. It also has an additional touch target for a secondary action.
+ * Displays the contact's picture overlaid with their name and number type in a tile.
  */
 public class PhoneFavoriteSquareTileView extends PhoneFavoriteTileView {
     private static final String TAG = PhoneFavoriteSquareTileView.class.getSimpleName();
+
+    private final float mHeightToWidthRatio;
+
     private ImageButton mSecondaryButton;
 
+    private ContactEntry mContactEntry;
+
     public PhoneFavoriteSquareTileView(Context context, AttributeSet attrs) {
         super(context, attrs);
+
+        mHeightToWidthRatio = getResources().getFraction(
+                R.dimen.contact_tile_height_to_width_ratio, 1, 1);
     }
 
     @Override
@@ -50,7 +54,7 @@
     @Override
     protected int getApproximateImageSize() {
         // The picture is the full size of the tile (minus some padding, but we can be generous)
-        return mListener.getApproximateTileWidth();
+        return getWidth();
     }
 
     private void launchQuickContact() {
@@ -69,5 +73,24 @@
                 }
             });
         }
+        mContactEntry = entry;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int width = MeasureSpec.getSize(widthMeasureSpec);
+        final int height = (int) (mHeightToWidthRatio * width);
+        final int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            getChildAt(i).measure(
+                    MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+                    MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
+                    );
+        }
+        setMeasuredDimension(width, height);
+    }
+
+    public ContactEntry getContactEntry() {
+        return mContactEntry;
     }
 }
diff --git a/src/com/android/dialer/list/PhoneFavoriteTileView.java b/src/com/android/dialer/list/PhoneFavoriteTileView.java
index 7fe4eaa..3626bcb 100644
--- a/src/com/android/dialer/list/PhoneFavoriteTileView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteTileView.java
@@ -29,7 +29,6 @@
 import com.android.contacts.common.list.ContactEntry;
 import com.android.contacts.common.list.ContactTileView;
 import com.android.dialer.R;
-import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow;
 
 /**
  * A light version of the {@link com.android.contacts.common.list.ContactTileView} that is used in
@@ -49,8 +48,6 @@
     private static final float DEFAULT_IMAGE_LETTER_OFFSET = -0.14f;
     private static final float DEFAULT_IMAGE_LETTER_SCALE = 0.70f;
 
-    /** The view that holds the list view row. */
-    protected ContactTileRow mParentRow;
     /** View that contains the transparent shadow that is overlaid on top of the contact image. */
     private View mShadowOverlay;
 
@@ -65,10 +62,6 @@
         super(context, attrs);
     }
 
-    public ContactTileRow getParentRow() {
-        return mParentRow;
-    }
-
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -108,11 +101,6 @@
     }
 
     @Override
-    protected void onAttachedToWindow() {
-        mParentRow = (ContactTileRow) getParent();
-    }
-
-    @Override
     protected boolean isDarkTheme() {
         return false;
     }
diff --git a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
index 0438fbd..95f53c5 100644
--- a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
+++ b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
@@ -76,7 +76,6 @@
     private int mDropEntryIndex = -1;
     /** New position of the temporarily entered contact in the cache. */
     private int mDragEnteredEntryIndex = -1;
-    private long mIdToKeepInPlace = -1;
 
     private boolean mAwaitingRemove = false;
     private boolean mDelayCursorUpdates = false;
@@ -85,10 +84,6 @@
     protected int mNumFrequents;
     protected int mNumStarred;
 
-    protected int mColumnCount;
-    private int mMaxTiledRows = ROW_LIMIT_DEFAULT;
-    private int mStarredIndex;
-
     protected int mIdIndex;
     protected int mLookupIndex;
     protected int mPhotoUriIndex;
@@ -100,11 +95,10 @@
     private int mPhoneNumberTypeIndex;
     private int mPhoneNumberLabelIndex;
     private int mIsDefaultNumberIndex;
+    private int mStarredIndex;
     protected int mPinnedIndex;
     protected int mContactIdIndex;
 
-    private final int mPaddingInPixels;
-
     /** Indicates whether a drag is in process. */
     private boolean mInDragging = false;
 
@@ -135,19 +129,14 @@
     };
 
     public PhoneFavoritesTileAdapter(Context context, ContactTileView.Listener listener,
-            OnDataSetChangedForAnimationListener dataSetChangedListener,
-            int numCols, int maxTiledRows) {
+            OnDataSetChangedForAnimationListener dataSetChangedListener) {
         mDataSetChangedListener = dataSetChangedListener;
         mListener = listener;
         mContext = context;
         mResources = context.getResources();
-        mColumnCount = numCols;
         mNumFrequents = 0;
-        mMaxTiledRows = maxTiledRows;
         mContactEntries = new ArrayList<ContactEntry>();
-        // Converting padding in dips to padding in pixels
-        mPaddingInPixels = mContext.getResources()
-                .getDimensionPixelSize(R.dimen.contact_tile_divider_width);
+
 
         bindColumnIndices();
     }
@@ -156,14 +145,6 @@
         mPhotoManager = photoLoader;
     }
 
-    public void setMaxRowCount(int maxRows) {
-        mMaxTiledRows = maxRows;
-    }
-
-    public void setColumnCount(int columnCount) {
-        mColumnCount = columnCount;
-    }
-
     /**
      * Indicates whether a drag is in process.
      *
@@ -228,12 +209,7 @@
             // cause a refresh of any views that rely on this data
             notifyDataSetChanged();
             // about to start redraw
-            if (mIdToKeepInPlace != -1) {
-                mDataSetChangedListener.onDataSetChangedForAnimation(mIdToKeepInPlace);
-            } else {
-                mDataSetChangedListener.onDataSetChangedForAnimation();
-            }
-            mIdToKeepInPlace = -1;
+            mDataSetChangedListener.onDataSetChangedForAnimation();
         }
     }
 
@@ -337,17 +313,6 @@
     }
 
     /**
-     * Loads a contact from the cached list.
-     *
-     * @param position Position of the Contact.
-     * @return Contact at the requested position.
-     */
-    protected ContactEntry getContactEntryFromCache(int position) {
-        if (mContactEntries.size() <= position) return null;
-        return mContactEntries.get(position);
-    }
-
-    /**
      * Returns the number of frequents that will be displayed in the list.
      */
     public int getNumFrequents() {
@@ -356,52 +321,11 @@
 
     @Override
     public int getCount() {
-        if (mContactEntries == null || mContactEntries.isEmpty()) {
+        if (mContactEntries == null) {
             return 0;
         }
 
-        int total = mContactEntries.size();
-        // The number of contacts that don't show up as tiles
-        final int nonTiledRows = Math.max(0, total - getMaxContactsInTiles());
-        // The number of tiled rows
-        final int tiledRows = getRowCount(total - nonTiledRows);
-        return nonTiledRows + tiledRows;
-    }
-
-    public int getMaxTiledRows() {
-        return mMaxTiledRows;
-    }
-
-    /**
-     * Returns the number of rows required to show the provided number of entries
-     * with the current number of columns.
-     */
-    protected int getRowCount(int entryCount) {
-        if (entryCount == 0) return 0;
-        final int nonLimitedRows = ((entryCount - 1) / mColumnCount) + 1;
-        if (mMaxTiledRows == NO_ROW_LIMIT) {
-            return nonLimitedRows;
-        }
-        return Math.min(mMaxTiledRows, nonLimitedRows);
-    }
-
-    private int getMaxContactsInTiles() {
-        if (mMaxTiledRows == NO_ROW_LIMIT) {
-            return Integer.MAX_VALUE;
-        }
-        return mColumnCount * mMaxTiledRows;
-    }
-
-    public int getRowIndex(int entryIndex) {
-        if (entryIndex < getMaxContactsInTiles()) {
-            return entryIndex / mColumnCount;
-        } else {
-            return entryIndex - mMaxTiledRows * (mColumnCount + 1);
-        }
-    }
-
-    public int getColumnCount() {
-        return mColumnCount;
+        return mContactEntries.size();
     }
 
     /**
@@ -409,44 +333,8 @@
      * on the row for the given position.
      */
     @Override
-    public ArrayList<ContactEntry> getItem(int position) {
-        ArrayList<ContactEntry> resultList = new ArrayList<ContactEntry>(mColumnCount);
-
-        final int entryIndex = getFirstContactEntryIndexForPosition(position);
-
-        final int viewType = getItemViewType(position);
-
-        final int columnCount;
-        if (viewType == ViewTypes.TOP) {
-            columnCount = mColumnCount;
-        } else {
-            columnCount = 1;
-        }
-
-        for (int i = 0; i < columnCount; i++) {
-            final ContactEntry entry = getContactEntryFromCache(entryIndex + i);
-            if (entry == null) break; // less than mColumnCount contacts
-            resultList.add(entry);
-        }
-
-        return resultList;
-    }
-
-    /*
-     * Given a position in the adapter, returns the index of the first contact entry that is to be
-     * in that row.
-     */
-    private int getFirstContactEntryIndexForPosition(int position) {
-        final int maxContactsInTiles = getMaxContactsInTiles();
-        if (position < getRowCount(maxContactsInTiles)) {
-            // Contacts that appear as tiles
-            return position * mColumnCount;
-        } else {
-            // Contacts that appear as rows
-            // The actual position of the contact in the cursor is simply total the number of
-            // tiled contacts + the given position
-            return maxContactsInTiles + position - mMaxTiledRows;
-        }
+    public ContactEntry getItem(int position) {
+        return mContactEntries.get(position);
     }
 
     /**
@@ -458,18 +346,7 @@
      */
     @Override
     public long getItemId(int position) {
-        return position;
-    }
-
-    /**
-     * Calculates the stable itemId for a particular entry based on the entry's contact ID. This
-     * stable itemId is used for animation purposes.
-     */
-    public long getAdjustedItemId(long id) {
-        if (mMaxTiledRows == NO_ROW_LIMIT) {
-            return id;
-        }
-        return mMaxTiledRows + id;
+        return getItem(position).id;
     }
 
     @Override
@@ -479,7 +356,6 @@
 
     @Override
     public boolean areAllItemsEnabled() {
-        // No dividers, so all items are enabled.
         return true;
     }
 
@@ -504,32 +380,21 @@
 
         int itemViewType = getItemViewType(position);
 
-        ContactTileRow contactTileRowView = null;
+        PhoneFavoriteTileView tileView = null;
 
-        if (convertView instanceof  ContactTileRow) {
-            contactTileRowView  = (ContactTileRow) convertView;
+        if (convertView instanceof PhoneFavoriteTileView) {
+            tileView  = (PhoneFavoriteTileView) convertView;
         }
 
-        ArrayList<ContactEntry> contactList = getItem(position);
-
-        if (contactTileRowView == null) {
-            // Creating new row if needed
-            contactTileRowView = new ContactTileRow(mContext, itemViewType, position);
+        if (tileView == null) {
+            tileView = (PhoneFavoriteTileView) View.inflate(mContext,
+                    R.layout.phone_favorite_tile_view, null);
         }
-
-        contactTileRowView.configureRow(contactList, position, position == getCount() - 1);
-
-        return contactTileRowView;
+        tileView.setPhotoManager(mPhotoManager);
+        tileView.loadFromContact(getItem(position));
+        return tileView;
     }
 
-    private int getLayoutResourceId(int viewType) {
-        switch (viewType) {
-          case ViewTypes.TOP:
-                return R.layout.phone_favorite_tile_view;
-            default:
-                throw new IllegalArgumentException("Unrecognized viewType " + viewType);
-        }
-    }
     @Override
     public int getViewTypeCount() {
         return ViewTypes.COUNT;
@@ -537,7 +402,7 @@
 
     @Override
     public int getItemViewType(int position) {
-        return ViewTypes.TOP;
+        return ViewTypes.TILE;
     }
 
     /**
@@ -595,7 +460,6 @@
                 // populated with the dragged ContactEntry at the correct spot.
                 mDropEntryIndex = mDragEnteredEntryIndex;
                 mContactEntries.set(mDropEntryIndex, mDraggedEntry);
-                mIdToKeepInPlace = getAdjustedItemId(mDraggedEntry.id);
                 mDataSetChangedListener.cacheOffsetsForDatasetChange();
                 changed = true;
             } else if (isIndexInBound(mDraggedEntryIndex)) {
@@ -641,271 +505,9 @@
     }
 
     /**
-     * Acts as a row item composed of {@link ContactTileView}
-     *
-     */
-    public class ContactTileRow extends FrameLayout {
-        public static final int CONTACT_ENTRY_INDEX_TAG = R.id.contact_entry_index_tag;
-
-        private int mItemViewType;
-        private int mLayoutResId;
-        private final int mRowPaddingStart;
-        private final int mRowPaddingEnd;
-        private final int mRowPaddingTop;
-        private final int mRowPaddingBottom;
-        private final float mHeightToWidthRatio;
-        private int mPosition;
-
-        public ContactTileRow(Context context, int itemViewType, int position) {
-            super(context);
-            mItemViewType = itemViewType;
-            mLayoutResId = getLayoutResourceId(mItemViewType);
-            mPosition = position;
-
-            final Resources resources = mContext.getResources();
-
-            mHeightToWidthRatio = getResources().getFraction(
-                    R.dimen.contact_tile_height_to_width_ratio, 1, 1);
-
-            if (mItemViewType == ViewTypes.TOP) {
-                // For tiled views, we still want padding to be set on the ContactTileRow.
-                // Otherwise the padding would be set around each of the tiles, which we don't want
-                mRowPaddingTop = resources.getDimensionPixelSize(
-                        R.dimen.favorites_row_top_padding);
-                mRowPaddingBottom = resources.getDimensionPixelSize(
-                        R.dimen.favorites_row_bottom_padding);
-                mRowPaddingStart = resources.getDimensionPixelSize(
-                        R.dimen.favorites_row_start_padding);
-                mRowPaddingEnd = resources.getDimensionPixelSize(
-                        R.dimen.favorites_row_end_padding);
-            } else {
-                // For row views, padding is set on the view itself.
-                mRowPaddingTop = 0;
-                mRowPaddingBottom = 0;
-                mRowPaddingStart = 0;
-                mRowPaddingEnd = 0;
-            }
-
-            setPaddingRelative(mRowPaddingStart, mRowPaddingTop, mRowPaddingEnd,
-                    mRowPaddingBottom);
-
-            // Remove row (but not children) from accessibility node tree.
-            setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
-        }
-
-        /**
-         * Configures the row to add {@link ContactEntry}s information to the views
-         */
-        public void configureRow(ArrayList<ContactEntry> list, int position, boolean isLastRow) {
-            final int columnCount = mColumnCount;
-            mPosition = position;
-
-            // Adding tiles to row and filling in contact information
-            for (int columnCounter = 0; columnCounter < columnCount; columnCounter++) {
-                ContactEntry entry =
-                        columnCounter < list.size() ? list.get(columnCounter) : null;
-                addTileFromEntry(entry, columnCounter, isLastRow);
-            }
-        }
-
-        private void addTileFromEntry(ContactEntry entry, int childIndex, boolean isLastRow) {
-            final PhoneFavoriteTileView contactTile;
-
-            if (getChildCount() <= childIndex) {
-
-                contactTile = (PhoneFavoriteTileView) inflate(mContext, mLayoutResId, null);
-                // Note: the layoutparam set here is only actually used for FREQUENT.
-                // We override onMeasure() for STARRED and we don't care the layout param there.
-                final Resources resources = mContext.getResources();
-                FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
-                        ViewGroup.LayoutParams.WRAP_CONTENT,
-                        ViewGroup.LayoutParams.WRAP_CONTENT);
-
-                params.setMargins(
-                        resources.getDimensionPixelSize(R.dimen.detail_item_side_margin), 0,
-                        resources.getDimensionPixelSize(R.dimen.detail_item_side_margin), 0);
-                contactTile.setLayoutParams(params);
-                contactTile.setPhotoManager(mPhotoManager);
-                contactTile.setListener(mListener);
-                addView(contactTile);
-            } else {
-                contactTile = (PhoneFavoriteTileView) getChildAt(childIndex);
-            }
-            contactTile.loadFromContact(entry);
-
-            int entryIndex = -1;
-            switch (mItemViewType) {
-                case ViewTypes.TOP:
-                    // Setting divider visibilities
-                    contactTile.setPaddingRelative(0, 0,
-                            childIndex >= mColumnCount - 1 ? 0 : mPaddingInPixels, 0);
-                    entryIndex = getFirstContactEntryIndexForPosition(mPosition) + childIndex;
-                    break;
-                default:
-                    break;
-            }
-        }
-
-        @Override
-        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-            switch (mItemViewType) {
-                case ViewTypes.TOP:
-                    onLayoutForTiles();
-                    return;
-                default:
-                    super.onLayout(changed, left, top, right, bottom);
-                    return;
-            }
-        }
-
-        private void onLayoutForTiles() {
-            final int count = getChildCount();
-
-            // Just line up children horizontally.
-            int childLeft = getPaddingStart();
-            for (int i = 0; i < count; i++) {
-                final View child = getChildAt(i);
-
-                // Note MeasuredWidth includes the padding.
-                final int childWidth = child.getMeasuredWidth();
-                child.layout(childLeft, getPaddingTop(), childLeft + childWidth,
-                        getPaddingTop() + child.getMeasuredHeight());
-                childLeft += childWidth;
-            }
-        }
-
-        @Override
-        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-            switch (mItemViewType) {
-                case ViewTypes.TOP:
-                    onMeasureForTiles(widthMeasureSpec);
-                    return;
-                default:
-                    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-                    return;
-            }
-        }
-
-        private void onMeasureForTiles(int widthMeasureSpec) {
-            final int width = MeasureSpec.getSize(widthMeasureSpec);
-
-            final int childCount = getChildCount();
-            if (childCount == 0) {
-                // Just in case...
-                setMeasuredDimension(width, 0);
-                return;
-            }
-
-            // 1. Calculate image size.
-            //      = ([total width] - [total padding]) / [child count]
-            //
-            // 2. Set it to width/height of each children.
-            //    If we have a remainder, some tiles will have 1 pixel larger width than its height.
-            //
-            // 3. Set the dimensions of itself.
-            //    Let width = given width.
-            //    Let height = image size + bottom paddding.
-
-            final int totalPaddingsInPixels = (mColumnCount - 1) * mPaddingInPixels
-                    + mRowPaddingStart + mRowPaddingEnd;
-
-            // Preferred width / height for images (excluding the padding).
-            // The actual width may be 1 pixel larger than this if we have a remainder.
-            final int imageWidth = (width - totalPaddingsInPixels) / mColumnCount;
-            final int remainder = width - (imageWidth * mColumnCount) - totalPaddingsInPixels;
-
-            final int height = (int) (mHeightToWidthRatio * imageWidth);
-
-            for (int i = 0; i < childCount; i++) {
-                final View child = getChildAt(i);
-                final int childWidth = imageWidth + child.getPaddingRight()
-                        // Compensate for the remainder
-                        + (i < remainder ? 1 : 0);
-                child.measure(
-                        MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY),
-                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
-                        );
-            }
-            setMeasuredDimension(width, height);
-        }
-
-        /**
-         * Gets the index of the item at the specified coordinates.
-         *
-         * @param itemX X-coordinate of the selected item.
-         * @param itemY Y-coordinate of the selected item.
-         * @return Index of the selected item in the cached array.
-         */
-        public int getItemIndex(float itemX, float itemY) {
-            if (mMaxTiledRows == NO_ROW_LIMIT || mPosition < mMaxTiledRows) {
-                if (DEBUG) {
-                    Log.v(TAG, String.valueOf(itemX) + " " + String.valueOf(itemY));
-                }
-                for (int i = 0; i < getChildCount(); ++i) {
-                    /** If the row contains multiple tiles, checks each tile to see if the point
-                     * is contained in the tile. */
-                    final View child = getChildAt(i);
-                    /** The coordinates passed in are based on the ListView,
-                     * translate for each child first */
-                    final int xInListView = child.getLeft() + getLeft();
-                    final int yInListView = child.getTop() + getTop();
-                    final int distanceX = (int) itemX - xInListView;
-                    final int distanceY = (int) itemY - yInListView;
-                    if ((distanceX > 0 && distanceX < child.getWidth()) &&
-                            (distanceY > 0 && distanceY < child.getHeight())) {
-                        /** If the point is contained in the rectangle, computes the index of the
-                         * item in the cached array. */
-                        return i + (mPosition) * mColumnCount;
-                    }
-                }
-            } else {
-                /** If the selected item is one of the rows, compute the index. */
-                return getRegularRowItemIndex();
-            }
-            return -1;
-        }
-
-        /**
-         * Gets the index of the regular row item.
-         *
-         * @return Index of the selected item in the cached array.
-         */
-        public int getRegularRowItemIndex() {
-            return (mPosition - mMaxTiledRows) + mColumnCount * mMaxTiledRows;
-        }
-
-        public PhoneFavoritesTileAdapter getTileAdapter() {
-            return PhoneFavoritesTileAdapter.this;
-        }
-
-        public int getPosition() {
-            return mPosition;
-        }
-
-        /**
-         * Find the view under the pointer.
-         */
-        public View getViewAtPosition(int x, int y) {
-            // find the view under the pointer, accounting for GONE views
-            final int count = getChildCount();
-            View view;
-            for (int childIdx = 0; childIdx < count; childIdx++) {
-                view = getChildAt(childIdx);
-                if (x >= view.getLeft() && x <= view.getRight()) {
-                    return view;
-                }
-            }
-            return null;
-        }
-
-        public int getItemViewType() {
-            return mItemViewType;
-        }
-    }
-
-    /**
-     * Used when a contact is swiped away. This will both unstar and set pinned position of the
-     * contact to PinnedPosition.DEMOTED so that it doesn't show up anymore in the favorites list.
+     * Used when a contact is removed from speeddial. This will both unstar and set pinned position
+     * of the contact to PinnedPosition.DEMOTED so that it doesn't show up anymore in the favorites
+     * list.
      */
     private void unstarAndUnpinContact(Uri contactUri) {
         final ContentValues values = new ContentValues(2);
@@ -1001,18 +603,25 @@
     }
 
     protected static class ViewTypes {
-        public static final int TOP = 0;
+        public static final int TILE = 0;
         public static final int COUNT = 1;
     }
 
     @Override
-    public void onDragStarted(int itemIndex, int x, int y, PhoneFavoriteTileView view) {
+    public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view) {
         setInDragging(true);
+        final int itemIndex = mContactEntries.indexOf(view.getContactEntry());
         popContactEntry(itemIndex);
     }
 
     @Override
-    public void onDragHovered(int itemIndex, int x, int y) {
+    public void onDragHovered(int x, int y, PhoneFavoriteSquareTileView view) {
+        if (view == null) {
+            // The user is hovering over a view that is not a contact tile, no need to do
+            // anything here.
+            return;
+        }
+        final int itemIndex = mContactEntries.indexOf(view.getContactEntry());
         if (mInDragging &&
                 mDragEnteredEntryIndex != itemIndex &&
                 isIndexInBound(itemIndex) &&
diff --git a/tests/src/com/android/dialer/list/PhoneFavoritesTileAdapterTest.java b/tests/src/com/android/dialer/list/PhoneFavoritesTileAdapterTest.java
index 7a2076d..c2069bd 100644
--- a/tests/src/com/android/dialer/list/PhoneFavoritesTileAdapterTest.java
+++ b/tests/src/com/android/dialer/list/PhoneFavoritesTileAdapterTest.java
@@ -53,75 +53,6 @@
 
     }
 
-    public void testGetRowIndex_NoRowLimit() {
-        mAdapter = getAdapterForTest(2, PhoneFavoritesTileAdapter.NO_ROW_LIMIT);
-        assertEquals(0, mAdapter.getRowCount(0));
-        assertEquals(1, mAdapter.getRowCount(1));
-        assertEquals(1, mAdapter.getRowCount(2));
-        assertEquals(2, mAdapter.getRowCount(4));
-        assertEquals(4, mAdapter.getRowCount(7));
-        assertEquals(100, mAdapter.getRowCount(199));
-
-        mAdapter = getAdapterForTest(5, PhoneFavoritesTileAdapter.NO_ROW_LIMIT);
-        assertEquals(0, mAdapter.getRowCount(0));
-        assertEquals(1, mAdapter.getRowCount(1));
-        assertEquals(1, mAdapter.getRowCount(3));
-        assertEquals(1, mAdapter.getRowCount(5));
-        assertEquals(2, mAdapter.getRowCount(7));
-        assertEquals(2, mAdapter.getRowCount(10));
-        assertEquals(40, mAdapter.getRowCount(199));
-    }
-
-    public void testGetItemId_NoRowLimit() {
-        mAdapter = getAdapterForTest(2, PhoneFavoritesTileAdapter.NO_ROW_LIMIT);
-        assertEquals(0, mAdapter.getItemId(0));
-        assertEquals(1, mAdapter.getItemId(1));
-        assertEquals(5, mAdapter.getItemId(5));
-        assertEquals(10, mAdapter.getItemId(10));
-    }
-
-    public void testGetAdjustedItemId_NoRowLimit() {
-        mAdapter = getAdapterForTest(2, PhoneFavoritesTileAdapter.NO_ROW_LIMIT);
-        assertEquals(0, mAdapter.getAdjustedItemId(0));
-        assertEquals(1, mAdapter.getAdjustedItemId(1));
-        assertEquals(5, mAdapter.getAdjustedItemId(5));
-        assertEquals(10, mAdapter.getAdjustedItemId(10));
-    }
-
-    public void testGetItem_NoRowLimit() {
-        mAdapter = getAdapterForTest(2, PhoneFavoritesTileAdapter.NO_ROW_LIMIT);
-        mAdapter.setContactCursor(getCursorForTest(5, 5));
-
-        final ArrayList<ContactEntry> row1 = new ArrayList<ContactEntry> ();
-        row1.add(getTestContactEntry(0, true));
-        row1.add(getTestContactEntry(1, true));
-        assertContactEntryRowsEqual(row1, mAdapter.getItem(0));
-
-        final ArrayList<ContactEntry> row3 = new ArrayList<ContactEntry> ();
-        row3.add(getTestContactEntry(4, true));
-        row3.add(getTestContactEntry(5, false));
-        assertContactEntryRowsEqual(row3, mAdapter.getItem(2));
-
-        final ArrayList<ContactEntry> row5 = new ArrayList<ContactEntry> ();
-        row5.add(getTestContactEntry(8, false));
-        row5.add(getTestContactEntry(9, false));
-        assertContactEntryRowsEqual(row5, mAdapter.getItem(4));
-    }
-
-    /**
-     * Ensures that PhoneFavoritesTileAdapter returns true for hasStableIds. This is needed for
-     * animation purposes.
-     */
-    public void testHasStableIds() {
-        mAdapter = new PhoneFavoritesTileAdapter(getContext(), null, null, 2, 2);
-        assertTrue(mAdapter.hasStableIds());
-    }
-
-    private PhoneFavoritesTileAdapter getAdapterForTest(int numCols, int numRows) {
-        return new PhoneFavoritesTileAdapter(getContext(), null,
-                sOnDataSetChangedForAnimationListener, numCols, numRows);
-    }
-
     /**
      * Returns a cursor containing starred and frequent contacts for test purposes.
      *