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

Commit 663d614c authored by Flavio Lerda's avatar Flavio Lerda Committed by Android (Google) Code Review
Browse files

Merge "Use ContactsContract.PhoneLookup to look up SIP addresses." into ics-mr1

parents 42f6d6de d70e5ad6
Loading
Loading
Loading
Loading
+53 −109
Original line number Diff line number Diff line
@@ -21,9 +21,7 @@ import com.android.contacts.util.UriUtils;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract.CommonDataKinds.SipAddress;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.PhoneLookup;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
@@ -96,87 +94,42 @@ public class ContactInfoHelper {
    }

    /**
     * Determines the contact information for the given SIP address.
     * Looks up a contact using the given URI.
     * <p>
     * It returns the contact info if found.
     * It returns null if an error occurs, {@link ContactInfo#EMPTY} if no matching contact is
     * found, or the {@link ContactInfo} for the given contact.
     * <p>
     * If no contact corresponds to the given SIP address, returns {@link ContactInfo#EMPTY}.
     * <p>
     * If the lookup fails for some other reason, it returns null.
     * The {@link ContactInfo#formattedNumber} field is always set to {@code null} in the returned
     * value.
     */
    private ContactInfo queryContactInfoForSipAddress(String sipAddress) {
    private ContactInfo lookupContactFromUri(Uri uri) {
        final ContactInfo info;

        // TODO: This code is duplicated from the
        // CallerInfoAsyncQuery class.  To avoid that, could the
        // code here just use CallerInfoAsyncQuery, rather than
        // manually running ContentResolver.query() itself?

        // We look up SIP addresses directly in the Data table:
        Uri contactRef = Data.CONTENT_URI;

        // Note Data.DATA1 and SipAddress.SIP_ADDRESS are equivalent.
        //
        // Also note we use "upper(data1)" in the WHERE clause, and
        // uppercase the incoming SIP address, in order to do a
        // case-insensitive match.
        //
        // TODO: SIP URIs are defined as being case sensitive for the user part (before the '@')
        // and case insensitive everywhere else. We should change the code to handle this
        // accordingly.
        //
        // TODO: May also need to normalize by adding "sip:" as a
        // prefix, if we start storing SIP addresses that way in the
        // database.
        String selection = "upper(" + Data.DATA1 + ")=?"
                + " AND "
                + Data.MIMETYPE + "='" + SipAddress.CONTENT_ITEM_TYPE + "'";
        String[] selectionArgs = new String[] { sipAddress.toUpperCase() };

        Cursor dataTableCursor =
        Cursor phonesCursor =
                mContext.getContentResolver().query(
                        contactRef,
                        null,  // projection
                        selection,  // selection
                        selectionArgs,  // selectionArgs
                        null);  // sortOrder
                        uri, PhoneQuery._PROJECTION, null, null, null);

        if (dataTableCursor != null) {
            if (dataTableCursor.moveToFirst()) {
        if (phonesCursor != null) {
            try {
                if (phonesCursor.moveToFirst()) {
                    info = new ContactInfo();

                // TODO: we could slightly speed this up using an
                // explicit projection (and thus not have to do
                // those getColumnIndex() calls) but the benefit is
                // very minimal.

                // Note the Data.CONTACT_ID column here is
                // equivalent to the PERSON_ID_COLUMN_INDEX column
                // we use with "phonesCursor" below.
                long contactId = dataTableCursor.getLong(
                        dataTableCursor.getColumnIndex(Data.CONTACT_ID));
                String lookupKey = dataTableCursor.getString(
                        dataTableCursor.getColumnIndex(Data.LOOKUP_KEY));
                    long contactId = phonesCursor.getLong(PhoneQuery.PERSON_ID);
                    String lookupKey = phonesCursor.getString(PhoneQuery.LOOKUP_KEY);
                    info.lookupUri = Contacts.getLookupUri(contactId, lookupKey);
                info.name = dataTableCursor.getString(
                        dataTableCursor.getColumnIndex(Data.DISPLAY_NAME));
                // "type" and "label" are currently unused for SIP addresses
                info.type = SipAddress.TYPE_OTHER;
                info.label = null;

                // And "number" is the SIP address.
                // Note Data.DATA1 and SipAddress.SIP_ADDRESS are equivalent.
                info.number = dataTableCursor.getString(dataTableCursor.getColumnIndex(Data.DATA1));
                info.normalizedNumber = null;  // meaningless for SIP addresses
                info.photoId = dataTableCursor.getLong(
                        dataTableCursor.getColumnIndex(Data.PHOTO_ID));
                info.photoUri = UriUtils.parseUriOrNull(dataTableCursor.getString(
                        dataTableCursor.getColumnIndex(Data.PHOTO_URI)));
                info.formattedNumber = null;  // meaningless for SIP addresses
                    info.name = phonesCursor.getString(PhoneQuery.NAME);
                    info.type = phonesCursor.getInt(PhoneQuery.PHONE_TYPE);
                    info.label = phonesCursor.getString(PhoneQuery.LABEL);
                    info.number = phonesCursor.getString(PhoneQuery.MATCHED_NUMBER);
                    info.normalizedNumber = phonesCursor.getString(PhoneQuery.NORMALIZED_NUMBER);
                    info.photoId = phonesCursor.getLong(PhoneQuery.PHOTO_ID);
                    info.photoUri =
                            UriUtils.parseUriOrNull(phonesCursor.getString(PhoneQuery.PHOTO_URI));
                    info.formattedNumber = null;
                } else {
                    info = ContactInfo.EMPTY;
                }
            dataTableCursor.close();
            } finally {
                phonesCursor.close();
            }
        } else {
            // Failed to fetch the data, ignore this request.
            info = null;
@@ -184,6 +137,25 @@ public class ContactInfoHelper {
        return info;
    }

    /**
     * Determines the contact information for the given SIP address.
     * <p>
     * It returns the contact info if found.
     * <p>
     * If no contact corresponds to the given SIP address, returns {@link ContactInfo#EMPTY}.
     * <p>
     * If the lookup fails for some other reason, it returns null.
     */
    private ContactInfo queryContactInfoForSipAddress(String sipAddress) {
        final ContactInfo info;

        // "contactNumber" is a SIP address, so use the PhoneLookup table with the SIP parameter.
        Uri.Builder uriBuilder = PhoneLookup.CONTENT_FILTER_URI.buildUpon();
        uriBuilder.appendPath(Uri.encode(sipAddress));
        uriBuilder.appendQueryParameter(PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, "1");
        return lookupContactFromUri(uriBuilder.build());
    }

    /**
     * Determines the contact information for the given phone number.
     * <p>
@@ -194,8 +166,6 @@ public class ContactInfoHelper {
     * If the lookup fails for some other reason, it returns null.
     */
    private ContactInfo queryContactInfoForPhoneNumber(String number, String countryIso) {
        final ContactInfo info;

        String contactNumber = number;
        if (!TextUtils.isEmpty(countryIso)) {
            // Normalize the number: this is needed because the PhoneLookup query below does not
@@ -207,37 +177,11 @@ public class ContactInfoHelper {
            }
        }

        // "contactNumber" is a regular phone number, so use the
        // PhoneLookup table:
        Cursor phonesCursor =
                mContext.getContentResolver().query(
                    Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
                            Uri.encode(contactNumber)),
                            PhoneQuery._PROJECTION, null, null, null);

        if (phonesCursor != null) {
            if (phonesCursor.moveToFirst()) {
                info = new ContactInfo();
                long contactId = phonesCursor.getLong(PhoneQuery.PERSON_ID);
                String lookupKey = phonesCursor.getString(PhoneQuery.LOOKUP_KEY);
                info.lookupUri = Contacts.getLookupUri(contactId, lookupKey);
                info.name = phonesCursor.getString(PhoneQuery.NAME);
                info.type = phonesCursor.getInt(PhoneQuery.PHONE_TYPE);
                info.label = phonesCursor.getString(PhoneQuery.LABEL);
                info.number = phonesCursor.getString(PhoneQuery.MATCHED_NUMBER);
                info.normalizedNumber = phonesCursor.getString(PhoneQuery.NORMALIZED_NUMBER);
                info.photoId = phonesCursor.getLong(PhoneQuery.PHOTO_ID);
                info.photoUri =
                        UriUtils.parseUriOrNull(phonesCursor.getString(PhoneQuery.PHOTO_URI));
        // The "contactNumber" is a regular phone number, so use the PhoneLookup table.
        Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(contactNumber));
        ContactInfo info = lookupContactFromUri(uri);
        if (info != null && info != ContactInfo.EMPTY) {
            info.formattedNumber = formatPhoneNumber(number, null, countryIso);

            } else {
                info = ContactInfo.EMPTY;
            }
            phonesCursor.close();
        } else {
            // Failed to fetch the data, ignore this request.
            info = null;
        }
        return info;
    }