Show text or icons for call log items.

The current code uses the small icons to show the type of call. The
design we want to implement allows for both icons and text to be
present, depending on the context.

This change adds a boolean flag to determine which one to use.

Change-Id: Ia3ec8bba44f46a4b4857654ffc0256e1af909741
diff --git a/res/layout/call_log_phone_call_details.xml b/res/layout/call_log_phone_call_details.xml
index 5da2773..5d167f1 100644
--- a/res/layout/call_log_phone_call_details.xml
+++ b/res/layout/call_log_phone_call_details.xml
@@ -16,21 +16,41 @@
 
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
     <LinearLayout
-        android:id="@+id/call_types"
+        android:id="@+id/call_type"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="?attr/call_detail_primary_text_color"
         android:layout_alignParentLeft="true"
         android:layout_alignParentBottom="true"
-    />
+    >
+        <LinearLayout
+            android:id="@+id/call_type_icons"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+        />
+        <TextView
+            android:id="@+id/call_type_name"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?attr/call_detail_primary_text_color"
+        />
+        <TextView
+            android:id="@+id/call_type_separator"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="?attr/call_detail_date_margin"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?attr/call_detail_primary_text_color"
+            android:text="@string/call_log_type_date_separator"
+        />
+    </LinearLayout>
     <TextView
         android:id="@+id/date"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textAppearance="?android:attr/textAppearanceSmall"
         android:textColor="?attr/call_detail_primary_text_color"
-        android:layout_toRightOf="@id/call_types"
+        android:layout_toRightOf="@id/call_type"
         android:layout_marginLeft="?attr/call_detail_date_margin"
         android:layout_alignParentBottom="true"
     />
@@ -41,7 +61,7 @@
         android:textAppearance="?android:attr/textAppearanceSmall"
         android:textColor="?attr/call_detail_primary_text_color"
         android:layout_alignParentLeft="true"
-        android:layout_above="@id/call_types"
+        android:layout_above="@id/call_type"
     />
     <TextView
         android:id="@+id/name"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e17648a..9e2e085 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -571,6 +571,9 @@
     <!-- Title for missed call details screen -->
     <string name="type_missed">Missed call</string>
 
+    <!-- Title for voicemail details screen -->
+    <string name="type_voicemail">Voicemail</string>
+
     <!-- Description for incoming calls going to voice mail vs. not -->
     <string name="actionIncomingCall">Incoming calls</string>
 
@@ -1601,4 +1604,7 @@
 
     <!-- Title of the notification of new voicemail. -->
     <string name="notification_voicemail_title">New voicemail</string>
+
+    <!-- The separator between the call type text and the date in the call log [CHAR LIMIT=3] -->
+    <string name="call_log_type_date_separator">/</string>
 </resources>
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index 1200cdf..5a795e2 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -305,7 +305,7 @@
                 }
                 mPhoneCallDetailsHelper.setPhoneCallDetails(mPhoneCallDetailsViews,
                         new PhoneCallDetails(numberText, callType, date, nameText, numberType,
-                                numberLabel));
+                                numberLabel), false);
 
                 loadContactPhotos(photoId);
             } else {
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
index f884df7..b52dacb 100644
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ b/src/com/android/contacts/PhoneCallDetailsHelper.java
@@ -47,6 +47,14 @@
     private final Drawable mMissedDrawable;
     /** Icon for voicemails. */
     private final Drawable mVoicemailDrawable;
+    /** Name used to identify incoming calls. */
+    private final String mIncomingName;
+    /** Name used to identify outgoing calls. */
+    private final String mOutgoingName;
+    /** Name used to identify missed calls. */
+    private final String mMissedName;
+    /** Name used to identify voicemail calls. */
+    private final String mVoicemailName;
     /** The injected current time in milliseconds since the epoch. Used only by tests. */
     private Long mCurrentTimeMillisForTest;
 
@@ -67,28 +75,76 @@
         mOutgoingDrawable = outgoingDrawable;
         mMissedDrawable = missedDrawable;
         mVoicemailDrawable = voicemailDrawable;
+        // Cache these values so that we do not need to look them up each time.
+        mIncomingName = mResources.getString(R.string.type_incoming);
+        mOutgoingName = mResources.getString(R.string.type_outgoing);
+        mMissedName = mResources.getString(R.string.type_missed);
+        mVoicemailName = mResources.getString(R.string.type_voicemail);
     }
 
     /** Fills the call details views with content. */
-    public void setPhoneCallDetails(PhoneCallDetailsViews views, PhoneCallDetails details) {
-        Drawable callTypeDrawable = null;
-        switch (details.callType) {
-            case Calls.INCOMING_TYPE:
-                callTypeDrawable = mIncomingDrawable;
-                break;
+    public void setPhoneCallDetails(PhoneCallDetailsViews views, PhoneCallDetails details,
+            boolean useIcons) {
+        if (useIcons) {
+            final Drawable callTypeDrawable;
+            switch (details.callType) {
+                case Calls.INCOMING_TYPE:
+                    callTypeDrawable = mIncomingDrawable;
+                    break;
 
-            case Calls.OUTGOING_TYPE:
-                callTypeDrawable = mOutgoingDrawable;
-                break;
+                case Calls.OUTGOING_TYPE:
+                    callTypeDrawable = mOutgoingDrawable;
+                    break;
 
-            case Calls.MISSED_TYPE:
-                callTypeDrawable = mMissedDrawable;
-                break;
+                case Calls.MISSED_TYPE:
+                    callTypeDrawable = mMissedDrawable;
+                    break;
 
-            case Calls.VOICEMAIL_TYPE:
-                callTypeDrawable = mVoicemailDrawable;
-                break;
+                case Calls.VOICEMAIL_TYPE:
+                    callTypeDrawable = mVoicemailDrawable;
+                    break;
+
+                default:
+                    throw new IllegalArgumentException("invalid call type: " + details.callType);
+            }
+            ImageView callTypeImage = new ImageView(mContext);
+            callTypeImage.setImageDrawable(callTypeDrawable);
+            views.callTypeIcons.removeAllViews();
+            views.callTypeIcons.addView(callTypeImage);
+
+            views.callTypeIcons.setVisibility(View.VISIBLE);
+            views.callTypeText.setVisibility(View.GONE);
+            views.callTypeSeparator.setVisibility(View.GONE);
+        } else {
+            String callTypeName;
+            switch (details.callType) {
+                case Calls.INCOMING_TYPE:
+                    callTypeName = mIncomingName;
+                    break;
+
+                case Calls.OUTGOING_TYPE:
+                    callTypeName = mOutgoingName;
+                    break;
+
+                case Calls.MISSED_TYPE:
+                    callTypeName = mMissedName;
+                    break;
+
+                case Calls.VOICEMAIL_TYPE:
+                    callTypeName = mVoicemailName;
+                    break;
+
+                default:
+                    throw new IllegalArgumentException("invalid call type: " + details.callType);
+            }
+            views.callTypeText.setText(callTypeName);
+            views.callTypeIcons.removeAllViews();
+
+            views.callTypeText.setVisibility(View.VISIBLE);
+            views.callTypeSeparator.setVisibility(View.VISIBLE);
+            views.callTypeIcons.setVisibility(View.GONE);
         }
+
         CharSequence shortDateText =
             DateUtils.getRelativeTimeSpanString(details.date,
                     getCurrentTimeMillis(),
@@ -121,11 +177,6 @@
             }
         }
 
-        ImageView callTypeImage = new ImageView(mContext);
-        callTypeImage.setImageDrawable(callTypeDrawable);
-        views.callTypesLayout.removeAllViews();
-        views.callTypesLayout.addView(callTypeImage);
-
         views.dateView.setText(shortDateText);
         views.dateView.setVisibility(View.VISIBLE);
         views.nameView.setText(nameText);
diff --git a/src/com/android/contacts/PhoneCallDetailsViews.java b/src/com/android/contacts/PhoneCallDetailsViews.java
index 483ec65..7453af0 100644
--- a/src/com/android/contacts/PhoneCallDetailsViews.java
+++ b/src/com/android/contacts/PhoneCallDetailsViews.java
@@ -25,14 +25,18 @@
  */
 public final class PhoneCallDetailsViews {
     public final TextView nameView;
-    public final LinearLayout callTypesLayout;
+    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 callTypesLayout,
-            TextView dateView, TextView numberView) {
+    private PhoneCallDetailsViews(TextView nameView, LinearLayout callTypeIcons,
+            TextView callTypeText, View callTypeSeparator, TextView dateView, TextView numberView) {
         this.nameView = nameView;
-        this.callTypesLayout = callTypesLayout;
+        this.callTypeIcons = callTypeIcons;
+        this.callTypeText = callTypeText;
+        this.callTypeSeparator = callTypeSeparator;
         this.dateView = dateView;
         this.numberView = numberView;
     }
@@ -46,13 +50,17 @@
      */
     public static PhoneCallDetailsViews fromView(View view) {
         return new PhoneCallDetailsViews((TextView) view.findViewById(R.id.name),
-                (LinearLayout) view.findViewById(R.id.call_types),
+                (LinearLayout) view.findViewById(R.id.call_type_icons),
+                (TextView) view.findViewById(R.id.call_type_name),
+                view.findViewById(R.id.call_type_separator),
                 (TextView) view.findViewById(R.id.date),
                 (TextView) view.findViewById(R.id.number));
     }
 
     public static PhoneCallDetailsViews createForTest(TextView nameView,
-            LinearLayout callTypesLayout, TextView dateView, TextView numberView) {
-        return new PhoneCallDetailsViews(nameView, callTypesLayout, dateView, numberView);
+            LinearLayout callTypeIcons, TextView callTypeText, View callTypeSeparator,
+            TextView dateView, TextView numberView) {
+        return new PhoneCallDetailsViews(nameView, callTypeIcons, callTypeText, callTypeSeparator,
+                dateView, numberView);
     }
 }
diff --git a/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java b/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
index 994f2cc..37e16a3 100644
--- a/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
+++ b/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
@@ -25,6 +25,7 @@
 import android.graphics.drawable.Drawable;
 import android.provider.CallLog.Calls;
 import android.test.AndroidTestCase;
+import android.view.View;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -64,7 +65,8 @@
                 TEST_VOICEMAIL_NUMBER, TEST_INCOMING_DRAWABLE, TEST_OUTGOING_DRAWABLE,
                 TEST_MISSED_DRAWABLE, TEST_VOICEMAIL_DRAWABLE);
         mViews = PhoneCallDetailsViews.createForTest(new TextView(context),
-                new LinearLayout(context), new TextView(context), new TextView(context));
+                new LinearLayout(context), new TextView(context), new View(context),
+                new TextView(context), new TextView(context));
     }
 
     @Override
@@ -126,20 +128,40 @@
         }
     }
 
-    public void testSetPhoneCallDetails_CallType() {
-        setPhoneCallDetailsWithCallType(Calls.INCOMING_TYPE);
+    public void testSetPhoneCallDetails_CallTypeIcons() {
+        setPhoneCallDetailsWithCallType(Calls.INCOMING_TYPE, true);
         assertCallTypeIconsEquals(TEST_INCOMING_DRAWABLE);
 
-        setPhoneCallDetailsWithCallType(Calls.OUTGOING_TYPE);
+        setPhoneCallDetailsWithCallType(Calls.OUTGOING_TYPE, true);
         assertCallTypeIconsEquals(TEST_OUTGOING_DRAWABLE);
 
-        setPhoneCallDetailsWithCallType(Calls.MISSED_TYPE);
+        setPhoneCallDetailsWithCallType(Calls.MISSED_TYPE, true);
         assertCallTypeIconsEquals(TEST_MISSED_DRAWABLE);
 
-        setPhoneCallDetailsWithCallType(Calls.VOICEMAIL_TYPE);
+        setPhoneCallDetailsWithCallType(Calls.VOICEMAIL_TYPE, true);
         assertCallTypeIconsEquals(TEST_VOICEMAIL_DRAWABLE);
     }
 
+    public void testSetPhoneCallDetails_CallTypeText() {
+        LocaleTestUtils localeTestUtils = new LocaleTestUtils(getContext());
+        localeTestUtils.setLocale(Locale.US);
+        try {
+            setPhoneCallDetailsWithCallType(Calls.INCOMING_TYPE, false);
+            assertCallTypeTextEquals("Incoming call");
+
+            setPhoneCallDetailsWithCallType(Calls.OUTGOING_TYPE, false);
+            assertCallTypeTextEquals("Outgoing call");
+
+            setPhoneCallDetailsWithCallType(Calls.MISSED_TYPE, false);
+            assertCallTypeTextEquals("Missed call");
+
+            setPhoneCallDetailsWithCallType(Calls.VOICEMAIL_TYPE, false);
+            assertCallTypeTextEquals("Voicemail");
+        } finally {
+            localeTestUtils.restoreLocale();
+        }
+    }
+
     /** Asserts that the name text field contains the value of the given string resource. */
     private void assertNameEqualsResource(int resId) {
         assertNameEquals(getContext().getString(resId));
@@ -155,30 +177,44 @@
         assertEquals(text, mViews.dateView.getText().toString());
     }
 
-    /** Asserts that the call type linear layout contains the images with the given drawables. */
+    /** Asserts that the call type contains the images with the given drawables. */
     private void assertCallTypeIconsEquals(Drawable... drawables) {
-        assertEquals(drawables.length, mViews.callTypesLayout.getChildCount());
+        assertEquals(drawables.length, mViews.callTypeIcons.getChildCount());
         for (int index = 0; index < drawables.length; ++index) {
             Drawable drawable = drawables[index];
-            ImageView imageView = (ImageView) mViews.callTypesLayout.getChildAt(index);
+            ImageView imageView = (ImageView) mViews.callTypeIcons.getChildAt(index);
             assertEquals(drawable, imageView.getDrawable());
         }
+        assertEquals(View.VISIBLE, mViews.callTypeIcons.getVisibility());
+        assertEquals(View.GONE, mViews.callTypeText.getVisibility());
+        assertEquals(View.GONE, mViews.callTypeSeparator.getVisibility());
+    }
+
+    /** Asserts that the call type contains the given text. */
+    private void assertCallTypeTextEquals(String text) {
+        assertEquals(text, mViews.callTypeText.getText().toString());
+        assertEquals(View.GONE, mViews.callTypeIcons.getVisibility());
+        assertEquals(View.VISIBLE, mViews.callTypeText.getVisibility());
+        assertEquals(View.VISIBLE, mViews.callTypeSeparator.getVisibility());
     }
 
     /** Sets the phone call details with default values and the given number. */
     private void setPhoneCallDetailsWithNumber(String number) {
         mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(number, Calls.INCOMING_TYPE, TEST_DATE));
+                new PhoneCallDetails(number, Calls.INCOMING_TYPE, TEST_DATE),
+                false);
     }
 
     /** Sets the phone call details with default values and the given date. */
     private void setPhoneCallDetailsWithDate(long date) {
         mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(TEST_NUMBER, Calls.INCOMING_TYPE, date));
+                new PhoneCallDetails(TEST_NUMBER, Calls.INCOMING_TYPE, date),
+                false);
     }
 
     /** Sets the phone call details with default values and the given call type. */
-    private void setPhoneCallDetailsWithCallType(int callType) {
-        mHelper.setPhoneCallDetails(mViews, new PhoneCallDetails(TEST_NUMBER, callType, TEST_DATE));
+    private void setPhoneCallDetailsWithCallType(int callType, boolean useIcons) {
+        mHelper.setPhoneCallDetails(mViews, new PhoneCallDetails(TEST_NUMBER, callType, TEST_DATE),
+                useIcons);
     }
 }