Merge "Import translations. DO NOT MERGE"
diff --git a/chips/src/com/android/ex/chips/BaseRecipientAdapter.java b/chips/src/com/android/ex/chips/BaseRecipientAdapter.java
index c24188a..fb6378b 100644
--- a/chips/src/com/android/ex/chips/BaseRecipientAdapter.java
+++ b/chips/src/com/android/ex/chips/BaseRecipientAdapter.java
@@ -148,6 +148,7 @@
         public final long contactId;
         public final long dataId;
         public final String thumbnailUriString;
+        public final int displayNameSource;
 
         public TemporaryEntry(Cursor cursor) {
             this.displayName = cursor.getString(Queries.Query.NAME);
@@ -157,6 +158,7 @@
             this.contactId = cursor.getLong(Queries.Query.CONTACT_ID);
             this.dataId = cursor.getLong(Queries.Query.DATA_ID);
             this.thumbnailUriString = cursor.getString(Queries.Query.PHOTO_THUMBNAIL_URI);
+            this.displayNameSource = cursor.getInt(Queries.Query.DISPLAY_NAME_SOURCE);
         }
     }
 
@@ -624,6 +626,7 @@
         if (!isAggregatedEntry) {
             nonAggregatedEntries.add(RecipientEntry.constructTopLevelEntry(
                     entry.displayName,
+                    entry.displayNameSource,
                     entry.destination, entry.destinationType, entry.destinationLabel,
                     entry.contactId, entry.dataId, entry.thumbnailUriString));
         } else if (entryMap.containsKey(entry.contactId)) {
@@ -631,12 +634,14 @@
             final List<RecipientEntry> entryList = entryMap.get(entry.contactId);
             entryList.add(RecipientEntry.constructSecondLevelEntry(
                     entry.displayName,
+                    entry.displayNameSource,
                     entry.destination, entry.destinationType, entry.destinationLabel,
                     entry.contactId, entry.dataId, entry.thumbnailUriString));
         } else {
             final List<RecipientEntry> entryList = new ArrayList<RecipientEntry>();
             entryList.add(RecipientEntry.constructTopLevelEntry(
                     entry.displayName,
+                    entry.displayNameSource,
                     entry.destination, entry.destinationType, entry.destinationLabel,
                     entry.contactId, entry.dataId, entry.thumbnailUriString));
             entryMap.put(entry.contactId, entryList);
@@ -840,7 +845,12 @@
                 if (TextUtils.isEmpty(displayName)
                         || TextUtils.equals(displayName, destination)) {
                     displayName = destination;
-                    destination = null;
+
+                    // We only show the destination for secondary entries, so clear it only for
+                    // the first level.
+                    if (entry.isFirstLevel()) {
+                        destination = null;
+                    }
                 }
 
                 final View itemView = convertView != null ? convertView
diff --git a/chips/src/com/android/ex/chips/Queries.java b/chips/src/com/android/ex/chips/Queries.java
index cfea9c1..f44ce73 100644
--- a/chips/src/com/android/ex/chips/Queries.java
+++ b/chips/src/com/android/ex/chips/Queries.java
@@ -34,7 +34,8 @@
             Phone.LABEL,                 // 3
             Phone.CONTACT_ID,            // 4
             Phone._ID,                   // 5
-            Contacts.PHOTO_THUMBNAIL_URI // 6
+            Contacts.PHOTO_THUMBNAIL_URI,// 6
+            Contacts.DISPLAY_NAME_SOURCE // 7
         }, Phone.CONTENT_FILTER_URI, Phone.CONTENT_URI) {
 
             @Override
@@ -51,8 +52,8 @@
             Email.LABEL,                 // 3
             Email.CONTACT_ID,            // 4
             Email._ID,                   // 5
-            Contacts.PHOTO_THUMBNAIL_URI // 6
-
+            Contacts.PHOTO_THUMBNAIL_URI,// 6
+            Contacts.DISPLAY_NAME_SOURCE // 7
         }, Email.CONTENT_FILTER_URI, Email.CONTENT_URI) {
 
             @Override
@@ -74,6 +75,7 @@
         public static final int CONTACT_ID = 4;
         public static final int DATA_ID = 5;
         public static final int PHOTO_THUMBNAIL_URI = 6;
+        public static final int DISPLAY_NAME_SOURCE = 7;
 
         public Query (String[] projection, Uri contentFilter, Uri content) {
             mProjection = projection;
diff --git a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java b/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java
index 80abdcd..9bc4645 100644
--- a/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java
+++ b/chips/src/com/android/ex/chips/RecipientAlternatesAdapter.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.database.Cursor;
+import android.provider.ContactsContract.DisplayNameSources;
 import android.text.util.Rfc822Token;
 import android.text.util.Rfc822Tokenizer;
 import android.util.Log;
@@ -104,6 +105,7 @@
                         String address = c.getString(Queries.Query.DESTINATION);
                         recipientEntries.put(address, RecipientEntry.constructTopLevelEntry(
                                 c.getString(Queries.Query.NAME),
+                                c.getInt(Queries.Query.DISPLAY_NAME_SOURCE),
                                 c.getString(Queries.Query.DESTINATION),
                                 c.getInt(Queries.Query.DESTINATION_TYPE),
                                 c.getString(Queries.Query.DESTINATION_LABEL),
@@ -180,6 +182,7 @@
         c.moveToPosition(position);
         return RecipientEntry.constructTopLevelEntry(
                 c.getString(Queries.Query.NAME),
+                c.getInt(Queries.Query.DISPLAY_NAME_SOURCE),
                 c.getString(Queries.Query.DESTINATION),
                 c.getInt(Queries.Query.DESTINATION_TYPE),
                 c.getString(Queries.Query.DESTINATION_LABEL),
diff --git a/chips/src/com/android/ex/chips/RecipientEditTextView.java b/chips/src/com/android/ex/chips/RecipientEditTextView.java
index 46ac2e7..eb8c639 100644
--- a/chips/src/com/android/ex/chips/RecipientEditTextView.java
+++ b/chips/src/com/android/ex/chips/RecipientEditTextView.java
@@ -674,6 +674,7 @@
         if (mInvalidChipBackground == null) {
             mInvalidChipBackground = r.getDrawable(R.drawable.chip_background_invalid);
         }
+        a.recycle();
     }
 
     // Visible for testing.
diff --git a/chips/src/com/android/ex/chips/RecipientEntry.java b/chips/src/com/android/ex/chips/RecipientEntry.java
index f307b25..4f22142 100644
--- a/chips/src/com/android/ex/chips/RecipientEntry.java
+++ b/chips/src/com/android/ex/chips/RecipientEntry.java
@@ -18,6 +18,7 @@
 
 import android.net.Uri;
 import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.DisplayNameSources;
 
 /**
  * Represents one entry inside recipient auto-complete list.
@@ -50,6 +51,7 @@
      */
     private boolean mIsFirstLevel;
     private final String mDisplayName;
+
     /** Destination for this contact entry. Would be an email address or a phone number. */
     private final String mDestination;
     /** Type of the destination like {@link Email#TYPE_HOME} */
@@ -123,6 +125,17 @@
     }
 
     /**
+     * @return the display name for the entry.  If the display name source is larger than
+     * {@link DisplayNameSources#PHONE} we use the contact's display name, but if not,
+     * i.e. the display name came from an email address or a phone number, we don't use it
+     * to avoid confusion and just use the destination instead.
+     */
+    private static String pickDisplayName(int displayNameSource, String displayName,
+            String destination) {
+        return (displayNameSource > DisplayNameSources.PHONE) ? displayName : destination;
+    }
+
+    /**
      * Construct a RecipientEntry from just an address that has been entered
      * with both an associated display name. This address has not been resolved
      * to a contact and therefore does not have a contact id or photo.
@@ -134,30 +147,31 @@
     }
 
     public static RecipientEntry constructTopLevelEntry(
-            String displayName, String destination, int destinationType, String destinationLabel,
-            long contactId, long dataId, Uri photoThumbnailUri) {
-        return new RecipientEntry(ENTRY_TYPE_PERSON, displayName,
+            String displayName, int displayNameSource, String destination, int destinationType,
+            String destinationLabel, long contactId, long dataId, Uri photoThumbnailUri) {
+        return new RecipientEntry(ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource, displayName,
+                    destination),
                 destination, destinationType, destinationLabel,
                 contactId, dataId,
                 photoThumbnailUri, true);
     }
 
     public static RecipientEntry constructTopLevelEntry(
-            String displayName, String destination, int destinationType, String destinationLabel,
-            long contactId, long dataId,
+            String displayName, int displayNameSource, String destination, int destinationType,
+            String destinationLabel, long contactId, long dataId,
             String thumbnailUriAsString) {
         return new RecipientEntry(
-                ENTRY_TYPE_PERSON, displayName,
+                ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource, displayName, destination),
                 destination, destinationType, destinationLabel,
                 contactId, dataId,
                 (thumbnailUriAsString != null ? Uri.parse(thumbnailUriAsString) : null), true);
     }
 
     public static RecipientEntry constructSecondLevelEntry(
-            String displayName, String destination, int destinationType, String destinationLabel,
-            long contactId, long dataId, String thumbnailUriAsString) {
+            String displayName, int displayNameSource, String destination, int destinationType,
+            String destinationLabel, long contactId, long dataId, String thumbnailUriAsString) {
         return new RecipientEntry(
-                ENTRY_TYPE_PERSON, displayName,
+                ENTRY_TYPE_PERSON, pickDisplayName(displayNameSource, displayName, destination),
                 destination, destinationType, destinationLabel,
                 contactId, dataId,
                 (thumbnailUriAsString != null ? Uri.parse(thumbnailUriAsString) : null), false);
diff --git a/chips/tests/Android.mk b/chips/tests/Android.mk
index 42bb6a3..313af7d 100644
--- a/chips/tests/Android.mk
+++ b/chips/tests/Android.mk
@@ -23,6 +23,8 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner
 LOCAL_STATIC_JAVA_LIBRARIES += android-common-chips
 LOCAL_RESOURCE_DIR := frameworks/ex/chips/res/
+LOCAL_AAPT_FLAGS := --auto-add-overlay
+LOCAL_AAPT_FLAGS += --extra-packages com.android.ex.chips
 
 include $(BUILD_PACKAGE)
 
diff --git a/chips/tests/src/com/android/ex/chips/ChipsTest.java b/chips/tests/src/com/android/ex/chips/ChipsTest.java
index 4d662f3..6639bcb 100644
--- a/chips/tests/src/com/android/ex/chips/ChipsTest.java
+++ b/chips/tests/src/com/android/ex/chips/ChipsTest.java
@@ -119,9 +119,16 @@
         }
     }
 
+    private class TestBaseRecipientAdapter extends BaseRecipientAdapter {
+        public TestBaseRecipientAdapter(Context context) {
+            super(context);
+        }
+    }
+
     private MockRecipientEditTextView createViewForTesting() {
         mEditable = new SpannableStringBuilder();
         MockRecipientEditTextView view = new MockRecipientEditTextView(getContext());
+        view.setAdapter(new TestBaseRecipientAdapter(getContext()));
         return view;
     }