Merge "Fix Contact photo flicker in People and Dialer" into klp-dev
diff --git a/src/com/android/contacts/common/list/DirectoryListLoader.java b/src/com/android/contacts/common/list/DirectoryListLoader.java
index be9a8e9..dedd62e 100644
--- a/src/com/android/contacts/common/list/DirectoryListLoader.java
+++ b/src/com/android/contacts/common/list/DirectoryListLoader.java
@@ -147,6 +147,9 @@
 
         Cursor cursor = context.getContentResolver().query(DirectoryQuery.URI,
                 DirectoryQuery.PROJECTION, selection, null, DirectoryQuery.ORDER_BY);
+        if (cursor == null) {
+            return result;
+        }
         try {
             while(cursor.moveToNext()) {
                 long directoryId = cursor.getLong(DirectoryQuery.ID);
diff --git a/src/com/android/contacts/common/list/ProfileAndContactsLoader.java b/src/com/android/contacts/common/list/ProfileAndContactsLoader.java
index 9d2bbbb..76715db 100644
--- a/src/com/android/contacts/common/list/ProfileAndContactsLoader.java
+++ b/src/com/android/contacts/common/list/ProfileAndContactsLoader.java
@@ -56,23 +56,31 @@
         if (mLoadProfile) {
             cursors.add(loadProfile());
         }
+        // ContactsCursor.loadInBackground() can return null; MergeCursor
+        // correctly handles null cursors.
         final Cursor contactsCursor = super.loadInBackground();
         cursors.add(contactsCursor);
         return new MergeCursor(cursors.toArray(new Cursor[cursors.size()])) {
             @Override
             public Bundle getExtras() {
                 // Need to get the extras from the contacts cursor.
-                return contactsCursor.getExtras();
+                return contactsCursor == null ? new Bundle() : contactsCursor.getExtras();
             }
         };
     }
 
     /**
-     * Loads the profile into a MatrixCursor.
+     * Loads the profile into a MatrixCursor. On failure returns null, which
+     * matches the behavior of CursorLoader.loadInBackground().
+     *
+     * @return MatrixCursor containing profile or null on query failure.
      */
     private MatrixCursor loadProfile() {
         Cursor cursor = getContext().getContentResolver().query(Profile.CONTENT_URI, mProjection,
                 null, null, null);
+        if (cursor == null) {
+            return null;
+        }
         try {
             MatrixCursor matrix = new MatrixCursor(mProjection);
             Object[] row = new Object[mProjection.length];
diff --git a/src/com/android/contacts/common/model/ContactLoader.java b/src/com/android/contacts/common/model/ContactLoader.java
index ce177b0..926c09f 100644
--- a/src/com/android/contacts/common/model/ContactLoader.java
+++ b/src/com/android/contacts/common/model/ContactLoader.java
@@ -790,26 +790,28 @@
         final Cursor cursor = getContext().getContentResolver().query(Groups.CONTENT_URI,
                 GroupQuery.COLUMNS, selection.toString(), selectionArgs.toArray(new String[0]),
                 null);
-        try {
-            while (cursor.moveToNext()) {
-                final String accountName = cursor.getString(GroupQuery.ACCOUNT_NAME);
-                final String accountType = cursor.getString(GroupQuery.ACCOUNT_TYPE);
-                final String dataSet = cursor.getString(GroupQuery.DATA_SET);
-                final long groupId = cursor.getLong(GroupQuery.ID);
-                final String title = cursor.getString(GroupQuery.TITLE);
-                final boolean defaultGroup = cursor.isNull(GroupQuery.AUTO_ADD)
-                        ? false
-                        : cursor.getInt(GroupQuery.AUTO_ADD) != 0;
-                final boolean favorites = cursor.isNull(GroupQuery.FAVORITES)
-                        ? false
-                        : cursor.getInt(GroupQuery.FAVORITES) != 0;
+        if (cursor != null) {
+            try {
+                while (cursor.moveToNext()) {
+                    final String accountName = cursor.getString(GroupQuery.ACCOUNT_NAME);
+                    final String accountType = cursor.getString(GroupQuery.ACCOUNT_TYPE);
+                    final String dataSet = cursor.getString(GroupQuery.DATA_SET);
+                    final long groupId = cursor.getLong(GroupQuery.ID);
+                    final String title = cursor.getString(GroupQuery.TITLE);
+                    final boolean defaultGroup = cursor.isNull(GroupQuery.AUTO_ADD)
+                            ? false
+                            : cursor.getInt(GroupQuery.AUTO_ADD) != 0;
+                    final boolean favorites = cursor.isNull(GroupQuery.FAVORITES)
+                            ? false
+                            : cursor.getInt(GroupQuery.FAVORITES) != 0;
 
-                groupListBuilder.add(new GroupMetaData(
-                        accountName, accountType, dataSet, groupId, title, defaultGroup,
-                        favorites));
+                    groupListBuilder.add(new GroupMetaData(
+                                    accountName, accountType, dataSet, groupId, title, defaultGroup,
+                                    favorites));
+                }
+            } finally {
+                cursor.close();
             }
-        } finally {
-            cursor.close();
         }
         result.setGroupMetaData(groupListBuilder.build());
     }
diff --git a/src/com/android/contacts/common/model/RawContactModifier.java b/src/com/android/contacts/common/model/RawContactModifier.java
index 0cd243c..954123b 100644
--- a/src/com/android/contacts/common/model/RawContactModifier.java
+++ b/src/com/android/contacts/common/model/RawContactModifier.java
@@ -305,7 +305,7 @@
     public static EditType getBestValidType(RawContactDelta state, DataKind kind,
             boolean includeSecondary, int exactValue) {
         // Shortcut when no types
-        if (kind.typeColumn == null) return null;
+        if (kind == null || kind.typeColumn == null) return null;
 
         // Find type counts and valid primary types, bail if none
         final SparseIntArray typeCount = getTypeFrequencies(state, kind);
@@ -347,6 +347,8 @@
      * {@link #getBestValidType(RawContactDelta, DataKind, boolean, int)}.
      */
     public static ValuesDelta insertChild(RawContactDelta state, DataKind kind) {
+        // Bail early if invalid kind
+        if (kind == null) return null;
         // First try finding a valid primary
         EditType bestType = getBestValidType(state, kind, false, Integer.MIN_VALUE);
         if (bestType == null) {
@@ -633,16 +635,18 @@
                                 StructuredName.SUFFIX,
                         }, null, null, null);
 
-                try {
-                    if (cursor.moveToFirst()) {
-                        child.put(StructuredName.PREFIX, cursor.getString(0));
-                        child.put(StructuredName.GIVEN_NAME, cursor.getString(1));
-                        child.put(StructuredName.MIDDLE_NAME, cursor.getString(2));
-                        child.put(StructuredName.FAMILY_NAME, cursor.getString(3));
-                        child.put(StructuredName.SUFFIX, cursor.getString(4));
+                if (cursor != null) {
+                    try {
+                        if (cursor.moveToFirst()) {
+                            child.put(StructuredName.PREFIX, cursor.getString(0));
+                            child.put(StructuredName.GIVEN_NAME, cursor.getString(1));
+                            child.put(StructuredName.MIDDLE_NAME, cursor.getString(2));
+                            child.put(StructuredName.FAMILY_NAME, cursor.getString(3));
+                            child.put(StructuredName.SUFFIX, cursor.getString(4));
+                        }
+                    } finally {
+                        cursor.close();
                     }
-                } finally {
-                    cursor.close();
                 }
             }
         }
diff --git a/src/com/android/contacts/common/util/NameConverter.java b/src/com/android/contacts/common/util/NameConverter.java
index 56f3192..9706353 100644
--- a/src/com/android/contacts/common/util/NameConverter.java
+++ b/src/com/android/contacts/common/util/NameConverter.java
@@ -94,12 +94,14 @@
                 StructuredName.DISPLAY_NAME,
         }, null, null, null);
 
-        try {
-            if (cursor.moveToFirst()) {
-                displayName = cursor.getString(0);
+        if (cursor != null) {
+            try {
+                if (cursor.moveToFirst()) {
+                    displayName = cursor.getString(0);
+                }
+            } finally {
+                cursor.close();
             }
-        } finally {
-            cursor.close();
         }
         return displayName;
     }
@@ -123,14 +125,16 @@
         Cursor cursor = context.getContentResolver().query(builder.build(), STRUCTURED_NAME_FIELDS,
                 null, null, null);
 
-        try {
-            if (cursor.moveToFirst()) {
-                for (int i = 0; i < STRUCTURED_NAME_FIELDS.length; i++) {
-                    structuredName.put(STRUCTURED_NAME_FIELDS[i], cursor.getString(i));
+        if (cursor != null) {
+            try {
+                if (cursor.moveToFirst()) {
+                    for (int i = 0; i < STRUCTURED_NAME_FIELDS.length; i++) {
+                        structuredName.put(STRUCTURED_NAME_FIELDS[i], cursor.getString(i));
+                    }
                 }
+            } finally {
+                cursor.close();
             }
-        } finally {
-            cursor.close();
         }
         return structuredName;
     }