RecipientAlternatesAdapter.java revision 771e417fe305e0aa65f0a864f2b4f4da7606b6b1
184dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira/*
284dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * Copyright (C) 2011 The Android Open Source Project
384dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira *
484dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * Licensed under the Apache License, Version 2.0 (the "License");
584dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * you may not use this file except in compliance with the License.
684dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * You may obtain a copy of the License at
784dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira *
884dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira *      http://www.apache.org/licenses/LICENSE-2.0
984dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira *
1084dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * Unless required by applicable law or agreed to in writing, software
1184dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * distributed under the License is distributed on an "AS IS" BASIS,
1284dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1384dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * See the License for the specific language governing permissions and
1484dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira * limitations under the License.
1584dd9a88f0d9984996e951e59e73cb76cd2eaa5eMindy Pereira */
1697d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira
1797d7768576ff27d779d68f77e23925b69f3290bcMindy Pereirapackage com.android.ex.chips;
1897d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira
1916923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport android.accounts.Account;
2016923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport android.content.ContentResolver;
2197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.content.Context;
2297d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.database.Cursor;
23a5d37c8a968edf94755215617b593d3f61738a92Makoto Onukiimport android.database.MatrixCursor;
2416923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport android.net.Uri;
2516923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport android.provider.ContactsContract;
26ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedyimport android.text.TextUtils;
271852931de1e24e77cb708f4ba010eaa269426657Mindy Pereiraimport android.text.util.Rfc822Token;
281852931de1e24e77cb708f4ba010eaa269426657Mindy Pereiraimport android.text.util.Rfc822Tokenizer;
2918987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereiraimport android.util.Log;
3097d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.view.LayoutInflater;
3197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.view.View;
3297d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.view.ViewGroup;
3397d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.widget.CursorAdapter;
3467ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereiraimport android.widget.ImageView;
3597d7768576ff27d779d68f77e23925b69f3290bcMindy Pereiraimport android.widget.TextView;
3697d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira
3716923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport com.android.ex.chips.BaseRecipientAdapter.DirectoryListQuery;
3816923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport com.android.ex.chips.BaseRecipientAdapter.DirectorySearchParams;
3980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylorimport com.android.ex.chips.Queries.Query;
40a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki
4103cfe3eee5635e419ab1d70d463b2b8beac72f00Mindy Pereiraimport java.util.ArrayList;
421852931de1e24e77cb708f4ba010eaa269426657Mindy Pereiraimport java.util.HashMap;
43a5d37c8a968edf94755215617b593d3f61738a92Makoto Onukiimport java.util.HashSet;
4416923ee63a79fce4be3f62b08bcd1f80617c1205mindypimport java.util.List;
4594fa301de71cc110671802eba8376c275b4055a4Scott Kennedyimport java.util.Map;
4694fa301de71cc110671802eba8376c275b4055a4Scott Kennedyimport java.util.Set;
471852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira
4880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor/**
4980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor * RecipientAlternatesAdapter backs the RecipientEditTextView for managing contacts
5080f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor * queried by email or by phone number.
5180f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor */
5297d7768576ff27d779d68f77e23925b69f3290bcMindy Pereirapublic class RecipientAlternatesAdapter extends CursorAdapter {
531852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira    static final int MAX_LOOKUPS = 50;
5497d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    private final LayoutInflater mLayoutInflater;
5597d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira
5697d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    private final long mCurrentId;
5797d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira
58007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira    private int mCheckedItemPosition = -1;
59007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira
605086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira    private OnCheckedItemChangedListener mCheckedItemChangedListener;
615086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira
6218987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira    private static final String TAG = "RecipAlternates";
6318987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira
6480f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor    public static final int QUERY_TYPE_EMAIL = 0;
6580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor    public static final int QUERY_TYPE_PHONE = 1;
6680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor    private Query mQuery;
6780f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor
6816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp    public interface RecipientMatchCallback {
6994fa301de71cc110671802eba8376c275b4055a4Scott Kennedy        public void matchesFound(Map<String, RecipientEntry> results);
7094fa301de71cc110671802eba8376c275b4055a4Scott Kennedy        /**
7194fa301de71cc110671802eba8376c275b4055a4Scott Kennedy         * Called with all addresses that could not be resolved to valid recipients.
7294fa301de71cc110671802eba8376c275b4055a4Scott Kennedy         */
73f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy        public void matchesNotFound(Set<String> unfoundAddresses);
7416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp    }
7516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp
7616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp    public static void getMatchingRecipients(Context context, ArrayList<String> inAddresses,
7716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            Account account, RecipientMatchCallback callback) {
7816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        getMatchingRecipients(context, inAddresses, QUERY_TYPE_EMAIL, account, callback);
7980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor    }
8080f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor
811852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira    /**
821852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira     * Get a HashMap of address to RecipientEntry that contains all contact
831852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira     * information for a contact with the provided address, if one exists. This
841852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira     * may block the UI, so run it in an async task.
851852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira     *
861852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira     * @param context Context.
877211747e51623ae1305053f533c09dd335e013a2Daisuke Miyakawa     * @param inAddresses Array of addresses on which to perform the lookup.
8816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp     * @param callback RecipientMatchCallback called when a match or matches are found.
891852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira     * @return HashMap<String,RecipientEntry>
901852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira     */
9116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp    public static void getMatchingRecipients(Context context, ArrayList<String> inAddresses,
9216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            int addressType, Account account, RecipientMatchCallback callback) {
9380f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        Queries.Query query;
9480f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        if (addressType == QUERY_TYPE_EMAIL) {
9580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor            query = Queries.EMAIL;
9680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        } else {
9780f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor            query = Queries.PHONE;
9880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        }
9903cfe3eee5635e419ab1d70d463b2b8beac72f00Mindy Pereira        int addressesSize = Math.min(MAX_LOOKUPS, inAddresses.size());
10016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        HashSet<String> addresses = new HashSet<String>();
1011852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira        StringBuilder bindString = new StringBuilder();
1021852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira        // Create the "?" string and set up arguments.
1031852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira        for (int i = 0; i < addressesSize; i++) {
10403cfe3eee5635e419ab1d70d463b2b8beac72f00Mindy Pereira            Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(inAddresses.get(i).toLowerCase());
10516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            addresses.add(tokens.length > 0 ? tokens[0].getAddress() : inAddresses.get(i));
1061852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira            bindString.append("?");
1071852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira            if (i < addressesSize - 1) {
1081852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira                bindString.append(",");
1091852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira            }
1101852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira        }
1111852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira
11218987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira        if (Log.isLoggable(TAG, Log.DEBUG)) {
11318987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira            Log.d(TAG, "Doing reverse lookup for " + addresses.toString());
11418987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira        }
11518987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira
11616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        String[] addressArray = new String[addresses.size()];
11716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        addresses.toArray(addressArray);
11816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        HashMap<String, RecipientEntry> recipientEntries = null;
11916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        Cursor c = null;
12016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp
12116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        try {
12216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            c = context.getContentResolver().query(
12316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                    query.getContentUri(),
12416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                    query.getProjection(),
12516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                    query.getProjection()[Queries.Query.DESTINATION] + " IN ("
12616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                            + bindString.toString() + ")", addressArray, null);
12716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            recipientEntries = processContactEntries(c);
12816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            callback.matchesFound(recipientEntries);
12916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        } finally {
13016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            if (c != null) {
13116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                c.close();
13216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            }
13316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        }
13416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        // See if any entries did not resolve; if so, we need to check other
13516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        // directories
13694fa301de71cc110671802eba8376c275b4055a4Scott Kennedy        final Set<String> matchesNotFound = new HashSet<String>();
13716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        if (recipientEntries.size() < addresses.size()) {
13816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            final List<DirectorySearchParams> paramsList;
139539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy            Cursor directoryCursor = null;
140539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy            try {
141539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy                directoryCursor = context.getContentResolver().query(DirectoryListQuery.URI,
142539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy                        DirectoryListQuery.PROJECTION, null, null, null);
143771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                if (directoryCursor == null) {
144771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                    paramsList = null;
145771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                } else {
146771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                    paramsList = BaseRecipientAdapter.setupOtherDirectories(context,
147771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                            directoryCursor, account);
148771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                }
149539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy            } finally {
150539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy                if (directoryCursor != null) {
151539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy                    directoryCursor.close();
152539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy                }
153539c2b12cca5e9bccd9acabc4721c876058a68d4Scott Kennedy            }
15416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            // Run a directory query for each unmatched recipient.
15516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            HashSet<String> unresolvedAddresses = new HashSet<String>();
15616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            for (String address : addresses) {
15716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                if (!recipientEntries.containsKey(address)) {
15816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                    unresolvedAddresses.add(address);
15916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                }
16016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            }
16194fa301de71cc110671802eba8376c275b4055a4Scott Kennedy
16294fa301de71cc110671802eba8376c275b4055a4Scott Kennedy            matchesNotFound.addAll(unresolvedAddresses);
16394fa301de71cc110671802eba8376c275b4055a4Scott Kennedy
164771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy            if (paramsList != null) {
165771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                Cursor directoryContactsCursor = null;
166771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                for (String unresolvedAddress : unresolvedAddresses) {
167771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                    for (int i = 0; i < paramsList.size(); i++) {
168771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                        try {
169771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                            directoryContactsCursor = doQuery(unresolvedAddress, 1,
170771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                                    paramsList.get(i).directoryId, account,
171771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                                    context.getContentResolver(), query);
172771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                        } finally {
173771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                            if (directoryContactsCursor != null
174771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                                    && directoryContactsCursor.getCount() == 0) {
175771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                                directoryContactsCursor.close();
176771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                                directoryContactsCursor = null;
177771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                            } else {
178771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                                break;
179771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                            }
18018987c44006700a2bfe614ec1e39a29ed5b23d78Mindy Pereira                        }
18116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                    }
182771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                    if (directoryContactsCursor != null) {
183771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                        try {
184771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                            final Map<String, RecipientEntry> entries =
185771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                                    processContactEntries(directoryContactsCursor);
18694fa301de71cc110671802eba8376c275b4055a4Scott Kennedy
187771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                            for (final String address : entries.keySet()) {
188771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                                matchesNotFound.remove(address);
189771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                            }
19094fa301de71cc110671802eba8376c275b4055a4Scott Kennedy
191771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                            callback.matchesFound(entries);
192771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                        } finally {
193771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                            directoryContactsCursor.close();
194771e417fe305e0aa65f0a864f2b4f4da7606b6b1Scott Kennedy                        }
19516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                    }
1961852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira                }
1971852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira            }
1981852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira        }
19994fa301de71cc110671802eba8376c275b4055a4Scott Kennedy
20094fa301de71cc110671802eba8376c275b4055a4Scott Kennedy        callback.matchesNotFound(matchesNotFound);
20116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp    }
20216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp
20316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp    private static HashMap<String, RecipientEntry> processContactEntries(Cursor c) {
20416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        HashMap<String, RecipientEntry> recipientEntries = new HashMap<String, RecipientEntry>();
20516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        if (c != null && c.moveToFirst()) {
20616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            do {
20716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                String address = c.getString(Queries.Query.DESTINATION);
208ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
209ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                final RecipientEntry newRecipientEntry = RecipientEntry.constructTopLevelEntry(
21016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                        c.getString(Queries.Query.NAME),
21116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                        c.getInt(Queries.Query.DISPLAY_NAME_SOURCE),
21216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                        c.getString(Queries.Query.DESTINATION),
21316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                        c.getInt(Queries.Query.DESTINATION_TYPE),
21416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                        c.getString(Queries.Query.DESTINATION_LABEL),
21516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                        c.getLong(Queries.Query.CONTACT_ID),
21616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                        c.getLong(Queries.Query.DATA_ID),
21716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                        c.getString(Queries.Query.PHOTO_THUMBNAIL_URI),
218ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                        true);
219ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
220ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                /*
221ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                 * In certain situations, we may have two results for one address, where one of the
222ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                 * results is just the email address, and the other has a name and photo, so we want
223ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                 * to use the better one.
224ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                 */
225ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                final RecipientEntry recipientEntry =
226ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                        getBetterRecipient(recipientEntries.get(address), newRecipientEntry);
227ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
228ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                recipientEntries.put(address, recipientEntry);
22916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                if (Log.isLoggable(TAG, Log.DEBUG)) {
23016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                    Log.d(TAG, "Received reverse look up information for " + address
23116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                            + " RESULTS: "
23216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                            + " NAME : " + c.getString(Queries.Query.NAME)
23316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                            + " CONTACT ID : " + c.getLong(Queries.Query.CONTACT_ID)
23416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                            + " ADDRESS :" + c.getString(Queries.Query.DESTINATION));
23516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                }
23616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            } while (c.moveToNext());
23716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        }
2381852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira        return recipientEntries;
2391852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira    }
2401852931de1e24e77cb708f4ba010eaa269426657Mindy Pereira
241ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy    /**
242ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy     * Given two {@link RecipientEntry}s for the same email address, this will return the one that
243ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy     * contains more complete information for display purposes. Defaults to <code>entry2</code> if
244ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy     * no significant differences are found.
245ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy     */
24678f38a09c9753c0ac1838ce0bfd3a6bc1a307ff7Scott Kennedy    static RecipientEntry getBetterRecipient(final RecipientEntry entry1,
247ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy            final RecipientEntry entry2) {
248ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        // If only one has passed in, use it
249ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        if (entry2 == null) {
250ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy            return entry1;
251ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        }
252ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
253ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        if (entry1 == null) {
254ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy            return entry2;
255ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        }
256ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
257ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        // If only one has a display name, use it
258ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        if (!TextUtils.isEmpty(entry1.getDisplayName())
259ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                && TextUtils.isEmpty(entry2.getDisplayName())) {
260ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy            return entry1;
261ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        }
262ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
263ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        if (!TextUtils.isEmpty(entry2.getDisplayName())
264ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                && TextUtils.isEmpty(entry1.getDisplayName())) {
265ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy            return entry2;
266ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        }
267ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
268ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        // If only one has a display name that is not the same as the destination, use it
269ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        if (!TextUtils.equals(entry1.getDisplayName(), entry1.getDestination())
270ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                && TextUtils.equals(entry2.getDisplayName(), entry2.getDestination())) {
271ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy            return entry1;
272ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        }
273ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
274ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        if (!TextUtils.equals(entry2.getDisplayName(), entry2.getDestination())
275ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                && TextUtils.equals(entry1.getDisplayName(), entry1.getDestination())) {
276ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy            return entry2;
277ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        }
278ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
279ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        // If only one has a photo, use it
280ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        if ((entry1.getPhotoThumbnailUri() != null || entry1.getPhotoBytes() != null)
281ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                && (entry2.getPhotoThumbnailUri() == null && entry2.getPhotoBytes() == null)) {
282ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy            return entry1;
283ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        }
284ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
285ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        if ((entry2.getPhotoThumbnailUri() != null || entry2.getPhotoBytes() != null)
286ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy                && (entry1.getPhotoThumbnailUri() == null && entry1.getPhotoBytes() == null)) {
287ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy            return entry2;
288ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        }
289ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
290ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        // Go with the second option as a default
291ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy        return entry2;
292ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy    }
293ef3f76c8c0e4fc83a0ab7fbe8db9a98cc1e2a357Scott Kennedy
29416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp    private static Cursor doQuery(CharSequence constraint, int limit, Long directoryId,
29516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            Account account, ContentResolver resolver, Query query) {
29616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        final Uri.Builder builder = query
29716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                .getContentFilterUri()
29816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                .buildUpon()
29916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                .appendPath(constraint.toString())
30016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY,
30116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                        String.valueOf(limit + BaseRecipientAdapter.ALLOWANCE_FOR_DUPLICATES));
30216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        if (directoryId != null) {
30316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
30416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                    String.valueOf(directoryId));
30516923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        }
30616923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        if (account != null) {
30716923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            builder.appendQueryParameter(BaseRecipientAdapter.PRIMARY_ACCOUNT_NAME, account.name);
30816923ee63a79fce4be3f62b08bcd1f80617c1205mindyp            builder.appendQueryParameter(BaseRecipientAdapter.PRIMARY_ACCOUNT_TYPE, account.type);
30916923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        }
31016923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        final Cursor cursor = resolver.query(builder.build(), query.getProjection(), null, null,
31116923ee63a79fce4be3f62b08bcd1f80617c1205mindyp                null);
31216923ee63a79fce4be3f62b08bcd1f80617c1205mindyp        return cursor;
31316923ee63a79fce4be3f62b08bcd1f80617c1205mindyp    }
31416923ee63a79fce4be3f62b08bcd1f80617c1205mindyp
315f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy    public RecipientAlternatesAdapter(Context context, long contactId, long currentId,
3165086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira            OnCheckedItemChangedListener listener) {
317f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy        this(context, contactId, currentId, QUERY_TYPE_EMAIL, listener);
31880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor    }
31980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor
320f7e202d8b83bfbd73ca47ba7843ebc4dd57c2fa4Scott Kennedy    public RecipientAlternatesAdapter(Context context, long contactId, long currentId,
32180f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor            int queryMode, OnCheckedItemChangedListener listener) {
32280f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        super(context, getCursorForConstruction(context, contactId, queryMode), 0);
32397d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira        mLayoutInflater = LayoutInflater.from(context);
32497d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira        mCurrentId = currentId;
3255086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira        mCheckedItemChangedListener = listener;
32680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor
32780f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        if (queryMode == QUERY_TYPE_EMAIL) {
32880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor            mQuery = Queries.EMAIL;
32980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        } else if (queryMode == QUERY_TYPE_PHONE) {
33080f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor            mQuery = Queries.PHONE;
33180f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        } else {
33280f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor            mQuery = Queries.EMAIL;
33380f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor            Log.e(TAG, "Unsupported query type: " + queryMode);
33480f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        }
33580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor    }
33680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor
33780f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor    private static Cursor getCursorForConstruction(Context context, long contactId, int queryType) {
338a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki        final Cursor cursor;
33980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        if (queryType == QUERY_TYPE_EMAIL) {
340a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki            cursor = context.getContentResolver().query(
34180f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                    Queries.EMAIL.getContentUri(),
34280f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                    Queries.EMAIL.getProjection(),
343a62ba492f901e024b249e0138e96374b09766a36Mindy Pereira                    Queries.EMAIL.getProjection()[Queries.Query.CONTACT_ID] + " =?", new String[] {
34480f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                        String.valueOf(contactId)
34580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                    }, null);
34680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        } else {
347a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki            cursor = context.getContentResolver().query(
34880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                    Queries.PHONE.getContentUri(),
34980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                    Queries.PHONE.getProjection(),
3509c17ab5f3bf0f88e3641faf98931c4f9e7d65366Tom Taylor                    Queries.PHONE.getProjection()[Queries.Query.CONTACT_ID] + " =?", new String[] {
35180f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                        String.valueOf(contactId)
35280f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                    }, null);
35380f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        }
354a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki        return removeDuplicateDestinations(cursor);
355a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki    }
356a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki
357a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki    /**
358a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki     * @return a new cursor based on the given cursor with all duplicate destinations removed.
359a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki     *
360a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki     * It's only intended to use for the alternate list, so...
361a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki     * - This method ignores all other fields and dedupe solely on the destination.  Normally,
362a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki     * if a cursor contains multiple contacts and they have the same destination, we'd still want
363a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki     * to show both.
364a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki     * - This method creates a MatrixCursor, so all data will be kept in memory.  We wouldn't want
365a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki     * to do this if the original cursor is large, but it's okay here because the alternate list
366a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki     * won't be that big.
367a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki     */
368a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki    // Visible for testing
369a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki    /* package */ static Cursor removeDuplicateDestinations(Cursor original) {
370a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki        final MatrixCursor result = new MatrixCursor(
371a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki                original.getColumnNames(), original.getCount());
372a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki        final HashSet<String> destinationsSeen = new HashSet<String>();
373a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki
374a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki        original.moveToPosition(-1);
375a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki        while (original.moveToNext()) {
376a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki            final String destination = original.getString(Query.DESTINATION);
377a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki            if (destinationsSeen.contains(destination)) {
378a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki                continue;
379a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki            }
380a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki            destinationsSeen.add(destination);
381a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki
382a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki            result.addRow(new Object[] {
383a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki                    original.getString(Query.NAME),
384a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki                    original.getString(Query.DESTINATION),
385a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki                    original.getInt(Query.DESTINATION_TYPE),
386a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki                    original.getString(Query.DESTINATION_LABEL),
387a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki                    original.getLong(Query.CONTACT_ID),
388a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki                    original.getLong(Query.DATA_ID),
389a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki                    original.getString(Query.PHOTO_THUMBNAIL_URI),
390a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki                    original.getInt(Query.DISPLAY_NAME_SOURCE)
391a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki                    });
392a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki        }
393a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki
394a5d37c8a968edf94755215617b593d3f61738a92Makoto Onuki        return result;
39597d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    }
39697d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira
39797d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    @Override
39897d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    public long getItemId(int position) {
39997d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira        Cursor c = getCursor();
4003bb52162b7e842243d4a14e73c15b20dbd1804d7Mindy Pereira        if (c.moveToPosition(position)) {
40180f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor            c.getLong(Queries.Query.DATA_ID);
4023bb52162b7e842243d4a14e73c15b20dbd1804d7Mindy Pereira        }
4033bb52162b7e842243d4a14e73c15b20dbd1804d7Mindy Pereira        return -1;
40497d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    }
40597d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira
40697d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    public RecipientEntry getRecipientEntry(int position) {
40797d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira        Cursor c = getCursor();
40897d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira        c.moveToPosition(position);
40980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        return RecipientEntry.constructTopLevelEntry(
41080f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                c.getString(Queries.Query.NAME),
41100adb32f3cea49ec82467c0e1a9e42659b556836Makoto Onuki                c.getInt(Queries.Query.DISPLAY_NAME_SOURCE),
41280f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                c.getString(Queries.Query.DESTINATION),
41380f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                c.getInt(Queries.Query.DESTINATION_TYPE),
41480f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                c.getString(Queries.Query.DESTINATION_LABEL),
41580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                c.getLong(Queries.Query.CONTACT_ID),
41680f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                c.getLong(Queries.Query.DATA_ID),
417ccb8e237ec80934d1c983bb61f66b75541786ddcmindyp                c.getString(Queries.Query.PHOTO_THUMBNAIL_URI),
418ccb8e237ec80934d1c983bb61f66b75541786ddcmindyp                true);
41997d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    }
42097d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira
42197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    @Override
42297d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    public View getView(int position, View convertView, ViewGroup parent) {
42367ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira        Cursor cursor = getCursor();
42467ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira        cursor.moveToPosition(position);
42597d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira        if (convertView == null) {
426007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira            convertView = newView();
427007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira        }
42880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        if (cursor.getLong(Queries.Query.DATA_ID) == mCurrentId) {
429007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira            mCheckedItemPosition = position;
4305086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira            if (mCheckedItemChangedListener != null) {
4315086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira                mCheckedItemChangedListener.onCheckedItemChanged(mCheckedItemPosition);
4325086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira            }
43397d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira        }
43467ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira        bindView(convertView, convertView.getContext(), cursor);
43597d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira        return convertView;
43697d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    }
43797d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira
43867ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira    // TODO: this is VERY similar to the BaseRecipientAdapter. Can we combine
43967ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira    // somehow?
44097d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    @Override
44197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    public void bindView(View view, Context context, Cursor cursor) {
44267ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira        int position = cursor.getPosition();
44367ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira
444102cf10189b2c13045b885a5479333ae3b304491Daisuke Miyakawa        TextView display = (TextView) view.findViewById(android.R.id.title);
44567ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira        ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);
44667ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira        RecipientEntry entry = getRecipientEntry(position);
44767ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira        if (position == 0) {
44880f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor            display.setText(cursor.getString(Queries.Query.NAME));
44967ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira            display.setVisibility(View.VISIBLE);
45067ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira            // TODO: see if this needs to be done outside the main thread
45167ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira            // as it may be too slow to get immediately.
45267ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira            imageView.setImageURI(entry.getPhotoThumbnailUri());
45367ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira            imageView.setVisibility(View.VISIBLE);
45467ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira        } else {
45567ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira            display.setVisibility(View.GONE);
45667ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira            imageView.setVisibility(View.GONE);
45767ad489cd290f7d2b468b4d69ce679edeac9bb7aMindy Pereira        }
458102cf10189b2c13045b885a5479333ae3b304491Daisuke Miyakawa        TextView destination = (TextView) view.findViewById(android.R.id.text1);
45980f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor        destination.setText(cursor.getString(Queries.Query.DESTINATION));
460102cf10189b2c13045b885a5479333ae3b304491Daisuke Miyakawa
461102cf10189b2c13045b885a5479333ae3b304491Daisuke Miyakawa        TextView destinationType = (TextView) view.findViewById(android.R.id.text2);
462f908b64e75e0bb38ff2806232ca57c93189156eaMindy Pereira        if (destinationType != null) {
46380f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor            destinationType.setText(mQuery.getTypeLabel(context.getResources(),
46480f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                    cursor.getInt(Queries.Query.DESTINATION_TYPE),
46580f4abfb682426384e88fb1dddc682be1c8a6c7fTom Taylor                    cursor.getString(Queries.Query.DESTINATION_LABEL)).toString().toUpperCase());
466f908b64e75e0bb38ff2806232ca57c93189156eaMindy Pereira        }
46797d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    }
46897d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira
46997d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    @Override
47097d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    public View newView(Context context, Cursor cursor, ViewGroup parent) {
471007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira        return newView();
472007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira    }
473007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira
474007a76baab414c9d432d31c661668b1bd07e3f80Mindy Pereira    private View newView() {
47552c441e2c03e0f48572348953b985a4bf989c057Mindy Pereira        return mLayoutInflater.inflate(R.layout.chips_recipient_dropdown_item, null);
47697d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    }
47797d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira
4785086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira    /*package*/ static interface OnCheckedItemChangedListener {
4795086391a478c3b1badbb86074c3cef72126c7d0fMindy Pereira        public void onCheckedItemChanged(int position);
48097d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira    }
48197d7768576ff27d779d68f77e23925b69f3290bcMindy Pereira}
482