Merge "Use ContactsContract.PhoneLookup to look up SIP addresses." into ics-mr1
diff --git a/src/com/android/contacts/calllog/ContactInfoHelper.java b/src/com/android/contacts/calllog/ContactInfoHelper.java
index 95ea6dc..b4e4cf7 100644
--- a/src/com/android/contacts/calllog/ContactInfoHelper.java
+++ b/src/com/android/contacts/calllog/ContactInfoHelper.java
@@ -21,9 +21,7 @@
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,6 +94,50 @@
}
/**
+ * Looks up a contact using the given URI.
+ * <p>
+ * 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>
+ * The {@link ContactInfo#formattedNumber} field is always set to {@code null} in the returned
+ * value.
+ */
+ private ContactInfo lookupContactFromUri(Uri uri) {
+ final ContactInfo info;
+ Cursor phonesCursor =
+ mContext.getContentResolver().query(
+ uri, PhoneQuery._PROJECTION, null, null, null);
+
+ if (phonesCursor != null) {
+ try {
+ 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));
+ info.formattedNumber = null;
+ } else {
+ info = ContactInfo.EMPTY;
+ }
+ } finally {
+ phonesCursor.close();
+ }
+ } else {
+ // Failed to fetch the data, ignore this request.
+ info = null;
+ }
+ return info;
+ }
+
+ /**
* Determines the contact information for the given SIP address.
* <p>
* It returns the contact info if found.
@@ -107,81 +149,11 @@
private ContactInfo queryContactInfoForSipAddress(String sipAddress) {
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 =
- mContext.getContentResolver().query(
- contactRef,
- null, // projection
- selection, // selection
- selectionArgs, // selectionArgs
- null); // sortOrder
-
- if (dataTableCursor != null) {
- if (dataTableCursor.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));
- 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
- } else {
- info = ContactInfo.EMPTY;
- }
- dataTableCursor.close();
- } else {
- // Failed to fetch the data, ignore this request.
- info = null;
- }
- return 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());
}
/**
@@ -194,8 +166,6 @@
* 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 @@
}
}
- // "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));
- info.formattedNumber = formatPhoneNumber(number, null, countryIso);
-
- } else {
- info = ContactInfo.EMPTY;
- }
- phonesCursor.close();
- } else {
- // Failed to fetch the data, ignore this request.
- info = null;
+ // 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);
}
return info;
}