Fix isInsert, isUpdate, isDelete in unit test on LMP

Using CPOWrapper and BuilderWrapper introduced by ag/828480

Bug 27244680
Bug 26818072
Bug 25629359

Change-Id: I0204122408aeed781e0ee81eff26581e1cc7c1ee
diff --git a/src/com/android/contacts/common/compat/CompatUtils.java b/src/com/android/contacts/common/compat/CompatUtils.java
index 58f0362..f833bd2 100644
--- a/src/com/android/contacts/common/compat/CompatUtils.java
+++ b/src/com/android/contacts/common/compat/CompatUtils.java
@@ -49,9 +49,28 @@
     public static boolean isInsertCompat(CPOWrapper cpoWrapper) {
         if (SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.M) >= Build.VERSION_CODES.M) {
             return cpoWrapper.getOperation().isInsert();
-        } else {
-            return (cpoWrapper.getType() == TYPE_INSERT);
         }
+        return (cpoWrapper.getType() == TYPE_INSERT);
+    }
+
+    /**
+     * Returns whether the operation in CPOWrapper is of TYPE_UPDATE;
+     */
+    public static boolean isUpdateCompat(CPOWrapper cpoWrapper) {
+        if (SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.M) >= Build.VERSION_CODES.M) {
+            return cpoWrapper.getOperation().isUpdate();
+        }
+        return (cpoWrapper.getType() == TYPE_UPDATE);
+    }
+
+    /**
+     * Returns whether the operation in CPOWrapper is of TYPE_DELETE;
+     */
+    public static boolean isDeleteCompat(CPOWrapper cpoWrapper) {
+        if (SdkVersionOverride.getSdkVersion(Build.VERSION_CODES.M) >= Build.VERSION_CODES.M) {
+            return cpoWrapper.getOperation().isDelete();
+        }
+        return (cpoWrapper.getType() == TYPE_DELETE);
     }
 
     /**
diff --git a/tests/src/com/android/contacts/common/RawContactDeltaListTests.java b/tests/src/com/android/contacts/common/RawContactDeltaListTests.java
index ebbddab..98f3f33 100644
--- a/tests/src/com/android/contacts/common/RawContactDeltaListTests.java
+++ b/tests/src/com/android/contacts/common/RawContactDeltaListTests.java
@@ -30,6 +30,8 @@
 import android.test.suitebuilder.annotation.LargeTest;
 
 import com.android.contacts.common.RawContactModifierTests.MockContactsSource;
+import com.android.contacts.common.compat.CompatUtils;
+import com.android.contacts.common.model.CPOWrapper;
 import com.android.contacts.common.model.RawContact;
 import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
@@ -292,13 +294,14 @@
 
     /**
      * Count number of {@link AggregationExceptions} updates contained in the
-     * given list of {@link ContentProviderOperation}.
+     * given list of {@link CPOWrapper}.
      */
-    static int countExceptionUpdates(ArrayList<ContentProviderOperation> diff) {
+    static int countExceptionUpdates(ArrayList<CPOWrapper> diff) {
         int updateCount = 0;
-        for (ContentProviderOperation oper : diff) {
+        for (CPOWrapper cpoWrapper : diff) {
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
             if (AggregationExceptions.CONTENT_URI.equals(oper.getUri())
-                    && oper.isUpdate()) {
+                    && CompatUtils.isUpdateCompat(cpoWrapper)) {
                 updateCount++;
             }
         }
@@ -310,7 +313,7 @@
         final RawContactDeltaList set = buildSet(insert);
 
         // Inserting single shouldn't create rules
-        final ArrayList<ContentProviderOperation> diff = set.buildDiff();
+        final ArrayList<CPOWrapper> diff = set.buildDiffWrapper();
         final int exceptionCount = countExceptionUpdates(diff);
         assertEquals("Unexpected exception updates", 0, exceptionCount);
     }
@@ -321,7 +324,7 @@
         final RawContactDeltaList set = buildSet(updateFirst, updateSecond);
 
         // Updating two existing shouldn't create rules
-        final ArrayList<ContentProviderOperation> diff = set.buildDiff();
+        final ArrayList<CPOWrapper> diff = set.buildDiffWrapper();
         final int exceptionCount = countExceptionUpdates(diff);
         assertEquals("Unexpected exception updates", 0, exceptionCount);
     }
@@ -332,7 +335,7 @@
         final RawContactDeltaList set = buildSet(update, insert);
 
         // New insert should only create one rule
-        final ArrayList<ContentProviderOperation> diff = set.buildDiff();
+        final ArrayList<CPOWrapper> diff = set.buildDiffWrapper();
         final int exceptionCount = countExceptionUpdates(diff);
         assertEquals("Unexpected exception updates", 1, exceptionCount);
     }
@@ -344,7 +347,7 @@
         final RawContactDeltaList set = buildSet(insertFirst, update, insertSecond);
 
         // Two inserts should create two rules to bind against single existing
-        final ArrayList<ContentProviderOperation> diff = set.buildDiff();
+        final ArrayList<CPOWrapper> diff = set.buildDiffWrapper();
         final int exceptionCount = countExceptionUpdates(diff);
         assertEquals("Unexpected exception updates", 2, exceptionCount);
     }
@@ -356,7 +359,7 @@
         final RawContactDeltaList set = buildSet(insertFirst, insertSecond, insertThird);
 
         // Three new inserts should create only two binding rules
-        final ArrayList<ContentProviderOperation> diff = set.buildDiff();
+        final ArrayList<CPOWrapper> diff = set.buildDiffWrapper();
         final int exceptionCount = countExceptionUpdates(diff);
         assertEquals("Unexpected exception updates", 2, exceptionCount);
     }
diff --git a/tests/src/com/android/contacts/common/RawContactDeltaTests.java b/tests/src/com/android/contacts/common/RawContactDeltaTests.java
index 3597524..90e663f 100644
--- a/tests/src/com/android/contacts/common/RawContactDeltaTests.java
+++ b/tests/src/com/android/contacts/common/RawContactDeltaTests.java
@@ -17,9 +17,9 @@
 package com.android.contacts.common;
 
 import android.content.ContentProviderOperation;
-import android.content.ContentProviderOperation.Builder;
 import android.content.ContentValues;
 import android.content.Context;
+import android.os.Build;
 import android.os.Parcel;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.Data;
@@ -27,6 +27,9 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 
+import com.android.contacts.common.compat.CompatUtils;
+import com.android.contacts.common.model.BuilderWrapper;
+import com.android.contacts.common.model.CPOWrapper;
 import com.android.contacts.common.model.RawContact;
 import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
@@ -147,8 +150,10 @@
         values.markDeleted();
 
         // Should produce a delete action
-        final Builder builder = values.buildDiff(Data.CONTENT_URI);
-        final boolean isDelete = builder.build().isDelete();
+        final BuilderWrapper builderWrapper = values.buildDiffWrapper(Data.CONTENT_URI);
+        final boolean isDelete = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
+                ? builderWrapper.getBuilder().build().isDelete()
+                : builderWrapper.getType() == CompatUtils.TYPE_DELETE;
         assertTrue("Didn't produce delete action", isDelete);
     }
 
@@ -316,14 +321,15 @@
         final ValuesDelta values = ValuesDelta.fromAfter(after);
         final RawContactDelta source = new RawContactDelta(values);
 
-        // Assert two operations: delete Contact and enforce version
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        source.buildAssert(diff);
-        source.buildDiff(diff);
+        // Assert two operations: insert Contact and enforce version
+        final ArrayList<CPOWrapper> diff = Lists.newArrayList();
+        source.buildAssertWrapper(diff);
+        source.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 2, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Incorrect type", oper.isInsert());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isInsertCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
     }
@@ -345,18 +351,20 @@
         source.addEntry(ValuesDelta.fromAfter(phone));
 
         // Assert two operations: delete Contact and enforce version
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        source.buildAssert(diff);
-        source.buildDiff(diff);
+        final ArrayList<CPOWrapper> diff = Lists.newArrayList();
+        source.buildAssertWrapper(diff);
+        source.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 3, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Incorrect type", oper.isInsert());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isInsertCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(1);
-            assertTrue("Incorrect type", oper.isInsert());
+            final CPOWrapper cpoWrapper = diff.get(1);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isInsertCompat(cpoWrapper));
             assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
 
         }
diff --git a/tests/src/com/android/contacts/common/RawContactModifierTests.java b/tests/src/com/android/contacts/common/RawContactModifierTests.java
index dcb2b25..15670c5 100644
--- a/tests/src/com/android/contacts/common/RawContactModifierTests.java
+++ b/tests/src/com/android/contacts/common/RawContactModifierTests.java
@@ -34,7 +34,9 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 
+import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.CPOWrapper;
 import com.android.contacts.common.model.RawContact;
 import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
@@ -387,33 +389,37 @@
         RawContactModifier.insertChild(state, kindPhone, typeHome);
 
         // Build diff, expecting insert for data row and update enforcement
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
+        final ArrayList<CPOWrapper> diff = Lists.newArrayList();
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 3, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Expected aggregation mode change", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Expected aggregation mode change", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(1);
-            assertTrue("Incorrect type", oper.isInsert());
+            final CPOWrapper cpoWrapper = diff.get(1);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isInsertCompat(cpoWrapper));
             assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(2);
-            assertTrue("Expected aggregation mode change", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(2);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Expected aggregation mode change", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
 
         // Trim empty rows and try again, expecting delete of overall contact
         RawContactModifier.trimEmpty(state, source);
         diff.clear();
-        state.buildDiff(diff);
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 1, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Incorrect type", oper.isDelete());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isDeleteCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
     }
@@ -486,14 +492,14 @@
         state.addEntry(ValuesDelta.fromBefore(before));
 
         // Build diff, expecting no changes
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
+        final ArrayList<CPOWrapper> diff = Lists.newArrayList();
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 0, diff.size());
 
         // Try trimming existing empty, which we shouldn't touch
         RawContactModifier.trimEmpty(state, source);
         diff.clear();
-        state.buildDiff(diff);
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 0, diff.size());
     }
 
@@ -511,40 +517,44 @@
         final RawContactDelta state = getRawContact(TEST_ID, before);
 
         // Build diff, expecting no changes
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
+        final ArrayList<CPOWrapper> diff = Lists.newArrayList();
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 0, diff.size());
 
         // Now update row by changing number to empty string, expecting single update
         final ValuesDelta child = state.getEntry(TEST_ID);
         child.put(Phone.NUMBER, "");
         diff.clear();
-        state.buildDiff(diff);
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 3, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Expected aggregation mode change", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Expected aggregation mode change", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(1);
-            assertTrue("Incorrect type", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(1);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(2);
-            assertTrue("Expected aggregation mode change", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(2);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Expected aggregation mode change", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
 
         // Now run trim, which should turn that update into delete
         RawContactModifier.trimEmpty(state, source);
         diff.clear();
-        state.buildDiff(diff);
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 1, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Incorrect type", oper.isDelete());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isDeleteCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
     }
@@ -560,21 +570,21 @@
         final RawContactDeltaList set = new RawContactDeltaList();
         set.add(state);
 
-
         // Build diff, expecting single insert
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
+        final ArrayList<CPOWrapper> diff = Lists.newArrayList();
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 2, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Incorrect type", oper.isInsert());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isInsertCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
 
         // Trim empty rows and try again, expecting no insert
         RawContactModifier.trimEmpty(set, accountTypes);
         diff.clear();
-        state.buildDiff(diff);
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 0, diff.size());
     }
 
@@ -591,24 +601,26 @@
         set.add(state);
 
         // Build diff, expecting two insert operations
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
+        final ArrayList<CPOWrapper> diff = Lists.newArrayList();
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 3, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Incorrect type", oper.isInsert());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isInsertCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(1);
-            assertTrue("Incorrect type", oper.isInsert());
+            final CPOWrapper cpoWrapper = diff.get(1);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isInsertCompat(cpoWrapper));
             assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
         }
 
         // Trim empty rows and try again, expecting silence
         RawContactModifier.trimEmpty(set, accountTypes);
         diff.clear();
-        state.buildDiff(diff);
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 0, diff.size());
     }
 
@@ -636,50 +648,56 @@
         set.add(state);
 
         // Build diff, expecting no changes
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
+        final ArrayList<CPOWrapper> diff = Lists.newArrayList();
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 0, diff.size());
 
         // Now update row by changing number to empty string, expecting single update
         final ValuesDelta child = state.getEntry(TEST_ID);
         child.put(Phone.NUMBER, "");
         diff.clear();
-        state.buildDiff(diff);
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 3, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Expected aggregation mode change", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Expected aggregation mode change", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(1);
-            assertTrue("Incorrect type", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(1);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(2);
-            assertTrue("Expected aggregation mode change", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(2);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Expected aggregation mode change", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
 
         // Now run trim, which should turn that update into delete
         RawContactModifier.trimEmpty(set, accountTypes);
         diff.clear();
-        state.buildDiff(diff);
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 3, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Expected aggregation mode change", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Expected aggregation mode change", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(1);
-            assertTrue("Incorrect type", oper.isDelete());
+            final CPOWrapper cpoWrapper = diff.get(1);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isDeleteCompat(cpoWrapper));
             assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(2);
-            assertTrue("Expected aggregation mode change", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(2);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Expected aggregation mode change", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
     }
@@ -702,40 +720,44 @@
         set.add(state);
 
         // Build diff, expecting no changes
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
+        final ArrayList<CPOWrapper> diff = Lists.newArrayList();
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 0, diff.size());
 
         // Now update row by changing number to empty string, expecting single update
         final ValuesDelta child = state.getEntry(TEST_ID);
         child.put(Phone.NUMBER, "");
         diff.clear();
-        state.buildDiff(diff);
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 3, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Expected aggregation mode change", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Expected aggregation mode change", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(1);
-            assertTrue("Incorrect type", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(1);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
         }
         {
-            final ContentProviderOperation oper = diff.get(2);
-            assertTrue("Expected aggregation mode change", oper.isUpdate());
+            final CPOWrapper cpoWrapper = diff.get(2);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Expected aggregation mode change", CompatUtils.isUpdateCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
 
         // Now run trim, which should turn into deleting the whole contact
         RawContactModifier.trimEmpty(set, accountTypes);
         diff.clear();
-        state.buildDiff(diff);
+        state.buildDiffWrapper(diff);
         assertEquals("Unexpected operations", 1, diff.size());
         {
-            final ContentProviderOperation oper = diff.get(0);
-            assertTrue("Incorrect type", oper.isDelete());
+            final CPOWrapper cpoWrapper = diff.get(0);
+            final ContentProviderOperation oper = cpoWrapper.getOperation();
+            assertTrue("Incorrect type", CompatUtils.isDeleteCompat(cpoWrapper));
             assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
         }
     }
diff --git a/tests/src/com/android/contacts/common/model/ContactLoaderTest.java b/tests/src/com/android/contacts/common/model/ContactLoaderTest.java
index 094e51c..9878a12 100644
--- a/tests/src/com/android/contacts/common/model/ContactLoaderTest.java
+++ b/tests/src/com/android/contacts/common/model/ContactLoaderTest.java
@@ -29,16 +29,22 @@
 import android.test.LoaderTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 
+import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.common.test.mocks.ContactsMockContext;
-import com.android.contacts.common.test.mocks.MockContentProvider;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.common.model.account.BaseAccountType;
 import com.android.contacts.common.testing.InjectedServices;
+import com.android.contacts.common.test.mocks.ContactsMockContext;
+import com.android.contacts.common.test.mocks.MockContentProvider;
+import com.android.contacts.common.test.mocks.MockContentProvider.Query;
 import com.android.contacts.common.test.mocks.MockAccountTypeManager;
 import com.android.contacts.common.util.Constants;
 
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
 import org.json.JSONException;
 import org.json.JSONObject;
 
@@ -154,7 +160,10 @@
         assertEquals(lookupUri, contact.getLookupUri());
         assertEquals(1, contact.getRawContacts().size());
         assertEquals(1, contact.getStatuses().size());
-        assertEquals(1, contact.getRawContacts().get(0).getDataItems().get(0).getCarrierPresence());
+        if (CompatUtils.isMarshmallowCompatible()) {
+            assertEquals(
+                    1, contact.getRawContacts().get(0).getDataItems().get(0).getCarrierPresence());
+        }
         mContactsProvider.verify();
     }
 
@@ -302,91 +311,105 @@
     class ContactQueries {
         public void fetchAllData(
                 Uri baseUri, long contactId, long rawContactId, long dataId, String encodedLookup) {
+            final String[] COLUMNS_INTERNAL = new String[] {
+                    Contacts.NAME_RAW_CONTACT_ID, Contacts.DISPLAY_NAME_SOURCE,
+                    Contacts.LOOKUP_KEY, Contacts.DISPLAY_NAME,
+                    Contacts.DISPLAY_NAME_ALTERNATIVE, Contacts.PHONETIC_NAME,
+                    Contacts.PHOTO_ID, Contacts.STARRED, Contacts.CONTACT_PRESENCE,
+                    Contacts.CONTACT_STATUS, Contacts.CONTACT_STATUS_TIMESTAMP,
+                    Contacts.CONTACT_STATUS_RES_PACKAGE, Contacts.CONTACT_STATUS_LABEL,
+
+                    Contacts.Entity.CONTACT_ID,
+                    Contacts.Entity.RAW_CONTACT_ID,
+
+                    RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE,
+                    RawContacts.DATA_SET,
+                    RawContacts.DIRTY, RawContacts.VERSION, RawContacts.SOURCE_ID,
+                    RawContacts.SYNC1, RawContacts.SYNC2, RawContacts.SYNC3, RawContacts.SYNC4,
+                    RawContacts.DELETED,
+
+                    Contacts.Entity.DATA_ID,
+
+                    Data.DATA1, Data.DATA2, Data.DATA3, Data.DATA4, Data.DATA5,
+                    Data.DATA6, Data.DATA7, Data.DATA8, Data.DATA9, Data.DATA10,
+                    Data.DATA11, Data.DATA12, Data.DATA13, Data.DATA14, Data.DATA15,
+                    Data.SYNC1, Data.SYNC2, Data.SYNC3, Data.SYNC4,
+                    Data.DATA_VERSION, Data.IS_PRIMARY,
+                    Data.IS_SUPER_PRIMARY, Data.MIMETYPE,
+
+                    GroupMembership.GROUP_SOURCE_ID,
+
+                    Data.PRESENCE, Data.CHAT_CAPABILITY,
+                    Data.STATUS, Data.STATUS_RES_PACKAGE, Data.STATUS_ICON,
+                    Data.STATUS_LABEL, Data.STATUS_TIMESTAMP,
+
+                    Contacts.PHOTO_URI,
+
+                    Contacts.SEND_TO_VOICEMAIL,
+                    Contacts.CUSTOM_RINGTONE,
+                    Contacts.IS_USER_PROFILE,
+
+                    Data.TIMES_USED,
+                    Data.LAST_TIME_USED
+            };
+
+            List<String> projectionList = Lists.newArrayList(COLUMNS_INTERNAL);
+            if (CompatUtils.isMarshmallowCompatible()) {
+                projectionList.add(Data.CARRIER_PRESENCE);
+            }
+            final String[] COLUMNS = projectionList.toArray(new String[projectionList.size()]);
+
+            final Object[] ROWS_INTERNAL = new Object[] {
+                    rawContactId, 40,
+                    "aa%12%@!", "John Doe", "Doe, John", "jdo",
+                    0, 0, StatusUpdates.AVAILABLE,
+                    "Having lunch", 0,
+                    "mockPkg1", 10,
+
+                    contactId,
+                    rawContactId,
+
+                    "mockAccountName", "mockAccountType", null,
+                    0, 1, 0,
+                    "sync1", "sync2", "sync3", "sync4",
+                    0,
+
+                    dataId,
+
+                    "dat1", "dat2", "dat3", "dat4", "dat5",
+                    "dat6", "dat7", "dat8", "dat9", "dat10",
+                    "dat11", "dat12", "dat13", "dat14", "dat15",
+                    "syn1", "syn2", "syn3", "syn4",
+
+                    0, 0,
+                    0, StructuredName.CONTENT_ITEM_TYPE,
+
+                    "groupId",
+
+                    StatusUpdates.INVISIBLE, null,
+                    "Having dinner", "mockPkg3", 0,
+                    20, 0,
+
+                    "content:some.photo.uri",
+
+                    0,
+                    null,
+                    0,
+
+                    0,
+                    0
+            };
+
+            List<Object> rowsList = Lists.newArrayList(ROWS_INTERNAL);
+            if (CompatUtils.isMarshmallowCompatible()) {
+                rowsList.add(Data.CARRIER_PRESENCE_VT_CAPABLE);
+            }
+            final Object[] ROWS = rowsList.toArray(new Object[rowsList.size()]);
+
             mContactsProvider.expectQuery(baseUri)
-                    .withProjection(new String[] {
-                        Contacts.NAME_RAW_CONTACT_ID, Contacts.DISPLAY_NAME_SOURCE,
-                        Contacts.LOOKUP_KEY, Contacts.DISPLAY_NAME,
-                        Contacts.DISPLAY_NAME_ALTERNATIVE, Contacts.PHONETIC_NAME,
-                        Contacts.PHOTO_ID, Contacts.STARRED, Contacts.CONTACT_PRESENCE,
-                        Contacts.CONTACT_STATUS, Contacts.CONTACT_STATUS_TIMESTAMP,
-                        Contacts.CONTACT_STATUS_RES_PACKAGE, Contacts.CONTACT_STATUS_LABEL,
-
-                        Contacts.Entity.CONTACT_ID,
-                        Contacts.Entity.RAW_CONTACT_ID,
-
-                        RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE,
-                        RawContacts.DATA_SET,
-                        RawContacts.DIRTY, RawContacts.VERSION, RawContacts.SOURCE_ID,
-                        RawContacts.SYNC1, RawContacts.SYNC2, RawContacts.SYNC3, RawContacts.SYNC4,
-                        RawContacts.DELETED,
-
-                        Contacts.Entity.DATA_ID,
-
-                        Data.DATA1, Data.DATA2, Data.DATA3, Data.DATA4, Data.DATA5,
-                        Data.DATA6, Data.DATA7, Data.DATA8, Data.DATA9, Data.DATA10,
-                        Data.DATA11, Data.DATA12, Data.DATA13, Data.DATA14, Data.DATA15,
-                        Data.SYNC1, Data.SYNC2, Data.SYNC3, Data.SYNC4,
-                        Data.DATA_VERSION, Data.IS_PRIMARY,
-                        Data.IS_SUPER_PRIMARY, Data.MIMETYPE,
-
-                        GroupMembership.GROUP_SOURCE_ID,
-
-                        Data.PRESENCE, Data.CHAT_CAPABILITY,
-                        Data.STATUS, Data.STATUS_RES_PACKAGE, Data.STATUS_ICON,
-                        Data.STATUS_LABEL, Data.STATUS_TIMESTAMP,
-
-                        Contacts.PHOTO_URI,
-
-                        Contacts.SEND_TO_VOICEMAIL,
-                        Contacts.CUSTOM_RINGTONE,
-                        Contacts.IS_USER_PROFILE,
-
-                        Data.TIMES_USED,
-                        Data.LAST_TIME_USED,
-                        Data.CARRIER_PRESENCE
-                    })
+                    .withProjection(COLUMNS)
                     .withSortOrder(Contacts.Entity.RAW_CONTACT_ID)
-                    .returnRow(
-                        rawContactId, 40,
-                        "aa%12%@!", "John Doe", "Doe, John", "jdo",
-                        0, 0, StatusUpdates.AVAILABLE,
-                        "Having lunch", 0,
-                        "mockPkg1", 10,
-
-                        contactId,
-                        rawContactId,
-
-                        "mockAccountName", "mockAccountType", null,
-                        0, 1, 0,
-                        "sync1", "sync2", "sync3", "sync4",
-                        0,
-
-                        dataId,
-
-                        "dat1", "dat2", "dat3", "dat4", "dat5",
-                        "dat6", "dat7", "dat8", "dat9", "dat10",
-                        "dat11", "dat12", "dat13", "dat14", "dat15",
-                        "syn1", "syn2", "syn3", "syn4",
-
-                        0, 0,
-                        0, StructuredName.CONTENT_ITEM_TYPE,
-
-                        "groupId",
-
-                        StatusUpdates.INVISIBLE, null,
-                        "Having dinner", "mockPkg3", 0,
-                        20, 0,
-
-                        "content:some.photo.uri",
-
-                        0,
-                        null,
-                        0,
-
-                        0,
-                        0,
-                        Data.CARRIER_PRESENCE_VT_CAPABLE
-                    );
+                    .returnRow(ROWS);
         }
 
         void fetchLookupAndId(final Uri sourceUri, final long expectedContactId,
diff --git a/tests/src/com/android/contacts/common/model/ValuesDeltaTests.java b/tests/src/com/android/contacts/common/model/ValuesDeltaTests.java
index c5297a9..77bf456 100644
--- a/tests/src/com/android/contacts/common/model/ValuesDeltaTests.java
+++ b/tests/src/com/android/contacts/common/model/ValuesDeltaTests.java
@@ -18,10 +18,14 @@
 
 import android.content.ContentProviderOperation.Builder;
 import android.content.ContentValues;
+import android.os.Build;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.Data;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.contacts.common.compat.CompatUtils;
+import com.android.contacts.common.model.BuilderWrapper;
+
 import junit.framework.TestCase;
 
 /**
@@ -44,8 +48,10 @@
         final ValuesDelta values = ValuesDelta.fromAfter(after);
 
         // Should produce an insert action
-        final Builder builder = values.buildDiff(Data.CONTENT_URI);
-        final boolean isInsert = builder.build().isInsert();
+        final BuilderWrapper builderWrapper = values.buildDiffWrapper(Data.CONTENT_URI);
+        final boolean isInsert = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
+                ? builderWrapper.getBuilder().build().isInsert()
+                : builderWrapper.getType() == CompatUtils.TYPE_INSERT;
         assertTrue("Didn't produce insert action", isInsert);
     }
 
@@ -75,8 +81,10 @@
         values.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
 
         // Should produce an update action
-        final Builder builder = values.buildDiff(Data.CONTENT_URI);
-        final boolean isUpdate = builder.build().isUpdate();
+        final BuilderWrapper builderWrapper = values.buildDiffWrapper(Data.CONTENT_URI);
+        final boolean isUpdate = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
+                ? builderWrapper.getBuilder().build().isUpdate()
+                : builderWrapper.getType() == CompatUtils.TYPE_UPDATE;
         assertTrue("Didn't produce update action", isUpdate);
     }
 }