am 2c919c4e: am becda5cc: Merge "Skip aggregation if candidate contact contains too many raw contacts" into lmp-mr1-dev

* commit '2c919c4e3a4bf1841f7f11855df44f7663bbbd92':
  Skip aggregation if candidate contact contains too many raw contacts
diff --git a/src/com/android/providers/contacts/aggregation/ContactAggregator.java b/src/com/android/providers/contacts/aggregation/ContactAggregator.java
index ce2c50a..8dcabca 100644
--- a/src/com/android/providers/contacts/aggregation/ContactAggregator.java
+++ b/src/com/android/providers/contacts/aggregation/ContactAggregator.java
@@ -136,6 +136,12 @@
     private static final int SECONDARY_HIT_LIMIT = 20;
     private static final String SECONDARY_HIT_LIMIT_STRING = String.valueOf(SECONDARY_HIT_LIMIT);
 
+    // If we encounter no less than this many raw contacts in the best matching contact during
+    // aggregation, don't attempt to aggregate - this is likely an error or a shared corporate
+    // data element.
+    @VisibleForTesting
+    static final int AGGREGATION_CONTACT_SIZE_LIMIT = 50;
+
     // If we encounter more than this many contacts with matching name during aggregation
     // suggestion lookup, ignore the remaining results.
     private static final int FIRST_LETTER_SUGGESTION_HIT_LIMIT = 100;
@@ -789,8 +795,19 @@
                     } finally {
                         rawContactsToAccountsCursor.close();
                     }
-                    final int actionCode = canJoinIntoContact(db, rawContactId,
-                            rawContactIdsInSameAccount, rawContactIdsInOtherAccount);
+                    final int actionCode;
+                    final int totalNumOfRawContactsInCandidate = rawContactIdsInSameAccount.size()
+                            + rawContactIdsInOtherAccount.size();
+                    if (totalNumOfRawContactsInCandidate >= AGGREGATION_CONTACT_SIZE_LIMIT) {
+                        if (VERBOSE_LOGGING) {
+                            Log.v(TAG, "Too many raw contacts (" + totalNumOfRawContactsInCandidate
+                                    + ") in the best matching contact, so skip aggregation");
+                        }
+                        actionCode = KEEP_SEPARATE;
+                    } else {
+                        actionCode = canJoinIntoContact(db, rawContactId,
+                                rawContactIdsInSameAccount, rawContactIdsInOtherAccount);
+                    }
                     if (actionCode == KEEP_SEPARATE) {
                         contactId = -1;
                     } else if (actionCode == RE_AGGREGATE) {
diff --git a/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java b/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java
index 63d5f3b..78f1b80 100644
--- a/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java
+++ b/tests/src/com/android/providers/contacts/aggregation/ContactAggregatorTest.java
@@ -1620,6 +1620,25 @@
         assertSuperPrimary(ContentUris.parseId(uri_org2), false);
     }
 
+    public void testNotAggregate_TooManyRawContactsInCandidate() {
+        long preId= 0;
+        for (int i = 0; i < ContactAggregator.AGGREGATION_CONTACT_SIZE_LIMIT; i++) {
+            long id = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
+            if (i >  0) {
+                setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, preId, id);
+            }
+            preId = id;
+        }
+        // Although the newly added raw contact matches the names with other raw contacts,
+        // but the best matching contact has already meets the size limit, so keep the new raw
+        // contact separate from other raw contacts.
+        long newId = RawContactUtil.createRawContact(mResolver,
+                new Account("account_new", "new account type"));
+        DataUtil.insertStructuredName(mResolver, newId, "John", "Doe");
+        assertNotAggregated(preId, newId);
+        assertTrue(queryContactId(newId) > 0);
+    }
+
     public void testFindConnectedRawContacts() {
         Set<Long> rawContactIdSet = new HashSet<Long>();
         rawContactIdSet.addAll(Arrays.asList(1l, 2l, 3l, 4l, 5l, 6l, 7l, 8l, 9l));