Guard against remote directories returning results with no phone numbers during search.
We have observed in the wild that some apps implementing remote directory don't seem to respect the where clause.
Note that if a search returns 10 results, and 4 of them have null numbers, we will only show 6 numbers where ideally we'd show 10. (It would take a lot of work to fix that just to workaround misbehaving providers which I don't think is worthwhile.)
Bug: 68942044
Test: unit + manually changed guard condition and observed rows hidden
PiperOrigin-RevId: 176183008
Change-Id: Icdb26fa043644e27a4b6ac3c767c728b3ca224ff
diff --git a/java/com/android/dialer/searchfragment/remote/RemoteContactsCursorLoader.java b/java/com/android/dialer/searchfragment/remote/RemoteContactsCursorLoader.java
index 64175be..5f92c49 100644
--- a/java/com/android/dialer/searchfragment/remote/RemoteContactsCursorLoader.java
+++ b/java/com/android/dialer/searchfragment/remote/RemoteContactsCursorLoader.java
@@ -19,11 +19,13 @@
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
+import android.database.MatrixCursor;
import android.net.Uri;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import com.android.dialer.searchfragment.common.Projections;
@@ -77,7 +79,7 @@
cursors[i] = null;
continue;
}
- cursors[i] =
+ Cursor cursor =
getContext()
.getContentResolver()
.query(
@@ -86,10 +88,57 @@
getSelection(),
getSelectionArgs(),
getSortOrder());
+ // Even though the cursor specifies "WHERE PHONE_NUMBER IS NOT NULL" the Blackberry Hub app's
+ // directory extension doesn't appear to respect it, and sometimes returns a null phone
+ // number. In this case just hide the row entirely. See a bug.
+ cursors[i] = createMatrixCursorFilteringNullNumbers(cursor);
}
return RemoteContactsCursor.newInstance(getContext(), cursors, directories);
}
+ private MatrixCursor createMatrixCursorFilteringNullNumbers(Cursor cursor) {
+ if (cursor == null) {
+ return null;
+ }
+ MatrixCursor matrixCursor = new MatrixCursor(cursor.getColumnNames());
+ try {
+ if (cursor.moveToFirst()) {
+ do {
+ String number = cursor.getString(Projections.PHONE_NUMBER);
+ if (number == null) {
+ continue;
+ }
+ matrixCursor.addRow(objectArrayFromCursor(cursor));
+ } while (cursor.moveToNext());
+ }
+ } finally {
+ cursor.close();
+ }
+ return matrixCursor;
+ }
+
+ @NonNull
+ private static Object[] objectArrayFromCursor(@NonNull Cursor cursor) {
+ Object[] values = new Object[cursor.getColumnCount()];
+ for (int i = 0; i < cursor.getColumnCount(); i++) {
+ int fieldType = cursor.getType(i);
+ if (fieldType == Cursor.FIELD_TYPE_BLOB) {
+ values[i] = cursor.getBlob(i);
+ } else if (fieldType == Cursor.FIELD_TYPE_FLOAT) {
+ values[i] = cursor.getDouble(i);
+ } else if (fieldType == Cursor.FIELD_TYPE_INTEGER) {
+ values[i] = cursor.getLong(i);
+ } else if (fieldType == Cursor.FIELD_TYPE_STRING) {
+ values[i] = cursor.getString(i);
+ } else if (fieldType == Cursor.FIELD_TYPE_NULL) {
+ values[i] = null;
+ } else {
+ throw new IllegalStateException("Unknown fieldType (" + fieldType + ") for column: " + i);
+ }
+ }
+ return values;
+ }
+
@VisibleForTesting
static Uri getContentFilterUri(String query, int directoryId) {
Uri baseUri =