Merge "Disable "Place on Home screen" in corp Contacts" into lmp-dev
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index a001a63..743e325 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -27,8 +27,9 @@
     <dimen name="search_view_width">400dip</dimen>
     <dimen name="contact_tile_list_padding_top">18dip</dimen>
     <dimen name="contact_browser_list_item_text_size">18sp</dimen>
+    <dimen name="contact_browser_list_item_padding_top_or_bottom">12dp</dimen>
     <dimen name="contact_browser_list_item_photo_size">50dp</dimen>
-    <dimen name="contact_browser_list_item_gap_between_image_and_text">15dp</dimen>
+    <dimen name="contact_browser_list_item_gap_between_image_and_text">25dp</dimen>
     <dimen name="contact_browser_list_top_margin">18dp</dimen>
     <!-- Contact list (vertical scroll bar comes left) -->
     <dimen name="list_visible_scrollbar_padding">32dip</dimen>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c44d899..fb9f08c 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -198,4 +198,6 @@
 
     <!-- Width of the box around a tab when the tab has focus -->
     <dimen name="tab_focused_stroke_width">1dp</dimen>
+
+    <dimen name="contact_browser_list_item_padding_top_or_bottom">8dp</dimen>
 </resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 73329b3..89338e1 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -72,9 +72,13 @@
         <item name="activated_background">@drawable/list_item_activated_background</item>
         <item name="section_header_background">@drawable/list_title_holo</item>
         <item name="list_section_header_height">24dip</item>
-        <item name="list_item_padding_top">8dip</item>
+        <item name="list_item_padding_top">
+            @dimen/contact_browser_list_item_padding_top_or_bottom
+        </item>
         <item name="list_item_padding_right">32dp</item>
-        <item name="list_item_padding_bottom">8dip</item>
+        <item name="list_item_padding_bottom">
+            @dimen/contact_browser_list_item_padding_top_or_bottom
+        </item>
         <item name="list_item_padding_left">16dip</item>
         <item name="list_item_gap_between_image_and_text">
             @dimen/contact_browser_list_item_gap_between_image_and_text
diff --git a/src/com/android/contacts/NonPhoneActivity.java b/src/com/android/contacts/NonPhoneActivity.java
index 4f0696f..bab3977 100644
--- a/src/com/android/contacts/NonPhoneActivity.java
+++ b/src/com/android/contacts/NonPhoneActivity.java
@@ -27,10 +27,9 @@
 import android.os.Bundle;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Intents.Insert;
+import android.telecomm.PhoneAccount;
 import android.text.TextUtils;
 
-import com.android.contacts.common.CallUtil;
-
 /**
  * Activity that intercepts DIAL and VIEW intents for phone numbers for devices that can not
  * be used as a phone. This allows the user to see the phone number
@@ -60,7 +59,7 @@
         final Uri data = getIntent().getData();
         if (data == null) return null;
         final String scheme = data.getScheme();
-        if (!CallUtil.SCHEME_TEL.equals(scheme)) return null;
+        if (!PhoneAccount.SCHEME_TEL.equals(scheme)) return null;
         return getIntent().getData().getSchemeSpecificPart();
     }
 
diff --git a/src/com/android/contacts/activities/ShowOrCreateActivity.java b/src/com/android/contacts/activities/ShowOrCreateActivity.java
index a8077cb..d8926f0 100755
--- a/src/com/android/contacts/activities/ShowOrCreateActivity.java
+++ b/src/com/android/contacts/activities/ShowOrCreateActivity.java
@@ -30,9 +30,10 @@
 import android.provider.ContactsContract.Intents;
 import android.provider.ContactsContract.PhoneLookup;
 import android.provider.ContactsContract.RawContacts;
+import android.telecomm.PhoneAccount;
 import android.util.Log;
 
-import com.android.contacts.common.CallUtil;
+import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.ContactsActivity;
 import com.android.contacts.R;
 import com.android.contacts.util.NotifyingAsyncQueryHandler;
@@ -119,13 +120,13 @@
         mCreateForce = intent.getBooleanExtra(Intents.EXTRA_FORCE_CREATE, false);
 
         // Handle specific query request
-        if (CallUtil.SCHEME_MAILTO.equals(scheme)) {
+        if (ContactsUtils.SCHEME_MAILTO.equals(scheme)) {
             mCreateExtras.putString(Intents.Insert.EMAIL, ssp);
 
             Uri uri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, Uri.encode(ssp));
             mQueryHandler.startQuery(QUERY_TOKEN, null, uri, CONTACTS_PROJECTION, null, null, null);
 
-        } else if (CallUtil.SCHEME_TEL.equals(scheme)) {
+        } else if (PhoneAccount.SCHEME_TEL.equals(scheme)) {
             mCreateExtras.putString(Intents.Insert.PHONE, ssp);
 
             Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, ssp);
diff --git a/src/com/android/contacts/interactions/CalendarInteraction.java b/src/com/android/contacts/interactions/CalendarInteraction.java
index 12a968e..efd724a 100644
--- a/src/com/android/contacts/interactions/CalendarInteraction.java
+++ b/src/com/android/contacts/interactions/CalendarInteraction.java
@@ -282,4 +282,9 @@
         // The default TalkBack is good
         return null;
     }
+
+    @Override
+    public int getIconResourceId() {
+        return CALENDAR_ICON_RES;
+    }
 }
diff --git a/src/com/android/contacts/interactions/CallLogInteraction.java b/src/com/android/contacts/interactions/CallLogInteraction.java
index 4e5a143..702c23b 100644
--- a/src/com/android/contacts/interactions/CallLogInteraction.java
+++ b/src/com/android/contacts/interactions/CallLogInteraction.java
@@ -202,4 +202,9 @@
         }
         return callType;
     }
+
+    @Override
+    public int getIconResourceId() {
+        return CALL_LOG_ICON_RES;
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/contacts/interactions/ContactInteraction.java b/src/com/android/contacts/interactions/ContactInteraction.java
index af19984..11bbb49 100644
--- a/src/com/android/contacts/interactions/ContactInteraction.java
+++ b/src/com/android/contacts/interactions/ContactInteraction.java
@@ -33,4 +33,6 @@
     Drawable getBodyIcon(Context context);
     Drawable getFooterIcon(Context context);
     String getContentDescription(Context context);
+    /** The resource id for the icon, if available. May be 0 if one is not available. */
+    int getIconResourceId();
 }
diff --git a/src/com/android/contacts/interactions/SmsInteraction.java b/src/com/android/contacts/interactions/SmsInteraction.java
index bc55572..34adfc1 100644
--- a/src/com/android/contacts/interactions/SmsInteraction.java
+++ b/src/com/android/contacts/interactions/SmsInteraction.java
@@ -160,4 +160,9 @@
         return context.getResources().getString(R.string.content_description_recent_sms,
                 messageDetails);
     }
+
+    @Override
+    public int getIconResourceId() {
+        return SMS_ICON_RES;
+    }
 }
diff --git a/src/com/android/contacts/list/EmailAddressListAdapter.java b/src/com/android/contacts/list/EmailAddressListAdapter.java
index 80a35a7..5df4b34 100644
--- a/src/com/android/contacts/list/EmailAddressListAdapter.java
+++ b/src/com/android/contacts/list/EmailAddressListAdapter.java
@@ -135,6 +135,7 @@
         ContactListItemView view = (ContactListItemView)itemView;
         bindSectionHeaderAndDivider(view, position);
         bindName(view, cursor);
+        bindViewId(view, cursor, EmailQuery.EMAIL_ID);
         bindPhoto(view, cursor);
         bindEmailAddress(view, cursor);
     }
diff --git a/src/com/android/contacts/list/JoinContactListAdapter.java b/src/com/android/contacts/list/JoinContactListAdapter.java
index a9c9c94..23dc109 100644
--- a/src/com/android/contacts/list/JoinContactListAdapter.java
+++ b/src/com/android/contacts/list/JoinContactListAdapter.java
@@ -187,14 +187,14 @@
                 final ContactListItemView view = (ContactListItemView) itemView;
                 view.setSectionHeader(null);
                 bindPhoto(view, partition, cursor);
-                bindName(view, cursor);
+                bindNameAndViewId(view, cursor);
                 break;
             }
             case PARTITION_ALL_CONTACTS: {
                 final ContactListItemView view = (ContactListItemView) itemView;
                 bindSectionHeaderAndDivider(view, position, cursor);
                 bindPhoto(view, partition, cursor);
-                bindName(view, cursor);
+                bindNameAndViewId(view, cursor);
                 break;
             }
         }
diff --git a/src/com/android/contacts/list/LegacyContactListAdapter.java b/src/com/android/contacts/list/LegacyContactListAdapter.java
index 27f0a8b..98144fe 100644
--- a/src/com/android/contacts/list/LegacyContactListAdapter.java
+++ b/src/com/android/contacts/list/LegacyContactListAdapter.java
@@ -84,6 +84,7 @@
     protected void bindView(View itemView, int partition, Cursor cursor, int position) {
         ContactListItemView view = (ContactListItemView)itemView;
         bindName(view, cursor);
+        bindViewId(view, cursor, PERSON_ID_COLUMN_INDEX);
         bindPresence(view, cursor);
     }
 
diff --git a/src/com/android/contacts/list/LegacyPhoneNumberListAdapter.java b/src/com/android/contacts/list/LegacyPhoneNumberListAdapter.java
index 85b9872..f9f0357 100644
--- a/src/com/android/contacts/list/LegacyPhoneNumberListAdapter.java
+++ b/src/com/android/contacts/list/LegacyPhoneNumberListAdapter.java
@@ -89,6 +89,7 @@
     protected void bindView(View itemView, int partition, Cursor cursor, int position) {
         ContactListItemView view = (ContactListItemView)itemView;
         bindName(view, cursor);
+        bindViewId(view, cursor, PHONE_ID_COLUMN_INDEX);
         bindPhoneNumber(view, cursor);
     }
 
diff --git a/src/com/android/contacts/list/LegacyPostalAddressListAdapter.java b/src/com/android/contacts/list/LegacyPostalAddressListAdapter.java
index 86a4c4a..d4919e7 100644
--- a/src/com/android/contacts/list/LegacyPostalAddressListAdapter.java
+++ b/src/com/android/contacts/list/LegacyPostalAddressListAdapter.java
@@ -89,6 +89,7 @@
     protected void bindView(View itemView, int partition, Cursor cursor, int position) {
         ContactListItemView view = (ContactListItemView)itemView;
         bindName(view, cursor);
+        bindViewId(view, cursor, POSTAL_ID_COLUMN_INDEX);
         bindPostalAddress(view, cursor);
     }
 
diff --git a/src/com/android/contacts/list/PostalAddressListAdapter.java b/src/com/android/contacts/list/PostalAddressListAdapter.java
index 4856d74..c715f30 100644
--- a/src/com/android/contacts/list/PostalAddressListAdapter.java
+++ b/src/com/android/contacts/list/PostalAddressListAdapter.java
@@ -126,6 +126,7 @@
         ContactListItemView view = (ContactListItemView)itemView;
         bindSectionHeaderAndDivider(view, position);
         bindName(view, cursor);
+        bindViewId(view, cursor, PostalQuery.POSTAL_ID);
         bindPhoto(view, cursor);
         bindPostalAddress(view, cursor);
     }
diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
index b590814..aacfedf 100644
--- a/src/com/android/contacts/quickcontact/DataAction.java
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -26,6 +26,7 @@
 import android.net.WebAddress;
 import android.provider.ContactsContract.CommonDataKinds.Im;
 import android.provider.ContactsContract.Data;
+import android.telecomm.PhoneAccount;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -124,7 +125,7 @@
                     Intent smsIntent = null;
                     if (hasSms) {
                         smsIntent = new Intent(Intent.ACTION_SENDTO,
-                                Uri.fromParts(CallUtil.SCHEME_SMSTO, number, null));
+                                Uri.fromParts(ContactsUtils.SCHEME_SMSTO, number, null));
                         smsIntent.setComponent(smsComponent);
                     }
 
@@ -146,7 +147,7 @@
                 final SipAddressDataItem sip = (SipAddressDataItem) item;
                 final String address = sip.getSipAddress();
                 if (!TextUtils.isEmpty(address)) {
-                    final Uri callUri = Uri.fromParts(CallUtil.SCHEME_SIP, address, null);
+                    final Uri callUri = Uri.fromParts(PhoneAccount.SCHEME_SIP, address, null);
                     mIntent = CallUtil.getCallIntent(callUri);
                     // Note that this item will get a SIP-specific variant
                     // of the "call phone" icon, rather than the standard
@@ -160,7 +161,7 @@
             final EmailDataItem email = (EmailDataItem) item;
             final String address = email.getData();
             if (!TextUtils.isEmpty(address)) {
-                final Uri mailUri = Uri.fromParts(CallUtil.SCHEME_MAILTO, address, null);
+                final Uri mailUri = Uri.fromParts(ContactsUtils.SCHEME_MAILTO, address, null);
                 mIntent = new Intent(Intent.ACTION_SENDTO, mailUri);
             }
 
@@ -195,7 +196,7 @@
 
                 if (!TextUtils.isEmpty(host) && !TextUtils.isEmpty(data)) {
                     final String authority = host.toLowerCase();
-                    final Uri imUri = new Uri.Builder().scheme(CallUtil.SCHEME_IMTO).authority(
+                    final Uri imUri = new Uri.Builder().scheme(ContactsUtils.SCHEME_IMTO).authority(
                             authority).appendPath(data).build();
                     mIntent = new Intent(Intent.ACTION_SENDTO, imUri);
 
diff --git a/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java b/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java
index db1f4a7..45d0e43 100644
--- a/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java
+++ b/src/com/android/contacts/quickcontact/ExpandingEntryCardView.java
@@ -86,17 +86,19 @@
         private final Drawable mThirdIcon;
         private final Intent mThirdIntent;
         private final String mThirdContentDescription;
+        private final int mIconResourceId;
 
         public Entry(int id, Drawable icon, String header, String subHeader, String text,
                 String primaryContentDescription, Intent intent, Drawable alternateIcon,
                 Intent alternateIntent, String alternateContentDescription,
                 boolean shouldApplyColor, boolean isEditable,
                 EntryContextMenuInfo entryContextMenuInfo, Drawable thirdIcon, Intent thirdIntent,
-                String thirdContentDescription) {
+                String thirdContentDescription, int iconResourceId) {
             this(id, icon, header, subHeader, null, text, null, primaryContentDescription, intent,
                     alternateIcon,
                     alternateIntent, alternateContentDescription, shouldApplyColor, isEditable,
-                    entryContextMenuInfo, thirdIcon, thirdIntent, thirdContentDescription);
+                    entryContextMenuInfo, thirdIcon, thirdIntent, thirdContentDescription,
+                    iconResourceId);
         }
 
         public Entry(int id, Drawable mainIcon, String header, String subHeader,
@@ -105,7 +107,7 @@
                 Drawable alternateIcon, Intent alternateIntent, String alternateContentDescription,
                 boolean shouldApplyColor, boolean isEditable,
                 EntryContextMenuInfo entryContextMenuInfo, Drawable thirdIcon, Intent thirdIntent,
-                String thirdContentDescription) {
+                String thirdContentDescription, int iconResourceId) {
             mId = id;
             mIcon = mainIcon;
             mHeader = header;
@@ -124,6 +126,7 @@
             mThirdIcon = thirdIcon;
             mThirdIntent = thirdIntent;
             mThirdContentDescription = thirdContentDescription;
+            mIconResourceId = iconResourceId;
         }
 
         Drawable getIcon() {
@@ -197,6 +200,10 @@
         String getThirdContentDescription() {
             return mThirdContentDescription;
         }
+
+        int getIconResourceId() {
+            return mIconResourceId;
+        }
     }
 
     public interface ExpandingEntryCardViewListener {
@@ -231,6 +238,7 @@
     private ViewGroup mAnimationViewGroup;
     private LinearLayout mBadgeContainer;
     private final List<ImageView> mBadges;
+    private final List<Integer> mBadgeIds;
     /**
      * List to hold the separators. This saves us from reconstructing every expand/collapse and
      * provides a smoother animation.
@@ -270,6 +278,7 @@
         mBadgeContainer = (LinearLayout) mExpandCollapseButton.findViewById(R.id.badge_container);
 
         mBadges = new ArrayList<ImageView>();
+        mBadgeIds = new ArrayList<Integer>();
     }
 
     /**
@@ -719,11 +728,17 @@
     private void updateBadges() {
         if (mIsExpanded) {
             mBadgeContainer.removeAllViews();
+            mBadgeIds.clear();
         } else {
             // Inflate badges if not yet created
             if (mBadges.size() < mEntries.size() - mCollapsedEntriesCount) {
                 for (int i = mCollapsedEntriesCount; i < mEntries.size(); i++) {
                     Drawable badgeDrawable = mEntries.get(i).get(0).getIcon();
+                    int badgeResourceId = mEntries.get(i).get(0).getIconResourceId();
+                    // Do not add the same badge twice
+                    if (badgeResourceId != 0 && mBadgeIds.contains(badgeResourceId)) {
+                        continue;
+                    }
                     if (badgeDrawable != null) {
                         ImageView badgeView = new ImageView(getContext());
                         LinearLayout.LayoutParams badgeViewParams = new LinearLayout.LayoutParams(
@@ -736,6 +751,7 @@
                         badgeView.setLayoutParams(badgeViewParams);
                         badgeView.setImageDrawable(badgeDrawable);
                         mBadges.add(badgeView);
+                        mBadgeIds.add(badgeResourceId);
                     }
                 }
             }
@@ -916,10 +932,17 @@
     public static final class EntryContextMenuInfo implements ContextMenuInfo {
         private final String mCopyText;
         private final String mCopyLabel;
+        private final String mMimeType;
+        private final long mId;
+        private final boolean mIsSuperPrimary;
 
-        public EntryContextMenuInfo(String copyText, String copyLabel) {
+        public EntryContextMenuInfo(String copyText, String copyLabel, String mimeType, long id,
+                boolean isSuperPrimary) {
             mCopyText = copyText;
             mCopyLabel = copyLabel;
+            mMimeType = mimeType;
+            mId = id;
+            mIsSuperPrimary = isSuperPrimary;
         }
 
         public String getCopyText() {
@@ -929,6 +952,18 @@
         public String getCopyLabel() {
             return mCopyLabel;
         }
+
+        public String getMimeType() {
+            return mMimeType;
+        }
+
+        public long getId() {
+            return mId;
+        }
+
+        public boolean isSuperPrimary() {
+            return mIsSuperPrimary;
+        }
     }
 
     static final class EntryTag {
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index 280a384..5c2522d 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -70,6 +70,7 @@
 import android.provider.ContactsContract.QuickContact;
 import android.provider.ContactsContract.RawContacts;
 import android.support.v7.graphics.Palette;
+import android.telecomm.PhoneAccount;
 import android.telecomm.TelecommManager;
 import android.text.TextUtils;
 import android.util.Log;
@@ -203,6 +204,8 @@
     private int mExtraMode;
     private int mStatusBarColor;
     private boolean mHasAlreadyBeenOpened;
+    private boolean mOnlyOnePhoneNumber;
+    private boolean mOnlyOneEmail;
 
     private QuickContactImageView mPhotoView;
     private ExpandingEntryCardView mContactCard;
@@ -324,7 +327,7 @@
 
             final Uri intentUri = intent.getData();
             if ((intentUri != null && intentUri.getScheme() != null &&
-                    intentUri.getScheme().equals(CallUtil.SCHEME_SMSTO)) ||
+                    intentUri.getScheme().equals(ContactsUtils.SCHEME_SMSTO)) ||
                     (intent.getType() != null && intent.getType().equals(MIMETYPE_SMS))) {
                 usageType = DataUsageFeedback.USAGE_TYPE_SHORT_TEXT;
             }
@@ -372,6 +375,12 @@
         }
     };
 
+    private interface ContextMenuIds {
+        static final int COPY_TEXT = 0;
+        static final int CLEAR_DEFAULT = 1;
+        static final int SET_DEFAULT = 2;
+    }
+
     private final OnCreateContextMenuListener mEntryContextMenuListener =
             new OnCreateContextMenuListener() {
         @Override
@@ -379,9 +388,36 @@
             if (menuInfo == null) {
                 return;
             }
-            EntryContextMenuInfo info = (EntryContextMenuInfo) menuInfo;
+            final EntryContextMenuInfo info = (EntryContextMenuInfo) menuInfo;
             menu.setHeaderTitle(info.getCopyText());
-            menu.add(R.string.copy_text);
+            menu.add(ContextMenu.NONE, ContextMenuIds.COPY_TEXT,
+                    ContextMenu.NONE, getString(R.string.copy_text));
+
+            // Don't allow setting or clearing of defaults for non-editable contacts
+            if (!isContactEditable()) {
+                return;
+            }
+
+            final String selectedMimeType = info.getMimeType();
+
+            // Defaults to true will only enable the detail to be copied to the clipboard.
+            boolean onlyOneOfMimeType = true;
+
+            // Only allow primary support for Phone and Email content types
+            if (Phone.CONTENT_ITEM_TYPE.equals(selectedMimeType)) {
+                onlyOneOfMimeType = mOnlyOnePhoneNumber;
+            } else if (Email.CONTENT_ITEM_TYPE.equals(selectedMimeType)) {
+                onlyOneOfMimeType = mOnlyOneEmail;
+            }
+
+            // Checking for previously set default
+            if (info.isSuperPrimary()) {
+                menu.add(ContextMenu.NONE, ContextMenuIds.CLEAR_DEFAULT,
+                        ContextMenu.NONE, getString(R.string.clear_default));
+            } else if (!onlyOneOfMimeType) {
+                menu.add(ContextMenu.NONE, ContextMenuIds.SET_DEFAULT,
+                        ContextMenu.NONE, getString(R.string.set_default));
+            }
         }
     };
 
@@ -395,8 +431,24 @@
             return false;
         }
 
-        ClipboardUtils.copyText(this, menuInfo.getCopyLabel(), menuInfo.getCopyText(), true);
-        return true;
+        switch (item.getItemId()) {
+            case ContextMenuIds.COPY_TEXT:
+                ClipboardUtils.copyText(this, menuInfo.getCopyLabel(), menuInfo.getCopyText(),
+                        true);
+                return true;
+            case ContextMenuIds.SET_DEFAULT:
+                final Intent setIntent = ContactSaveService.createSetSuperPrimaryIntent(this,
+                        menuInfo.getId());
+                this.startService(setIntent);
+                return true;
+            case ContextMenuIds.CLEAR_DEFAULT:
+                final Intent clearIntent = ContactSaveService.createClearPrimaryIntent(this,
+                        menuInfo.getId());
+                this.startService(clearIntent);
+                return true;
+            default:
+                throw new IllegalArgumentException("Unknown menu option " + item.getItemId());
+        }
     }
 
     /**
@@ -826,6 +878,9 @@
     private void startInteractionLoaders(Cp2DataCardModel cp2DataCardModel) {
         final Map<String, List<DataItem>> dataItemsMap = cp2DataCardModel.dataItemsMap;
         final List<DataItem> phoneDataItems = dataItemsMap.get(Phone.CONTENT_ITEM_TYPE);
+        if (phoneDataItems != null && phoneDataItems.size() == 1) {
+            mOnlyOnePhoneNumber = true;
+        }
         String[] phoneNumbers = null;
         if (phoneDataItems != null) {
             phoneNumbers = new String[phoneDataItems.size()];
@@ -853,6 +908,9 @@
 
         Trace.beginSection("start calendar loader");
         final List<DataItem> emailDataItems = dataItemsMap.get(Email.CONTENT_ITEM_TYPE);
+        if (emailDataItems != null && emailDataItems.size() == 1) {
+            mOnlyOneEmail = true;
+        }
         String[] emailAddresses = null;
         if (emailDataItems != null) {
             emailAddresses = new String[emailDataItems.size()];
@@ -951,10 +1009,12 @@
                     /* shouldApplyColor = */ false,
                     /* isEditable = */ false,
                     /* EntryContextMenuInfo = */ new EntryContextMenuInfo(phoneticName,
-                            getResources().getString(R.string.name_phonetic)),
+                            getResources().getString(R.string.name_phonetic),
+                            /* mimeType = */ null, /* id = */ -1, /* isPrimary = */ false),
                     /* thirdIcon = */ null,
                     /* thirdIntent = */ null,
-                    /* thirdContentDescription = */ null);
+                    /* thirdContentDescription = */ null,
+                    /* iconResourceId = */ 0);
             List<Entry> phoneticList = new ArrayList<>();
             phoneticList.add(phoneticEntry);
             // Phonetic name comes after nickname. Check to see if the first entry type is nickname
@@ -1007,7 +1067,7 @@
                 /* alternateContentDescription = */ null, /* shouldApplyColor = */ true,
                 /* isEditable = */ false, /* EntryContextMenuInfo = */ null,
                 /* thirdIcon = */ null, /* thirdIntent = */ null,
-                /* thirdContentDescription = */ null);
+                /* thirdContentDescription = */ null, R.drawable.ic_phone_24dp);
 
         final Drawable emailIcon = getResources().getDrawable(
                 R.drawable.ic_email_24dp).mutate();
@@ -1018,7 +1078,8 @@
                 /* alternateIntent = */ null, /* alternateContentDescription = */ null,
                 /* shouldApplyColor = */ true, /* isEditable = */ false,
                 /* EntryContextMenuInfo = */ null, /* thirdIcon = */ null,
-                /* thirdIntent = */ null, /* thirdContentDescription = */ null);
+                /* thirdIntent = */ null, /* thirdContentDescription = */ null,
+                R.drawable.ic_email_24dp);
 
         final List<List<Entry>> promptEntries = new ArrayList<>();
         promptEntries.add(new ArrayList<Entry>(1));
@@ -1183,6 +1244,7 @@
         Drawable thirdIcon = null;
         Intent thirdIntent = null;
         String thirdContentDescription = null;
+        int iconResourceId = 0;
 
         context = context.getApplicationContext();
         final Resources res = context.getResources();
@@ -1210,12 +1272,14 @@
                         im.getCustomProtocol()).toString();
                 subHeader = im.getData();
             }
-            entryContextMenuInfo = new EntryContextMenuInfo(im.getData(), header);
+            entryContextMenuInfo = new EntryContextMenuInfo(im.getData(), header,
+                    dataItem.getMimeType(), dataItem.getId(), dataItem.isSuperPrimary());
         } else if (dataItem instanceof OrganizationDataItem) {
             final OrganizationDataItem organization = (OrganizationDataItem) dataItem;
             header = res.getString(R.string.header_organization_entry);
             subHeader = organization.getCompany();
-            entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header);
+            entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header,
+                    dataItem.getMimeType(), dataItem.getId(), dataItem.isSuperPrimary());
             text = organization.getTitle();
         } else if (dataItem instanceof NicknameDataItem) {
             final NicknameDataItem nickname = (NicknameDataItem) dataItem;
@@ -1230,18 +1294,21 @@
             if (!duplicatesTitle) {
                 header = res.getString(R.string.header_nickname_entry);
                 subHeader = nickname.getName();
-                entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header);
+                entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header,
+                        dataItem.getMimeType(), dataItem.getId(), dataItem.isSuperPrimary());
             }
         } else if (dataItem instanceof NoteDataItem) {
             final NoteDataItem note = (NoteDataItem) dataItem;
             header = res.getString(R.string.header_note_entry);
             subHeader = note.getNote();
-            entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header);
+            entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header,
+                    dataItem.getMimeType(), dataItem.getId(), dataItem.isSuperPrimary());
         } else if (dataItem instanceof WebsiteDataItem) {
             final WebsiteDataItem website = (WebsiteDataItem) dataItem;
             header = res.getString(R.string.header_website_entry);
             subHeader = website.getUrl();
-            entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header);
+            entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header,
+                    dataItem.getMimeType(), dataItem.getId(), dataItem.isSuperPrimary());
             try {
                 final WebAddress webAddress = new WebAddress(website.buildDataString(context,
                         kind));
@@ -1267,7 +1334,8 @@
                         event.getLabel()).toString();
             }
             text = DateUtils.formatDate(context, dataString);
-            entryContextMenuInfo = new EntryContextMenuInfo(text, header);
+            entryContextMenuInfo = new EntryContextMenuInfo(text, header,
+                    dataItem.getMimeType(), dataItem.getId(), dataItem.isSuperPrimary());
         } else if (dataItem instanceof RelationDataItem) {
             final RelationDataItem relation = (RelationDataItem) dataItem;
             final String dataString = relation.buildDataString(context, kind);
@@ -1278,7 +1346,8 @@
             }
             header = res.getString(R.string.header_relation_entry);
             subHeader = relation.getName();
-            entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header);
+            entryContextMenuInfo = new EntryContextMenuInfo(subHeader, header,
+                    dataItem.getMimeType(), dataItem.getId(), dataItem.isSuperPrimary());
             if (relation.hasKindTypeColumn(kind)) {
                 text = Relation.getTypeLabel(res,
                         relation.getKindTypeColumn(kind),
@@ -1290,7 +1359,8 @@
                 primaryContentDescription.append(res.getString(R.string.call_other)).append(" ");
                 header = phone.buildDataString(context, kind);
                 entryContextMenuInfo = new EntryContextMenuInfo(header,
-                        res.getString(R.string.phoneLabelsGroup));
+                        res.getString(R.string.phoneLabelsGroup), dataItem.getMimeType(),
+                        dataItem.getId(), dataItem.isSuperPrimary());
                 if (phone.hasKindTypeColumn(kind)) {
                     text = Phone.getTypeLabel(res, phone.getKindTypeColumn(kind),
                             phone.getLabel()).toString();
@@ -1298,11 +1368,12 @@
                 }
                 primaryContentDescription.append(header);
                 icon = res.getDrawable(R.drawable.ic_phone_24dp);
+                iconResourceId = R.drawable.ic_phone_24dp;
                 if (PhoneCapabilityTester.isPhone(context)) {
                     intent = CallUtil.getCallIntent(phone.getNumber());
                 }
                 alternateIntent = new Intent(Intent.ACTION_SENDTO,
-                        Uri.fromParts(CallUtil.SCHEME_SMSTO, phone.getNumber(), null));
+                        Uri.fromParts(ContactsUtils.SCHEME_SMSTO, phone.getNumber(), null));
 
                 alternateIcon = res.getDrawable(R.drawable.ic_message_24dp);
                 alternateContentDescription.append(res.getString(R.string.sms_custom, header));
@@ -1321,11 +1392,12 @@
             final String address = email.getData();
             if (!TextUtils.isEmpty(address)) {
                 primaryContentDescription.append(res.getString(R.string.email_other)).append(" ");
-                final Uri mailUri = Uri.fromParts(CallUtil.SCHEME_MAILTO, address, null);
+                final Uri mailUri = Uri.fromParts(ContactsUtils.SCHEME_MAILTO, address, null);
                 intent = new Intent(Intent.ACTION_SENDTO, mailUri);
                 header = email.getAddress();
                 entryContextMenuInfo = new EntryContextMenuInfo(header,
-                        res.getString(R.string.emailLabelsGroup));
+                        res.getString(R.string.emailLabelsGroup), dataItem.getMimeType(),
+                        dataItem.getId(), dataItem.isSuperPrimary());
                 if (email.hasKindTypeColumn(kind)) {
                     text = Email.getTypeLabel(res, email.getKindTypeColumn(kind),
                             email.getLabel()).toString();
@@ -1333,6 +1405,7 @@
                 }
                 primaryContentDescription.append(header);
                 icon = res.getDrawable(R.drawable.ic_email_24dp);
+                iconResourceId = R.drawable.ic_email_24dp;
             }
         } else if (dataItem instanceof StructuredPostalDataItem) {
             StructuredPostalDataItem postal = (StructuredPostalDataItem) dataItem;
@@ -1342,7 +1415,8 @@
                 intent = StructuredPostalUtils.getViewPostalAddressIntent(postalAddress);
                 header = postal.getFormattedAddress();
                 entryContextMenuInfo = new EntryContextMenuInfo(header,
-                        res.getString(R.string.postalLabelsGroup));
+                        res.getString(R.string.postalLabelsGroup), dataItem.getMimeType(),
+                        dataItem.getId(), dataItem.isSuperPrimary());
                 if (postal.hasKindTypeColumn(kind)) {
                     text = StructuredPostal.getTypeLabel(res,
                             postal.getKindTypeColumn(kind), postal.getLabel()).toString();
@@ -1355,6 +1429,7 @@
                 alternateContentDescription.append(res.getString(
                         R.string.content_description_directions)).append(" ").append(header);
                 icon = res.getDrawable(R.drawable.ic_place_24dp);
+                iconResourceId = R.drawable.ic_place_24dp;
             }
         } else if (dataItem instanceof SipAddressDataItem) {
             if (PhoneCapabilityTester.isSipPhone(context)) {
@@ -1363,11 +1438,12 @@
                 if (!TextUtils.isEmpty(address)) {
                     primaryContentDescription.append(res.getString(R.string.call_other)).append(
                             " ");
-                    final Uri callUri = Uri.fromParts(CallUtil.SCHEME_SIP, address, null);
+                    final Uri callUri = Uri.fromParts(PhoneAccount.SCHEME_SIP, address, null);
                     intent = CallUtil.getCallIntent(callUri);
                     header = address;
                     entryContextMenuInfo = new EntryContextMenuInfo(header,
-                            res.getString(R.string.phoneLabelsGroup));
+                            res.getString(R.string.phoneLabelsGroup), dataItem.getMimeType(),
+                            dataItem.getId(), dataItem.isSuperPrimary());
                     if (sip.hasKindTypeColumn(kind)) {
                         text = SipAddress.getTypeLabel(res,
                                 sip.getKindTypeColumn(kind), sip.getLabel()).toString();
@@ -1375,6 +1451,7 @@
                     }
                     primaryContentDescription.append(header);
                     icon = res.getDrawable(R.drawable.ic_dialer_sip_black_24dp);
+                    iconResourceId = R.drawable.ic_dialer_sip_black_24dp;
                 }
             }
         } else if (dataItem instanceof StructuredNameDataItem) {
@@ -1403,19 +1480,25 @@
                                 intent.getDataString())) {
                             icon = res.getDrawable(
                                     R.drawable.ic_add_to_circles_black_24);
+                            iconResourceId = R.drawable.ic_add_to_circles_black_24;
                         } else {
                             icon = res.getDrawable(R.drawable.ic_google_plus_24dp);
+                            iconResourceId = R.drawable.ic_google_plus_24dp;
                         }
                         break;
                     case MIMETYPE_HANGOUTS:
                         if (INTENT_DATA_HANGOUTS_VIDEO.equals(intent.getDataString())) {
                             icon = res.getDrawable(R.drawable.ic_hangout_video_24dp);
+                            iconResourceId = R.drawable.ic_hangout_video_24dp;
                         } else {
                             icon = res.getDrawable(R.drawable.ic_hangout_24dp);
+                            iconResourceId = R.drawable.ic_hangout_24dp;
                         }
                         break;
                     default:
-                        entryContextMenuInfo = new EntryContextMenuInfo(header, mimetype);
+                        entryContextMenuInfo = new EntryContextMenuInfo(header, mimetype,
+                                dataItem.getMimeType(), dataItem.getId(),
+                                dataItem.isSuperPrimary());
                         icon = ResolveCache.getInstance(context).getIcon(
                                 dataItem.getMimeType(), intent);
                         // Call mutate to create a new Drawable.ConstantState for color filtering
@@ -1457,7 +1540,8 @@
         return new Entry(dataId, icon, header, subHeader, subHeaderIcon, text, textIcon,
                 primaryContentDescription.toString(), intent, alternateIcon, alternateIntent,
                 alternateContentDescription.toString(), shouldApplyColor, isEditable,
-                entryContextMenuInfo, thirdIcon, thirdIntent, thirdContentDescription);
+                entryContextMenuInfo, thirdIcon, thirdIntent, thirdContentDescription,
+                iconResourceId);
     }
 
     private List<Entry> dataItemsToEntries(List<DataItem> dataItems,
@@ -1640,7 +1724,8 @@
                     /* EntryContextMenuInfo = */ null,
                     /* thirdIcon = */ null,
                     /* thirdIntent = */ null,
-                    /* thirdContentDescription = */ null));
+                    /* thirdContentDescription = */ null,
+                    interaction.getIconResourceId()));
         }
         return entries;
     }
diff --git a/src/com/android/contacts/util/PhoneCapabilityTester.java b/src/com/android/contacts/util/PhoneCapabilityTester.java
index eec9916..b2d10be 100644
--- a/src/com/android/contacts/util/PhoneCapabilityTester.java
+++ b/src/com/android/contacts/util/PhoneCapabilityTester.java
@@ -27,7 +27,7 @@
 import android.provider.Telephony;
 import android.telephony.TelephonyManager;
 
-import com.android.contacts.common.CallUtil;
+import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.R;
 
 import java.util.List;
@@ -84,7 +84,7 @@
         if (smsPackage != null) {
             final PackageManager packageManager = context.getPackageManager();
             final Intent intent = new Intent(Intent.ACTION_SENDTO,
-                    Uri.fromParts(CallUtil.SCHEME_SMSTO, "", null));
+                    Uri.fromParts(ContactsUtils.SCHEME_SMSTO, "", null));
             final List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0);
             for (ResolveInfo resolveInfo : resolveInfos) {
                 if (smsPackage.equals(resolveInfo.activityInfo.packageName)) {
diff --git a/src/com/android/contacts/widget/MultiShrinkScroller.java b/src/com/android/contacts/widget/MultiShrinkScroller.java
index c5492d2..47b6d6f 100644
--- a/src/com/android/contacts/widget/MultiShrinkScroller.java
+++ b/src/com/android/contacts/widget/MultiShrinkScroller.java
@@ -347,6 +347,11 @@
                             largeTextLayoutParams.leftMargin - largeTextLayoutParams.rightMargin;
                     largeTextLayoutParams.gravity = Gravity.BOTTOM | Gravity.START;
                     mLargeTextView.setLayoutParams(largeTextLayoutParams);
+                } else {
+                    // Set the width of mLargeTextView as if it was nested inside
+                    // mPhotoViewContainer.
+                    mLargeTextView.setWidth(mPhotoViewContainer.getWidth()
+                            - 2 * mMaximumTitleMargin);
                 }
 
                 calculateCollapsedLargeTitlePadding();