Merge "Fix crash when separating multiple empty raw contacts"
diff --git a/src/com/android/contacts/model/EntitySet.java b/src/com/android/contacts/model/EntitySet.java
index 83fe338..830f8da 100644
--- a/src/com/android/contacts/model/EntitySet.java
+++ b/src/com/android/contacts/model/EntitySet.java
@@ -130,11 +130,13 @@
// Second pass builds actual operations
for (EntityDelta delta : this) {
final int firstBatch = diff.size();
- backRefs[rawContactIndex++] = firstBatch;
+ final boolean isInsert = delta.isContactInsert();
+ backRefs[rawContactIndex++] = isInsert ? firstBatch : -1;
+
delta.buildDiff(diff);
// Only create rules for inserts
- if (!delta.isContactInsert()) continue;
+ if (!isInsert) continue;
// If we are going to split all contacts, there is no point in first combining them
if (mSplitRawContacts) continue;
@@ -208,18 +210,25 @@
builder.withValue(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_SEPARATE);
Long rawContactId1 = get(index1).getValues().getAsLong(RawContacts._ID);
+ int backRef1 = backRefs[index1];
if (rawContactId1 != null && rawContactId1 >= 0) {
builder.withValue(AggregationExceptions.RAW_CONTACT_ID1, rawContactId1);
+ } else if (backRef1 >= 0) {
+ builder.withValueBackReference(AggregationExceptions.RAW_CONTACT_ID1, backRef1);
} else {
- builder.withValueBackReference(AggregationExceptions.RAW_CONTACT_ID1, backRefs[index1]);
+ return;
}
Long rawContactId2 = get(index2).getValues().getAsLong(RawContacts._ID);
+ int backRef2 = backRefs[index2];
if (rawContactId2 != null && rawContactId2 >= 0) {
builder.withValue(AggregationExceptions.RAW_CONTACT_ID2, rawContactId2);
+ } else if (backRef2 >= 0) {
+ builder.withValueBackReference(AggregationExceptions.RAW_CONTACT_ID2, backRef2);
} else {
- builder.withValueBackReference(AggregationExceptions.RAW_CONTACT_ID2, backRefs[index2]);
+ return;
}
+
diff.add(builder.build());
}
diff --git a/tests/src/com/android/contacts/EntitySetTests.java b/tests/src/com/android/contacts/EntitySetTests.java
index edfca6d..037c927 100644
--- a/tests/src/com/android/contacts/EntitySetTests.java
+++ b/tests/src/com/android/contacts/EntitySetTests.java
@@ -358,6 +358,58 @@
assertEquals("Unexpected exception updates", 2, exceptionCount);
}
+ public void testInsertInsertSeparate() {
+ // This assumes getInsert() will return back an "empty" raw
+ // contact meaning it will contain no actual information
+ final EntityDelta insertFirst = getInsert();
+ final EntityDelta insertSecond = getInsert();
+ final EntitySet set = buildSet(insertFirst, insertSecond);
+
+ // This would normally build a TYPE_KEEP_SEPARATE aggregation exception,
+ // but since the raw contacts won't be added because they are empty,
+ // we should get 0 exceptions back
+ set.splitRawContacts();
+
+ final ArrayList<ContentProviderOperation> diff = set.buildDiff();
+ final int exceptionCount = countExceptionUpdates(diff);
+ assertEquals("Unexpected exception updates", 0, exceptionCount);
+ }
+
+ public void testUpdateInsertSeparate() {
+ // This assumes getInsert() will return back an "empty" raw
+ // contact meaning it will contain no actual information
+ final EntityDelta update = getUpdate(CONTACT_FIRST);
+ final EntityDelta insert = getInsert();
+ final EntitySet set = buildSet(update, insert);
+
+ // This would normally build a KEEP_SEPARATE aggregation exception,
+ // but since the insert won't be added because it is empty,
+ // we should get 0 exceptions back
+ set.splitRawContacts();
+
+ final ArrayList<ContentProviderOperation> diff = set.buildDiff();
+ final int exceptionCount = countExceptionUpdates(diff);
+ assertEquals("Unexpected exception updates", 0, exceptionCount);
+ }
+
+ public void testUpdateInsertInsertSeparate() {
+ // This assumes getInsert() will return back an "empty" raw
+ // contact meaning it will contain no actual information
+ final EntityDelta update = getUpdate(CONTACT_FIRST);
+ final EntityDelta insertFirst = getInsert();
+ final EntityDelta insertSecond = getInsert();
+ final EntitySet set = buildSet(update, insertFirst, insertSecond);
+
+ // This would normally build a KEEP_SEPARATE aggregation exception,
+ // but since the inserts won't be added because they are empty,
+ // we should get 0 exceptions back
+ set.splitRawContacts();
+
+ final ArrayList<ContentProviderOperation> diff = set.buildDiff();
+ final int exceptionCount = countExceptionUpdates(diff);
+ assertEquals("Unexpected exception updates", 0, exceptionCount);
+ }
+
public void testMergeDataRemoteInsert() {
final EntitySet first = buildSet(buildBeforeEntity(CONTACT_BOB, VER_FIRST,
buildPhone(PHONE_RED)));