Collapsed and expanded voicemail cards show duration.

The duration of the voicemail is appended to the date in a MM:SS format.

BUG=25728257

Change-Id: I9c3e392336877c2ca69707e14c6ab2eed6f2e7c6
(cherry picked from commit 3f70c27d80b2e3176159f561248f95612d66afe2)
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6d2bd5e..34fd2e5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -455,6 +455,12 @@
          The date will be replaced by 'Today' for voicemails created on the current day. For example: Today at 2:49 PM -->
     <string name="voicemailCallLogDateTimeFormat"><xliff:g id="date" example="Jul 25, 2014">%1$s</xliff:g> at <xliff:g id="time" example="2:49 PM">%2$s</xliff:g></string>
 
+    <!-- Format for duration of voicemails which are displayed when viewing voicemail logs. For example "01:22" -->
+    <string name="voicemailDurationFormat"><xliff:g id="minutes" example="10">%1$02d</xliff:g>:<xliff:g id="seconds" example="20">%2$02d</xliff:g></string>
+
+    <!-- A format string used for displaying the date, time and duration for a voicemail call log. For example: Jul 25, 2014 at 2:49 PM • 00:34 -->
+    <string name="voicemailCallLogDateTimeFormatWithDuration"><xliff:g id="dateAndTime" example="Jul 25, 2014 at 2:49PM">%1$s</xliff:g> \u2022 <xliff:g id="duration" example="01:22">%2$s</xliff:g></string>
+
     <!-- Dialog message which is shown when the user tries to make a phone call
          to prohibited phone numbers [CHAR LIMIT=NONE] -->
     <string name="dialog_phone_call_prohibited_message" msgid="4313552620858880999">Can\'t call this number</string>
diff --git a/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java b/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java
index e6b8508..be02e4c 100644
--- a/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java
+++ b/src/com/android/dialer/calllog/PhoneCallDetailsHelper.java
@@ -40,6 +40,7 @@
 
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Helper class to fill in the views in {@link PhoneCallDetailsViews}.
@@ -110,10 +111,8 @@
             callCount = null;
         }
 
-        CharSequence callLocationAndDate = getCallLocationAndDate(details);
-
-        // Set the call count, location and date.
-        setCallCountAndDate(views, callCount, callLocationAndDate);
+        // Set the call count, location, date and if voicemail, set the duration.
+        setDetailText(views, callCount, details);
 
         // Set the account label if it exists.
         String accountLabel = mCallLogCache.getAccountLabel(details.accountHandle);
@@ -314,10 +313,11 @@
         }
     }
 
-    /** Sets the call count and date. */
-    private void setCallCountAndDate(PhoneCallDetailsViews views, Integer callCount,
-            CharSequence dateText) {
+    /** Sets the call count, date, and if it is a voicemail, sets the duration. */
+    private void setDetailText(PhoneCallDetailsViews views, Integer callCount,
+                               PhoneCallDetails details) {
         // Combine the count (if present) and the date.
+        CharSequence dateText = getCallLocationAndDate(details);
         final CharSequence text;
         if (callCount != null) {
             text = mResources.getString(
@@ -326,6 +326,22 @@
             text = dateText;
         }
 
-        views.callLocationAndDate.setText(text);
+        if (details.callTypes[0] == Calls.VOICEMAIL_TYPE) {
+            views.callLocationAndDate.setText(mResources.getString(
+                    R.string.voicemailCallLogDateTimeFormatWithDuration, text,
+                    getVoicemailDuration(details)));
+        } else {
+            views.callLocationAndDate.setText(text);
+        }
+
+    }
+
+    private String getVoicemailDuration(PhoneCallDetails details) {
+        long minutes = TimeUnit.SECONDS.toMinutes(details.duration);
+        long seconds = details.duration - TimeUnit.MINUTES.toSeconds(minutes);
+        if (minutes > 99) {
+            minutes = 99;
+        }
+        return mResources.getString(R.string.voicemailDurationFormat, minutes, seconds);
     }
 }
diff --git a/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java b/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java
index b6202b9..4e00a46 100644
--- a/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java
+++ b/tests/src/com/android/dialer/calllog/PhoneCallDetailsHelperTest.java
@@ -34,6 +34,8 @@
 
 import java.util.GregorianCalendar;
 import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Unit tests for {@link PhoneCallDetailsHelper}.
@@ -141,7 +143,27 @@
 
     public void testVoicemailLocationNotShownWithDate() {
         setVoicemailPhoneCallDetailsWithDate(TEST_DATE);
-        assertLocationAndDateExactEquals("Jun 3 at 1:00 PM");
+        assertLocationAndDateExactEquals("Jun 3 at 1:00 PM • 99:20");
+    }
+
+    public void testVoicemailDuration() {
+        setVoicemailPhoneCallDetailsWithDuration(100);
+        assertDurationExactEquals("01:40");
+    }
+
+    public void testVoicemailDuration_Capped() {
+        setVoicemailPhoneCallDetailsWithDuration(TEST_DURATION);
+        assertDurationExactEquals("99:20");
+    }
+
+    public void testVoicemailDuration_Zero() {
+        setVoicemailPhoneCallDetailsWithDuration(0);
+        assertDurationExactEquals("00:00");
+    }
+
+    public void testVoicemailDuration_EvenMinute() {
+        setVoicemailPhoneCallDetailsWithDuration(60);
+        assertDurationExactEquals("01:00");
     }
 
     /** Asserts that a char sequence is actually a Spanned corresponding to the expected HTML. */
@@ -346,6 +368,14 @@
         assertEquals(text, mViews.callLocationAndDate.getText());
     }
 
+    /** Asserts that the duration is exactly as included in the location and date text field. */
+    private void assertDurationExactEquals(String text) {
+        Matcher matcher = Pattern.compile("(.*) (\\u2022) (\\d{2}:\\d{2})").matcher(
+                mViews.callLocationAndDate.getText());
+        assertEquals(true, matcher.matches());
+        assertEquals(text, matcher.group(3));
+    }
+
     /** Asserts that the video icon is shown. */
     private void assertIsVideoCall(boolean isVideoCall) {
         assertEquals(isVideoCall, mViews.callTypeIcons.isVideoShown());
@@ -407,6 +437,14 @@
         mHelper.setPhoneCallDetails(mViews, details);
     }
 
+    /** Sets the voice mail details with default values and the given duration. */
+    private void setVoicemailPhoneCallDetailsWithDuration(long duration) {
+        PhoneCallDetails details = getPhoneCallDetails();
+        details.duration = duration;
+        details.callTypes = new int[] {Calls.VOICEMAIL_TYPE};
+        mHelper.setPhoneCallDetails(mViews, details);
+    }
+
     /** Sets the phone call details with default values and the given call types using icons. */
     private void setPhoneCallDetailsWithCallTypeIcons(int... callTypes) {
         PhoneCallDetails details = getPhoneCallDetails();