Merge "Apply contact save ops before we reach the max batch op threshold" into ub-contactsdialer-a-dev
diff --git a/Android.mk b/Android.mk
index f449a60..7d18e7d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -6,12 +6,18 @@
 contacts_common_dir := ../ContactsCommon
 phone_common_dir := ../PhoneCommon
 
+ifeq ($(TARGET_BUILD_APPS),)
+support_library_root_dir := frameworks/support
+else
+support_library_root_dir := prebuilts/sdk/current/support
+endif
+
 src_dirs := src $(contacts_common_dir)/src $(phone_common_dir)/src
 res_dirs := res $(contacts_common_dir)/res $(phone_common_dir)/res
 
 LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs))
 LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs)) \
-    frameworks/support/v7/cardview/res
+    $(support_library_root_dir)/v7/cardview/res
 
 LOCAL_AAPT_FLAGS := \
     --auto-add-overlay \
diff --git a/res/layout/editor_account_header_expandable.xml b/res/layout/editor_account_header_expandable.xml
index 5d347f0..2636f9c 100644
--- a/res/layout/editor_account_header_expandable.xml
+++ b/res/layout/editor_account_header_expandable.xml
@@ -25,12 +25,22 @@
     android:focusable="true"
     >
 
+    <!-- TODO: consider making this a new style, like EditKindIconStyle -->
+    <ImageView
+        android:id="@android:id/icon"
+        android:layout_width="@dimen/editor_kind_icon_size"
+        android:layout_height="@dimen/editor_kind_icon_size"
+        android:layout_marginEnd="28dp"
+        android:layout_gravity="center_vertical"
+        />
+
     <LinearLayout
+        android:id="@+id/account_info"
         android:layout_height="wrap_content"
-        android:layout_width="0dp"
+        android:layout_width="match_parent"
         android:layout_weight="1"
-        android:paddingBottom="24dp"
-        android:paddingTop="24dp"
+        android:paddingBottom="@dimen/editor_account_header_expandable_top_bottom_padding"
+        android:paddingTop="@dimen/editor_account_header_expandable_top_bottom_padding"
         android:orientation="vertical"
         >
 
diff --git a/res/layout/editor_account_selector.xml b/res/layout/editor_account_selector.xml
index 3a1bf83..6ba18a9 100644
--- a/res/layout/editor_account_selector.xml
+++ b/res/layout/editor_account_selector.xml
@@ -40,8 +40,9 @@
         android:layout_weight="1"
         android:layout_gravity="center_vertical"
         android:orientation="vertical"
+        android:layout_marginStart="4dp"
         android:layout_marginEnd="48dp"
-        style="@android:style/Widget.Material.Spinner.Underlined">
+        >
 
         <TextView
             android:id="@+id/account_type_selector"
@@ -65,4 +66,16 @@
 
     </LinearLayout>
 
+    <ImageView
+        android:src="@drawable/ic_menu_expander_minimized_holo_light"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical|end"
+        android:layout_alignParentEnd="true"
+        android:paddingStart="@dimen/editor_round_button_padding_left"
+        android:paddingEnd="@dimen/editor_round_button_padding_right"
+        android:paddingTop="@dimen/editor_round_button_padding_top"
+        android:paddingBottom="@dimen/editor_round_button_padding_bottom"/>
+
+
 </LinearLayout>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 000a32b..cffe8c4 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -108,6 +108,12 @@
     <!-- Top margin for the first field of the compact contact editor -->
     <dimen name="editor_compact_first_field_padding">10dp</dimen>
 
+    <!-- Top and bottom padding for the two text views in editor account header expandable -->
+    <dimen name="editor_account_header_expandable_top_bottom_padding">24dp</dimen>
+
+    <!-- left padding for the two text views in editor account header expandable -->
+    <dimen name="editor_account_header_expandable_left_padding">4dp</dimen>
+
     <!-- Width and height of the expanded contact photo on the contact detail page -->
     <dimen name="detail_contact_photo_expanded_size">400dip</dimen>
 
@@ -278,4 +284,5 @@
 
     <!-- Top margin for "Saving to" account header text field. -->
     <dimen name="compact_editor_account_header_top_margin">3dp</dimen>
+
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 53579bd..d14a7fa 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -141,20 +141,23 @@
     <!-- Menu item (in the action bar) that creates a new group [CHAR LIMIT=30] -->
     <string name="menu_new_group_action_bar">Add Group</string>
 
-    <!-- Title of the confirmation dialog for separating contacts into multiple instances [CHAR LIMIT=40] -->
-    <string name="splitConfirmation_title">Unlink contact?</string>
-
     <!-- Confirmation dialog for unlinking contacts into multiple instances [CHAR LIMIT=NONE] -->
-    <string name="splitConfirmation">This contact will be unlinked into multiple contacts.</string>
+    <string name="splitConfirmation">Unlink this contact into multiple contacts?</string>
+
+    <!-- Positive button text from the confirmation dialog for unlinking contacts [CHAR LIMIT = 30] -->
+    <string name="splitConfirmation_positive_button">Unlink</string>
 
     <!-- Confirmation dialog for unlinking contacts into multiple instances when there are also unsaved changes for the current contact. [CHAR LIMIT=NONE] -->
-    <string name="splitConfirmationWithPendingChanges">There are unsaved changes. Do you want to save them before unlinking this contact into multiple contacts?</string>
+    <string name="splitConfirmationWithPendingChanges">Would you like to save the changes you already made and unlink this contact into multiple contacts?</string>
 
-    <!-- Title of the confirmation dialog for joining contacts when there are unsaved changes. [CHAR LIMIT=40] -->
-    <string name="joinConfirmation_title">Link contact?</string>
+    <!-- Positive button text from the confirmation dialog for unlinking contacts with pending changes [CHAR LIMIT = 60] -->
+    <string name="splitConfirmationWithPendingChanges_positive_button">Save and Unlink</string>
 
     <!-- Confirmation dialog message for joining contacts when there are unsaved changes. [CHAR LIMIT=NONE] -->
-    <string name="joinConfirmation">There are unsaved changes. Do you want to save them before linking?</string>
+    <string name="joinConfirmation">Would you like to save the changes you already made and link with the contact selected?</string>
+
+    <!-- Positive button text from the confirmation dialog for joining contacts when there are unsaved changes. [CHAR LIMIT = 60] -->
+    <string name="joinConfirmation_positive_button">Save and Link</string>
 
     <!-- Menu item that links an aggregate with another aggregate -->
     <string name="menu_joinAggregate">Link</string>
@@ -193,32 +196,44 @@
     <!-- Menu item that opens the Options activity for a given contact [CHAR LIMIT=30] -->
     <string name="menu_redirect_calls_to_vm">All calls to voicemail</string>
 
-    <!-- Warning dialog contents after users selects to delete a ReadOnly contact. [CHAR LIMIT=NONE] -->
-    <string name="readOnlyContactWarning">You can\'t delete contacts from read-only accounts, but you can hide them in your contacts lists.</string>
+    <!-- Warning dialog contents after users select to delete a ReadOnly contact. [CHAR LIMIT=NONE] -->
+    <string name="readOnlyContactWarning">Contacts from your read-only accounts cannot be deleted, but they can be hidden on this device.</string>
 
-    <!-- Warning dialog contents after users selects to delete a contact with ReadOnly and Writable sources. -->
-    <string name="readOnlyContactDeleteConfirmation">This contact contains information from multiple accounts. Information from read-only accounts will be hidden in your contacts lists, not deleted.</string>
+    <!-- Positive button text of the warning dialog contents after users select to delete a ReadOnly contact. [CHAR LIMIT=30]-->
+    <string name="readOnlyContactWarning_positive_button">Hide</string>
+
+    <!-- Warning dialog contents after users selects to delete a contact with ReadOnly and Writable sources. [CHAR LIMIT=NONE]-->
+    <string name="readOnlyContactDeleteConfirmation">This contact to be deleted has details from multiple accounts. Details from read-only accounts will be hidden on this device, not deleted.</string>
 
     <!-- Warning dialog. Shown if user selects a single contact to link. [CHAR LIMIT=NONE]  -->
     <string name="batch_link_single_contact_warning">You need at least two contacts selected to perform a link.</string>
 
     <!-- Confirmation dialog. Shown after user selects to link contacts. [CHAR LIMIT=NONE]  -->
-    <string name="batch_link_confirmation">The selected contacts will be linked into a single contact.</string>
+    <string name="batch_link_confirmation">Link selected contacts?</string>
 
-    <!-- Confirmation dialog. Shown after user selects to delete writable contacts. [CHAR LIMIT=NONE]  -->
-    <string name="batch_delete_confirmation">The selected contacts will be deleted.</string>
+    <!-- Positive button text from confirmation dialog. Shown after user selects to link contacts. [CHAR LIMIT=40]  -->
+    <string name="batch_link_confirmation_positive_button">Link</string>
+
+    <!-- Confirmation dialog. Shown after user selects to delete one writable contact [CHAR LIMIT=NONE]  -->
+    <string name="single_delete_confirmation">Delete this contact?</string>
+
+    <!-- Confirmation dialog. Shown after user selects to delete multimple writable contacts. [CHAR LIMIT=NONE]  -->
+    <string name="batch_delete_confirmation">Delete selected contacts?</string>
 
     <!-- Confirmation dialog. Shown after user selects to delete readonly contacts. [CHAR LIMIT=NONE] -->
-    <string name="batch_delete_read_only_contact_confirmation">Information from read-only accounts will be hidden in your contacts lists, not deleted.</string>
+    <string name="batch_delete_read_only_contact_confirmation">Contacts from your read-only accounts cannot be deleted, but they can be hidden on this device.</string>
 
     <!-- Confirmation dialog. Shown after user selects to delete contacts from multiple accounts. [CHAR LIMIT=NONE]  -->
-    <string name="batch_delete_multiple_accounts_confirmation">These contacts contains information from multiple accounts. Information from read-only accounts will be hidden in your contacts lists, not deleted.</string>
+    <string name="batch_delete_multiple_accounts_confirmation">These contacts to be deleted have details from multiple accounts. Details from read-only accounts will be hidden on this device, not deleted.</string>
 
     <!-- Warning dialog contents after users selects to delete a contact with multiple Writable sources. -->
-    <string name="multipleContactDeleteConfirmation">Deleting this contact will delete information from multiple accounts.</string>
+    <string name="multipleContactDeleteConfirmation">Deleting this contact will delete details from multiple accounts.</string>
 
     <!-- Confirmation dialog contents after users selects to delete a Writable contact. -->
-    <string name="deleteConfirmation">This contact will be deleted.</string>
+    <string name="deleteConfirmation">Delete this contact?</string>
+
+    <!-- Positive button text of confirmation dialog contents after users selects to delete a Writable contact. [CHAR LIMIT=30] -->
+    <string name="deleteConfirmation_positive_button">Delete</string>
 
     <!-- Menu item to indicate you want to stop editing a contact and NOT save the changes you've made [CHAR LIMIT=30] -->
     <string name="menu_discard">Discard changes</string>
@@ -227,8 +242,11 @@
          for some reason doesn't exist anymore. [CHAR LIMIT=NONE]-->
     <string name="invalidContactMessage">The contact doesn\'t exist.</string>
 
-    <!-- Message displayed in a toast after you create a contact shortcut in the launcher [CHAR LIMIT=NONE]-->
-    <string name="createContactShortcutSuccessful">Contact widget added to Home screen.</string>
+    <!-- Message without name displayed in a toast after you create a contact shortcut in the launcher [CHAR LIMIT=NONE]-->
+    <string name="createContactShortcutSuccessful_NoName">Contact added to Home screen.</string>
+
+    <!-- Message with name displayed in a toast after you create a contact shortcut in the launcher [CHAR LIMIT=NONE]-->
+    <string name="createContactShortcutSuccessful"><xliff:g id="name">%s</xliff:g> added to Home screen.</string>
 
     <!-- When picking a contact from a list of all contacts there is an entry at the top of the
          list that allows the user to create a new contact, which this string is used for -->
@@ -337,7 +355,7 @@
     </plurals>
 
     <!-- The title of "all contacts" tab. [CHAR LIMIT=14] -->
-    <string name="all_contacts_tab_label">All contacts</string>
+    <string name="all_contacts_tab_label">All</string>
 
     <!-- The title of "favorites" tab. [CHAR LIMIT=14] -->
     <string name="favorites_tab_label">Favorites</string>
@@ -619,6 +637,9 @@
     <!-- Contents of the alert dialog when the user hits the Cancel button in the editor [CHAR LIMIT=128] -->
     <string name="cancel_confirmation_dialog_message">Discard your changes?</string>
 
+    <!-- Positive button text of the alert dialog when the user hits the Cancel button in the editor [CHAR LIMIT=40] -->
+    <string name="cancel_confirmation_dialog_message_positive_button">Discard</string>
+
     <!-- Description of a call log entry, made of a call type and a date -->
     <string name="call_type_and_date">
         <xliff:g id="call_type" example="Friends">%1$s</xliff:g>  <xliff:g id="call_short_date" example="Friends">%2$s</xliff:g>
@@ -660,7 +681,7 @@
     <string name="contact_editor_prompt_one_account">Your new contact will be synchronized with <xliff:g id="account_name">%1$s</xliff:g>.</string>
 
     <!-- Message in the contact editor prompt that asks the user which account they want to save the newly created contact to. [CHAR LIMIT=NONE] -->
-    <string name="contact_editor_prompt_multiple_accounts">You can synchronize your new contact with one of the following accounts. Which do you want to use?</string>
+    <string name="contact_editor_prompt_multiple_accounts">Choose a default account for new contacts:</string>
 
     <!-- Title of the ContactEditorActivity when creating a new contact. The char
          limit is short and cannot be increased, since this needs to be displayed in a single line
@@ -837,8 +858,8 @@
     <!-- "Duplicates" title showing in suggestion card in Quick contact. [CHAR LIMIT=30]-->
     <string name="suggestion_card_duplicates_title">Possible duplicates</string>
 
-    <!-- Help message showing in suggestion card in Quick contact. [CHAR LIMIT=500]-->
-    <string name="suggestion_card_help_message">Clean up duplicate contacts for the same person by linking them together.</string>
+    <!-- Help message showing in suggestion card in Quick contact. [CHAR LIMIT=NONE]-->
+    <string name="suggestion_card_help_message">These contacts might be the same person. You can link them together as a single contact.</string>
 
     <!-- Linked contacts title showing in contact editor UI. [CHAR LIMIT=30]-->
     <string name="compact_editor_linked_contacts_title">Linked contacts</string>
diff --git a/src/com/android/contacts/editor/CancelEditDialogFragment.java b/src/com/android/contacts/editor/CancelEditDialogFragment.java
index 300759e..6780578 100644
--- a/src/com/android/contacts/editor/CancelEditDialogFragment.java
+++ b/src/com/android/contacts/editor/CancelEditDialogFragment.java
@@ -46,7 +46,8 @@
         return new AlertDialog.Builder(getActivity())
                 .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setMessage(R.string.cancel_confirmation_dialog_message)
-                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                .setPositiveButton(R.string.cancel_confirmation_dialog_message_positive_button,
+                        new DialogInterface.OnClickListener() {
                             @Override
                             public void onClick(DialogInterface dialogInterface, int which) {
                                 final Listener targetListener = (Listener) getTargetFragment();
diff --git a/src/com/android/contacts/editor/CompactRawContactsEditorView.java b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
index d6ffdb9..09315d5 100644
--- a/src/com/android/contacts/editor/CompactRawContactsEditorView.java
+++ b/src/com/android/contacts/editor/CompactRawContactsEditorView.java
@@ -852,7 +852,7 @@
                 EditorUiUtils.getAccountInfoContentDescription(
                         accountInfo.first, selectorTitle));
 
-        mAccountSelector.setOnClickListener(new View.OnClickListener() {
+        mAccountSelectorContainer.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 final ListPopupWindow popup = new ListPopupWindow(getContext(), null);
diff --git a/src/com/android/contacts/editor/JoinContactConfirmationDialogFragment.java b/src/com/android/contacts/editor/JoinContactConfirmationDialogFragment.java
index dc83239..55a066e 100644
--- a/src/com/android/contacts/editor/JoinContactConfirmationDialogFragment.java
+++ b/src/com/android/contacts/editor/JoinContactConfirmationDialogFragment.java
@@ -70,16 +70,15 @@
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-        builder.setTitle(R.string.joinConfirmation_title);
-        builder.setIconAttribute(android.R.attr.alertDialogIcon);
         builder.setMessage(R.string.joinConfirmation);
-        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                final Listener targetListener = (Listener) getTargetFragment();
-                targetListener.onJoinContactConfirmed(mContactId);
-            }
-        });
+        builder.setPositiveButton(R.string.joinConfirmation_positive_button,
+                new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        final Listener targetListener = (Listener) getTargetFragment();
+                        targetListener.onJoinContactConfirmed(mContactId);
+                    }
+                });
         builder.setNegativeButton(android.R.string.cancel, null);
         builder.setCancelable(false);
         return builder.create();
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index b6320e9..5a4c9db 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -31,6 +31,8 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 
 import com.android.contacts.GroupMetaDataLoader;
@@ -77,6 +79,7 @@
     private View mAccountHeader;
     private TextView mAccountHeaderTypeTextView;
     private TextView mAccountHeaderNameTextView;
+    private ImageView mAccountIconImageView;
 
     private long mRawContactId = -1;
     private boolean mAutoAddToDefaultGroup = true;
@@ -140,6 +143,17 @@
         mAccountHeader = findViewById(R.id.account_header_container);
         mAccountHeaderTypeTextView = (TextView) findViewById(R.id.account_type);
         mAccountHeaderNameTextView = (TextView) findViewById(R.id.account_name);
+        mAccountIconImageView = (ImageView) findViewById(android.R.id.icon);
+
+        // The same header is used by both full editor and read-only editor view. The header is
+        // left-aligned with read-only editor view but is not aligned well with full editor. So we
+        // need to shift the text in the header a little bit for full editor.
+        LinearLayout accountInfoView = (LinearLayout) findViewById(R.id.account_info);
+        final int topBottomPaddingDp = (int) getResources().getDimension(R.dimen
+                .editor_account_header_expandable_top_bottom_padding);
+        final int leftPaddingDp = (int) getResources().getDimension(R.dimen
+                .editor_account_header_expandable_left_padding);
+        accountInfoView.setPadding(leftPaddingDp, topBottomPaddingDp, 0, topBottomPaddingDp);
 
         mAccountSelector = findViewById(R.id.account_selector_container);
         mAccountSelectorTypeTextView = (TextView) findViewById(R.id.account_type_selector);
@@ -212,6 +226,9 @@
         mAccountHeader.setVisibility(mAccountSelector.getVisibility() == View.GONE
                 ? View.VISIBLE : View.GONE);
 
+        mAccountIconImageView.setImageDrawable(state.getRawContactAccountType(getContext())
+                .getDisplayIcon(getContext()));
+
         // Show photo editor when supported
         RawContactModifier.ensureKindExists(state, type, Photo.CONTENT_ITEM_TYPE);
         setHasPhotoEditor((type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE) != null));
diff --git a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
index ad2e013..8c54b05 100644
--- a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
+++ b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
@@ -61,6 +61,7 @@
 
     private TextView mAccountHeaderTypeTextView;
     private TextView mAccountHeaderNameTextView;
+    private ImageView mAccountIconImageView;
 
     private String mAccountName;
     private String mAccountType;
@@ -91,6 +92,7 @@
 
         mAccountHeaderTypeTextView = (TextView) findViewById(R.id.account_type);
         mAccountHeaderNameTextView = (TextView) findViewById(R.id.account_name);
+        mAccountIconImageView = (ImageView) findViewById(android.R.id.icon);
     }
 
     /**
@@ -128,6 +130,9 @@
         mAccountHeaderTypeTextView.setText(accountInfo.second);
         updateAccountHeaderContentDescription();
 
+        mAccountIconImageView.setImageDrawable(state.getRawContactAccountType(getContext())
+                .getDisplayIcon(getContext()));
+
         // TODO: Expose data set in the UI somehow?
 
         mRawContactId = state.getRawContactId();
diff --git a/src/com/android/contacts/editor/SplitContactConfirmationDialogFragment.java b/src/com/android/contacts/editor/SplitContactConfirmationDialogFragment.java
index 521a689..f3d0ef4 100644
--- a/src/com/android/contacts/editor/SplitContactConfirmationDialogFragment.java
+++ b/src/com/android/contacts/editor/SplitContactConfirmationDialogFragment.java
@@ -71,18 +71,19 @@
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-        builder.setTitle(R.string.splitConfirmation_title);
-        builder.setIconAttribute(android.R.attr.alertDialogIcon);
         builder.setMessage(mHasPendingChanges
                 ? R.string.splitConfirmationWithPendingChanges
                 : R.string.splitConfirmation);
-        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                final Listener targetListener = (Listener) getTargetFragment();
-                targetListener.onSplitContactConfirmed(mHasPendingChanges);
-            }
-        });
+        builder.setPositiveButton(mHasPendingChanges
+                ? R.string.splitConfirmationWithPendingChanges_positive_button
+                : R.string.splitConfirmation_positive_button,
+                new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        final Listener targetListener = (Listener) getTargetFragment();
+                        targetListener.onSplitContactConfirmed(mHasPendingChanges);
+                    }
+                });
         builder.setNegativeButton(android.R.string.cancel, null);
         builder.setCancelable(false);
         return builder.create();
diff --git a/src/com/android/contacts/interactions/ContactDeletionInteraction.java b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
index 5855788..c9a5a9b 100644
--- a/src/com/android/contacts/interactions/ContactDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
@@ -264,18 +264,22 @@
 
         int readOnlyCount = readOnlyRawContacts.size();
         int writableCount = writableRawContacts.size();
+        int positiveButtonId = android.R.string.ok;
         if (readOnlyCount > 0 && writableCount > 0) {
             mMessageId = R.string.readOnlyContactDeleteConfirmation;
         } else if (readOnlyCount > 0 && writableCount == 0) {
             mMessageId = R.string.readOnlyContactWarning;
+            positiveButtonId = R.string.readOnlyContactWarning_positive_button;
         } else if (readOnlyCount == 0 && writableCount > 1) {
             mMessageId = R.string.multipleContactDeleteConfirmation;
+            positiveButtonId = R.string.deleteConfirmation_positive_button;
         } else {
             mMessageId = R.string.deleteConfirmation;
+            positiveButtonId = R.string.deleteConfirmation_positive_button;
         }
 
         final Uri contactUri = Contacts.getLookupUri(contactId, lookupKey);
-        showDialog(mMessageId, contactUri);
+        showDialog(mMessageId, positiveButtonId, contactUri);
 
         // We don't want onLoadFinished() calls any more, which may come when the database is
         // updating.
@@ -286,12 +290,12 @@
     public void onLoaderReset(Loader<Cursor> loader) {
     }
 
-    private void showDialog(int messageId, final Uri contactUri) {
+    private void showDialog(int messageId, int positiveButtonId, final Uri contactUri) {
         mDialog = new AlertDialog.Builder(getActivity())
                 .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setMessage(messageId)
                 .setNegativeButton(android.R.string.cancel, null)
-                .setPositiveButton(android.R.string.ok,
+                .setPositiveButton(positiveButtonId,
                     new DialogInterface.OnClickListener() {
                         @Override
                         public void onClick(DialogInterface dialog, int whichButton) {
diff --git a/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java b/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
index 7c13178..173f66e 100644
--- a/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactMultiDeletionInteraction.java
@@ -214,12 +214,18 @@
         final int writableCount = writableRawContacts.size();
 
         final int messageId;
+        int positiveButtonId = android.R.string.ok;
         if (readOnlyCount > 0 && writableCount > 0) {
             messageId = R.string.batch_delete_multiple_accounts_confirmation;
         } else if (readOnlyCount > 0 && writableCount == 0) {
             messageId = R.string.batch_delete_read_only_contact_confirmation;
+            positiveButtonId = R.string.readOnlyContactWarning_positive_button;
+        } else if (writableCount == 1) {
+            messageId = R.string.single_delete_confirmation;
+            positiveButtonId = R.string.deleteConfirmation_positive_button;
         } else {
             messageId = R.string.batch_delete_confirmation;
+            positiveButtonId = R.string.deleteConfirmation_positive_button;
         }
 
         // Convert set of contact ids into a format that is easily parcellable and iterated upon
@@ -230,7 +236,7 @@
             contactIdArray[i] = contactIdObjectArray[i];
         }
 
-        showDialog(messageId, contactIdArray);
+        showDialog(messageId, positiveButtonId, contactIdArray);
 
         // We don't want onLoadFinished() calls any more, which may come when the database is
         // updating.
@@ -241,12 +247,12 @@
     public void onLoaderReset(Loader<Cursor> loader) {
     }
 
-    private void showDialog(int messageId, final long[] contactIds) {
+    private void showDialog(int messageId, int positiveButtonId, final long[] contactIds) {
         mDialog = new AlertDialog.Builder(getActivity())
                 .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setMessage(messageId)
                 .setNegativeButton(android.R.string.cancel, null)
-                .setPositiveButton(android.R.string.ok,
+                .setPositiveButton(positiveButtonId,
                     new DialogInterface.OnClickListener() {
                         @Override
                         public void onClick(DialogInterface dialog, int whichButton) {
diff --git a/src/com/android/contacts/interactions/JoinContactsDialogFragment.java b/src/com/android/contacts/interactions/JoinContactsDialogFragment.java
index e5fd890..205e18e 100644
--- a/src/com/android/contacts/interactions/JoinContactsDialogFragment.java
+++ b/src/com/android/contacts/interactions/JoinContactsDialogFragment.java
@@ -73,7 +73,7 @@
                 .setIconAttribute(android.R.attr.alertDialogIcon)
                 .setMessage(R.string.batch_link_confirmation)
                 .setNegativeButton(android.R.string.cancel, null)
-                .setPositiveButton(android.R.string.ok,
+                .setPositiveButton(R.string.batch_link_confirmation_positive_button,
                         new DialogInterface.OnClickListener() {
                             @Override
                             public void onClick(DialogInterface dialog, int whichButton) {
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 5daf25a..af6dfdb 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -2685,8 +2685,11 @@
 
                         // Send a toast to give feedback to the user that a shortcut to this
                         // contact was added to the launcher.
-                        Toast.makeText(QuickContactActivity.this,
-                                R.string.createContactShortcutSuccessful,
+                        final String displayName = mContactData.getDisplayName();
+                        final String toastMessage = TextUtils.isEmpty(displayName)
+                                ? getString(R.string.createContactShortcutSuccessful_NoName)
+                                : getString(R.string.createContactShortcutSuccessful, displayName);
+                        Toast.makeText(QuickContactActivity.this, toastMessage,
                                 Toast.LENGTH_SHORT).show();
                     }