Merge "Show presence in QuickContacts and remove "CHAT USING" for consistency"
diff --git a/res/layout/quickcontact_photo_container.xml b/res/layout/quickcontact_photo_container.xml
index e970934..3b46ef9 100644
--- a/res/layout/quickcontact_photo_container.xml
+++ b/res/layout/quickcontact_photo_container.xml
@@ -26,11 +26,6 @@
             android:layout_height="match_parent"
             android:scaleType="centerCrop" />
         <View
-            android:layout_width="match_parent"
-            android:layout_height="1dip"
-            android:layout_alignParentTop="true"
-            android:background="#4CFFFFFF" />
-        <View
             android:id="@+id/photo_text_bar"
             android:layout_width="0dip"
             android:layout_height="42dip"
diff --git a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
index 4b297d9..98abfbc 100644
--- a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
+++ b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
@@ -319,15 +319,23 @@
         // Apply a limit of 1 result to the query because we only need to
         // determine whether or not at least one other contact has the same
         // name. We don't need to find ALL other contacts with the same name.
-        Builder builder = Contacts.CONTENT_URI.buildUpon();
+        final Builder builder = Contacts.CONTENT_URI.buildUpon();
         builder.appendQueryParameter("limit", String.valueOf(1));
-        Uri uri = builder.build();
+        final Uri uri = builder.build();
 
+        final String displayNameSelection;
+        final String[] selectionArgs;
+        if (TextUtils.isEmpty(contactDisplayName)) {
+            displayNameSelection = Contacts.DISPLAY_NAME_PRIMARY + " IS NULL";
+            selectionArgs = new String[] { String.valueOf(mContactId) };
+        } else {
+            displayNameSelection = Contacts.DISPLAY_NAME_PRIMARY + " = ?";
+            selectionArgs = new String[] { contactDisplayName, String.valueOf(mContactId) };
+        }
         mQueryHandler.startQuery(TOKEN_DISAMBIGUATION_QUERY, null, uri,
                 new String[] { Contacts._ID } /* unused projection but a valid one was needed */,
-                Contacts.DISPLAY_NAME_PRIMARY + " = ? and " + Contacts.PHOTO_ID + " is null and "
-                + Contacts._ID + " <> ?",
-                new String[] { contactDisplayName, String.valueOf(mContactId) }, null);
+                displayNameSelection + " AND " + Contacts.PHOTO_ID + " IS NULL AND "
+                + Contacts._ID + " <> ?", selectionArgs, null);
     }
 
     /**
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index 2a1ec5e..c9e713b 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -286,7 +286,17 @@
         }
 
         // Field changes are saved directly
+        saveValue(column, value);
+
+        // Notify listener if applicable
+        notifyEditorListener();
+    }
+
+    protected void saveValue(String column, String value) {
         mEntry.put(column, value);
+    }
+
+    protected void notifyEditorListener() {
         if (mListener != null) {
             mListener.onRequest(EditorListener.FIELD_CHANGED);
         }
diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java
index 6911628..af1b3cf 100644
--- a/src/com/android/contacts/editor/StructuredNameEditorView.java
+++ b/src/com/android/contacts/editor/StructuredNameEditorView.java
@@ -77,11 +77,12 @@
         if (!isFieldChanged(column, value)) {
             return;
         }
-        super.onFieldChanged(column, value);
 
+        // First save the new value for the column.
+        saveValue(column, value);
         mChanged = true;
 
-        // Make sure the display name and the structured name are synced
+        // Next make sure the display name and the structured name are synced
         if (hasShortAndLongForms()) {
             if (areOptionalFieldsVisible()) {
                 rebuildFullName(getValues());
@@ -89,6 +90,10 @@
                 rebuildStructuredName(getValues());
             }
         }
+
+        // Then notify the listener, which will rely on the display and structured names to be
+        // synced (in order to provide aggregate suggestions).
+        notifyEditorListener();
     }
 
     @Override
diff --git a/src/com/android/contacts/list/ContactEntryListAdapter.java b/src/com/android/contacts/list/ContactEntryListAdapter.java
index d95a1bc..ac4d399 100644
--- a/src/com/android/contacts/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/list/ContactEntryListAdapter.java
@@ -18,7 +18,6 @@
 import com.android.contacts.ContactPhotoManager;
 import com.android.contacts.R;
 import com.android.contacts.widget.IndexerListAdapter;
-import com.android.contacts.widget.TextWithHighlightingFactory;
 
 import android.content.Context;
 import android.content.CursorLoader;
@@ -619,8 +618,16 @@
 
     // TODO: move sharable logic (bindXX() methods) to here with extra arguments
 
+    /**
+     * Loads the photo for the quick contact view and assigns the contact uri.
+     * @param photoIdColumn Index of the photo id column
+     * @param photoUriColumn Index of the photo uri column. Optional: Can be -1
+     * @param contactIdColumn Index of the contact id column
+     * @param lookUpKeyColumn Index of the lookup key column
+     */
     protected void bindQuickContact(final ContactListItemView view, int partitionIndex,
-            Cursor cursor, int photoIdColumn, int contactIdColumn, int lookUpKeyColumn) {
+            Cursor cursor, int photoIdColumn, int photoUriColumn, int contactIdColumn,
+            int lookUpKeyColumn) {
         long photoId = 0;
         if (!cursor.isNull(photoIdColumn)) {
             photoId = cursor.getLong(photoIdColumn);
@@ -629,7 +636,15 @@
         QuickContactBadge quickContact = view.getQuickContact();
         quickContact.assignContactUri(
                 getContactUri(partitionIndex, cursor, contactIdColumn, lookUpKeyColumn));
-        getPhotoLoader().loadPhoto(quickContact, photoId, false, mDarkTheme);
+
+        if (photoId != 0 || photoUriColumn == -1) {
+            getPhotoLoader().loadPhoto(quickContact, photoId, false, mDarkTheme);
+        } else {
+            final String photoUriString = cursor.getString(photoUriColumn);
+            final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString);
+            getPhotoLoader().loadPhoto(quickContact, photoUri, false, mDarkTheme);
+        }
+
     }
 
     protected Uri getContactUri(int partitionIndex, Cursor cursor,
diff --git a/src/com/android/contacts/list/ContactListAdapter.java b/src/com/android/contacts/list/ContactListAdapter.java
index a8caf3b..81fcb84 100644
--- a/src/com/android/contacts/list/ContactListAdapter.java
+++ b/src/com/android/contacts/list/ContactListAdapter.java
@@ -23,7 +23,6 @@
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.ContactCounts;
 import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.Directory;
 import android.provider.ContactsContract.SearchSnippetColumns;
 import android.text.TextUtils;
diff --git a/src/com/android/contacts/list/DefaultContactListAdapter.java b/src/com/android/contacts/list/DefaultContactListAdapter.java
index 348abb9..7a32e25 100644
--- a/src/com/android/contacts/list/DefaultContactListAdapter.java
+++ b/src/com/android/contacts/list/DefaultContactListAdapter.java
@@ -26,9 +26,7 @@
 import android.net.Uri.Builder;
 import android.preference.PreferenceManager;
 import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
 import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.Directory;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.SearchSnippetColumns;
@@ -209,7 +207,8 @@
 
         if (isQuickContactEnabled()) {
             bindQuickContact(view, partition, cursor, ContactQuery.CONTACT_PHOTO_ID,
-                    ContactQuery.CONTACT_ID, ContactQuery.CONTACT_LOOKUP_KEY);
+                    ContactQuery.CONTACT_PHOTO_URI, ContactQuery.CONTACT_ID,
+                    ContactQuery.CONTACT_LOOKUP_KEY);
         } else {
             bindPhoto(view, partition, cursor);
         }
diff --git a/src/com/android/contacts/list/PhoneNumberListAdapter.java b/src/com/android/contacts/list/PhoneNumberListAdapter.java
index 79114eb..960614c 100644
--- a/src/com/android/contacts/list/PhoneNumberListAdapter.java
+++ b/src/com/android/contacts/list/PhoneNumberListAdapter.java
@@ -15,8 +15,6 @@
  */
 package com.android.contacts.list;
 
-import com.android.contacts.R;
-
 import android.content.ContentUris;
 import android.content.Context;
 import android.content.CursorLoader;
@@ -262,7 +260,9 @@
         if (isFirstEntry) {
             bindName(view, cursor);
             if (isQuickContactEnabled()) {
-                bindQuickContact(view, partition, cursor, PhoneQuery.PHONE_PHOTO_ID,
+                // No need for photo uri here, because we can not have directory results. If we
+                // ever do, we need to add photo uri to the query
+                bindQuickContact(view, partition, cursor, PhoneQuery.PHONE_PHOTO_ID, -1,
                         PhoneQuery.PHONE_CONTACT_ID, PhoneQuery.PHONE_LOOKUP_KEY);
             } else {
                 bindPhoto(view, cursor);