Updates to visual design.

- Use sizes from spec.
- Show only contact name in call details header.
- Add spacing between contact icons.
- Updates a few assets.
- Add contentDescription to a number of elements.
- Use @dimen instead of ?attr for dimensions.

Bug: 4989127
Bug: 4989128
Bug: 5039572
Bug: 5038409
Change-Id: I3a59af44c77f739185feef39afd57193b5e0176a
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index 68c9f61..d732d66 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -147,13 +147,9 @@
         mResources = getResources();
 
         mPhoneCallDetailsViews = PhoneCallDetailsViews.fromView(getWindow().getDecorView());
-        mCallTypeHelper = new CallTypeHelper(getResources(),
-                getResources().getDrawable(R.drawable.ic_call_incoming_holo_dark),
-                getResources().getDrawable(R.drawable.ic_call_outgoing_holo_dark),
-                getResources().getDrawable(R.drawable.ic_call_missed_holo_dark),
-                getResources().getDrawable(R.drawable.ic_call_voicemail_holo_dark));
+        mCallTypeHelper = new CallTypeHelper(getResources(), mInflater);
         mPhoneNumberHelper = new PhoneNumberHelper(mResources, getVoicemailNumber());
-        mPhoneCallDetailsHelper = new PhoneCallDetailsHelper(this, mResources, mCallTypeHelper,
+        mPhoneCallDetailsHelper = new PhoneCallDetailsHelper(mResources, mCallTypeHelper,
                 mPhoneNumberHelper);
         mVoicemailStatusHelper = new VoicemailStatusHelperImpl();
         mAsyncQueryHandler = new CallDetailActivityQueryHandler(this);
@@ -286,7 +282,7 @@
 
         // Set the details header, based on the first phone call.
         mPhoneCallDetailsHelper.setPhoneCallDetails(mPhoneCallDetailsViews,
-                details[0], false, false);
+                details[0], false, false, true);
 
         // Cache the details about the phone number.
         final Uri numberCallUri = mPhoneNumberHelper.getCallUri(mNumber);
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
index b2810bc..019e608 100644
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ b/src/com/android/contacts/PhoneCallDetailsHelper.java
@@ -20,7 +20,6 @@
 import com.android.contacts.calllog.PhoneNumberHelper;
 import com.android.contacts.format.FormatUtils;
 
-import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Typeface;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
@@ -29,7 +28,6 @@
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.view.View;
-import android.widget.ImageView;
 
 /**
  * Helper class to fill in the views in {@link PhoneCallDetailsViews}.
@@ -38,7 +36,6 @@
     /** The maximum number of icons will be shown to represent the call types in a group. */
     private static final int MAX_CALL_TYPE_ICONS = 3;
 
-    private final Context mContext;
     private final Resources mResources;
     /** The injected current time in milliseconds since the epoch. Used only by tests. */
     private Long mCurrentTimeMillisForTest;
@@ -53,9 +50,8 @@
      *
      * @param resources used to look up strings
      */
-    public PhoneCallDetailsHelper(Context context, Resources resources,
-            CallTypeHelper callTypeHelper, PhoneNumberHelper phoneNumberHelper) {
-        mContext = context;
+    public PhoneCallDetailsHelper(Resources resources, CallTypeHelper callTypeHelper,
+            PhoneNumberHelper phoneNumberHelper) {
         mResources = resources;
         mCallTypeHelper = callTypeHelper;
         mPhoneNumberHelper = phoneNumberHelper;
@@ -63,15 +59,12 @@
 
     /** Fills the call details views with content. */
     public void setPhoneCallDetails(PhoneCallDetailsViews views, PhoneCallDetails details,
-            boolean useIcons, boolean isHighlighted) {
+            boolean useIcons, boolean isHighlighted, boolean nameOnly) {
         if (useIcons) {
             views.callTypeIcons.removeAllViews();
             int count = details.callTypes.length;
             for (int index = 0; index < count && index < MAX_CALL_TYPE_ICONS; ++index) {
-                int callType = details.callTypes[index];
-                ImageView callTypeImage = new ImageView(mContext);
-                callTypeImage.setImageDrawable(mCallTypeHelper.getCallTypeDrawable(callType));
-                views.callTypeIcons.addView(callTypeImage);
+                mCallTypeHelper.inflateCallTypeIcon(details.callTypes[index], views.callTypeIcons);
             }
             views.callTypeIcons.setVisibility(View.VISIBLE);
             if (count > MAX_CALL_TYPE_ICONS) {
@@ -144,6 +137,10 @@
         } else {
             views.numberView.setVisibility(View.GONE);
         }
+
+        // Hide the rest if not visible.
+        views.callTypeView.setVisibility(nameOnly ? View.GONE : View.VISIBLE);
+        views.numberView.setVisibility(nameOnly ? View.GONE : View.VISIBLE);
     }
 
     public void setCurrentTimeForTest(long currentTimeMillis) {
diff --git a/src/com/android/contacts/PhoneCallDetailsViews.java b/src/com/android/contacts/PhoneCallDetailsViews.java
index 7453af0..19e931f 100644
--- a/src/com/android/contacts/PhoneCallDetailsViews.java
+++ b/src/com/android/contacts/PhoneCallDetailsViews.java
@@ -16,6 +16,7 @@
 
 package com.android.contacts;
 
+import android.content.Context;
 import android.view.View;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -25,15 +26,17 @@
  */
 public final class PhoneCallDetailsViews {
     public final TextView nameView;
+    public final View callTypeView;
     public final LinearLayout callTypeIcons;
     public final TextView callTypeText;
     public final View callTypeSeparator;
     public final TextView dateView;
     public final TextView numberView;
 
-    private PhoneCallDetailsViews(TextView nameView, LinearLayout callTypeIcons,
+    private PhoneCallDetailsViews(TextView nameView, View callTypeView, LinearLayout callTypeIcons,
             TextView callTypeText, View callTypeSeparator, TextView dateView, TextView numberView) {
         this.nameView = nameView;
+        this.callTypeView = callTypeView;
         this.callTypeIcons = callTypeIcons;
         this.callTypeText = callTypeText;
         this.callTypeSeparator = callTypeSeparator;
@@ -50,6 +53,7 @@
      */
     public static PhoneCallDetailsViews fromView(View view) {
         return new PhoneCallDetailsViews((TextView) view.findViewById(R.id.name),
+                view.findViewById(R.id.call_type),
                 (LinearLayout) view.findViewById(R.id.call_type_icons),
                 (TextView) view.findViewById(R.id.call_type_name),
                 view.findViewById(R.id.call_type_separator),
@@ -57,10 +61,14 @@
                 (TextView) view.findViewById(R.id.number));
     }
 
-    public static PhoneCallDetailsViews createForTest(TextView nameView,
-            LinearLayout callTypeIcons, TextView callTypeText, View callTypeSeparator,
-            TextView dateView, TextView numberView) {
-        return new PhoneCallDetailsViews(nameView, callTypeIcons, callTypeText, callTypeSeparator,
-                dateView, numberView);
+    public static PhoneCallDetailsViews createForTest(Context context) {
+        return new PhoneCallDetailsViews(
+                new TextView(context),
+                new View(context),
+                new LinearLayout(context),
+                new TextView(context),
+                new View(context),
+                new TextView(context),
+                new TextView(context));
     }
 }
diff --git a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
index ae81a79..e55020c 100644
--- a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
+++ b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
@@ -26,7 +26,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.BaseAdapter;
-import android.widget.ImageView;
+import android.widget.FrameLayout;
 import android.widget.TextView;
 
 /**
@@ -69,13 +69,14 @@
         }
 
         PhoneCallDetails details = mPhoneCallDetails[position];
-        ImageView callTypeIconView = (ImageView) convertView.findViewById(R.id.call_type_icon);
+        FrameLayout callTypeIconView = (FrameLayout) convertView.findViewById(R.id.call_type_icon);
         TextView callTypeTextView = (TextView) convertView.findViewById(R.id.call_type_text);
         TextView dateView = (TextView) convertView.findViewById(R.id.date);
         TextView durationView = (TextView) convertView.findViewById(R.id.duration);
 
         int callType = details.callTypes[0];
-        callTypeIconView.setImageDrawable(mCallTypeHelper.getCallTypeDrawable(callType));
+        callTypeIconView.removeAllViews();
+        mCallTypeHelper.inflateCallTypeIcon(callType, callTypeIconView);
         callTypeTextView.setText(mCallTypeHelper.getCallTypeText(callType));
         // Set the date.
         CharSequence dateValue = DateUtils.formatDateRange(mContext, details.date, details.date,
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 9f64815..f059292 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -312,11 +312,8 @@
             mPreDrawListener = null;
 
             Resources resources = getResources();
-            CallTypeHelper callTypeHelper = new CallTypeHelper(resources,
-                    resources.getDrawable(R.drawable.ic_call_incoming_holo_dark),
-                    resources.getDrawable(R.drawable.ic_call_outgoing_holo_dark),
-                    resources.getDrawable(R.drawable.ic_call_missed_holo_dark),
-                    resources.getDrawable(R.drawable.ic_call_voicemail_holo_dark));
+            LayoutInflater layoutInflater = getActivity().getLayoutInflater();
+            CallTypeHelper callTypeHelper = new CallTypeHelper(resources, layoutInflater);
             Drawable callDrawable = resources.getDrawable(R.drawable.ic_dial_action_call);
             Drawable playDrawable = resources.getDrawable(
                     R.drawable.ic_call_log_list_action_play);
@@ -324,7 +321,7 @@
             mContactPhotoManager = ContactPhotoManager.getInstance(getActivity());
             mPhoneNumberHelper = new PhoneNumberHelper(getResources(), mVoiceMailNumber);
             PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
-                    getActivity(), resources, callTypeHelper, mPhoneNumberHelper);
+                    resources, callTypeHelper, mPhoneNumberHelper);
             mCallLogViewsHelper =
                     new CallLogListItemHelper(phoneCallDetailsHelper, mPhoneNumberHelper);
             mCallLogGroupBuilder = new CallLogGroupBuilder(this);
@@ -659,7 +656,6 @@
             // Get the views to bind to.
             CallLogListItemViews views = CallLogListItemViews.fromView(view);
             views.callView.setOnClickListener(this);
-            views.playView.setOnClickListener(this);
             view.setTag(views);
         }
 
@@ -697,21 +693,18 @@
             final String formattedNumber;
             final String countryIso = c.getString(CallLogQuery.COUNTRY_ISO);
 
-            // Store away the number so we can call it directly if you click on the call icon.
-            if (!TextUtils.isEmpty(number)) {
-                views.callView.setTag(IntentProvider.getReturnCallIntentProvider(number));
-            } else {
-                views.callView.setTag(null);
-            }
-
             // Store away the voicemail information so we can play it directly.
             if (callType == Calls.VOICEMAIL_TYPE) {
                 String voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI);
                 final long rowId = c.getLong(CallLogQuery.ID);
-                views.playView.setTag(
+                views.callView.setTag(
                         IntentProvider.getPlayVoicemailIntentProvider(rowId, voicemailUri));
+            } else if (!TextUtils.isEmpty(number)) {
+                // Store away the number so we can call it directly if you click on the call icon.
+                views.callView.setTag(IntentProvider.getReturnCallIntentProvider(number));
             } else {
-                views.playView.setTag(null);
+                // No action enabled.
+                views.callView.setTag(null);
             }
 
             // Lookup contacts with this number
diff --git a/src/com/android/contacts/calllog/CallLogListItemHelper.java b/src/com/android/contacts/calllog/CallLogListItemHelper.java
index d4f2291..d8184d2 100644
--- a/src/com/android/contacts/calllog/CallLogListItemHelper.java
+++ b/src/com/android/contacts/calllog/CallLogListItemHelper.java
@@ -54,19 +54,27 @@
     public void setPhoneCallDetails(CallLogListItemViews views, PhoneCallDetails details,
             boolean useIcons, boolean isHighlighted) {
         mPhoneCallDetailsHelper.setPhoneCallDetails(views.phoneCallDetailsViews, details, useIcons,
-                isHighlighted);
-        boolean callVisible = mPhoneNumberHelper.canPlaceCallsTo(details.number);
-        boolean playVisible = details.callTypes[0] == Calls.VOICEMAIL_TYPE;
+                isHighlighted, false);
+        boolean canCall = mPhoneNumberHelper.canPlaceCallsTo(details.number);
+        boolean canPlay = details.callTypes[0] == Calls.VOICEMAIL_TYPE;
 
-        if (callVisible || playVisible) {
-            // At least one is visible. Keep the divider and the space for the call button.
-            views.callView.setVisibility(callVisible ? View.VISIBLE : View.INVISIBLE);
-            views.playView.setVisibility(playVisible ? View.VISIBLE : View.GONE);
+        if (canPlay) {
+            // Playback action takes preference.
+            views.callView.setVisibility(View.GONE);
+            views.playView.setVisibility(View.VISIBLE);
+            views.unheardView.setVisibility(isHighlighted ? View.VISIBLE : View.GONE);
+            views.dividerView.setVisibility(View.VISIBLE);
+        } else if (canCall) {
+            // Call is the main action.
+            views.callView.setVisibility(View.VISIBLE);
+            views.playView.setVisibility(View.GONE);
+            views.unheardView.setVisibility(View.GONE);
             views.dividerView.setVisibility(View.VISIBLE);
         } else {
-            // Neither is visible, remove all of them entirely.
+            // No action available.
             views.callView.setVisibility(View.GONE);
             views.playView.setVisibility(View.GONE);
+            views.unheardView.setVisibility(View.GONE);
             views.dividerView.setVisibility(View.GONE);
         }
     }
diff --git a/src/com/android/contacts/calllog/CallLogListItemViews.java b/src/com/android/contacts/calllog/CallLogListItemViews.java
index b66d84e..51bc535 100644
--- a/src/com/android/contacts/calllog/CallLogListItemViews.java
+++ b/src/com/android/contacts/calllog/CallLogListItemViews.java
@@ -19,8 +19,8 @@
 import com.android.contacts.PhoneCallDetailsViews;
 import com.android.contacts.R;
 
+import android.content.Context;
 import android.view.View;
-import android.widget.ImageView;
 import android.widget.QuickContactBadge;
 import android.widget.TextView;
 
@@ -31,9 +31,11 @@
     /** The quick contact badge for the contact. Only present for group and stand alone entries. */
     public final QuickContactBadge photoView;
     /** The main action button on the entry. */
-    public final ImageView callView;
+    public final View callView;
     /** The play action button used for voicemail. */
-    public final ImageView playView;
+    public final View playView;
+    /** The icon used for unheard voicemail. */
+    public final View unheardView;
     /** The divider between callView and playView. */
     public final View dividerView;
     /** The details of the phone call. */
@@ -45,12 +47,14 @@
     /** The text of the header in a stand-alone row, or null for other types of rows. */
     public final TextView listHeaderTextView;
 
-    private CallLogListItemViews(QuickContactBadge photoView, ImageView callView,
-            ImageView playView, View dividerView, PhoneCallDetailsViews phoneCallDetailsViews,
-            View listItemView, View listHeaderView, TextView listHeaderTextView) {
+    private CallLogListItemViews(QuickContactBadge photoView, View callView,
+            View playView, View unheardView, View dividerView,
+            PhoneCallDetailsViews phoneCallDetailsViews, View listItemView, View listHeaderView,
+            TextView listHeaderTextView) {
         this.photoView = photoView;
         this.callView = callView;
         this.playView = playView;
+        this.unheardView = unheardView;
         this.dividerView = dividerView;
         this.phoneCallDetailsViews = phoneCallDetailsViews;
         this.listItemView = listItemView;
@@ -60,8 +64,9 @@
 
     public static CallLogListItemViews fromView(View view) {
         return new CallLogListItemViews((QuickContactBadge) view.findViewById(R.id.contact_photo),
-                (ImageView) view.findViewById(R.id.call_icon),
-                (ImageView) view.findViewById(R.id.play_icon),
+                view.findViewById(R.id.call_icon),
+                view.findViewById(R.id.play_icon),
+                view.findViewById(R.id.unheard_icon),
                 view.findViewById(R.id.divider),
                 PhoneCallDetailsViews.fromView(view),
                 view.findViewById(R.id.call_log_item),
@@ -69,12 +74,16 @@
                 (TextView) view.findViewById(R.id.call_log_header_text));
     }
 
-    public static CallLogListItemViews createForTest(QuickContactBadge photoView,
-            ImageView callView, ImageView playView, View dividerView,
-            PhoneCallDetailsViews phoneCallDetailsViews, View standAloneItemView,
-            View standAloneHeaderView, TextView standAloneHeaderTextView) {
-        return new CallLogListItemViews(photoView, callView, playView, dividerView,
-                phoneCallDetailsViews, standAloneItemView, standAloneHeaderView,
-                standAloneHeaderTextView);
+    public static CallLogListItemViews createForTest(Context context) {
+        return new CallLogListItemViews(
+                new QuickContactBadge(context),
+                new View(context),
+                new View(context),
+                new View(context),
+                new View(context),
+                PhoneCallDetailsViews.createForTest(context),
+                new View(context),
+                new View(context),
+                new TextView(context));
     }
 }
diff --git a/src/com/android/contacts/calllog/CallTypeHelper.java b/src/com/android/contacts/calllog/CallTypeHelper.java
index 0c2068e..465e2bf 100644
--- a/src/com/android/contacts/calllog/CallTypeHelper.java
+++ b/src/com/android/contacts/calllog/CallTypeHelper.java
@@ -20,25 +20,21 @@
 
 import android.content.res.Resources;
 import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
 import android.provider.CallLog.Calls;
 import android.text.SpannableString;
 import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
 import android.text.style.StyleSpan;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
 
 /**
  * Helper class to perform operations related to call types.
  */
 public class CallTypeHelper {
-    /** Icon for incoming calls. */
-    private final Drawable mIncomingDrawable;
-    /** Icon for outgoing calls. */
-    private final Drawable mOutgoingDrawable;
-    /** Icon for missed calls. */
-    private final Drawable mMissedDrawable;
-    /** Icon for voicemails. */
-    private final Drawable mVoicemailDrawable;
+    /** Used to create the views for the call types. */
+    private final LayoutInflater mLayoutInflater;
     /** Name used to identify incoming calls. */
     private final CharSequence mIncomingName;
     /** Name used to identify outgoing calls. */
@@ -52,12 +48,8 @@
     /** Name used to identify new voicemail calls. */
     private final CharSequence mNewVoicemailName;
 
-    public CallTypeHelper(Resources resources, Drawable incomingDrawable, Drawable outgoingDrawable,
-            Drawable missedDrawable, Drawable voicemailDrawable) {
-        mIncomingDrawable = incomingDrawable;
-        mOutgoingDrawable = outgoingDrawable;
-        mMissedDrawable = missedDrawable;
-        mVoicemailDrawable = voicemailDrawable;
+    public CallTypeHelper(Resources resources, LayoutInflater layoutInflater) {
+        mLayoutInflater = layoutInflater;
         // Cache these values so that we do not need to look them up each time.
         mIncomingName = resources.getString(R.string.type_incoming);
         mOutgoingName = resources.getString(R.string.type_outgoing);
@@ -111,20 +103,20 @@
         }
     }
 
-    /** Returns the drawable of the icon associated with the given call type. */
-    public Drawable getCallTypeDrawable(int callType) {
+    /** Returns a new view for the icon to be used to represent a given call type. */
+    public View inflateCallTypeIcon(int callType, ViewGroup root) {
         switch (callType) {
             case Calls.INCOMING_TYPE:
-                return mIncomingDrawable;
+                return mLayoutInflater.inflate(R.layout.call_log_incoming_call_icon, root);
 
             case Calls.OUTGOING_TYPE:
-                return mOutgoingDrawable;
+                return mLayoutInflater.inflate(R.layout.call_log_outgoing_call_icon, root);
 
             case Calls.MISSED_TYPE:
-                return mMissedDrawable;
+                return mLayoutInflater.inflate(R.layout.call_log_missed_call_icon, root);
 
             case Calls.VOICEMAIL_TYPE:
-                return mVoicemailDrawable;
+                return mLayoutInflater.inflate(R.layout.call_log_voicemail_icon, root);
 
             default:
                 throw new IllegalArgumentException("invalid call type: " + callType);