Remove default settings during contacts aggregation.

Set is_super_primary to 0 for all the shared mime-types's data
between aggregated contacts.

Bug:5080996
Change-Id: Ie65259c11d719b343f234e5fccf883491e7992a7
diff --git a/src/com/android/providers/contacts/aggregation/ContactAggregator.java b/src/com/android/providers/contacts/aggregation/ContactAggregator.java
index 390871c..e4044c2 100644
--- a/src/com/android/providers/contacts/aggregation/ContactAggregator.java
+++ b/src/com/android/providers/contacts/aggregation/ContactAggregator.java
@@ -797,6 +797,7 @@
                 mAggregatedPresenceDelete.execute();
             }
 
+            clearSuperPrimarySetting(db, contactId, rawContactId);
             setContactIdAndMarkAggregated(rawContactId, contactId);
             computeAggregateData(db, contactId, mContactUpdate);
             mContactUpdate.bindLong(ContactReplaceSqlStatement.CONTACT_ID, contactId);
@@ -815,6 +816,58 @@
     }
 
     /**
+     * Find out which mime-types are shared by raw contact of {@code rawContactId} and raw contacts
+     * of {@code contactId}. Clear the is_super_primary settings for these mime-types.
+     */
+    private void clearSuperPrimarySetting(SQLiteDatabase db, long contactId, long rawContactId) {
+        final String[] args = {String.valueOf(contactId), String.valueOf(rawContactId)};
+
+        // Find out which mime-types are shared by raw contact of rawContactId and raw contacts
+        // of contactId
+        int index = 0;
+        final StringBuilder mimeTypeCondition = new StringBuilder();
+        mimeTypeCondition.append(" AND " + DataColumns.MIMETYPE_ID + " IN (");
+
+        final Cursor c = db.rawQuery(
+                "SELECT DISTINCT(a." + DataColumns.MIMETYPE_ID + ")" +
+                " FROM (SELECT " + DataColumns.MIMETYPE_ID + " FROM " + Tables.DATA + " WHERE " +
+                        Data.RAW_CONTACT_ID + " IN (SELECT " + RawContacts._ID + " FROM " +
+                        Tables.RAW_CONTACTS + " WHERE " + RawContacts.CONTACT_ID + "=?1)) AS a" +
+                " JOIN  (SELECT " + DataColumns.MIMETYPE_ID + " FROM " + Tables.DATA + " WHERE "
+                        + Data.RAW_CONTACT_ID + "=?2) AS b" +
+                " ON a." + DataColumns.MIMETYPE_ID + "=b." + DataColumns.MIMETYPE_ID,
+                args);
+        try {
+            c.moveToPosition(-1);
+            while (c.moveToNext()) {
+                if (index > 0) {
+                    mimeTypeCondition.append(',');
+                }
+                mimeTypeCondition.append(c.getLong((0)));
+                index++;
+            }
+        } finally {
+            c.close();
+        }
+
+        // Clear is_super_primary setting for all the mime-types exist in both raw contact
+        // of rawContactId and raw contacts of contactId
+        String superPrimaryUpdateSql = "UPDATE " + Tables.DATA +
+                " SET " + Data.IS_SUPER_PRIMARY + "=0" +
+                " WHERE (" +  Data.RAW_CONTACT_ID +
+                        " IN (SELECT " + RawContacts._ID +  " FROM " + Tables.RAW_CONTACTS +
+                        " WHERE " + RawContacts.CONTACT_ID + "=?1)" +
+                        " OR " +  Data.RAW_CONTACT_ID + "=?2)";
+
+        if (index > 0) {
+            mimeTypeCondition.append(')');
+            superPrimaryUpdateSql += mimeTypeCondition.toString();
+        }
+
+        db.execSQL(superPrimaryUpdateSql, args);
+    }
+
+    /**
      * @return true if the raw contact of {@code rawContactId} can be joined into the existing
      * contact of {@code of contactId}.
      *
diff --git a/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java b/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
index b90e88b..ed0c06d 100644
--- a/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
@@ -232,16 +232,24 @@
     }
 
     protected Uri insertOrganization(long rawContactId, ContentValues values) {
-        return insertOrganization(rawContactId, values, false);
+        return insertOrganization(rawContactId, values, false, false);
     }
 
     protected Uri insertOrganization(long rawContactId, ContentValues values, boolean primary) {
+        return insertOrganization(rawContactId, values, primary, false);
+    }
+
+    protected Uri insertOrganization(long rawContactId, ContentValues values, boolean primary,
+            boolean superPrimary) {
         values.put(Data.RAW_CONTACT_ID, rawContactId);
         values.put(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE);
         values.put(Organization.TYPE, Organization.TYPE_WORK);
         if (primary) {
             values.put(Data.IS_PRIMARY, 1);
         }
+        if (superPrimary) {
+            values.put(Data.IS_SUPER_PRIMARY, 1);
+        }
 
         Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
         return resultUri;
@@ -252,11 +260,21 @@
     }
 
     protected Uri insertPhoneNumber(long rawContactId, String phoneNumber, boolean primary) {
-        return insertPhoneNumber(rawContactId, phoneNumber, primary, Phone.TYPE_HOME);
+        return insertPhoneNumber(rawContactId, phoneNumber, primary, false, Phone.TYPE_HOME);
+    }
+
+    protected Uri insertPhoneNumber(long rawContactId, String phoneNumber, boolean primary,
+            boolean superPrimary) {
+        return insertPhoneNumber(rawContactId, phoneNumber, primary, superPrimary, Phone.TYPE_HOME);
     }
 
     protected Uri insertPhoneNumber(long rawContactId, String phoneNumber, boolean primary,
             int type) {
+        return insertPhoneNumber(rawContactId, phoneNumber, primary, false, type);
+    }
+
+    protected Uri insertPhoneNumber(long rawContactId, String phoneNumber, boolean primary,
+            boolean superPrimary, int type) {
         ContentValues values = new ContentValues();
         values.put(Data.RAW_CONTACT_ID, rawContactId);
         values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
@@ -265,6 +283,9 @@
         if (primary) {
             values.put(Data.IS_PRIMARY, 1);
         }
+        if (superPrimary) {
+            values.put(Data.IS_SUPER_PRIMARY, 1);
+        }
 
         Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
         return resultUri;
@@ -712,6 +733,20 @@
         }
     }
 
+    protected void assertSuperPrimary(Long dataId, boolean isSuperPrimary) {
+        final String[] projection = new String[]{Data.MIMETYPE, Data._ID, Data.IS_SUPER_PRIMARY};
+        Cursor c = mResolver.query(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
+                projection, null, null, null);
+
+        c.moveToFirst();
+        if (isSuperPrimary) {
+            assertEquals(1, c.getInt(c.getColumnIndexOrThrow(Data.IS_SUPER_PRIMARY)));
+        } else {
+            assertEquals(0, c.getInt(c.getColumnIndexOrThrow(Data.IS_SUPER_PRIMARY)));
+        }
+
+    }
+
     protected void assertDataRow(ContentValues actual, String expectedMimetype,
             Object... expectedArguments) {
         assertEquals(actual.toString(), expectedMimetype, actual.getAsString(Data.MIMETYPE));
diff --git a/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java b/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java
index cb0766e..6ce98a7 100644
--- a/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java
+++ b/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java
@@ -1486,6 +1486,46 @@
         cursor.close();
     }
 
+    public void testAggregation_clearSuperPrimary() {
+        // Three types of mime-type super primary merging are tested here
+        // 1. both raw contacts have super primary phone numbers
+        // 2. both raw contacts have emails, but only one has super primary email
+        // 3. only raw contact1 has organizations and it has set the super primary organization
+        ContentValues values = new ContentValues();
+        long rawContactId1 = RawContactUtil.createRawContact(mResolver, ACCOUNT_1);
+        Uri uri_phone1 = insertPhoneNumber(rawContactId1, "(222)222-2222", false, false);
+        Uri uri_email1 = insertEmail(rawContactId1, "one@gmail.com", true, true);
+        values.clear();
+        values.put(Organization.COMPANY, "Monsters Inc");
+        Uri uri_org1 = insertOrganization(rawContactId1, values, true, true);
+        values.clear();
+        values.put(Organization.TITLE, "CEO");
+        Uri uri_org2 = insertOrganization(rawContactId1, values, false, false);
+
+        long rawContactId2 = RawContactUtil.createRawContact(mResolver, ACCOUNT_2);
+        Uri uri_phone2 = insertPhoneNumber(rawContactId2, "(333)333-3333", false, false);
+        Uri uri_email2 = insertEmail(rawContactId2, "two@gmail.com", false, false);
+
+        // Two raw contacts with same phone number will trigger the aggregation
+        Uri uri_phone3 = insertPhoneNumber(rawContactId1, "(111)111-1111", true, true);
+        Uri uri_phone4 = insertPhoneNumber(rawContactId2, "1(111)111-1111", true, true);
+
+        // After aggregation, the super primary flag should be cleared for both case 1 and case 2,
+        // i.e., phone and email mime-types. Only case 3, i.e. organization mime-type, has the
+        // super primary flag unchanged.
+        assertAggregated(rawContactId1, rawContactId2);
+        assertSuperPrimary(ContentUris.parseId(uri_phone1), false);
+        assertSuperPrimary(ContentUris.parseId(uri_phone2), false);
+        assertSuperPrimary(ContentUris.parseId(uri_phone3), false);
+        assertSuperPrimary(ContentUris.parseId(uri_phone4), false);
+
+        assertSuperPrimary(ContentUris.parseId(uri_email1), false);
+        assertSuperPrimary(ContentUris.parseId(uri_email2), false);
+
+        assertSuperPrimary(ContentUris.parseId(uri_org1), true);
+        assertSuperPrimary(ContentUris.parseId(uri_org2), false);
+    }
+
     private void assertSuggestions(long contactId, long... suggestions) {
         final Uri aggregateUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
         Uri uri = Uri.withAppendedPath(aggregateUri,