Improved the phone lookup and the phone filter
a. Altered the phone_lookup table to allow the rows with the same data_id.
b. Added E164 and normalized number for a phone number if it is applicable.
c. Improve the phone lookup by using the build in SQLite function.
d. Improve the phone filter by using 'Like filterparam%'
Change-Id: I1b23d0a10e46ef26467fb72528a7999d23e36c5e
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 24e8a54..0bf3cb4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -12,6 +12,8 @@
<uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.cp" />
<uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_READ" />
<uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application android:process="android.process.acore"
android:label="@string/app_label"
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index 03f93a8..ad3ab72 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -34,6 +34,7 @@
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.database.sqlite.SQLiteStatement;
+import android.location.CountryDetector;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -87,7 +88,7 @@
* 400-499 Honeycomb
* </pre>
*/
- static final int DATABASE_VERSION = 404;
+ static final int DATABASE_VERSION = 405;
private static final String DATABASE_NAME = "contacts2.db";
private static final String DATABASE_PRESENCE = "presence_db";
@@ -785,7 +786,7 @@
// Private phone numbers table used for lookup
db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" +
PhoneLookupColumns.DATA_ID
- + " INTEGER PRIMARY KEY REFERENCES data(_id) NOT NULL," +
+ + " INTEGER REFERENCES data(_id) NOT NULL," +
PhoneLookupColumns.RAW_CONTACT_ID
+ " INTEGER REFERENCES raw_contacts(_id) NOT NULL," +
PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," +
@@ -1584,6 +1585,12 @@
oldVersion = 404;
}
+ if (oldVersion == 404) {
+ upgradeViewsAndTriggers = true;
+ upgradeToVersion405(db);
+ oldVersion = 405;
+ }
+
if (upgradeViewsAndTriggers) {
createContactsViews(db);
createGroupsView(db);
@@ -2530,6 +2537,72 @@
+ " ADD is_read_only INTEGER NOT NULL DEFAULT 0;");
}
+ private void upgradeToVersion405(SQLiteDatabase db) {
+ db.execSQL("DROP TABLE IF EXISTS phone_lookup;");
+ // Private phone numbers table used for lookup
+ db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" +
+ PhoneLookupColumns.DATA_ID
+ + " INTEGER REFERENCES data(_id) NOT NULL," +
+ PhoneLookupColumns.RAW_CONTACT_ID
+ + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," +
+ PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," +
+ PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" +
+ ");");
+
+ db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" +
+ PhoneLookupColumns.NORMALIZED_NUMBER + "," +
+ PhoneLookupColumns.RAW_CONTACT_ID + "," +
+ PhoneLookupColumns.DATA_ID +
+ ");");
+
+ db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" +
+ PhoneLookupColumns.MIN_MATCH + "," +
+ PhoneLookupColumns.RAW_CONTACT_ID + "," +
+ PhoneLookupColumns.DATA_ID +
+ ");");
+
+ final long mimeTypeId = lookupMimeTypeId(db, Phone.CONTENT_ITEM_TYPE);
+ if (mimeTypeId == -1) {
+ return;
+ }
+
+ String mCountryIso = getCountryIso();
+ Cursor cursor = db.rawQuery(
+ "SELECT _id, " + Phone.RAW_CONTACT_ID + ", " + Phone.NUMBER +
+ " FROM " + Tables.DATA +
+ " WHERE " + DataColumns.MIMETYPE_ID + "=" + mimeTypeId
+ + " AND " + Phone.NUMBER + " NOT NULL", null);
+
+ ContentValues phoneValues = new ContentValues();
+ try {
+ while (cursor.moveToNext()) {
+ long dataID = cursor.getLong(0);
+ long rawContactID = cursor.getLong(1);
+ String number = cursor.getString(2);
+ String numberE164 = PhoneNumberUtils.formatNumberToE164(number, mCountryIso);
+ String normalizedNumber = PhoneNumberUtils.normalizeNumber(number);
+ if (!TextUtils.isEmpty(normalizedNumber)) {
+ phoneValues.clear();
+ phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactID);
+ phoneValues.put(PhoneLookupColumns.DATA_ID, dataID);
+ phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber);
+ phoneValues.put(PhoneLookupColumns.MIN_MATCH,
+ PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber));
+ db.insert(Tables.PHONE_LOOKUP, null, phoneValues);
+
+ if (numberE164 != null && !numberE164.equals(normalizedNumber)) {
+ phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, numberE164);
+ phoneValues.put(PhoneLookupColumns.MIN_MATCH,
+ PhoneNumberUtils.toCallerIDMinMatch(numberE164));
+ db.insert(Tables.PHONE_LOOKUP, null, phoneValues);
+ }
+ }
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
public String extractHandleFromEmailAddress(String email) {
Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email);
if (tokens.length == 0) {
@@ -2856,30 +2929,15 @@
}
}
- public void buildPhoneLookupAndRawContactQuery(SQLiteQueryBuilder qb, String number) {
- String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number);
- qb.setTables(Tables.DATA_JOIN_RAW_CONTACTS +
- " JOIN " + Tables.PHONE_LOOKUP
- + " ON(" + DataColumns.CONCRETE_ID + "=" + PhoneLookupColumns.DATA_ID + ")");
-
- StringBuilder sb = new StringBuilder();
- sb.append(PhoneLookupColumns.MIN_MATCH + "='");
- sb.append(minMatch);
- sb.append("' AND PHONE_NUMBERS_EQUAL(data." + Phone.NUMBER + ", ");
- DatabaseUtils.appendEscapedSQLString(sb, number);
- sb.append(mUseStrictPhoneNumberComparison ? ", 1)" : ", 0)");
-
- qb.appendWhere(sb.toString());
- }
-
- public void buildPhoneLookupAndContactQuery(SQLiteQueryBuilder qb, String number) {
- String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number);
+ public void buildPhoneLookupAndContactQuery(
+ SQLiteQueryBuilder qb, String normalizedNumber, String numberE164) {
+ String minMatch = PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber);
StringBuilder sb = new StringBuilder();
appendPhoneLookupTables(sb, minMatch, true);
qb.setTables(sb.toString());
sb = new StringBuilder();
- appendPhoneLookupSelection(sb, number);
+ appendPhoneLookupSelection(sb, normalizedNumber, numberE164);
qb.appendWhere(sb.toString());
}
@@ -2889,7 +2947,7 @@
sb.append("(SELECT DISTINCT raw_contact_id" + " FROM ");
appendPhoneLookupTables(sb, minMatch, false);
sb.append(" WHERE ");
- appendPhoneLookupSelection(sb, number);
+ appendPhoneLookupSelection(sb, number, null);
sb.append(")");
return sb.toString();
}
@@ -2901,17 +2959,38 @@
sb.append(" JOIN " + getContactView() + " contacts_view"
+ " ON (contacts_view._id = raw_contacts.contact_id)");
}
- sb.append(", (SELECT data_id FROM phone_lookup "
- + "WHERE (" + Tables.PHONE_LOOKUP + "." + PhoneLookupColumns.MIN_MATCH + " = '");
+ sb.append(", (SELECT data_id, normalized_number, length(normalized_number) as len "
+ + " FROM phone_lookup " + " WHERE (" + Tables.PHONE_LOOKUP + "."
+ + PhoneLookupColumns.MIN_MATCH + " = '");
sb.append(minMatch);
sb.append("')) AS lookup, " + Tables.DATA);
}
- private void appendPhoneLookupSelection(StringBuilder sb, String number) {
- sb.append("lookup.data_id=data._id AND data.raw_contact_id=raw_contacts._id"
- + " AND PHONE_NUMBERS_EQUAL(data." + Phone.NUMBER + ", ");
- DatabaseUtils.appendEscapedSQLString(sb, number);
- sb.append(mUseStrictPhoneNumberComparison ? ", 1)" : ", 0)");
+ private void appendPhoneLookupSelection(StringBuilder sb, String number, String numberE164) {
+ sb.append("lookup.data_id=data._id AND data.raw_contact_id=raw_contacts._id");
+ boolean hasNumberE164 = !TextUtils.isEmpty(numberE164);
+ boolean hasNumber = !TextUtils.isEmpty(number);
+ if (hasNumberE164 || hasNumber) {
+ sb.append(" AND ( ");
+ if (hasNumberE164) {
+ sb.append(" lookup.normalized_number = ");
+ DatabaseUtils.appendEscapedSQLString(sb, numberE164);
+ }
+ if (hasNumberE164 && hasNumber) {
+ 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");
+ }
+ sb.append(')');
+ }
}
public String getUseStrictPhoneNumberComparisonParameter() {
@@ -3198,4 +3277,10 @@
return sb.toString();
}
+
+ protected String getCountryIso() {
+ CountryDetector detector =
+ (CountryDetector) mContext.getSystemService(Context.COUNTRY_DETECTOR);
+ return detector.detectCountry().getCountryIso();
+ }
}
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index 7828a3a..cdcceab 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -74,11 +74,16 @@
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.database.sqlite.SQLiteStatement;
+import android.location.Country;
+import android.location.CountryDetector;
+import android.location.CountryListener;
import android.net.Uri;
import android.net.Uri.Builder;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.HandlerThread;
import android.os.MemoryFile;
+import android.os.Process;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.preference.PreferenceManager;
@@ -1540,14 +1545,17 @@
long dataId;
if (values.containsKey(Phone.NUMBER)) {
String number = values.getAsString(Phone.NUMBER);
- String normalizedNumber = computeNormalizedNumber(number);
- values.put(PhoneColumns.NORMALIZED_NUMBER, normalizedNumber);
+ String numberE164 =
+ PhoneNumberUtils.formatNumberToE164(number, getCurrentCountryIso());
+ if (numberE164 != null) {
+ values.put(PhoneColumns.NORMALIZED_NUMBER, numberE164);
+ }
dataId = super.insert(db, rawContactId, values);
- updatePhoneLookup(db, rawContactId, dataId, number, normalizedNumber);
+ updatePhoneLookup(db, rawContactId, dataId, number, numberE164);
mContactAggregator.updateHasPhoneNumber(db, rawContactId);
fixRawContactDisplayName(db, rawContactId);
- if (normalizedNumber != null) {
+ if (numberE164 != null) {
triggerAggregation(rawContactId);
}
} else {
@@ -1561,10 +1569,16 @@
boolean callerIsSyncAdapter) {
String number = null;
String normalizedNumber = null;
+ String numberE164 = null;
if (values.containsKey(Phone.NUMBER)) {
number = values.getAsString(Phone.NUMBER);
- normalizedNumber = computeNormalizedNumber(number);
- values.put(PhoneColumns.NORMALIZED_NUMBER, normalizedNumber);
+ if (number != null) {
+ numberE164 =
+ PhoneNumberUtils.formatNumberToE164(number, getCurrentCountryIso());
+ }
+ if (numberE164 != null) {
+ values.put(PhoneColumns.NORMALIZED_NUMBER, numberE164);
+ }
}
if (!super.update(db, values, c, callerIsSyncAdapter)) {
@@ -1574,7 +1588,7 @@
if (values.containsKey(Phone.NUMBER)) {
long dataId = c.getLong(DataUpdateQuery._ID);
long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID);
- updatePhoneLookup(db, rawContactId, dataId, number, normalizedNumber);
+ updatePhoneLookup(db, rawContactId, dataId, number, numberE164);
mContactAggregator.updateHasPhoneNumber(db, rawContactId);
fixRawContactDisplayName(db, rawContactId);
triggerAggregation(rawContactId);
@@ -1596,28 +1610,28 @@
return count;
}
- private String computeNormalizedNumber(String number) {
- String normalizedNumber = null;
- if (number != null) {
- normalizedNumber = PhoneNumberUtils.getStrippedReversed(number);
- }
- return normalizedNumber;
- }
-
private void updatePhoneLookup(SQLiteDatabase db, long rawContactId, long dataId,
- String number, String normalizedNumber) {
+ String number, String numberE164) {
+ mSelectionArgs1[0] = String.valueOf(dataId);
+ db.delete(Tables.PHONE_LOOKUP, PhoneLookupColumns.DATA_ID + "=?", mSelectionArgs1);
if (number != null) {
- ContentValues phoneValues = new ContentValues();
- phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactId);
- phoneValues.put(PhoneLookupColumns.DATA_ID, dataId);
- phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber);
- phoneValues.put(PhoneLookupColumns.MIN_MATCH,
- PhoneNumberUtils.toCallerIDMinMatch(number));
+ String normalizedNumber = PhoneNumberUtils.normalizeNumber(number);
+ if (!TextUtils.isEmpty(normalizedNumber)) {
+ ContentValues phoneValues = new ContentValues();
+ phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactId);
+ phoneValues.put(PhoneLookupColumns.DATA_ID, dataId);
+ phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber);
+ phoneValues.put(PhoneLookupColumns.MIN_MATCH,
+ PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber));
+ db.insert(Tables.PHONE_LOOKUP, null, phoneValues);
- db.replace(Tables.PHONE_LOOKUP, null, phoneValues);
- } else {
- mSelectionArgs1[0] = String.valueOf(dataId);
- db.delete(Tables.PHONE_LOOKUP, PhoneLookupColumns.DATA_ID + "=?", mSelectionArgs1);
+ if (numberE164 != null && !numberE164.equals(normalizedNumber)) {
+ phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, numberE164);
+ phoneValues.put(PhoneLookupColumns.MIN_MATCH,
+ PhoneNumberUtils.toCallerIDMinMatch(numberE164));
+ db.insert(Tables.PHONE_LOOKUP, null, phoneValues);
+ }
+ }
}
}
@@ -1835,6 +1849,7 @@
private Locale mCurrentLocale;
+ private String mCurrentCountryIso;
@Override
@@ -1980,6 +1995,26 @@
return (mDb != null);
}
+ protected synchronized String getCurrentCountryIso() {
+ if (mCurrentCountryIso == null) {
+ final CountryDetector countryDetector =
+ (CountryDetector)getContext().getSystemService(Context.COUNTRY_DETECTOR);
+ mCurrentCountryIso = countryDetector.detectCountry().getCountryIso();
+ // Start a new thread to listen to the country change.
+ (new HandlerThread("country listener", Process.THREAD_PRIORITY_BACKGROUND) {
+ @Override
+ protected void onLooperPrepared() {
+ countryDetector.addCountryListener(new CountryListener() {
+ public void onCountryDetected(Country country) {
+ mCurrentCountryIso = country.getCountryIso();
+ }
+ }, null);
+ }
+ }).start();
+ }
+ return mCurrentCountryIso;
+ }
+
private void initDataRowHandlers() {
mDataRowHandlers = new HashMap<String, DataRowHandler>();
@@ -3091,12 +3126,16 @@
Cursor c = mDb.query(Tables.RAW_CONTACTS,
new String[]{RawContacts._ID, RawContacts.STARRED},
selection, selectionArgs, null, null, null);
- while (c.moveToNext()) {
- if (c.getLong(1) != 0) {
- final long rawContactId = c.getLong(0);
- insertDataGroupMembership(rawContactId, result);
- setRawContactDirty(rawContactId);
+ try {
+ while (c.moveToNext()) {
+ if (c.getLong(1) != 0) {
+ final long rawContactId = c.getLong(0);
+ insertDataGroupMembership(rawContactId, result);
+ setRawContactDirty(rawContactId);
+ }
}
+ } finally {
+ c.close();
}
}
@@ -4625,18 +4664,17 @@
hasCondition = true;
}
- if (isPhoneNumber(filterParam)) {
+ String number = PhoneNumberUtils.normalizeNumber(filterParam);
+ if (!TextUtils.isEmpty(number)) {
if (orNeeded) {
sb.append(" OR ");
}
- String number = PhoneNumberUtils.convertKeypadLettersToDigits(filterParam);
- String reversed = PhoneNumberUtils.getStrippedReversed(number);
sb.append(Data._ID +
- " IN (SELECT " + PhoneLookupColumns.DATA_ID
- + " FROM " + Tables.PHONE_LOOKUP
- + " WHERE " + PhoneLookupColumns.NORMALIZED_NUMBER + " LIKE '%");
- sb.append(reversed);
- sb.append("')");
+ " IN (SELECT DISTINCT " + PhoneLookupColumns.DATA_ID
+ + " FROM " + Tables.PHONE_LOOKUP
+ + " WHERE " + PhoneLookupColumns.NORMALIZED_NUMBER + " LIKE '");
+ sb.append(number);
+ sb.append("%')");
hasCondition = true;
}
@@ -4787,13 +4825,16 @@
if (TextUtils.isEmpty(sortOrder)) {
// Default the sort order to something reasonable so we get consistent
// results when callers don't request an ordering
- sortOrder = RawContactsColumns.CONCRETE_ID;
+ sortOrder = " length(lookup.normalized_number) DESC";
}
String number = uri.getPathSegments().size() > 1 ? uri.getLastPathSegment() : "";
- mDbHelper.buildPhoneLookupAndContactQuery(qb, number);
+ String numberE164 =
+ PhoneNumberUtils.formatNumberToE164(number, getCurrentCountryIso());
+ String normalizedNumber =
+ PhoneNumberUtils.normalizeNumber(number);
+ mDbHelper.buildPhoneLookupAndContactQuery(qb, normalizedNumber, numberE164);
qb.setProjectionMap(sPhoneLookupProjectionMap);
-
// Phone lookup cannot be combined with a selection
selection = null;
selectionArgs = null;
@@ -5703,36 +5744,6 @@
}
}
- /**
- * Returns true if all the characters are meaningful as digits
- * in a phone number -- letters, digits, and a few punctuation marks.
- */
- private boolean isPhoneNumber(CharSequence cons) {
- int len = cons.length();
-
- for (int i = 0; i < len; i++) {
- char c = cons.charAt(i);
-
- if ((c >= '0') && (c <= '9')) {
- continue;
- }
- if ((c == ' ') || (c == '-') || (c == '(') || (c == ')') || (c == '.') || (c == '+')
- || (c == '#') || (c == '*')) {
- continue;
- }
- if ((c >= 'A') && (c <= 'Z')) {
- continue;
- }
- if ((c >= 'a') && (c <= 'z')) {
- continue;
- }
-
- return false;
- }
-
- return true;
- }
-
String getContactsRestrictions() {
if (mDbHelper.hasAccessToRestrictedData()) {
return "1";
diff --git a/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java b/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
index 3f672e4..944e853 100644
--- a/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
@@ -732,6 +732,10 @@
assertStoredValues(rowUri, null, null, expectedValues);
}
+ protected void assertStoredValues(Uri rowUri, ContentValues[] expectedValues) {
+ assertStoredValues(rowUri, null, null, expectedValues);
+ }
+
protected void assertStoredValues(Uri rowUri, String selection, String[] selectionArgs,
ContentValues expectedValues) {
Cursor c = mResolver.query(rowUri, null, selection, selectionArgs, null);
@@ -755,6 +759,17 @@
}
}
+ protected void assertStoredValues(
+ Uri rowUri, String selection, String[] selectionArgs, ContentValues[] expectedValues) {
+ Cursor c = mResolver.query(rowUri, null, selection, selectionArgs, null);
+ try {
+ assertEquals("Record count", expectedValues.length, c.getCount());
+ assertCursorValues(c, expectedValues);
+ } finally {
+ c.close();
+ }
+ }
+
/**
* Constructs a selection (where clause) out of all supplied values, uses it
* to query the provider and verifies that a single row is returned and it
@@ -804,11 +819,36 @@
}
protected void assertCursorValues(Cursor cursor, ContentValues expectedValues) {
+ StringBuilder message = new StringBuilder();
+ boolean result = equalsWithExpectedValues(cursor, expectedValues, message);
+ assertTrue(message.toString(), result);
+ }
+
+ protected void assertCursorValues(Cursor cursor, ContentValues[] expectedValues) {
+ StringBuilder message = new StringBuilder();
+ for (ContentValues v : expectedValues) {
+ boolean found = false;
+ cursor.moveToPosition(-1);
+ while (cursor.moveToNext()) {
+ found = equalsWithExpectedValues(cursor, v, message);
+ if (found) {
+ break;
+ }
+ }
+ assertTrue("Expected values can not be found " + v + message.toString(), found);
+ }
+ }
+
+ private boolean equalsWithExpectedValues(Cursor cursor, ContentValues expectedValues,
+ StringBuilder msgBuffer) {
Set<Map.Entry<String, Object>> entries = expectedValues.valueSet();
for (Map.Entry<String, Object> entry : entries) {
String column = entry.getKey();
int index = cursor.getColumnIndex(column);
- assertTrue("No such column: " + column, index != -1);
+ if (index == -1) {
+ msgBuffer.append("No such column: ").append(column);
+ return false;
+ }
Object expectedValue = expectedValues.get(column);
String value;
if (expectedValue instanceof byte[]) {
@@ -818,8 +858,20 @@
expectedValue = expectedValues.getAsString(column);
value = cursor.getString(index);
}
- assertEquals("Column value " + column, expectedValue, value);
+ if (expectedValue != null && !expectedValue.equals(value) || value != null
+ && !value.equals(expectedValue)) {
+ msgBuffer
+ .append("Column value ")
+ .append(column)
+ .append(" expected <")
+ .append(expectedValue)
+ .append(">, but was <")
+ .append(value)
+ .append('>');
+ return false;
+ }
}
+ return true;
}
private String[] buildProjection(ContentValues values) {
diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
index db1edf0..8882869 100644
--- a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
@@ -891,16 +891,77 @@
values.put(PhoneLookup.SEND_TO_VOICEMAIL, 1);
assertStoredValues(lookupUri1, values);
- // The strict comparation, adopted in Donut, does not allow the behavior like
- // "8004664411 == 4664411", while the loose comparation, which had been used in Cupcake
- // and reverted back into the default in Eclair, allows it. Hmm...
- final boolean useStrictComparation =
- mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_use_strict_phone_number_comparation);
- final int expectedResult = (useStrictComparation ? 0 : 1);
-
+ // In the context that 8004664411 is a valid number, "4664411" as a
+ // call id should not match to "8004664411"
Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "4664411");
- assertEquals(expectedResult, getCount(lookupUri2, null, null));
+ assertEquals(0, getCount(lookupUri2, null, null));
+ }
+
+ public void testPhoneLookupUseCases() {
+ ContentValues values = new ContentValues();
+ Uri rawContactUri;
+ long rawContactId;
+ Uri lookupUri2;
+
+ values.put(RawContacts.CUSTOM_RINGTONE, "d");
+ values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
+
+ // International format in contacts
+ rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
+ rawContactId = ContentUris.parseId(rawContactUri);
+
+ insertStructuredName(rawContactId, "Hot", "Tamale");
+ insertPhoneNumber(rawContactId, "+1-650-861-0000");
+
+ values.clear();
+
+ // match with international format
+ lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0000");
+ assertEquals(1, getCount(lookupUri2, null, null));
+
+ // match with national format
+ lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0000");
+ assertEquals(1, getCount(lookupUri2, null, null));
+
+ // National format in contacts
+ values.clear();
+ values.put(RawContacts.CUSTOM_RINGTONE, "d");
+ values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
+ rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
+ rawContactId = ContentUris.parseId(rawContactUri);
+
+ insertStructuredName(rawContactId, "Hot1", "Tamale");
+ insertPhoneNumber(rawContactId, "650-861-0001");
+
+ values.clear();
+
+ // match with international format
+ lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0001");
+ assertEquals(2, getCount(lookupUri2, null, null));
+
+ // match with national format
+ lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0001");
+ assertEquals(2, getCount(lookupUri2, null, null));
+
+ // Local format in contacts
+ values.clear();
+ values.put(RawContacts.CUSTOM_RINGTONE, "d");
+ values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
+ rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
+ rawContactId = ContentUris.parseId(rawContactUri);
+
+ insertStructuredName(rawContactId, "Hot2", "Tamale");
+ insertPhoneNumber(rawContactId, "861-0002");
+
+ values.clear();
+
+ // match with international format
+ lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0002");
+ assertEquals(1, getCount(lookupUri2, null, null));
+
+ // match with national format
+ lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0002");
+ assertEquals(1, getCount(lookupUri2, null, null));
}
public void testPhoneUpdate() {
diff --git a/tests/src/com/android/providers/contacts/LegacyContactsProviderTest.java b/tests/src/com/android/providers/contacts/LegacyContactsProviderTest.java
index 85ed6a7..d2e4365 100644
--- a/tests/src/com/android/providers/contacts/LegacyContactsProviderTest.java
+++ b/tests/src/com/android/providers/contacts/LegacyContactsProviderTest.java
@@ -392,19 +392,22 @@
values.put(Phones.ISPRIMARY, 1);
Uri uri = mResolver.insert(Phones.CONTENT_URI, values);
-
+ ContentValues expectedResults[] = new ContentValues[2];
// Adding another value to assert
- values.put(Phones.NUMBER_KEY, "11446640081");
-
+ expectedResults[0] = new ContentValues(values);
+ expectedResults[0].put(Phones.NUMBER_KEY, "+18004664411");
+ expectedResults[1] = values;
+ expectedResults[1].put(Phones.NUMBER_KEY, "18004664411");
// The result is joined with People
- putContactValues(values);
- assertStoredValues(uri, values);
+ putContactValues(expectedResults[0]);
+ putContactValues(expectedResults[1]);
+ assertStoredValues(uri, expectedResults);
assertSelection(Phones.CONTENT_URI, values, "phones",
Phones._ID, ContentUris.parseId(uri));
// Access the phone through People
Uri twigUri = Uri.withAppendedPath(personUri, People.Phones.CONTENT_DIRECTORY);
- assertStoredValues(twigUri, values);
+ assertStoredValues(twigUri, expectedResults);
// Now the person should be joined with Phone
values.clear();
@@ -443,7 +446,12 @@
mResolver.update(uri, values, null, null);
- assertStoredValues(uri, values);
+ ContentValues[] expectedValues = new ContentValues[2];
+ expectedValues[0] = values;
+ expectedValues[0].put(Phones.NUMBER_KEY, "18005554663");
+ expectedValues[1] = new ContentValues(values);
+ expectedValues[1].put(Phones.NUMBER_KEY, "+18005554663");
+ assertStoredValues(uri, expectedValues);
}
public void testPhonesFilterQuery() {
@@ -456,13 +464,18 @@
values.put(Phones.PERSON_ID, personId);
values.put(Phones.TYPE, Phones.TYPE_CUSTOM);
values.put(Phones.LABEL, "Directory");
- values.put(Phones.NUMBER, "1-800-4664-411");
+ values.put(Phones.NUMBER, "800-4664-411");
values.put(Phones.ISPRIMARY, 1);
Uri uri = mResolver.insert(Phones.CONTENT_URI, values);
- Uri filterUri1 = Uri.withAppendedPath(Phones.CONTENT_FILTER_URL, "8004664411");
- assertStoredValues(filterUri1, values);
+ Uri filterUri1 = Uri.withAppendedPath(Phones.CONTENT_FILTER_URL, "18004664411");
+ ContentValues[] expectedValues = new ContentValues[2];
+ expectedValues[0] = values;
+ expectedValues[0].put(Phones.NUMBER_KEY, "8004664411");
+ expectedValues[1] = new ContentValues(values);
+ expectedValues[1].put(Phones.NUMBER_KEY, "+18004664411");
+ assertStoredValues(filterUri1, expectedValues);
Uri filterUri2 = Uri.withAppendedPath(Phones.CONTENT_FILTER_URL, "7773334444");
assertEquals(0, getCount(filterUri2, null, null));
diff --git a/tests/src/com/android/providers/contacts/SynchronousContactsProvider2.java b/tests/src/com/android/providers/contacts/SynchronousContactsProvider2.java
index ba8b7f8..a280bb2 100644
--- a/tests/src/com/android/providers/contacts/SynchronousContactsProvider2.java
+++ b/tests/src/com/android/providers/contacts/SynchronousContactsProvider2.java
@@ -38,7 +38,12 @@
@Override
protected ContactsDatabaseHelper getDatabaseHelper(final Context context) {
if (mDbHelper == null) {
- mDbHelper = new ContactsDatabaseHelper(context);
+ mDbHelper = new ContactsDatabaseHelper(context) {
+ @Override
+ protected String getCountryIso() {
+ return "US";
+ }
+ };
}
return mDbHelper;
}
@@ -166,4 +171,9 @@
// We have an explicit test for data conversion - no need to do it every time
return false;
}
+
+ @Override
+ protected String getCurrentCountryIso() {
+ return "us";
+ }
}