Merge "Fix missing name attribute for no favorites string." into klp-dev
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 7b6310d..d55d185 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -132,7 +132,7 @@
     <string name="meid" msgid="6210568493746275750">"MEID"</string>
     <string name="simContacts_emptyLoading" msgid="6700035985448642408">"טוען מכרטיס SIM…"</string>
     <string name="simContacts_title" msgid="27341688347689769">"אנשי קשר בכרטיס SIM"</string>
-    <string name="add_contact_not_available" msgid="1419207765446461366">"הפעל מחדש את יישום אנשי הקשר כדי להשתמש בתכונה זו."</string>
+    <string name="add_contact_not_available" msgid="1419207765446461366">"הפעל מחדש את אפליקציית אנשי הקשר כדי להשתמש בתכונה זו."</string>
     <string name="dialer_hint_find_contact" msgid="8798845521253672403">"הקלד שם או מספר טלפון"</string>
     <string name="call_log_all_title" msgid="3566738938889333307">"הכול"</string>
     <string name="call_log_missed_title" msgid="4541142293870638971">"שיחה שלא נענתה"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 37daeb3..07b7bc9 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -40,10 +40,10 @@
     <string name="notification_action_voicemail_play" msgid="6113133136977996863">"Пусти"</string>
     <string name="notification_voicemail_callers_list" msgid="1153954809339404149">"<xliff:g id="NEWER_CALLERS">%1$s</xliff:g>, <xliff:g id="OLDER_CALLER">%2$s</xliff:g>"</string>
     <string name="notification_new_voicemail_ticker" msgid="895342132049452081">"Нова говорна порука од <xliff:g id="CALLER">%1$s</xliff:g>"</string>
-    <string name="voicemail_playback_error" msgid="1811242131549854624">"Није било могуће пустити говорну пошту."</string>
+    <string name="voicemail_playback_error" msgid="1811242131549854624">"Није могуће пустити говорну пошту."</string>
     <string name="voicemail_buffering" msgid="738287747618697097">"Баферовање..."</string>
     <string name="voicemail_fetching_content" msgid="877911315738258780">"Преузимање говорне поште..."</string>
-    <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Није било могуће преузети говорну пошту."</string>
+    <string name="voicemail_fetching_timout" msgid="6691792377574905201">"Није могуће преузети говорну пошту."</string>
     <string name="call_log_voicemail_header" msgid="3945407886667089173">"Само позиви са говорном поштом"</string>
     <string name="call_log_incoming_header" msgid="2787722299753674684">"Само долазни позиви"</string>
     <string name="call_log_outgoing_header" msgid="761009180766735769">"Само одлазни позиви"</string>
@@ -95,7 +95,7 @@
     <string name="menu_newContact" msgid="1209922412763274638">"Нови контакт"</string>
     <string name="menu_allContacts" msgid="6948308384034051670">"Сви контакти"</string>
     <string name="callDetailTitle" msgid="5340227785196217938">"Детаљи позива"</string>
-    <string name="toast_call_detail_error" msgid="7200975244804730096">"Није било могуће прочитати детаље о захтеваном позиву."</string>
+    <string name="toast_call_detail_error" msgid="7200975244804730096">"Није могуће прочитати детаље о захтеваном позиву."</string>
     <string name="dialer_useDtmfDialpad" msgid="1707548397435075040">"Употребите бројчаник за тонско бирање"</string>
     <string name="dialer_returnToInCallScreen" msgid="3719386377550913067">"Врати се на позив који је у току"</string>
     <string name="dialer_addAnotherCall" msgid="4205688819890074468">"Додај позив"</string>
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 8b7e27d..37dbdf3 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -336,8 +336,7 @@
      * up the contact information (if it has not been already started). Otherwise, it will be
      * started with a delay. See {@link #START_PROCESSING_REQUESTS_DELAY_MILLIS}.
      */
-    @VisibleForTesting
-    void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo,
+    protected void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo,
             boolean immediate) {
         ContactInfoRequest request = new ContactInfoRequest(number, countryIso, callLogInfo);
         synchronized (mRequests) {
@@ -516,7 +515,7 @@
             views.primaryActionView.setTag(
                     IntentProvider.getCallDetailIntentProvider(
                             getCursor(), c.getPosition(), c.getLong(CallLogQuery.ID), count));
-        } else {
+        } else if (PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation)) {
             // Sets the primary action to call the number.
             views.primaryActionView.setTag(IntentProvider.getReturnCallIntentProvider(number));
         }
diff --git a/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java b/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java
index e911710..4f3a4da 100644
--- a/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java
+++ b/src/com/android/dialer/list/DialerPhoneNumberListAdapter.java
@@ -3,7 +3,6 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -29,9 +28,8 @@
     public final static int SHORTCUT_INVALID = -1;
     public final static int SHORTCUT_DIRECT_CALL = 0;
     public final static int SHORTCUT_ADD_NUMBER_TO_CONTACTS = 1;
-    public final static int SHORTCUT_ADD_NEW_NAMED_CONTACT = 2;
 
-    public final static int SHORTCUT_COUNT = 3;
+    public final static int SHORTCUT_COUNT = 2;
 
     private final boolean[] mShortcutEnabled = new boolean[SHORTCUT_COUNT];
 
@@ -147,10 +145,6 @@
                 text = resources.getString(R.string.search_shortcut_add_to_contacts);
                 drawableId = R.drawable.ic_add_person_dk;
                 break;
-            case SHORTCUT_ADD_NEW_NAMED_CONTACT:
-                text = resources.getString(R.string.search_shortcut_add_to_contacts);
-                drawableId = R.drawable.ic_add_person_dk;
-                break;
             default:
                 throw new IllegalArgumentException("Invalid shortcut type");
         }
@@ -169,20 +163,8 @@
 
     @Override
     public void setQueryString(String queryString) {
-        boolean containsNonDialableCharacters = false;
-        for (int i = 0; i < queryString.length(); i++) {
-            if (!PhoneNumberUtils.isDialable(queryString.charAt(i))) {
-                containsNonDialableCharacters = true;
-                break;
-            }
-        }
-
-        if (containsNonDialableCharacters) {
-            mFormattedQueryString = null;
-        } else {
-            mFormattedQueryString = PhoneNumberUtils.formatNumber(queryString, mCountryIso);
-        }
-
+        mFormattedQueryString = PhoneNumberUtils.formatNumber(
+                PhoneNumberUtils.convertAndStrip(queryString), mCountryIso);
         super.setQueryString(queryString);
     }
 }
diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java
index 84bd4b4..d731786 100644
--- a/src/com/android/dialer/list/PhoneFavoriteFragment.java
+++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java
@@ -15,6 +15,9 @@
  */
 package com.android.dialer.list;
 
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.app.Activity;
 import android.app.Fragment;
 import android.app.LoaderManager;
@@ -404,19 +407,42 @@
         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)) {
-                child.setAlpha(0.0f);
-                child.animate().alpha(1.0f)
-                        .setDuration(mAnimationDuration)
-                        .start();
+                animators.add(ObjectAnimator.ofFloat(
+                        child, "alpha", 0.0f, 1.0f));
                 break;
+            } else {
+                Integer startLeft = mItemIdLeftMap.get(itemId);
+                int left = child.getLeft();
+                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));
+                    }
+                } else {
+                    // In case the last square row is pushed up from the non-square section.
+                    animators.add(ObjectAnimator.ofFloat(
+                            child, "translationX", left, 0.0f));
+                }
             }
         }
+        if (animators.size() > 0) {
+            animSet.setDuration(mAnimationDuration).playTogether(animators);
+            animSet.start();
+        }
     }
 
     /*
@@ -437,6 +463,8 @@
             public boolean onPreDraw() {
                 observer.removeOnPreDrawListener(this);
                 final int firstVisiblePosition = mListView.getFirstVisiblePosition();
+                final AnimatorSet animSet = new AnimatorSet();
+                final ArrayList<Animator> animators = new ArrayList<Animator>();
                 for (int i = 0; i < mListView.getChildCount(); i++) {
                     final View child = mListView.getChildAt(i);
                     int position = firstVisiblePosition + i;
@@ -450,17 +478,12 @@
                     final long itemId = mAdapter.getItemId(position);
 
                     if (containsId(idsInPlace, itemId)) {
-                        child.setAlpha(0.0f);
-                        child.animate().alpha(1.0f)
-                                .setDuration(mAnimationDuration)
-                                .start();
+                        animators.add(ObjectAnimator.ofFloat(
+                                child, "alpha", 0.0f, 1.0f));
+                        break;
                     } else {
                         Integer startTop = mItemIdTopMap.get(itemId);
                         final int top = child.getTop();
-                        if (DEBUG) {
-                            Log.d(TAG, "Found itemId: " + itemId + " for listview child " + i +
-                                    " Top: " + top);
-                        }
                         int delta = 0;
                         if (startTop != null) {
                             if (startTop != top) {
@@ -473,14 +496,30 @@
                             int childHeight = child.getHeight() + mListView.getDividerHeight();
                             startTop = top + (i > 0 ? childHeight : -childHeight);
                             delta = startTop - top;
+                        } else {
+                            // In case the first non-square row is pushed down
+                            // from the square section.
+                            animators.add(ObjectAnimator.ofFloat(
+                                    child, "alpha", 0.0f, 1.0f));
+                        }
+                        if (DEBUG) {
+                            Log.d(TAG, "Found itemId: " + itemId + " for listview child " + i +
+                                    " Top: " + top +
+                                    " Delta: " + delta);
                         }
 
                         if (delta != 0) {
-                            child.setTranslationY(delta);
-                            child.animate().setDuration(mAnimationDuration).translationY(0);
+                            animators.add(ObjectAnimator.ofFloat(
+                                    child, "translationY", delta, 0.0f));
                         }
                     }
                 }
+
+                if (animators.size() > 0) {
+                    animSet.setDuration(mAnimationDuration).playTogether(animators);
+                    animSet.start();
+                }
+
                 mItemIdTopMap.clear();
                 mItemIdLeftMap.clear();
                 return true;
diff --git a/src/com/android/dialer/list/PhoneFavoriteListView.java b/src/com/android/dialer/list/PhoneFavoriteListView.java
index 04bbe6b..4e0b8ff 100644
--- a/src/com/android/dialer/list/PhoneFavoriteListView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteListView.java
@@ -105,7 +105,8 @@
 
     private final AnimatorListenerAdapter mDragShadowOverAnimatorListener =
             new AnimatorListenerAdapter() {
-        private void recycleDragShadow() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
             if (mDragShadowBitmap != null) {
                 mDragShadowBitmap.recycle();
                 mDragShadowBitmap = null;
@@ -113,16 +114,6 @@
             mDragShadowOverlay.setVisibility(GONE);
             mDragShadowOverlay.setImageBitmap(null);
         }
-
-        @Override
-        public void onAnimationCancel(Animator animation) {
-            recycleDragShadow();
-        }
-
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            recycleDragShadow();
-        }
     };
 
     public PhoneFavoriteListView(Context context) {
diff --git a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
index 2e18118..2b232e8 100644
--- a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
+++ b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
@@ -407,7 +407,7 @@
         return mColumnCount * mMaxTiledRows;
     }
 
-    protected int getRowIndex(int entryIndex) {
+    public int getRowIndex(int entryIndex) {
         if (entryIndex < mMaxTiledRows * mColumnCount) {
             return entryIndex / mColumnCount;
         } else {
@@ -593,11 +593,14 @@
      */
     private void markDropArea(int itemIndex) {
         if (isIndexInBound(mDragEnteredEntryIndex) && isIndexInBound(itemIndex)) {
+            mDataSetChangedListener.cacheOffsetsForDatasetChange();
             // Remove the old placeholder item and place the new placeholder item.
+            final int oldIndex = mDragEnteredEntryIndex;
             mContactEntries.remove(mDragEnteredEntryIndex);
             mDragEnteredEntryIndex = itemIndex;
             mContactEntries.add(mDragEnteredEntryIndex, ContactEntry.BLANK_ENTRY);
             ContactEntry.BLANK_ENTRY.id = mDraggedEntry.id;
+            mDataSetChangedListener.onDataSetChangedForAnimation();
             notifyDataSetChanged();
         }
     }
diff --git a/src/com/android/dialer/list/RegularSearchListAdapter.java b/src/com/android/dialer/list/RegularSearchListAdapter.java
index 5877912..05af3c7 100644
--- a/src/com/android/dialer/list/RegularSearchListAdapter.java
+++ b/src/com/android/dialer/list/RegularSearchListAdapter.java
@@ -67,7 +67,6 @@
         // a dialable number, then clicking add to contact should add it as a number.
         // Otherwise, it should add it to a new contact as a name.
         setShortcutEnabled(SHORTCUT_ADD_NUMBER_TO_CONTACTS, showNumberShortcuts);
-        setShortcutEnabled(SHORTCUT_ADD_NEW_NAMED_CONTACT, !showNumberShortcuts);
         super.setQueryString(queryString);
     }
 }
diff --git a/src/com/android/dialer/list/SearchFragment.java b/src/com/android/dialer/list/SearchFragment.java
index 0302d97..006729b 100644
--- a/src/com/android/dialer/list/SearchFragment.java
+++ b/src/com/android/dialer/list/SearchFragment.java
@@ -106,10 +106,6 @@
             final String number = adapter.getFormattedQueryString();
             final Intent intent = DialtactsActivity.getAddNumberToContactIntent(number);
             startActivityWithErrorToast(intent);
-        } else if (shortcutType == DialerPhoneNumberListAdapter.SHORTCUT_ADD_NEW_NAMED_CONTACT) {
-            final String name = adapter.getQueryString();
-            final Intent intent = DialtactsActivity.getInsertContactWithNameIntent(name);
-            startActivityWithErrorToast(intent);
         }
     }
 
diff --git a/src/com/android/dialer/list/SmartDialSearchFragment.java b/src/com/android/dialer/list/SmartDialSearchFragment.java
index 4248c85..0efe918 100644
--- a/src/com/android/dialer/list/SmartDialSearchFragment.java
+++ b/src/com/android/dialer/list/SmartDialSearchFragment.java
@@ -41,8 +41,6 @@
         // Disable the direct call shortcut for the smart dial fragment, since the call button
         // will already be showing anyway.
         adapter.setShortcutEnabled(SmartDialNumberListAdapter.SHORTCUT_DIRECT_CALL, false);
-        adapter.setShortcutEnabled(SmartDialNumberListAdapter.SHORTCUT_ADD_NEW_NAMED_CONTACT,
-                false);
         return adapter;
     }
 
diff --git a/src/com/android/dialer/list/SwipeHelper.java b/src/com/android/dialer/list/SwipeHelper.java
index ce46ec3..03300df4 100644
--- a/src/com/android/dialer/list/SwipeHelper.java
+++ b/src/com/android/dialer/list/SwipeHelper.java
@@ -337,24 +337,12 @@
                 invalidateGlobalRegion(animView);
             }
         });
-        anim.addListener(new Animator.AnimatorListener() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-            }
-
+        anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
                 animView.setAlpha(mStartAlpha);
                 mCallback.onDragCancelled(mCurrView);
             }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-            }
-
-            @Override
-            public void onAnimationRepeat(Animator animation) {
-            }
         });
         anim.start();
     }
diff --git a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
index ce862de..55e4224 100644
--- a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
@@ -216,7 +216,7 @@
         }
 
         @Override
-        void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo,
+        protected void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo,
                 boolean immediate) {
             requests.add(new Request(number, countryIso, callLogInfo, immediate));
         }