Get rid of invisible contacts from group member picker using Data Uri

Bug 29126479

Change-Id: Ia28eeccb15c789394bdbe8221a49f48dcaf96d50
diff --git a/src/com/android/contacts/list/GroupMemberPickListAdapter.java b/src/com/android/contacts/list/GroupMemberPickListAdapter.java
index ae6517c..d25aafd 100644
--- a/src/com/android/contacts/list/GroupMemberPickListAdapter.java
+++ b/src/com/android/contacts/list/GroupMemberPickListAdapter.java
@@ -19,6 +19,7 @@
 import android.content.CursorLoader;
 import android.database.Cursor;
 import android.net.Uri;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
 import android.text.TextUtils;
@@ -43,21 +44,21 @@
     static class GroupMembersQuery {
 
         private static final String[] PROJECTION_PRIMARY = new String[] {
-                RawContacts._ID,                        // 0
-                RawContacts.CONTACT_ID,                 // 1
-                RawContacts.DISPLAY_NAME_PRIMARY,       // 2
+                Data.RAW_CONTACT_ID,             // 0
+                Data.CONTACT_ID,                 // 1
+                Data.DISPLAY_NAME_PRIMARY,       // 2
                 // Dummy columns overwritten by the cursor wrapper
-                RawContacts.SYNC1,                      // 3
-                RawContacts.SYNC2                       // 4
+                Data.PHOTO_ID,                   // 3
+                Data.LOOKUP_KEY                  // 4
         };
 
         private static final String[] PROJECTION_ALTERNATIVE = new String[] {
-                RawContacts._ID,                        // 0
-                RawContacts.CONTACT_ID,                 // 1
-                RawContacts.DISPLAY_NAME_ALTERNATIVE,   // 2
+                Data.RAW_CONTACT_ID,             // 0
+                Data.CONTACT_ID,                 // 1
+                Data.DISPLAY_NAME_ALTERNATIVE,   // 2
                 // Dummy columns overwritten by the cursor wrapper
-                RawContacts.SYNC1,                      // 3
-                RawContacts.SYNC2                       // 4
+                Data.PHOTO_ID,                   // 3
+                Data.LOOKUP_KEY                  // 4
         };
 
         static final int RAW_CONTACT_ID = 0;
@@ -101,7 +102,10 @@
 
     @Override
     public void configureLoader(CursorLoader loader, long directoryId) {
-        loader.setUri(RawContacts.CONTENT_URI);
+        final Uri uri = Data.CONTENT_URI.buildUpon()
+                .appendQueryParameter(Data.VISIBLE_CONTACTS_ONLY, "true")
+                .build();
+        loader.setUri(uri);
         loader.setProjection(
                 getContactNameDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY
                         ? GroupMembersQuery.PROJECTION_PRIMARY
@@ -115,7 +119,8 @@
 
     private String getSelection() {
         // Select raw contacts by account
-        String result = RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=? AND ";
+        String result = RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=? AND "
+                + Data.MIMETYPE + "=? AND ";
         if (TextUtils.isEmpty(mAccount.dataSet)) {
             result += Data.DATA_SET + " IS NULL";
         } else {
@@ -128,6 +133,7 @@
         final ArrayList<String> result = new ArrayList<>();
         result.add(mAccount.name);
         result.add(mAccount.type);
+        result.add(GroupMembership.CONTENT_ITEM_TYPE);
         if (!TextUtils.isEmpty(mAccount.dataSet)) result.add(mAccount.dataSet);
         return result.toArray(new String[0]);
     }
@@ -135,7 +141,7 @@
     public Uri getRawContactUri(int position) {
         final Cursor cursor = (Cursor) getItem(position);
         final long rawContactId = cursor.getLong(GroupMembersQuery.RAW_CONTACT_ID);
-        return RawContacts.CONTENT_URI.buildUpon()
+        return Data.CONTENT_URI.buildUpon()
                 .appendPath(Long.toString(rawContactId))
                 .build();
     }
diff --git a/src/com/android/contacts/list/GroupMemberPickerFragment.java b/src/com/android/contacts/list/GroupMemberPickerFragment.java
index d965e21..edd5739 100644
--- a/src/com/android/contacts/list/GroupMemberPickerFragment.java
+++ b/src/com/android/contacts/list/GroupMemberPickerFragment.java
@@ -23,7 +23,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.Data;
 import android.util.Log;
 import android.util.Pair;
 import android.view.LayoutInflater;
@@ -38,7 +38,9 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Fragment containing raw contacts for a specified account that are not already in a group.
@@ -84,12 +86,17 @@
                         + (mContactPhotosMap == null ? 0 : mContactPhotosMap.size()));
             }
 
+            final Set<String> uniqueRawContactIds = new HashSet<String>();
+
             for (int i = 0; i < mCount; i++) {
                 super.moveToPosition(i);
                 final String rawContactId = getString(GroupMembersQuery.RAW_CONTACT_ID);
-                if (!mRawContactIds.contains(rawContactId)) {
+                if (!mRawContactIds.contains(rawContactId)
+                        && !uniqueRawContactIds.contains(rawContactId)) {
                     mIndex[mPos++] = i;
-                } else if (mContactPhotosMap != null) {
+                    uniqueRawContactIds.add(rawContactId);
+                }
+                if (mRawContactIds.contains(rawContactId) && mContactPhotosMap != null) {
                     final long contactId = getLong(GroupMembersQuery.CONTACT_ID);
                     mContactPhotosMap.remove(contactId);
                 }
@@ -117,10 +124,10 @@
         }
 
         private int getColumnIndexForContactColumn(String columnName) {
-            if (Contacts.PHOTO_ID.equals(columnName)) {
+            if (Data.PHOTO_ID.equals(columnName)) {
                 return GroupMembersQuery.CONTACT_PHOTO_ID;
             }
-            if (Contacts.LOOKUP_KEY.equals(columnName)) {
+            if (Data.LOOKUP_KEY.equals(columnName)) {
                 return GroupMembersQuery.CONTACT_LOOKUP_KEY;
             }
             return -1;
@@ -130,14 +137,14 @@
         public String[] getColumnNames() {
             final String displayNameColumnName =
                     getContactNameDisplayOrder() == ContactsPreferences.DISPLAY_ORDER_PRIMARY
-                            ? RawContacts.DISPLAY_NAME_PRIMARY
-                            : RawContacts.DISPLAY_NAME_ALTERNATIVE;
+                            ? Data.DISPLAY_NAME_PRIMARY
+                            : Data.DISPLAY_NAME_ALTERNATIVE;
             return new String[] {
-                    RawContacts._ID,
-                    RawContacts.CONTACT_ID,
+                    Data._ID,
+                    Data.CONTACT_ID,
                     displayNameColumnName,
-                    Contacts.PHOTO_ID,
-                    Contacts.LOOKUP_KEY,
+                    Data.PHOTO_ID,
+                    Data.LOOKUP_KEY,
             };
         }
 
@@ -219,15 +226,15 @@
     private final LoaderCallbacks<Cursor> mContactsEntityCallbacks = new LoaderCallbacks<Cursor>() {
 
         private final String[] PROJECTION = new String[] {
-                Contacts._ID,
-                Contacts.PHOTO_ID,
-                Contacts.LOOKUP_KEY
+                Data.CONTACT_ID,
+                Data.PHOTO_ID,
+                Data.LOOKUP_KEY
         };
 
         @Override
         public CursorLoader onCreateLoader(int id, Bundle args) {
             final CursorLoader loader = new CursorLoader(getActivity());
-            loader.setUri(Contacts.CONTENT_URI);
+            loader.setUri(Data.CONTENT_URI);
             loader.setProjection(PROJECTION);
             return loader;
         }
@@ -311,7 +318,9 @@
 
     @Override
     public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
-        super.onLoadFinished(loader, new FilterCursorWrapper(data));
+        if (data != null) {
+            super.onLoadFinished(loader, new FilterCursorWrapper(data));
+        }
     }
 
     @Override