Merge "Modify QuickContact options menu" into ub-contactsdialer-h-dev
diff --git a/res/drawable/ic_group_add.xml b/res/drawable/ic_group_add.xml
deleted file mode 100644
index 6d8776e..0000000
--- a/res/drawable/ic_group_add.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M8,10L5,10L5,7L3,7v3L0,10v2h3v3h2v-3h3v-2zM18,11c1.66,0 2.99,-1.34 2.99,-3S19.66,5 18,5c-0.32,0 -0.63,0.05 -0.91,0.14 0.57,0.81 0.9,1.79 0.9,2.86s-0.34,2.04 -0.9,2.86c0.28,0.09 0.59,0.14 0.91,0.14zM13,11c1.66,0 2.99,-1.34 2.99,-3S14.66,5 13,5c-1.66,0 -3,1.34 -3,3s1.34,3 3,3zM19.62,13.16c0.83,0.73 1.38,1.66 1.38,2.84v2h3v-2c0,-1.54 -2.37,-2.49 -4.38,-2.84zM13,13c-2,0 -6,1 -6,3v2h12v-2c0,-2 -4,-3 -6,-3z"/>
-</vector>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5080e2c..4f4b298 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -169,7 +169,10 @@
     <!-- List separator for the Join Contact list: A-Z -->
     <string name="separatorJoinAggregateAll">All contacts</string>
 
-    <!-- Toast shown after two contacts have been linked by a user action. [CHAR LIMIT=NONE] -->
+    <!-- Toast shown after two contacts have been linked by a user action with a name. [CHAR LIMIT=NONE] -->
+    <string name="contactsJoinedNamedMessage"><xliff:g id="name">%s</xliff:g> linked</string>
+
+    <!-- Toast shown after two contacts have been linked by a user action without a name. [CHAR LIMIT=NONE] -->
     <string name="contactsJoinedMessage">Contacts linked</string>
 
     <!-- Toast shown with names after user selected contacts are deleted by user action. [CHAR LIMIT=30] -->
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index 1dcc838..1b2c22d 100755
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -47,6 +47,7 @@
 import android.provider.ContactsContract.RawContactsEntity;
 import android.support.v4.content.LocalBroadcastManager;
 import android.support.v4.os.ResultReceiver;
+import android.text.TextUtils;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -61,6 +62,8 @@
 import com.android.contacts.common.model.RawContactModifier;
 import com.android.contacts.common.model.SimContact;
 import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.preference.ContactsPreferences;
+import com.android.contacts.common.util.ContactDisplayUtils;
 import com.android.contacts.common.util.PermissionsUtil;
 import com.android.contacts.compat.PinnedPositionsCompat;
 import com.android.contacts.util.ContactPhotoUtils;
@@ -1407,7 +1410,11 @@
                 result.putString(EXTRA_DISPLAY_NAME, name);
                 receiver.send(CONTACTS_LINKED, result);
             } else {
-                showToast(R.string.contactsJoinedMessage);
+                if (TextUtils.isEmpty(name)) {
+                    showToast(R.string.contactsJoinedMessage);
+                } else {
+                    showToast(R.string.contactsJoinedNamedMessage, name);
+                }
             }
         } else {
             if (receiver != null) {
@@ -1427,22 +1434,28 @@
         }
         whereBuilder.deleteCharAt(whereBuilder.length() - 1).append(')');
         final Cursor cursor = getContentResolver().query(Contacts.CONTENT_URI,
-                new String[]{Contacts._ID, Contacts.DISPLAY_NAME},
+                new String[]{Contacts._ID, Contacts.DISPLAY_NAME,
+                        Contacts.DISPLAY_NAME_ALTERNATIVE},
                 whereBuilder.toString(), whereArgs, null);
 
         String name = null;
+        String nameAlt = null;
         long contactId = 0;
         try {
             if (cursor.moveToFirst()) {
                 contactId = cursor.getLong(0);
                 name = cursor.getString(1);
+                nameAlt = cursor.getString(2);
             }
             while(cursor.moveToNext()) {
                 if (cursor.getLong(0) != contactId) {
                     return null;
                 }
             }
-            return name == null ? "" : name;
+
+            final String formattedName = ContactDisplayUtils.getPreferredDisplayName(name, nameAlt,
+                    new ContactsPreferences(getApplicationContext()));
+            return formattedName == null ? "" : formattedName;
         } finally {
             if (cursor != null) {
                 cursor.close();
@@ -1533,6 +1546,11 @@
         final String name = queryNameOfLinkedContacts(new long[] {contactId1, contactId2});
         Intent callbackIntent = intent.getParcelableExtra(EXTRA_CALLBACK_INTENT);
         if (success && name != null) {
+            if (TextUtils.isEmpty(name)) {
+                showToast(R.string.contactsJoinedMessage);
+            } else {
+                showToast(R.string.contactsJoinedNamedMessage, name);
+            }
             Uri uri = RawContacts.getContactLookupUri(resolver,
                     ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactIds[0]));
             callbackIntent.setData(uri);
@@ -1698,6 +1716,22 @@
     }
 
     /**
+     * Shows a toast on the UI thread by formatting messageId using args.
+     * @param messageId id of message string
+     * @param args args to format string
+     */
+    private void showToast(final int messageId, final Object... args) {
+        final String message = getResources().getString(messageId, args);
+        mMainHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                Toast.makeText(ContactSaveService.this, message, Toast.LENGTH_LONG).show();
+            }
+        });
+    }
+
+
+    /**
      * Shows a toast on the UI thread.
      */
     private void showToast(final int message) {
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index b26a52f..bbe9721 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -278,7 +278,7 @@
                 return;
             }
             if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "Received group URI " + mGroupUri);
-            switchToOrUpdateGroupView(intent.getAction());
+            switchView(ContactsView.GROUP_VIEW);
             return;
         }
 
@@ -298,7 +298,7 @@
                 return;
             }
             if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "Received group URI " + mGroupUri);
-            switchToOrUpdateGroupView(intent.getAction());
+            switchView(ContactsView.GROUP_VIEW);
         }
 
         setIntent(intent);
@@ -899,9 +899,11 @@
     }
 
     private void handleFilterChangeForFragment(ContactListFilter filter) {
-        mAllFragment.setFilterAndUpdateTitle(filter);
-        // Scroll to top after filter is changed.
-        mAllFragment.scrollToTop();
+        if (mAllFragment.canSetActionBar()) {
+            mAllFragment.setFilterAndUpdateTitle(filter);
+            // Scroll to top after filter is changed.
+            mAllFragment.scrollToTop();
+        }
     }
 
     private void handleFilterChangeForActivity(ContactListFilter filter) {
diff --git a/src/com/android/contacts/editor/EditorIntents.java b/src/com/android/contacts/editor/EditorIntents.java
index c903b84..2d05eb2 100644
--- a/src/com/android/contacts/editor/EditorIntents.java
+++ b/src/com/android/contacts/editor/EditorIntents.java
@@ -25,6 +25,7 @@
 
 import com.android.contacts.activities.ContactEditorActivity;
 import com.android.contacts.activities.ContactEditorSpringBoardActivity;
+import com.android.contacts.activities.ContactSelectionActivity;
 import com.android.contacts.common.model.RawContactDeltaList;
 import com.android.contacts.common.util.MaterialColorMapUtils.MaterialPalette;
 
@@ -75,9 +76,7 @@
                 context, ContactEditorActivity.class);
         intent.putExtra(
                 ContactEditorFragment.INTENT_EXTRA_NEW_LOCAL_PROFILE, isNewLocalProfile);
-        if (rawContactDeltaList != null || displayName != null || phoneticName != null) {
-            putRawContactDeltaValues(intent, rawContactDeltaList, displayName, phoneticName);
-        }
+        putRawContactDeltaValues(intent, rawContactDeltaList, displayName, phoneticName);
         return intent;
     }
 
@@ -100,6 +99,18 @@
         return intent;
     }
 
+    /**
+     * Returns an Intent to start the {@link ContactSelectionActivity} for a
+     * new or existing contact.
+     */
+    public static Intent createInsertOrEditContactIntent(Context context,
+            RawContactDeltaList rawContactDeltaList, String displayName, String phoneticName) {
+        final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT, Contacts.CONTENT_URI,
+                context, ContactSelectionActivity.class);
+        putRawContactDeltaValues(intent, rawContactDeltaList, displayName, phoneticName);
+        return intent;
+    }
+
     private static void putMaterialPalette(Intent intent, MaterialPalette materialPalette) {
         if (materialPalette != null) {
             intent.putExtra(
diff --git a/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java b/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
index b63eacd..a649f2b 100644
--- a/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
@@ -38,6 +38,7 @@
 import android.database.Cursor;
 import android.os.Bundle;
 import android.provider.ContactsContract.RawContacts;
+import android.text.TextUtils;
 import android.util.Log;
 
 import java.util.HashSet;
@@ -213,8 +214,11 @@
             final String displayName = cursor.getString(COLUMN_INDEX_DISPLAY_NAME);
             final String displayNameAlt = cursor.getString(COLUMN_INDEX_DISPLAY_NAME_ALT);
 
-            names.add(ContactDisplayUtils.getPreferredDisplayName(displayName, displayNameAlt,
-                    contactsPreferences));
+            final String name = ContactDisplayUtils.getPreferredDisplayName(displayName,
+                    displayNameAlt, contactsPreferences);
+            if (!TextUtils.isEmpty(name)) {
+                names.add(name);
+            }
 
             contactIds.add(contactId);
             final AccountType type = accountTypes.getAccountType(accountType, dataSet);
diff --git a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
index 03933a1..331c566 100644
--- a/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/DefaultContactBrowseListFragment.java
@@ -128,6 +128,8 @@
     private boolean mIsRecreatedInstance;
     private boolean mOptionsMenuContactsAvailable;
 
+    private boolean mCanSetActionBar = false;
+
     /**
      * If {@link #configureFragment()} is already called. Used to avoid calling it twice
      * in {@link #onResume()}.
@@ -649,6 +651,7 @@
         }
 
         setDirectorySearchMode();
+        mCanSetActionBar = true;
     }
 
     public void initializeActionBarAdapter(Bundle savedInstanceState) {
@@ -1205,4 +1208,8 @@
 
         return false;
     }
+
+    public boolean canSetActionBar() {
+        return mCanSetActionBar;
+    }
 }