Merge "Use PhoneFavoritesTileAdapter directly in GridView"
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.
      *