diff options
author | Brian Attwell <brianattwell@google.com> | 2015-01-27 19:07:27 -0800 |
---|---|---|
committer | Brian Attwell <brianattwell@google.com> | 2015-01-30 14:53:53 -0800 |
commit | f256a7cf7f78d5ff2573358eb2eadd6f3a2ec9db (patch) | |
tree | 8a309aa80ec9e908f5ee104207fe4ffd17c522f7 | |
parent | aa7951f3147076cbcb70ec85bb4351600378806a (diff) | |
download | packages_providers_ContactsProvider-f256a7cf7f78d5ff2573358eb2eadd6f3a2ec9db.zip packages_providers_ContactsProvider-f256a7cf7f78d5ff2573358eb2eadd6f3a2ec9db.tar.gz packages_providers_ContactsProvider-f256a7cf7f78d5ff2573358eb2eadd6f3a2ec9db.tar.bz2 |
Remove NAME_VERIFIED. Part3
Support use of IS_SUPER_PRIMARY instead of NAME_VERIFIED.
The contact aggregator now pays attention to
IS_SUPER_PRIMARY.
Remove all references to NAME_VERIFIED from CP2.
Bug: 18777272
Change-Id: I1579a3122b2d45b80de7106a2b9616e323855045
5 files changed, 122 insertions, 91 deletions
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java index d8f9330..f1ce638 100644 --- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java +++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java @@ -445,8 +445,6 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper { Tables.RAW_CONTACTS + "." + DISPLAY_NAME; public static final String CONCRETE_CONTACT_ID = Tables.RAW_CONTACTS + "." + RawContacts.CONTACT_ID; - public static final String CONCRETE_NAME_VERIFIED = - Tables.RAW_CONTACTS + "." + RawContacts.NAME_VERIFIED; public static final String PHONEBOOK_LABEL_PRIMARY = ContactsColumns.PHONEBOOK_LABEL_PRIMARY; public static final String PHONEBOOK_BUCKET_PRIMARY = @@ -455,6 +453,13 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper { ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE; public static final String PHONEBOOK_BUCKET_ALTERNATIVE = ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE; + + /** + * This column is no longer used, but we keep it in the table so an upgraded database + * will look the same as a new database. This reduces the chance of OEMs adding a second + * column with the same name. + */ + public static final String NAME_VERIFIED_OBSOLETE = "name_verified"; } public interface ViewRawContactsColumns { @@ -1230,7 +1235,7 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper { ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," + RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE + " TEXT," + RawContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE + " INTEGER," + - RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0," + + RawContactsColumns.NAME_VERIFIED_OBSOLETE + " INTEGER NOT NULL DEFAULT 0," + RawContacts.SYNC1 + " TEXT, " + RawContacts.SYNC2 + " TEXT, " + RawContacts.SYNC3 + " TEXT, " + @@ -1838,8 +1843,6 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper { + AccountsColumns.CONCRETE_DATA_SET + " END) AS " + RawContacts.ACCOUNT_TYPE_AND_DATA_SET + "," + RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + "," - + RawContactsColumns.CONCRETE_NAME_VERIFIED + " AS " - + RawContacts.NAME_VERIFIED + "," + RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + "," + RawContactsColumns.CONCRETE_DIRTY + " AS " + RawContacts.DIRTY + "," + RawContactsColumns.CONCRETE_SYNC1 + " AS " + RawContacts.SYNC1 + "," @@ -3180,7 +3183,7 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper { private void upgrateToVersion206(SQLiteDatabase db) { db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS - + " ADD " + RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0;"); + + " ADD name_verified INTEGER NOT NULL DEFAULT 0;"); } /** @@ -5405,26 +5408,6 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper { } /** - * Resets the {@link RawContacts#NAME_VERIFIED} flag to 0 on all other raw - * contacts in the same aggregate - */ - public void resetNameVerifiedForOtherRawContacts(long rawContactId) { - if (mResetNameVerifiedForOtherRawContacts == null) { - mResetNameVerifiedForOtherRawContacts = getWritableDatabase().compileStatement( - "UPDATE " + Tables.RAW_CONTACTS + - " SET " + RawContacts.NAME_VERIFIED + "=0" + - " WHERE " + RawContacts.CONTACT_ID + "=(" + - "SELECT " + RawContacts.CONTACT_ID + - " FROM " + Tables.RAW_CONTACTS + - " WHERE " + RawContacts._ID + "=?)" + - " AND " + RawContacts._ID + "!=?"); - } - mResetNameVerifiedForOtherRawContacts.bindLong(1, rawContactId); - mResetNameVerifiedForOtherRawContacts.bindLong(2, rawContactId); - mResetNameVerifiedForOtherRawContacts.execute(); - } - - /** * Updates a raw contact display name based on data rows, e.g. structured name, * organization, email etc. */ diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java index aa804c3..06d198e 100644 --- a/src/com/android/providers/contacts/ContactsProvider2.java +++ b/src/com/android/providers/contacts/ContactsProvider2.java @@ -605,7 +605,6 @@ public class ContactsProvider2 extends AbstractContactsProvider RawContacts.DATA_SET, RawContacts.ACCOUNT_TYPE_AND_DATA_SET, RawContacts.DIRTY, - RawContacts.NAME_VERIFIED, RawContacts.SOURCE_ID, RawContacts.VERSION, }; @@ -666,7 +665,6 @@ public class ContactsProvider2 extends AbstractContactsProvider .add(RawContacts.DATA_SET) .add(RawContacts.ACCOUNT_TYPE_AND_DATA_SET) .add(RawContacts.DIRTY) - .add(RawContacts.NAME_VERIFIED) .add(RawContacts.SOURCE_ID) .add(RawContacts.VERSION) .build(); @@ -4410,14 +4408,6 @@ public class ContactsProvider2 extends AbstractContactsProvider if (values.containsKey(RawContacts.SOURCE_ID)) { aggregator.updateLookupKeyForRawContact(db, rawContactId); } - if (flagExists(values, RawContacts.NAME_VERIFIED)) { - // If setting NAME_VERIFIED for this raw contact, reset it for all - // other raw contacts in the same aggregate - if (flagIsSet(values, RawContacts.NAME_VERIFIED)) { - mDbHelper.get().resetNameVerifiedForOtherRawContacts(rawContactId); - } - aggregator.updateDisplayNameForRawContact(db, rawContactId); - } if (requestUndoDelete && previousDeleted == 1) { // Note before the accounts refactoring, we used to use the *old* account here, // which doesn't make sense, so now we pass the *new* account. diff --git a/src/com/android/providers/contacts/aggregation/ContactAggregator.java b/src/com/android/providers/contacts/aggregation/ContactAggregator.java index 2c16f92..a970d3b 100644 --- a/src/com/android/providers/contacts/aggregation/ContactAggregator.java +++ b/src/com/android/providers/contacts/aggregation/ContactAggregator.java @@ -260,7 +260,7 @@ public class ContactAggregator { long rawContactId; String displayName; int displayNameSource; - boolean verified; + boolean isNameSuperPrimary; boolean writableAccount; public DisplayNameCandidate() { @@ -271,7 +271,7 @@ public class ContactAggregator { rawContactId = -1; displayName = null; displayNameSource = DisplayNameSources.UNDEFINED; - verified = false; + isNameSuperPrimary = false; writableAccount = false; } } @@ -396,11 +396,11 @@ public class ContactAggregator { // Query used to retrieve data from raw contacts to populate the corresponding aggregate mRawContactsQueryByRawContactId = String.format(Locale.US, RawContactsQuery.SQL_FORMAT_BY_RAW_CONTACT_ID, - mMimeTypeIdPhoto, mMimeTypeIdPhone); + mDbHelper.getMimeTypeIdForStructuredName(), mMimeTypeIdPhoto, mMimeTypeIdPhone); mRawContactsQueryByContactId = String.format(Locale.US, RawContactsQuery.SQL_FORMAT_BY_CONTACT_ID, - mMimeTypeIdPhoto, mMimeTypeIdPhone); + mDbHelper.getMimeTypeIdForStructuredName(), mMimeTypeIdPhoto, mMimeTypeIdPhone); } public void setEnabled(boolean enabled) { @@ -1981,6 +1981,13 @@ public class ContactAggregator { } private interface RawContactsQuery { + String SQL_FORMAT_HAS_SUPER_PRIMARY_NAME = + " EXISTS(SELECT 1 " + + " FROM " + Tables.DATA + " d " + + " WHERE d." + DataColumns.MIMETYPE_ID + "=%d " + + " AND d." + Data.RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + + " AND d." + Data.IS_SUPER_PRIMARY + "=1)"; + String SQL_FORMAT = "SELECT " + RawContactsColumns.CONCRETE_ID + "," @@ -1996,11 +2003,11 @@ public class ContactAggregator { + RawContacts.TIMES_CONTACTED + "," + RawContacts.STARRED + "," + RawContacts.PINNED + "," - + RawContacts.NAME_VERIFIED + "," + DataColumns.CONCRETE_ID + "," + DataColumns.CONCRETE_MIMETYPE_ID + "," + Data.IS_SUPER_PRIMARY + "," - + Photo.PHOTO_FILE_ID + + + Photo.PHOTO_FILE_ID + "," + + SQL_FORMAT_HAS_SUPER_PRIMARY_NAME + " FROM " + Tables.RAW_CONTACTS + " JOIN " + Tables.ACCOUNTS + " ON (" + AccountsColumns.CONCRETE_ID + "=" + RawContactsColumns.CONCRETE_ACCOUNT_ID @@ -2032,11 +2039,11 @@ public class ContactAggregator { int TIMES_CONTACTED = 10; int STARRED = 11; int PINNED = 12; - int NAME_VERIFIED = 13; - int DATA_ID = 14; - int MIMETYPE_ID = 15; - int IS_SUPER_PRIMARY = 16; - int PHOTO_FILE_ID = 17; + int DATA_ID = 13; + int MIMETYPE_ID = 14; + int IS_SUPER_PRIMARY = 15; + int PHOTO_FILE_ID = 16; + int HAS_SUPER_PRIMARY_NAME = 17; } private interface ContactReplaceSqlStatement { @@ -2149,10 +2156,10 @@ public class ContactAggregator { // Display name String displayName = c.getString(RawContactsQuery.DISPLAY_NAME); int displayNameSource = c.getInt(RawContactsQuery.DISPLAY_NAME_SOURCE); - int nameVerified = c.getInt(RawContactsQuery.NAME_VERIFIED); + int isNameSuperPrimary = c.getInt(RawContactsQuery.HAS_SUPER_PRIMARY_NAME); processDisplayNameCandidate(rawContactId, displayName, displayNameSource, mContactsProvider.isWritableAccountWithDataSet(accountWithDataSet), - nameVerified != 0); + isNameSuperPrimary != 0); // Contact options if (!c.isNull(RawContactsQuery.SEND_TO_VOICEMAIL)) { @@ -2283,17 +2290,17 @@ public class ContactAggregator { * {@link #mDisplayNameCandidate} with the new values. */ private void processDisplayNameCandidate(long rawContactId, String displayName, - int displayNameSource, boolean writableAccount, boolean verified) { + int displayNameSource, boolean writableAccount, boolean isNameSuperPrimary) { boolean replace = false; if (mDisplayNameCandidate.rawContactId == -1) { // No previous values available replace = true; } else if (!TextUtils.isEmpty(displayName)) { - if (!mDisplayNameCandidate.verified && verified) { - // A verified name is better than any other name + if (isNameSuperPrimary) { + // A super primary name is better than any other name replace = true; - } else if (mDisplayNameCandidate.verified == verified) { + } else if (mDisplayNameCandidate.isNameSuperPrimary == isNameSuperPrimary) { if (mDisplayNameCandidate.displayNameSource < displayNameSource) { // New values come from an superior source, e.g. structured name vs phone number replace = true; @@ -2315,7 +2322,7 @@ public class ContactAggregator { mDisplayNameCandidate.rawContactId = rawContactId; mDisplayNameCandidate.displayName = displayName; mDisplayNameCandidate.displayNameSource = displayNameSource; - mDisplayNameCandidate.verified = verified; + mDisplayNameCandidate.isNameSuperPrimary = isNameSuperPrimary; mDisplayNameCandidate.writableAccount = writableAccount; } } @@ -2463,19 +2470,29 @@ public class ContactAggregator { } private interface DisplayNameQuery { - String[] COLUMNS = new String[] { - RawContacts._ID, - RawContactsColumns.DISPLAY_NAME, - RawContactsColumns.DISPLAY_NAME_SOURCE, - RawContacts.NAME_VERIFIED, - RawContacts.SOURCE_ID, - RawContacts.ACCOUNT_TYPE_AND_DATA_SET, - }; + String SQL_HAS_SUPER_PRIMARY_NAME = + " EXISTS(SELECT 1 " + + " FROM " + Tables.DATA + " d " + + " WHERE d." + DataColumns.MIMETYPE_ID + "=? " + + " AND d." + Data.RAW_CONTACT_ID + "=" + Views.RAW_CONTACTS + + "." + RawContacts._ID + + " AND d." + Data.IS_SUPER_PRIMARY + "=1)"; + + String SQL = + "SELECT " + + RawContacts._ID + "," + + RawContactsColumns.DISPLAY_NAME + "," + + RawContactsColumns.DISPLAY_NAME_SOURCE + "," + + SQL_HAS_SUPER_PRIMARY_NAME + "," + + RawContacts.SOURCE_ID + "," + + RawContacts.ACCOUNT_TYPE_AND_DATA_SET + + " FROM " + Views.RAW_CONTACTS + + " WHERE " + RawContacts.CONTACT_ID + "=? "; int _ID = 0; int DISPLAY_NAME = 1; int DISPLAY_NAME_SOURCE = 2; - int NAME_VERIFIED = 3; + int HAS_SUPER_PRIMARY_NAME = 3; int SOURCE_ID = 4; int ACCOUNT_TYPE_AND_DATA_SET = 5; } @@ -2494,20 +2511,20 @@ public class ContactAggregator { mDisplayNameCandidate.clear(); - mSelectionArgs1[0] = String.valueOf(contactId); - final Cursor c = db.query(Views.RAW_CONTACTS, DisplayNameQuery.COLUMNS, - RawContacts.CONTACT_ID + "=?", mSelectionArgs1, null, null, null); + mSelectionArgs2[0] = String.valueOf(mDbHelper.getMimeTypeIdForStructuredName()); + mSelectionArgs2[1] = String.valueOf(contactId); + final Cursor c = db.rawQuery(DisplayNameQuery.SQL, mSelectionArgs2); try { while (c.moveToNext()) { long rawContactId = c.getLong(DisplayNameQuery._ID); String displayName = c.getString(DisplayNameQuery.DISPLAY_NAME); int displayNameSource = c.getInt(DisplayNameQuery.DISPLAY_NAME_SOURCE); - int nameVerified = c.getInt(DisplayNameQuery.NAME_VERIFIED); + int isNameSuperPrimary = c.getInt(DisplayNameQuery.HAS_SUPER_PRIMARY_NAME); String accountTypeAndDataSet = c.getString( DisplayNameQuery.ACCOUNT_TYPE_AND_DATA_SET); processDisplayNameCandidate(rawContactId, displayName, displayNameSource, mContactsProvider.isWritableAccountWithDataSet(accountTypeAndDataSet), - nameVerified != 0); + isNameSuperPrimary != 0); // If the raw contact has no source id, the lookup key is based on the display // name, so the lookup key needs to be updated. diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java index 482a072..d8dc737 100644 --- a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java +++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java @@ -318,7 +318,6 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test { RawContacts.DISPLAY_NAME_SOURCE, RawContacts.PHONETIC_NAME, RawContacts.PHONETIC_NAME_STYLE, - RawContacts.NAME_VERIFIED, RawContacts.SORT_KEY_PRIMARY, RawContacts.SORT_KEY_ALTERNATIVE, RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, @@ -384,7 +383,6 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test { RawContacts.SOURCE_ID, RawContacts.VERSION, RawContacts.DIRTY, - RawContacts.NAME_VERIFIED, RawContacts.RAW_CONTACT_IS_USER_PROFILE, Contacts._ID, Contacts.DISPLAY_NAME_PRIMARY, @@ -550,7 +548,6 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test { RawContacts.VERSION, RawContacts.DELETED, RawContacts.DIRTY, - RawContacts.NAME_VERIFIED, RawContacts.SYNC1, RawContacts.SYNC2, RawContacts.SYNC3, @@ -609,7 +606,6 @@ public class ContactsProvider2Test extends BaseContactsProvider2Test { RawContacts.SOURCE_ID, RawContacts.VERSION, RawContacts.DIRTY, - RawContacts.NAME_VERIFIED, RawContacts.DELETED, RawContacts.SYNC1, RawContacts.SYNC2, diff --git a/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java b/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java index c8e6810..204875b 100644 --- a/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java +++ b/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java @@ -1315,34 +1315,79 @@ public class ContactAggregatorTest extends BaseContactsProvider2Test { assertEquals("Eclair Android", queryDisplayName(contactId)); } - public void testVerifiedName() { - long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "test1", "TEST1", - ACCOUNT_1); - storeValue(RawContacts.CONTENT_URI, rawContactId1, RawContacts.NAME_VERIFIED, "1"); - long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "test2", "TEST2", - ACCOUNT_2); - long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "test3", - "TEST3 LONG", ACCOUNT_3); + public void testMergeSuperPrimaryName_rawContact1() { + // Setup: raw contact #1 has a super primary name. #2 doesn't. + long rawContactId1 = RawContactUtil.createRawContact(mResolver, ACCOUNT_1); + DataUtil.insertStructuredName(mResolver, rawContactId1, "name1", null, null, + /* isSuperPrimary = */ true); + long rawContactId2 = RawContactUtil.createRawContact(mResolver, ACCOUNT_1); + DataUtil.insertStructuredName(mResolver, rawContactId2, "name2", null, null, + /* isSuperPrimary = */ false); + // Action: aggregate setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2); + + // Verify: the aggregate's name comes from raw contact #1 + long contactId = queryContactId(rawContactId1); + assertEquals("name1", queryDisplayName(contactId)); + } + + public void testMergeSuperPrimaryName_rawContact2AndEdit() { + // Setup: raw contact #2 has a super primary name. #1 doesn't. + long rawContactId1 = RawContactUtil.createRawContact(mResolver, ACCOUNT_1); + final Uri nameUri1 = DataUtil.insertStructuredName(mResolver, rawContactId1, "name1", + null, null, /* isSuperPrimary = */ false); + long rawContactId2 = RawContactUtil.createRawContact(mResolver, ACCOUNT_1); + final Uri nameUri2 = DataUtil.insertStructuredName(mResolver, rawContactId2, "name2", null, + null, /* isSuperPrimary = */ true); + + // Action: aggregate setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, - rawContactId3); + rawContactId2); + // Verify: the aggregate's name comes from raw contact #2. This is the opposite of the check + // inside testMergeSuperPrimaryName_rawContact1(). long contactId = queryContactId(rawContactId1); + assertEquals("name2", queryDisplayName(contactId)); - // Should be the verified name - assertEquals("test1 TEST1", queryDisplayName(contactId)); + // Action: edit the super primary name + final ContentValues values = new ContentValues(); + values.put(StructuredName.GIVEN_NAME, "edited name"); + mResolver.update(nameUri2, values, null, null); - // Mark a different name as verified - this should reset the NAME_VERIFIED field - // for the other rawContacts - storeValue(RawContacts.CONTENT_URI, rawContactId2, RawContacts.NAME_VERIFIED, "1"); - assertStoredValue(RawContacts.CONTENT_URI, rawContactId1, RawContacts.NAME_VERIFIED, 0); - assertEquals("test2 TEST2", queryDisplayName(contactId)); + // Verify: editing the super primary name affects aggregate name + assertEquals("edited name", queryDisplayName(contactId)); - // Reset the NAME_VERIFIED flag - now the most complex of the three names should win - storeValue(RawContacts.CONTENT_URI, rawContactId2, RawContacts.NAME_VERIFIED, "0"); - assertEquals("test3 TEST3 LONG", queryDisplayName(contactId)); + // Action: edit the non primary name + values.put(StructuredName.GIVEN_NAME, "edited name2"); + mResolver.update(nameUri1, values, null, null); + + // Verify: aggregate name is still based off the primary name + assertEquals("edited name", queryDisplayName(contactId)); + } + + public void testMergedSuperPrimaryName_changeSuperPrimary() { + // Setup: aggregated contact where raw contact #1 has a super primary name. #2 doesn't. + long rawContactId1 = RawContactUtil.createRawContact(mResolver, ACCOUNT_1); + final Uri nameUri1 = DataUtil.insertStructuredName(mResolver, rawContactId1, "name1", + null, null, /* isSuperPrimary = */ true); + long rawContactId2 = RawContactUtil.createRawContact(mResolver, ACCOUNT_1); + final Uri nameUri2 = DataUtil.insertStructuredName(mResolver, rawContactId2, "name2", null, + null, /* isSuperPrimary = */ false); + setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, + rawContactId2); + + // Action: make raw contact 2's name super primary + storeValue(nameUri2, Data.IS_SUPER_PRIMARY, 1); + + // Sanity check. + assertStoredValue(nameUri1, Data.IS_SUPER_PRIMARY, 0); + assertStoredValue(nameUri2, Data.IS_SUPER_PRIMARY, 1); + + // Verify: aggregate name is based off of the newly super primary name + long contactId = queryContactId(rawContactId1); + assertEquals("name2", queryDisplayName(contactId)); } public void testAggregationModeSuspendedSeparateTransactions() { |