diff options
3 files changed, 112 insertions, 9 deletions
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java index fc4d343..564bd4c 100644 --- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java +++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java @@ -4818,7 +4818,14 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper { return mMimeTypeIdSip; } - public int getDisplayNameSourceForMimeTypeId(int mimeTypeId) { + /** + * Returns a {@link ContactsContract.DisplayNameSources} value based on {@param mimeTypeId}. + * This does not return {@link ContactsContract.DisplayNameSources#STRUCTURED_PHONETIC_NAME}. + * The calling client needs to inspect the structured name itself to distinguish between + * {@link ContactsContract.DisplayNameSources#STRUCTURED_NAME} and + * {@code STRUCTURED_PHONETIC_NAME}. + */ + private int getDisplayNameSourceForMimeTypeId(int mimeTypeId) { if (mimeTypeId == mMimeTypeIdStructuredName) { return DisplayNameSources.STRUCTURED_NAME; } @@ -5540,6 +5547,22 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper { while (c.moveToNext()) { int mimeType = c.getInt(RawContactNameQuery.MIMETYPE); int source = getDisplayNameSourceForMimeTypeId(mimeType); + + if (source == DisplayNameSources.STRUCTURED_NAME) { + final String given = c.getString(RawContactNameQuery.GIVEN_NAME); + final String middle = c.getString(RawContactNameQuery.MIDDLE_NAME); + final String family = c.getString(RawContactNameQuery.FAMILY_NAME); + final String suffix = c.getString(RawContactNameQuery.SUFFIX); + final String prefix = c.getString(RawContactNameQuery.PREFIX); + if (TextUtils.isEmpty(given) && TextUtils.isEmpty(middle) + && TextUtils.isEmpty(family) && TextUtils.isEmpty(suffix) + && TextUtils.isEmpty(prefix)) { + // Every non-phonetic name component is empty. Therefore, lets lower the + // source score to STRUCTURED_PHONETIC_NAME. + source = DisplayNameSources.STRUCTURED_PHONETIC_NAME; + } + } + if (source < bestDisplayNameSource || source == DisplayNameSources.UNDEFINED) { continue; } @@ -5626,7 +5649,8 @@ public class ContactsDatabaseHelper extends SQLiteOpenHelper { String sortKeyAlternative = null; int displayNameStyle = FullNameStyle.UNDEFINED; - if (bestDisplayNameSource == DisplayNameSources.STRUCTURED_NAME) { + if (bestDisplayNameSource == DisplayNameSources.STRUCTURED_NAME + || bestDisplayNameSource == DisplayNameSources.STRUCTURED_PHONETIC_NAME) { displayNameStyle = bestName.fullNameStyle; if (displayNameStyle == FullNameStyle.CJK || displayNameStyle == FullNameStyle.UNDEFINED) { diff --git a/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java b/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java index 204875b..43fc488 100644 --- a/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java +++ b/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java @@ -1618,6 +1618,74 @@ public class ContactAggregatorTest extends BaseContactsProvider2Test { cursor.close(); } + public void testAggregation_phoneticNamePriority1() { + // Setup: one raw contact has a complex phonetic name and the other a simple given name + long rawContactId1 = RawContactUtil.createRawContact(mResolver, ACCOUNT_1); + DataUtil.insertPhoneticName(mResolver, rawContactId1, "name phonetic"); + long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, null, + "name", ACCOUNT_1); + + // Action: aggregate + setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, + rawContactId2); + + // Verify: given name is used instead of phonetic, contrary to results of + // testAggregation_nameComplexity + long contactId = queryContactId(rawContactId1); + assertEquals("name", queryDisplayName(contactId)); + } + + // Same as testAggregation_phoneticNamePriority1, but with setup order reversed + public void testAggregation_phoneticNamePriority2() { + // Setup: one raw contact has a complex phonetic name and the other a simple given name + long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, null, + "name", ACCOUNT_1); + long rawContactId1 = RawContactUtil.createRawContact(mResolver, ACCOUNT_1); + DataUtil.insertPhoneticName(mResolver, rawContactId1, "name phonetic"); + + // Action: aggregate + setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, + rawContactId2); + + // Verify: given name is used instead of phonetic, contrary to results of + // testAggregation_nameComplexity + long contactId = queryContactId(rawContactId1); + assertEquals("name", queryDisplayName(contactId)); + } + + public void testAggregation_nameComplexity1() { + // Setup: two names, one of which is unambiguously more complex + long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, null, + "name", ACCOUNT_1); + long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, null, + "name phonetic", ACCOUNT_1); + + // Action: aggregate + setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, + rawContactId2); + + // Verify: more complex name is used + long contactId = queryContactId(rawContactId1); + assertEquals("name phonetic", queryDisplayName(contactId)); + } + + // Same as testAggregation_nameComplexity1, but with setup order reversed + public void testAggregation_nameComplexity2() { + // Setup: two names, one of which is unambiguously more complex + long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, null, + "name phonetic", ACCOUNT_1); + long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, null, + "name", ACCOUNT_1); + + // Action: aggregate + setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, + rawContactId2); + + // Verify: more complex name is used + long contactId = queryContactId(rawContactId1); + assertEquals("name phonetic", queryDisplayName(contactId)); + } + public void testAggregation_clearSuperPrimary() { // Three types of mime-type super primary merging are tested here // 1. both raw contacts have super primary phone numbers diff --git a/tests/src/com/android/providers/contacts/testutil/DataUtil.java b/tests/src/com/android/providers/contacts/testutil/DataUtil.java index 1f4f35a..2afd567 100644 --- a/tests/src/com/android/providers/contacts/testutil/DataUtil.java +++ b/tests/src/com/android/providers/contacts/testutil/DataUtil.java @@ -59,14 +59,14 @@ public class DataUtil { public static Uri insertStructuredName( ContentResolver resolver, long rawContactId, String givenName, String familyName, - String phoneticGiven) { - return insertStructuredName(resolver, rawContactId, givenName, familyName, phoneticGiven, + String phoneticFamily) { + return insertStructuredName(resolver, rawContactId, givenName, familyName, phoneticFamily, /* isSuperPrimary = true */ false); } public static Uri insertStructuredName( ContentResolver resolver, long rawContactId, String givenName, String familyName, - String phoneticGiven, boolean isSuperPrimary) { + String phoneticFamily, boolean isSuperPrimary) { ContentValues values = new ContentValues(); StringBuilder sb = new StringBuilder(); if (givenName != null) { @@ -78,14 +78,16 @@ public class DataUtil { if (familyName != null) { sb.append(familyName); } - if (sb.length() == 0 && phoneticGiven != null) { - sb.append(phoneticGiven); + if (sb.length() == 0 && phoneticFamily != null) { + sb.append(phoneticFamily); } values.put(StructuredName.DISPLAY_NAME, sb.toString()); values.put(StructuredName.GIVEN_NAME, givenName); values.put(StructuredName.FAMILY_NAME, familyName); - if (phoneticGiven != null) { - values.put(StructuredName.PHONETIC_GIVEN_NAME, phoneticGiven); + if (phoneticFamily != null) { + // When creating phonetic names, be careful to use PHONETIC_FAMILY_NAME instead of + // PHONETIC_GIVEN_NAME, to work around b/19612393. + values.put(StructuredName.PHONETIC_FAMILY_NAME, phoneticFamily); } if (isSuperPrimary) { values.put(Data.IS_PRIMARY, 1); @@ -94,4 +96,13 @@ public class DataUtil { return insertStructuredName(resolver, rawContactId, values); } + + public static Uri insertPhoneticName(ContentResolver resolver, long rawContactId, + String phoneticFamilyName) { + ContentValues values = new ContentValues(); + // When creating phonetic names, be careful to use PHONETIC_FAMILY_NAME instead of + // PHONETIC_GIVEN_NAME, to work around b/19612393. + values.put(StructuredName.PHONETIC_FAMILY_NAME, phoneticFamilyName); + return insertStructuredName(resolver, rawContactId, values); + } }
\ No newline at end of file |