diff options
author | Dave Santoro <dsantoro@google.com> | 2011-12-22 15:53:59 -0800 |
---|---|---|
committer | Dave Santoro <dsantoro@google.com> | 2011-12-22 15:53:59 -0800 |
commit | 9357fc5b4f8d4646df6477138071a3bd931bb86e (patch) | |
tree | d9aeee0d81d909c21e2c14441de8b911c5b74fff | |
parent | 1bc8603830a07b4ff641bf74227c654c99a8473b (diff) | |
download | ContactsProvider-ics-mr1.tar.gz |
More aggressive fix for phone lookup issues.android-cts-4.0.3_r2ics-mr1
Rather than relying on a trailing suffix match on the longer of the
two numbers (the one from caller ID and the one in the database),
this first attempts to do the full internationalized-number-aware
query that we'd normally do, and if no results are returned, falls
back to a comparison of the trailing 7 digits of each number, as
we did in Gingerbread.
Also ports in Makoto's fix to the phone lookup tests.
Bug: 5742389
Change-Id: Idda8474337bedaced59916c2b0af87b62b737d83
4 files changed, 127 insertions, 5 deletions
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java index 8940c61a..f5f1a6aa 100644 --- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java +++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java @@ -4146,6 +4146,24 @@ import java.util.Locale; } /** + * As opposed to {@link #buildPhoneLookupAndContactQuery}, this phone lookup will only do + * a comparison based on the last seven digits of the given phone number. This is only intended + * to be used as a fallback, in case the regular lookup does not return any results. + * @param qb The query builder. + * @param number The phone number to search for. + */ + public void buildMinimalPhoneLookupAndContactQuery(SQLiteQueryBuilder qb, String number) { + String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number); + StringBuilder sb = new StringBuilder(); + appendPhoneLookupTables(sb, minMatch, true); + qb.setTables(sb.toString()); + + sb = new StringBuilder(); + appendPhoneLookupSelection(sb, null, null); + qb.appendWhere(sb.toString()); + } + + /** * Adds query for selecting the contact with the given {@code sipAddress} to the given * {@link StringBuilder}. * diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java index 120c0de5..59b21708 100644 --- a/src/com/android/providers/contacts/ContactsProvider2.java +++ b/src/com/android/providers/contacts/ContactsProvider2.java @@ -5770,6 +5770,30 @@ public class ContactsProvider2 extends AbstractContactsProvider mDbHelper.get().buildPhoneLookupAndContactQuery( qb, normalizedNumber, numberE164); qb.setProjectionMap(sPhoneLookupProjectionMap); + + // Peek at the results of the first query (which attempts to use fully + // normalized and internationalized numbers for comparison). If no results + // were returned, fall back to doing a match of the trailing 7 digits. + qb.setStrict(true); + boolean foundResult = false; + Cursor cursor = query(mActiveDb.get(), qb, projection, selection, selectionArgs, + sortOrder, groupBy, limit); + try { + if (cursor.getCount() > 0) { + foundResult = true; + return cursor; + } else { + qb = new SQLiteQueryBuilder(); + mDbHelper.get().buildMinimalPhoneLookupAndContactQuery( + qb, normalizedNumber); + qb.setProjectionMap(sPhoneLookupProjectionMap); + } + } finally { + if (!foundResult) { + // We'll be returning a different cursor, so close this one. + cursor.close(); + } + } } break; } diff --git a/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java b/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java index 6080f7ef..33a39ec1 100644 --- a/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java +++ b/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java @@ -57,6 +57,7 @@ import android.util.Log; import java.util.ArrayList; import java.util.Arrays; +import java.util.BitSet; import java.util.Comparator; import java.util.Iterator; import java.util.Map; @@ -1021,12 +1022,20 @@ public abstract class BaseContactsProvider2Test extends PhotoLoadingTestCase { protected void assertCursorValues(Cursor cursor, ContentValues[] expectedValues) { StringBuilder message = new StringBuilder(); + + // In case if expectedValues contains multiple identical values, remember which cursor + // rows are "consumed" to prevent multiple ContentValues from hitting the same row. + final BitSet used = new BitSet(cursor.getCount()); + for (ContentValues v : expectedValues) { boolean found = false; cursor.moveToPosition(-1); while (cursor.moveToNext()) { + final int pos = cursor.getPosition(); + if (used.get(pos)) continue; found = equalsWithExpectedValues(cursor, v, message); if (found) { + used.set(pos); break; } } diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java index eae168f4..cbb1c493 100644 --- a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java +++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java @@ -982,6 +982,9 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test { insertStructuredName(rawContactId, "Hot", "Tamale"); insertPhoneNumber(rawContactId, "18004664411"); + // We'll create two lookup records, 18004664411 and +18004664411, and the below lookup + // will match both. + Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411"); values.clear(); @@ -992,7 +995,7 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test { values.putNull(PhoneLookup.LABEL); values.put(PhoneLookup.CUSTOM_RINGTONE, "d"); values.put(PhoneLookup.SEND_TO_VOICEMAIL, 1); - assertStoredValues(lookupUri1, values); + assertStoredValues(lookupUri1, null, null, new ContentValues[] {values, values}); // In the context that 8004664411 is a valid number, "4664411" as a // call id should match to both "8004664411" and "+18004664411". @@ -1067,6 +1070,70 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test { assertEquals(1, getCount(lookupUri2, null, null)); } + public void testIntlPhoneLookupUseCases() { + // Checks the logic that relies on using the trailing 7-digits as a fallback for phone + // number lookups. + String fullNumber = "01197297427289"; + + ContentValues values = new ContentValues(); + values.put(RawContacts.CUSTOM_RINGTONE, "d"); + values.put(RawContacts.SEND_TO_VOICEMAIL, 1); + long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values)); + insertStructuredName(rawContactId, "Senor", "Chang"); + insertPhoneNumber(rawContactId, fullNumber); + + // Full number should definitely match. + assertEquals(2, getCount(Uri.withAppendedPath( + PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null)); + + // Shorter (local) number with 0 prefix should also match. + assertEquals(2, getCount(Uri.withAppendedPath( + PhoneLookup.CONTENT_FILTER_URI, "097427289"), null, null)); + + // Shorter (local) number with +0 prefix should also match. + assertEquals(2, getCount(Uri.withAppendedPath( + PhoneLookup.CONTENT_FILTER_URI, "+097427289"), null, null)); + + // Same shorter number with dashes should match. + assertEquals(2, getCount(Uri.withAppendedPath( + PhoneLookup.CONTENT_FILTER_URI, "09-742-7289"), null, null)); + + // Same shorter number with spaces should match. + assertEquals(2, getCount(Uri.withAppendedPath( + PhoneLookup.CONTENT_FILTER_URI, "09 742 7289"), null, null)); + + // Some other number should not match. + assertEquals(0, getCount(Uri.withAppendedPath( + PhoneLookup.CONTENT_FILTER_URI, "049102395"), null, null)); + } + + public void testPhoneLookupB5252190() { + // Test cases from b/5252190 + String storedNumber = "796010101"; + + ContentValues values = new ContentValues(); + values.put(RawContacts.CUSTOM_RINGTONE, "d"); + values.put(RawContacts.SEND_TO_VOICEMAIL, 1); + long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values)); + insertStructuredName(rawContactId, "Senor", "Chang"); + insertPhoneNumber(rawContactId, storedNumber); + + assertEquals(1, getCount(Uri.withAppendedPath( + PhoneLookup.CONTENT_FILTER_URI, "0796010101"), null, null)); + + assertEquals(1, getCount(Uri.withAppendedPath( + PhoneLookup.CONTENT_FILTER_URI, "+48796010101"), null, null)); + + assertEquals(1, getCount(Uri.withAppendedPath( + PhoneLookup.CONTENT_FILTER_URI, "48796010101"), null, null)); + + assertEquals(1, getCount(Uri.withAppendedPath( + PhoneLookup.CONTENT_FILTER_URI, "4-879-601-0101"), null, null)); + + assertEquals(1, getCount(Uri.withAppendedPath( + PhoneLookup.CONTENT_FILTER_URI, "4 879 601 0101"), null, null)); + } + public void testPhoneUpdate() { ContentValues values = new ContentValues(); Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values); @@ -1076,27 +1143,31 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test { Uri phoneUri = insertPhoneNumber(rawContactId, "18004664411"); Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411"); - assertStoredValue(lookupUri1, PhoneLookup.DISPLAY_NAME, "Hot Tamale"); + Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664422"); + assertEquals(2, getCount(lookupUri1, null, null)); + assertEquals(0, getCount(lookupUri2, null, null)); values.clear(); values.put(Phone.NUMBER, "18004664422"); mResolver.update(phoneUri, values, null, null); - Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664422"); - assertStoredValue(lookupUri2, PhoneLookup.DISPLAY_NAME, "Hot Tamale"); + assertEquals(0, getCount(lookupUri1, null, null)); + assertEquals(2, getCount(lookupUri2, null, null)); // Setting number to null will remove the phone lookup record values.clear(); values.putNull(Phone.NUMBER); mResolver.update(phoneUri, values, null, null); + assertEquals(0, getCount(lookupUri1, null, null)); assertEquals(0, getCount(lookupUri2, null, null)); // Let's restore that phone lookup record values.clear(); values.put(Phone.NUMBER, "18004664422"); mResolver.update(phoneUri, values, null, null); - assertStoredValue(lookupUri2, PhoneLookup.DISPLAY_NAME, "Hot Tamale"); + assertEquals(0, getCount(lookupUri1, null, null)); + assertEquals(2, getCount(lookupUri2, null, null)); assertNetworkNotified(true); } |