Merge "Fix possible FragmentManager NPE in Dialer" into klp-dev
diff --git a/src/com/android/dialer/CallDetailActivity.java b/src/com/android/dialer/CallDetailActivity.java
index 2b16a98..a24940d 100644
--- a/src/com/android/dialer/CallDetailActivity.java
+++ b/src/com/android/dialer/CallDetailActivity.java
@@ -489,6 +489,8 @@
                     nameOrNumber = firstDetails.number;
                 }
 
+                boolean skipBind = false;
+
                 if (contactUri != null && !UriUtils.isEncodedContactUri(contactUri)) {
                     mainActionIntent = new Intent(Intent.ACTION_VIEW, contactUri);
                     // This will launch People's detail contact screen, so we probably want to
@@ -505,6 +507,7 @@
                     mainActionIntent = null;
                     mainActionIcon = R.drawable.ic_add_contact_holo_dark;
                     mainActionDescription = getString(R.string.description_add_contact);
+                    skipBind = true;
                 } else if (isVoicemailNumber) {
                     mainActionIntent = null;
                     mainActionIcon = 0;
@@ -536,7 +539,10 @@
                     mainActionDescription = null;
                 }
 
-                bindContactPhotoAction(mainActionIntent, mainActionIcon, mainActionDescription);
+                if (!skipBind) {
+                    bindContactPhotoAction(mainActionIntent, mainActionIcon,
+                            mainActionDescription);
+                }
 
                 // This action allows to call the number that places the call.
                 if (canPlaceCallsTo) {
diff --git a/src/com/android/dialer/calllog/CallDetailHistoryAdapter.java b/src/com/android/dialer/calllog/CallDetailHistoryAdapter.java
index 52435aa..8af3b82 100644
--- a/src/com/android/dialer/calllog/CallDetailHistoryAdapter.java
+++ b/src/com/android/dialer/calllog/CallDetailHistoryAdapter.java
@@ -150,7 +150,7 @@
                 DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_YEAR);
         dateView.setText(dateValue);
         // Set the duration
-        if (callType == Calls.MISSED_TYPE || callType == Calls.VOICEMAIL_TYPE) {
+        if (Calls.VOICEMAIL_TYPE == callType || CallTypeHelper.isMissedCallType(callType)) {
             durationView.setVisibility(View.GONE);
         } else {
             durationView.setVisibility(View.VISIBLE);
diff --git a/src/com/android/dialer/calllog/CallLogGroupBuilder.java b/src/com/android/dialer/calllog/CallLogGroupBuilder.java
index 1e4684e..213f1e7 100644
--- a/src/com/android/dialer/calllog/CallLogGroupBuilder.java
+++ b/src/com/android/dialer/calllog/CallLogGroupBuilder.java
@@ -78,8 +78,7 @@
                 shouldGroup = false;
             } else {
                 // Incoming, outgoing, and missed calls group together.
-                shouldGroup = (callType == Calls.INCOMING_TYPE || callType == Calls.OUTGOING_TYPE ||
-                        callType == Calls.MISSED_TYPE);
+                shouldGroup = callType != Calls.VOICEMAIL_TYPE;
             }
 
             if (shouldGroup) {
diff --git a/src/com/android/dialer/calllog/CallTypeHelper.java b/src/com/android/dialer/calllog/CallTypeHelper.java
index 0f9b737..1c4f44f 100644
--- a/src/com/android/dialer/calllog/CallTypeHelper.java
+++ b/src/com/android/dialer/calllog/CallTypeHelper.java
@@ -64,7 +64,7 @@
                 return mVoicemailName;
 
             default:
-                throw new IllegalArgumentException("invalid call type: " + callType);
+                return mMissedName;
         }
     }
 
@@ -86,7 +86,15 @@
                 return mNewVoicemailColor;
 
             default:
-                throw new IllegalArgumentException("invalid call type: " + callType);
+                // Don't highlight calls of unknown types. They are treated as missed calls by
+                // the rest of the UI, but since they will never be marked as read by
+                // {@link CallLogQueryHandler}, just don't ever highlight them anyway.
+                return null;
         }
     }
+
+    public static boolean isMissedCallType(int callType) {
+        return (callType != Calls.INCOMING_TYPE && callType != Calls.OUTGOING_TYPE &&
+                callType != Calls.VOICEMAIL_TYPE);
+    }
 }
diff --git a/src/com/android/dialer/calllog/CallTypeIconsView.java b/src/com/android/dialer/calllog/CallTypeIconsView.java
index e835128..a65f2c2 100644
--- a/src/com/android/dialer/calllog/CallTypeIconsView.java
+++ b/src/com/android/dialer/calllog/CallTypeIconsView.java
@@ -86,7 +86,11 @@
             case Calls.VOICEMAIL_TYPE:
                 return mResources.voicemail;
             default:
-                throw new IllegalArgumentException("invalid call type: " + callType);
+                // It is possible for users to end up with calls with unknown call types in their
+                // call history, possibly due to 3rd party call log implementations (e.g. to
+                // distinguish between rejected and missed calls). Instead of crashing, just
+                // assume that all unknown call types are missed calls.
+                return mResources.missed;
         }
     }