Handles special numbers in call details page.

Some numbers (unknown, private, payphones, and voicemails) should be
shown using text instead of the row number strings.

Change-Id: I297d44bd762548f08c975adc1ba56fc4a9edd146
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index 43b3bee..43376ca 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -114,8 +114,8 @@
         mInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
         mResources = getResources();
 
-        mPhoneCallDetailsViews = new PhoneCallDetailsViews(getWindow().getDecorView());
-        mPhoneCallDetailsHelper = new PhoneCallDetailsHelper(getResources());
+        mPhoneCallDetailsViews = PhoneCallDetailsViews.fromView(getWindow().getDecorView());
+        mPhoneCallDetailsHelper = new PhoneCallDetailsHelper(getResources(), getVoicemailNumber());
         mCallActionView = findViewById(R.id.call);
         mContactPhotoView = (ImageView) findViewById(R.id.contact_photo);
         mContactBackgroundView = (ImageView) findViewById(R.id.contact_background);
@@ -307,6 +307,12 @@
         return getString(R.string.callDetailsDurationFormat, minutes, seconds);
     }
 
+    private String getVoicemailNumber() {
+        TelephonyManager telephonyManager =
+                (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
+        return telephonyManager.getVoiceMailNumber();
+    }
+
     static final class ViewEntry {
         public int icon = -1;
         public String text = null;
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
index 6542f7d..fc96a89 100644
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ b/src/com/android/contacts/PhoneCallDetailsHelper.java
@@ -17,6 +17,7 @@
 package com.android.contacts;
 
 import com.android.contacts.format.FormatUtils;
+import com.android.internal.telephony.CallerInfo;
 
 import android.content.res.Resources;
 import android.graphics.Typeface;
@@ -33,6 +34,7 @@
  */
 public class PhoneCallDetailsHelper {
     private final Resources mResources;
+    private final String mVoicemailNumber;
     private final String mTypeIncomingText;
     private final String mTypeOutgoingText;
     private final String mTypeMissedText;
@@ -44,8 +46,9 @@
      *
      * @param resources used to look up strings
      */
-    public PhoneCallDetailsHelper(Resources resources) {
+    public PhoneCallDetailsHelper(Resources resources, String voicemailNumber) {
         mResources = resources;
+        mVoicemailNumber = voicemailNumber;
         mTypeIncomingText = mResources.getString(R.string.type_incoming);
         mTypeOutgoingText = mResources.getString(R.string.type_outgoing);
         mTypeMissedText = mResources.getString(R.string.type_missed);
@@ -98,11 +101,11 @@
         CharSequence nameText;
         CharSequence numberText;
         if (TextUtils.isEmpty(name)) {
-            nameText = number;
+            nameText = getDisplayNumber(number);
             numberText = "";
         } else {
             nameText = name;
-            numberText = number;
+            numberText = getDisplayNumber(number);
             if (callType != 0 && numberFormattedLabel != null) {
                 numberText = FormatUtils.applyStyleToSpan(Typeface.BOLD,
                         numberFormattedLabel + " " + number, 0,
@@ -124,4 +127,23 @@
             views.mNumberView.setVisibility(View.GONE);
         }
     }
+
+    private CharSequence getDisplayNumber(CharSequence number) {
+        if (TextUtils.isEmpty(number)) {
+            return "";
+        }
+        if (number.equals(CallerInfo.UNKNOWN_NUMBER)) {
+            return mResources.getString(R.string.unknown);
+        }
+        if (number.equals(CallerInfo.PRIVATE_NUMBER)) {
+            return mResources.getString(R.string.private_num);
+        }
+        if (number.equals(CallerInfo.PAYPHONE_NUMBER)) {
+            return mResources.getString(R.string.payphone);
+        }
+        if (PhoneNumberUtils.extractNetworkPortion(number.toString()).equals(mVoicemailNumber)) {
+            return mResources.getString(R.string.voicemail);
+        }
+        return number;
+    }
 }
diff --git a/src/com/android/contacts/PhoneCallDetailsViews.java b/src/com/android/contacts/PhoneCallDetailsViews.java
index f9f8572..c2819c3 100644
--- a/src/com/android/contacts/PhoneCallDetailsViews.java
+++ b/src/com/android/contacts/PhoneCallDetailsViews.java
@@ -27,14 +27,27 @@
     public final TextView mCallTypeAndDateView;
     public final TextView mNumberView;
 
+    private PhoneCallDetailsViews(TextView nameView, TextView callTypeAndDateView,
+            TextView numberView) {
+        mNameView = nameView;
+        mCallTypeAndDateView = callTypeAndDateView;
+        mNumberView = numberView;
+    }
+
     /**
-     * Creates a new instance and caches its views.
-     *
-     * @param view the view which contains the elements to fill
+     * Create a new instance by extracting the elements from the given view.
+     * <p>
+     * The view should contain three text views with identifiers {@code R.id.name},
+     * {@code R.id.call_type}, and {@code R.id.number}.
      */
-    public PhoneCallDetailsViews(View view) {
-        mNameView = (TextView) view.findViewById(R.id.name);
-        mCallTypeAndDateView = (TextView) view.findViewById(R.id.call_type);
-        mNumberView = (TextView) view.findViewById(R.id.number);
+    public static PhoneCallDetailsViews fromView(View view) {
+        return new PhoneCallDetailsViews((TextView) view.findViewById(R.id.name),
+                (TextView) view.findViewById(R.id.call_type),
+                (TextView) view.findViewById(R.id.number));
+    }
+
+    public static PhoneCallDetailsViews createForTest(TextView nameView,
+            TextView callTypeAndDateView, TextView numberView) {
+        return new PhoneCallDetailsViews(nameView, callTypeAndDateView, numberView);
     }
 }