Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5456440d authored by Walter Jang's avatar Walter Jang
Browse files

Order strequent contacts above type-to-filter search results

Screenshots at go/b20545359

Bug 20545359
Bug 26697731

Change-Id: I32f0aa216834f2d33f4537d37199203fb089b932
parent 4a459181
Loading
Loading
Loading
Loading
+59 −5
Original line number Diff line number Diff line
@@ -23,11 +23,9 @@ import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Directory;
import android.provider.ContactsContract.SearchSnippets;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
import com.android.contacts.common.R;
import com.android.contacts.common.compat.ContactsCompat;
@@ -72,7 +70,9 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter {
            Contacts.PHOTO_THUMBNAIL_URI,           // 5
            Contacts.LOOKUP_KEY,                    // 6
            Contacts.IS_USER_PROFILE,               // 7
            SearchSnippets.SNIPPET,           // 8
            Contacts.TIMES_CONTACTED,               // 8
            Contacts.STARRED,                       // 9
            SearchSnippets.SNIPPET,                 // 10
        };

        private static final String[] FILTER_PROJECTION_ALTERNATIVE = new String[] {
@@ -84,7 +84,9 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter {
            Contacts.PHOTO_THUMBNAIL_URI,           // 5
            Contacts.LOOKUP_KEY,                    // 6
            Contacts.IS_USER_PROFILE,               // 7
            SearchSnippets.SNIPPET,           // 8
            Contacts.TIMES_CONTACTED,               // 8
            Contacts.STARRED,                       // 9
            SearchSnippets.SNIPPET,                 // 10
        };

        public static final int CONTACT_ID               = 0;
@@ -95,7 +97,52 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter {
        public static final int CONTACT_PHOTO_URI        = 5;
        public static final int CONTACT_LOOKUP_KEY       = 6;
        public static final int CONTACT_IS_USER_PROFILE  = 7;
        public static final int CONTACT_SNIPPET          = 8;
        public static final int CONTACT_TIMES_CONTACTED  = 8;
        public static final int CONTACT_STARRED          = 9;
        public static final int CONTACT_SNIPPET          = 10;
    }

    protected static class StrequentQuery {

        private static final String[] FILTER_PROJECTION_PRIMARY = new String[] {
                Contacts._ID,                           // 0
                Contacts.DISPLAY_NAME_PRIMARY,          // 1
                Contacts.CONTACT_PRESENCE,              // 2
                Contacts.CONTACT_STATUS,                // 3
                Contacts.PHOTO_ID,                      // 4
                Contacts.PHOTO_THUMBNAIL_URI,           // 5
                Contacts.LOOKUP_KEY,                    // 6
                Contacts.IS_USER_PROFILE,               // 7
                Contacts.TIMES_CONTACTED,               // 8
                Contacts.STARRED,                       // 9
                // SearchSnippets.SNIPPET not supported
        };

        private static final String[] FILTER_PROJECTION_ALTERNATIVE = new String[] {
                Contacts._ID,                           // 0
                Contacts.DISPLAY_NAME_ALTERNATIVE,      // 1
                Contacts.CONTACT_PRESENCE,              // 2
                Contacts.CONTACT_STATUS,                // 3
                Contacts.PHOTO_ID,                      // 4
                Contacts.PHOTO_THUMBNAIL_URI,           // 5
                Contacts.LOOKUP_KEY,                    // 6
                Contacts.IS_USER_PROFILE,               // 7
                Contacts.TIMES_CONTACTED,               // 8
                Contacts.STARRED,                       // 9
                // SearchSnippets.SNIPPET not supported
        };

        public static final int CONTACT_ID               = 0;
        public static final int CONTACT_DISPLAY_NAME     = 1;
        public static final int CONTACT_PRESENCE_STATUS  = 2;
        public static final int CONTACT_CONTACT_STATUS   = 3;
        public static final int CONTACT_PHOTO_ID         = 4;
        public static final int CONTACT_PHOTO_URI        = 5;
        public static final int CONTACT_LOOKUP_KEY       = 6;
        public static final int CONTACT_IS_USER_PROFILE  = 7;
        public static final int CONTACT_TIMES_CONTACTED  = 8;
        public static final int CONTACT_STARRED          = 9;
        // SearchSnippets.SNIPPET not supported
    }

    private CharSequence mUnknownNameText;
@@ -384,4 +431,11 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter {
            }
        }
    }

    protected final String[] getStrequentProjection() {
        final int sortOrder = getContactNameDisplayOrder();
        return sortOrder == ContactsPreferences.DISPLAY_ORDER_PRIMARY
                ? StrequentQuery.FILTER_PROJECTION_PRIMARY
                : StrequentQuery.FILTER_PROJECTION_ALTERNATIVE;
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.SearchSnippets;
import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.widget.AppCompatCheckBox;
@@ -1481,7 +1482,8 @@ public class ContactListItemView extends ViewGroup
     * Shows search snippet.
     */
    public void showSnippet(Cursor cursor, int summarySnippetColumnIndex) {
        if (cursor.getColumnCount() <= summarySnippetColumnIndex) {
        if (cursor.getColumnCount() <= summarySnippetColumnIndex
            || !SearchSnippets.SNIPPET.equals(cursor.getColumnName(summarySnippetColumnIndex))) {
            setSnippet(null);
            return;
        }
+33 −8
Original line number Diff line number Diff line
@@ -44,6 +44,10 @@ public class DefaultContactListAdapter extends ContactListAdapter {
    public static final char SNIPPET_START_MATCH = '[';
    public static final char SNIPPET_END_MATCH = ']';

    // Whether to show strequent contacts before the normal type-to-filter search results.
    // TODO(wjang): set this using phenotype
    private final boolean mShowStrequentsSearchResultsFirst = false;

    public DefaultContactListAdapter(Context context) {
        super(context);
    }
@@ -69,16 +73,26 @@ public class DefaultContactListAdapter extends ContactListAdapter {
                loader.setSelection("0");
            } else {
                final Builder builder = ContactsCompat.getContentUri().buildUpon();
                builder.appendPath(query); // Builder will encode the query
                builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
                        String.valueOf(directoryId));
                if (directoryId != Directory.DEFAULT && directoryId != Directory.LOCAL_INVISIBLE) {
                    builder.appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY,
                            String.valueOf(getDirectoryResultLimit(getDirectoryById(directoryId))));
                }
                builder.appendQueryParameter(SearchSnippets.DEFERRED_SNIPPETING_KEY, "1");
                appendSearchParameters(builder, query, directoryId);
                loader.setUri(builder.build());
                loader.setProjection(getProjection(true));
                if (mShowStrequentsSearchResultsFirst) {
                    // Filter out starred and frequently contacted contacts from the main loader
                    // query results
                    loader.setSelection(Contacts.TIMES_CONTACTED + "=0 AND "
                            + Contacts.STARRED + "=0");

                    // Strequent contacts will be merged back in before the main loader query
                    // results and after the profile (ME).
                    final ProfileAndContactsLoader profileAndContactsLoader =
                            (ProfileAndContactsLoader) loader;
                    profileAndContactsLoader.setLoadStrequent(true);
                    final Builder strequentBuilder =
                            Contacts.CONTENT_STREQUENT_FILTER_URI.buildUpon();
                    appendSearchParameters(strequentBuilder, query, directoryId);
                    profileAndContactsLoader.setStrequentUri(strequentBuilder.build());
                    profileAndContactsLoader.setStrequentProjection(getStrequentProjection());
                }
            }
        } else {
            configureUri(loader, directoryId, filter);
@@ -96,6 +110,17 @@ public class DefaultContactListAdapter extends ContactListAdapter {
        loader.setSortOrder(sortOrder);
    }

    private void appendSearchParameters(Builder builder, String query, long directoryId) {
        builder.appendPath(query); // Builder will encode the query
        builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
                String.valueOf(directoryId));
        if (directoryId != Directory.DEFAULT && directoryId != Directory.LOCAL_INVISIBLE) {
            builder.appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY,
                    String.valueOf(getDirectoryResultLimit(getDirectoryById(directoryId))));
        }
        builder.appendQueryParameter(SearchSnippets.DEFERRED_SNIPPETING_KEY, "1");
    }

    protected void configureUri(CursorLoader loader, long directoryId, ContactListFilter filter) {
        Uri uri = Contacts.CONTENT_URI;
        if (filter != null && filter.filterType == ContactListFilter.FILTER_TYPE_SINGLE_CONTACT) {
+28 −0
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@ import android.content.CursorLoader;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MergeCursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Profile;

import com.google.common.collect.Lists;
@@ -34,7 +36,10 @@ import java.util.List;
public class ProfileAndContactsLoader extends CursorLoader {

    private boolean mLoadProfile;
    private boolean mLoadStrequent;
    private String[] mProjection;
    private String[] mStrequentProjection;
    private Uri mStrequentUri;

    public ProfileAndContactsLoader(Context context) {
        super(context);
@@ -44,11 +49,23 @@ public class ProfileAndContactsLoader extends CursorLoader {
        mLoadProfile = flag;
    }

    public void setLoadStrequent(boolean flag) {
        mLoadStrequent = flag;
    }

    public void setProjection(String[] projection) {
        super.setProjection(projection);
        mProjection = projection;
    }

    public void setStrequentProjection(String[] projection) {
        mStrequentProjection = projection;
    }

    public void setStrequentUri(Uri uri) {
        mStrequentUri = uri;
    }

    @Override
    public Cursor loadInBackground() {
        // First load the profile, if enabled.
@@ -56,6 +73,9 @@ public class ProfileAndContactsLoader extends CursorLoader {
        if (mLoadProfile) {
            cursors.add(loadProfile());
        }
        if (mLoadStrequent) {
            cursors.add(loadStrequent());
        }
        // ContactsCursor.loadInBackground() can return null; MergeCursor
        // correctly handles null cursors.
        Cursor cursor = null;
@@ -101,4 +121,12 @@ public class ProfileAndContactsLoader extends CursorLoader {
            cursor.close();
        }
    }

    /**
     * Loads starred and frequently contacted contacts
     */
    private Cursor loadStrequent() {
        return getContext().getContentResolver().query(
                mStrequentUri, mStrequentProjection, null, null, null);
    }
}