Merge "Catch ActivityNotFoundException in CallDetailActivity" into klp-dev
diff --git a/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java b/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java
index 9913c20..3eacfec 100644
--- a/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java
+++ b/src/com/android/dialer/calllog/PhoneNumberUtilsWrapper.java
@@ -50,7 +50,7 @@
      * mock-out this, it is not a static method.
      */
     public boolean isVoicemailNumber(CharSequence number) {
-        return PhoneNumberUtils.isVoiceMailNumber(number.toString());
+        return number!= null && PhoneNumberUtils.isVoiceMailNumber(number.toString());
     }
 
     /**
@@ -58,7 +58,7 @@
      * static method.
      */
     public boolean isSipNumber(CharSequence number) {
-        return PhoneNumberUtils.isUriNumber(number.toString());
+        return number != null && PhoneNumberUtils.isUriNumber(number.toString());
     }
 
     public static boolean isUnknownNumberThatCanBeLookedUp(CharSequence number, int presentation) {
@@ -77,13 +77,13 @@
         if (new PhoneNumberUtilsWrapper().isVoicemailNumber(number)) {
             return false;
         }
-        if (isLegacyUnknownNumbers(number.toString())) {
+        if (isLegacyUnknownNumbers(number)) {
             return false;
         }
         return true;
     }
 
     public static boolean isLegacyUnknownNumbers(CharSequence number) {
-        return LEGACY_UNKNOWN_NUMBERS.contains(number.toString());
+        return number != null && LEGACY_UNKNOWN_NUMBERS.contains(number.toString());
     }
 }
diff --git a/src/com/android/dialer/database/DialerDatabaseHelper.java b/src/com/android/dialer/database/DialerDatabaseHelper.java
index b9e4b9a..852b7c1 100644
--- a/src/com/android/dialer/database/DialerDatabaseHelper.java
+++ b/src/com/android/dialer/database/DialerDatabaseHelper.java
@@ -628,10 +628,26 @@
 
             updatedContactCursor.moveToPosition(-1);
             while (updatedContactCursor.moveToNext()) {
-                insert.bindLong(1, updatedContactCursor.getLong(PhoneQuery.PHONE_ID));
-                insert.bindString(2, updatedContactCursor.getString(PhoneQuery.PHONE_NUMBER));
-                insert.bindLong(3, updatedContactCursor.getLong(PhoneQuery.PHONE_CONTACT_ID));
-                insert.bindString(4, updatedContactCursor.getString(PhoneQuery.PHONE_LOOKUP_KEY));
+                insert.clearBindings();
+
+                // Handle string columns which can possibly be null first. In the case of certain
+                // null columns (due to malformed rows possibly inserted by third-party apps
+                // or sync adapters), skip the phone number row.
+                final String number = updatedContactCursor.getString(PhoneQuery.PHONE_NUMBER);
+                if (TextUtils.isEmpty(number)) {
+                    continue;
+                } else {
+                    insert.bindString(2, number);
+                }
+
+                final String lookupKey = updatedContactCursor.getString(
+                        PhoneQuery.PHONE_LOOKUP_KEY);
+                if (TextUtils.isEmpty(lookupKey)) {
+                    continue;
+                } else {
+                    insert.bindString(4, lookupKey);
+                }
+
                 final String displayName = updatedContactCursor.getString(
                         PhoneQuery.PHONE_DISPLAY_NAME);
                 if (displayName == null) {
@@ -639,6 +655,9 @@
                 } else {
                     insert.bindString(5, displayName);
                 }
+
+                insert.bindLong(1, updatedContactCursor.getLong(PhoneQuery.PHONE_ID));
+                insert.bindLong(3, updatedContactCursor.getLong(PhoneQuery.PHONE_CONTACT_ID));
                 insert.bindLong(6, updatedContactCursor.getLong(PhoneQuery.PHONE_PHOTO_ID));
                 insert.bindLong(7, updatedContactCursor.getLong(PhoneQuery.PHONE_LAST_TIME_USED));
                 insert.bindLong(8, updatedContactCursor.getInt(PhoneQuery.PHONE_TIMES_USED));
@@ -648,8 +667,6 @@
                 insert.bindLong(12, updatedContactCursor.getInt(PhoneQuery.PHONE_IS_PRIMARY));
                 insert.bindLong(13, currentMillis);
                 insert.executeInsert();
-                insert.clearBindings();
-
                 final String contactPhoneNumber =
                         updatedContactCursor.getString(PhoneQuery.PHONE_NUMBER);
                 final ArrayList<String> numberPrefixes =
diff --git a/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java b/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java
index 30d01d2..fb9b1d1 100644
--- a/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java
+++ b/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java
@@ -41,16 +41,16 @@
             if (TextUtils.isEmpty(number)) {
                 return;
             }
-            final long id = getContactIdFromPhoneNumber(context, number);
-            if (id != NO_CONTACT_FOUND) {
-                final Thread thread = new Thread() {
-                    @Override
-                    public void run() {
+            final Thread thread = new Thread() {
+                @Override
+                public void run() {
+                    final long id = getContactIdFromPhoneNumber(context, number);
+                    if (id != NO_CONTACT_FOUND) {
                         undemoteContactWithId(context, id);
                     }
-                };
-                thread.start();
-            }
+                }
+            };
+            thread.start();
         }
     }
 
diff --git a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
index e28fd73..cd4fb00 100644
--- a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
+++ b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
@@ -88,6 +88,7 @@
     private long mIdToKeepInPlace = -1;
 
     private boolean mAwaitingRemove = false;
+    private boolean mDelayCursorUpdates = false;
 
     private ContactPhotoManager mPhotoManager;
     protected int mNumFrequents;
@@ -178,6 +179,7 @@
      * @param inDragging Boolean variable indicating whether there is a drag in process.
      */
     public void setInDragging(boolean inDragging) {
+        mDelayCursorUpdates = inDragging;
         mInDragging = inDragging;
     }
 
@@ -224,7 +226,7 @@
      * Else use {@link ContactTileLoaderFactory}
      */
     public void setContactCursor(Cursor cursor) {
-        if (cursor != null && !cursor.isClosed()) {
+        if (!mDelayCursorUpdates && cursor != null && !cursor.isClosed()) {
             mNumStarred = getNumStarredContacts(cursor);
             if (mAwaitingRemove) {
                 mDataSetChangedListener.cacheOffsetsForDatasetChange();