Merge "Send a broadcast when profile changes" into jb-mr1-dev
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index 62f49ae..95008d7 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -4453,20 +4453,35 @@
}
/**
- * 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.
+ * Phone lookup method that uses the custom SQLite function phone_number_compare_loose
+ * that serves 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);
+ public void buildFallbackPhoneLookupAndContactQuery(SQLiteQueryBuilder qb, String number) {
+ final String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number);
+ final StringBuilder sb = new StringBuilder();
+ //append lookup tables
+ sb.append(Tables.RAW_CONTACTS);
+ sb.append(" JOIN " + Views.CONTACTS + " as contacts_view"
+ + " ON (contacts_view._id = " + Tables.RAW_CONTACTS
+ + "." + RawContacts.CONTACT_ID + ")" +
+ " JOIN (SELECT " + PhoneLookupColumns.DATA_ID + "," +
+ PhoneLookupColumns.NORMALIZED_NUMBER + " FROM "+ Tables.PHONE_LOOKUP + " "
+ + "WHERE (" + Tables.PHONE_LOOKUP + "." + PhoneLookupColumns.MIN_MATCH + " = '");
+ sb.append(minMatch);
+ sb.append("')) AS lookup " +
+ "ON lookup." + PhoneLookupColumns.DATA_ID + "=" + Tables.DATA + "." + Data._ID
+ + " JOIN " + Tables.DATA + " "
+ + "ON " + Tables.DATA + "." + Data.RAW_CONTACT_ID + "=" + Tables.RAW_CONTACTS + "."
+ + RawContacts._ID);
+
qb.setTables(sb.toString());
- sb = new StringBuilder();
- appendPhoneLookupSelection(sb, null, null);
+ sb.setLength(0);
+ sb.append("PHONE_NUMBERS_EQUAL(" + Tables.DATA + "." + Phone.NUMBER + ", ");
+ DatabaseUtils.appendEscapedSQLString(sb, number);
+ sb.append(mUseStrictPhoneNumberComparison ? ", 1)" : ", 0)");
qb.appendWhere(sb.toString());
}
@@ -4526,28 +4541,33 @@
sb.append(" OR ");
}
if (hasNumber) {
- int numberLen = number.length();
- sb.append(" lookup.len <= ");
- sb.append(numberLen);
- sb.append(" AND substr(");
- DatabaseUtils.appendEscapedSQLString(sb, number);
- sb.append(',');
- sb.append(numberLen);
- sb.append(" - lookup.len + 1) = lookup.normalized_number");
+ // skip the suffix match entirely if we are using strict number comparison
+ if (!mUseStrictPhoneNumberComparison) {
+ int numberLen = number.length();
+ sb.append(" lookup.len <= ");
+ sb.append(numberLen);
+ sb.append(" AND substr(");
+ DatabaseUtils.appendEscapedSQLString(sb, number);
+ sb.append(',');
+ sb.append(numberLen);
+ sb.append(" - lookup.len + 1) = lookup.normalized_number");
- // Some countries (e.g. Brazil) can have incoming calls which contain only the local
- // number (no country calling code and no area code). This case is handled below.
- // Details see b/5197612.
- // This also handles a Gingerbread -> ICS upgrade issue; see b/5638376.
- sb.append(" OR (");
- sb.append(" lookup.len > ");
- sb.append(numberLen);
- sb.append(" AND substr(lookup.normalized_number,");
- sb.append("lookup.len + 1 - ");
- sb.append(numberLen);
- sb.append(") = ");
- DatabaseUtils.appendEscapedSQLString(sb, number);
- sb.append(")");
+ // Some countries (e.g. Brazil) can have incoming calls which contain only the local
+ // number (no country calling code and no area code). This case is handled below.
+ // Details see b/5197612.
+ // This also handles a Gingerbread -> ICS upgrade issue; see b/5638376.
+ sb.append(" OR (");
+ sb.append(" lookup.len > ");
+ sb.append(numberLen);
+ sb.append(" AND substr(lookup.normalized_number,");
+ sb.append("lookup.len + 1 - ");
+ sb.append(numberLen);
+ sb.append(") = ");
+ DatabaseUtils.appendEscapedSQLString(sb, number);
+ sb.append(")");
+ } else {
+ sb.append("0");
+ }
}
sb.append(')');
}
@@ -5276,6 +5296,16 @@
}
@NeededForTesting
+ /* package */ void setUseStrictPhoneNumberComparisonForTest(boolean useStrict) {
+ mUseStrictPhoneNumberComparison = useStrict;
+ }
+
+ @NeededForTesting
+ /* package */ boolean getUseStrictPhoneNumberComparisonForTest() {
+ return mUseStrictPhoneNumberComparison;
+ }
+
+ @NeededForTesting
/* package */ String querySearchIndexContentForTest(long contactId) {
return DatabaseUtils.stringForQuery(getReadableDatabase(),
"SELECT " + SearchIndexColumns.CONTENT +
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index ef2ea9a..d236de3 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -5768,10 +5768,13 @@
selectionArgs = mDbHelper.get().buildSipContactQuery(sb, sipAddress);
selection = sb.toString();
} else {
+ // Use this flag to track whether sortOrder was originally empty
+ boolean sortOrderIsEmpty = false;
if (TextUtils.isEmpty(sortOrder)) {
// Default the sort order to something reasonable so we get consistent
// results when callers don't request an ordering
sortOrder = " length(lookup.normalized_number) DESC";
+ sortOrderIsEmpty = true;
}
String number = uri.getPathSegments().size() > 1
@@ -5786,7 +5789,8 @@
// 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.
+ // were returned, fall back to using the SQLite function
+ // phone_number_compare_loose.
qb.setStrict(true);
boolean foundResult = false;
Cursor cursor = query(db, qb, projection, selection, selectionArgs,
@@ -5796,9 +5800,15 @@
foundResult = true;
return cursor;
} else {
+ // Use fallback lookup method
+
qb = new SQLiteQueryBuilder();
- mDbHelper.get().buildMinimalPhoneLookupAndContactQuery(
- qb, normalizedNumber);
+
+ // use the raw number instead of the normalized number because
+ // phone_number_compare_loose in SQLite works only with non-normalized
+ // numbers
+ mDbHelper.get().buildFallbackPhoneLookupAndContactQuery(qb, number);
+
qb.setProjectionMap(sPhoneLookupProjectionMap);
}
} finally {
diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
index 003012e..77789c3 100644
--- a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
@@ -67,6 +67,7 @@
import android.text.TextUtils;
import com.android.internal.util.ArrayUtils;
+import com.android.providers.contacts.ContactsDatabaseHelper;
import com.android.providers.contacts.ContactsDatabaseHelper.AggregationExceptionColumns;
import com.android.providers.contacts.ContactsDatabaseHelper.DataUsageStatColumns;
import com.android.providers.contacts.ContactsDatabaseHelper.DbProperties;
@@ -1282,6 +1283,10 @@
// call id should match to both "8004664411" and "+18004664411".
Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "4664411");
assertEquals(2, getCount(lookupUri2, null, null));
+
+ // A wrong area code 799 vs 800 should not be matched
+ lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "7994664411");
+ assertEquals(0, getCount(lookupUri2, null, null));
}
public void testPhoneLookupUseCases() {
@@ -1310,6 +1315,18 @@
lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0000");
assertEquals(1, getCount(lookupUri2, null, null));
+ // does not match with wrong area code
+ lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "649 861 0000");
+ assertEquals(0, getCount(lookupUri2, null, null));
+
+ // does not match with missing digits in mistyped area code
+ lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "5 861 0000");
+ assertEquals(0, getCount(lookupUri2, null, null));
+
+ // does not match with missing digit in mistyped area code
+ lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "65 861 0000");
+ assertEquals(0, getCount(lookupUri2, null, null));
+
// National format in contacts
values.clear();
values.put(RawContacts.CUSTOM_RINGTONE, "d");
@@ -1352,8 +1369,8 @@
}
public void testIntlPhoneLookupUseCases() {
- // Checks the logic that relies on using the trailing 7-digits as a fallback for phone
- // number lookups.
+ // Checks the logic that relies on phone_number_compare_loose(Gingerbread) as a fallback
+ //for phone number lookups.
String fullNumber = "01197297427289";
ContentValues values = new ContentValues();
@@ -1371,9 +1388,9 @@
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));
+ // Number with international (+972) prefix should also match.
+ assertEquals(1, getCount(Uri.withAppendedPath(
+ PhoneLookup.CONTENT_FILTER_URI, "+97297427289"), null, null));
// Same shorter number with dashes should match.
assertEquals(2, getCount(Uri.withAppendedPath(
@@ -1415,6 +1432,63 @@
PhoneLookup.CONTENT_FILTER_URI, "4 879 601 0101"), null, null));
}
+ public void testPhoneLookupUseStrictPhoneNumberCompare() {
+ // Test lookup cases when mUseStrictPhoneNumberComparison is true
+ final ContactsProvider2 cp = (ContactsProvider2) getProvider();
+ final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
+ // Get and save the original value of mUseStrictPhoneNumberComparison so that we
+ // can restore it when we are done with the test
+ final boolean oldUseStrict = dbHelper.getUseStrictPhoneNumberComparisonForTest();
+ dbHelper.setUseStrictPhoneNumberComparisonForTest(true);
+
+
+ try {
+ 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);
+ insertPhoneNumber(rawContactId, "5103337596");
+ insertPhoneNumber(rawContactId, "+19012345678");
+ // One match for full number
+ assertEquals(1, getCount(Uri.withAppendedPath(
+ PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
+
+ // No matches for extra digit at the front
+ assertEquals(0, getCount(Uri.withAppendedPath(
+ PhoneLookup.CONTENT_FILTER_URI, "55103337596"), null, null));
+ // No matches for mispelled area code
+ assertEquals(0, getCount(Uri.withAppendedPath(
+ PhoneLookup.CONTENT_FILTER_URI, "5123337596"), null, null));
+
+ // One match for matching number with dashes
+ assertEquals(1, getCount(Uri.withAppendedPath(
+ PhoneLookup.CONTENT_FILTER_URI, "510-333-7596"), null, null));
+
+ // One match for matching number with international code
+ assertEquals(1, getCount(Uri.withAppendedPath(
+ PhoneLookup.CONTENT_FILTER_URI, "+1-510-333-7596"), null, null));
+ values.clear();
+
+ // No matches for extra 0 in front
+ assertEquals(0, getCount(Uri.withAppendedPath(
+ PhoneLookup.CONTENT_FILTER_URI, "0-510-333-7596"), null, null));
+ values.clear();
+
+ // No matches for different country code
+ assertEquals(0, getCount(Uri.withAppendedPath(
+ PhoneLookup.CONTENT_FILTER_URI, "+819012345678"), null, null));
+ values.clear();
+ } finally {
+ // restore the original value of mUseStrictPhoneNumberComparison
+ // upon test completion or failure
+ dbHelper.setUseStrictPhoneNumberComparisonForTest(oldUseStrict);
+ }
+ }
+
public void testPhoneUpdate() {
ContentValues values = new ContentValues();
Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);