Merge "Update of holo resources." into jb-mr2-dev
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/Android.mk b/apps/CtsVerifier/jni/cameraanalyzer/Android.mk
index 2859074..ed66992 100644
--- a/apps/CtsVerifier/jni/cameraanalyzer/Android.mk
+++ b/apps/CtsVerifier/jni/cameraanalyzer/Android.mk
@@ -35,6 +35,6 @@
 LOCAL_SHARED_LIBRARIES := libjnigraphics \
                           libstlport \
                           libcutils \
-                          libutils
+                          libutils liblog
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/suite/pts/deviceTests/opengl/jni/Android.mk b/suite/pts/deviceTests/opengl/jni/Android.mk
index be69522..8155bac 100644
--- a/suite/pts/deviceTests/opengl/jni/Android.mk
+++ b/suite/pts/deviceTests/opengl/jni/Android.mk
@@ -26,6 +26,6 @@
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
-LOCAL_SHARED_LIBRARIES := libEGL libGLESv2 libandroid libutils libcutils
+LOCAL_SHARED_LIBRARIES := libEGL libGLESv2 libandroid libutils libcutils liblog
 
-include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
+include $(BUILD_SHARED_LIBRARY)
diff --git a/suite/pts/deviceTests/opengl/test/Android.mk b/suite/pts/deviceTests/opengl/test/Android.mk
index 1939b2d..faf5f16 100644
--- a/suite/pts/deviceTests/opengl/test/Android.mk
+++ b/suite/pts/deviceTests/opengl/test/Android.mk
@@ -26,9 +26,9 @@
 
 #$(info $(LOCAL_SRC_FILES))
 LOCAL_C_INCLUDES += external/gtest/include $(LOCAL_PATH)/../jni/graphics/
-LOCAL_STATIC_LIBRARIES := libutils libcutils libgtest_host libgtest_main_host
+LOCAL_STATIC_LIBRARIES := libutils libcutils libgtest_host libgtest_main_host liblog
 LOCAL_LDFLAGS:= -g -lrt -ldl -lstdc++ -lm -fno-exceptions
 LOCAL_MODULE:= pts_device_opengl_test
 include $(BUILD_HOST_EXECUTABLE)
 
-endif # linux
\ No newline at end of file
+endif # linux
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
index 574e9e9..c865140 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
@@ -16,21 +16,36 @@
 
 package android.hardware.cts;
 
+import java.lang.IllegalArgumentException;
+import java.lang.Override;
 import java.util.List;
 
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
+import android.hardware.TriggerEvent;
+import android.hardware.TriggerEventListener;
 import android.test.AndroidTestCase;
 
 public class SensorTest extends AndroidTestCase {
+    private SensorManager mSensorManager;
+    private TriggerListener mTriggerListener;
+    private SensorListener mSensorListener;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
+        mTriggerListener = new TriggerListener();
+        mSensorListener = new SensorListener();
+    }
 
     public void testSensorOperations() {
         // Because we can't know every sensors unit details, so we can't assert
         // get values with specified values.
-        final SensorManager mSensorManager =
-            (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
         List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
         assertNotNull(sensors);
         Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
@@ -70,7 +85,48 @@
         }
     }
 
-    private void assertSensorValues(Sensor sensor) {
+    public void testRequestTriggerWithNonTriggerSensor() {
+        Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+        boolean result;
+        if (sensor != null) {
+            result = mSensorManager.requestTriggerSensor(mTriggerListener, sensor);
+            assertFalse(result);
+        }
+    }
+
+    public void testCancelTriggerWithNonTriggerSensor() {
+        Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+        boolean result;
+        if (sensor != null) {
+            result = mSensorManager.cancelTriggerSensor(mTriggerListener, sensor);
+            assertFalse(result);
+        }
+    }
+
+    public void testRegisterWithTriggerSensor() {
+        Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
+        boolean result;
+        if (sensor != null) {
+            result = mSensorManager.registerListener(mSensorListener, sensor,
+                    SensorManager.SENSOR_DELAY_NORMAL);
+            assertFalse(result);
+        }
+    }
+
+    public void testRegisterTwiceWithSameSensor() {
+        Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+        boolean result;
+        if (sensor != null) {
+            result = mSensorManager.registerListener(mSensorListener, sensor,
+                    SensorManager.SENSOR_DELAY_NORMAL);
+            assertTrue(result);
+            result = mSensorManager.registerListener(mSensorListener, sensor,
+                    SensorManager.SENSOR_DELAY_NORMAL);
+            assertFalse(result);
+        }
+    }
+
+        private void assertSensorValues(Sensor sensor) {
         assertTrue(sensor.getMaximumRange() >= 0);
         assertTrue(sensor.getPower() >= 0);
         assertTrue(sensor.getResolution() >= 0);
@@ -96,4 +152,20 @@
         }
         assertEquals(sensors, mSensorManager.getSensors());
     }
+
+    class TriggerListener extends TriggerEventListener {
+        @Override
+        public void onTrigger(TriggerEvent event) {
+        }
+    }
+
+    class SensorListener implements SensorEventListener {
+        @Override
+        public void onSensorChanged(SensorEvent event) {
+        }
+
+        @Override
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+        }
+    }
 }
diff --git a/tests/tests/nativemedia/sl/Android.mk b/tests/tests/nativemedia/sl/Android.mk
index 85b88ca..d999b57 100644
--- a/tests/tests/nativemedia/sl/Android.mk
+++ b/tests/tests/nativemedia/sl/Android.mk
@@ -18,6 +18,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
   libutils \
+  liblog \
   libOpenSLES \
   libstlport
 
diff --git a/tests/tests/nativemedia/xa/Android.mk b/tests/tests/nativemedia/xa/Android.mk
index 634bf4e..dad8acd 100644
--- a/tests/tests/nativemedia/xa/Android.mk
+++ b/tests/tests/nativemedia/xa/Android.mk
@@ -18,6 +18,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
   libutils \
+  liblog \
   libOpenMAXAL \
   libstlport
 
diff --git a/tests/tests/openglperf/jni/Android.mk b/tests/tests/openglperf/jni/Android.mk
index 77db1df..2cebaec 100644
--- a/tests/tests/openglperf/jni/Android.mk
+++ b/tests/tests/openglperf/jni/Android.mk
@@ -24,7 +24,7 @@
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) $(call include-path-for, system-core) frameworks/native/opengl/include
 
-LOCAL_SHARED_LIBRARIES := libnativehelper libcutils libGLES_trace libEGL
+LOCAL_SHARED_LIBRARIES := libnativehelper libcutils liblog libGLES_trace libEGL
 
 LOCAL_SDK_VERSION := 14
 
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index c5c158f..7b6a932 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -660,14 +660,30 @@
         assertTrue("Cannot find /system partition", foundSystem);
     }
 
-    public void testAllBlockDevicesAreSecure() throws Exception {
-        Set<File> insecure = getAllInsecureBlockDevicesInDirAndSubdir(new File("/dev"));
+    private static final Set<File> DEV_EXCEPTIONS = new HashSet<File>(
+            Arrays.asList(
+                // Known good devices- should be present everywhere
+                new File("/dev/ashmem"),
+                new File("/dev/binder"),
+                new File("/dev/full"),
+                new File("/dev/ion"),
+                new File("/dev/null"),
+                new File("/dev/random"),
+                new File("/dev/tty"),
+                new File("/dev/urandom"),
+                new File("/dev/zero")
+                // Other exceptions go below here, along with a bug #
+            ));
+
+    public void testAllDevicesAreSecure() throws Exception {
+        Set<File> insecure = getAllInsecureDevicesInDirAndSubdir(new File("/dev"));
+        insecure.removeAll(DEV_EXCEPTIONS);
         assertTrue("Found insecure: " + insecure.toString(),
                 insecure.isEmpty());
     }
 
     private static Set<File>
-    getAllInsecureBlockDevicesInDirAndSubdir(File dir) throws Exception {
+    getAllInsecureDevicesInDirAndSubdir(File dir) throws Exception {
         assertTrue(dir.isDirectory());
         Set<File> retval = new HashSet<File>();
         File[] subDirectories = dir.listFiles(new FileFilter() {
@@ -680,7 +696,7 @@
         /* recurse into subdirectories */
         if (subDirectories != null) {
             for (File f : subDirectories) {
-                retval.addAll(getAllInsecureBlockDevicesInDirAndSubdir(f));
+                retval.addAll(getAllInsecureDevicesInDirAndSubdir(f));
             }
         }
 
@@ -692,16 +708,16 @@
         for (File f: filesInThisDirectory) {
             FileUtils.FileStatus status = new FileUtils.FileStatus();
             FileUtils.getFileStatus(f.getAbsolutePath(), status, false);
-            if (status.hasModeFlag(FileUtils.S_IFBLK)) {
+            if (status.hasModeFlag(FileUtils.S_IFBLK) || status.hasModeFlag(FileUtils.S_IFCHR)) {
                 if (f.canRead() || f.canWrite() || f.canExecute()) {
                     retval.add(f);
                 }
                 if (status.uid == 2000) {
-                    // The shell user should not own any block devices
+                    // The shell user should not own any devices
                     retval.add(f);
                 }
 
-                // Don't allow block devices owned by GIDs
+                // Don't allow devices owned by GIDs
                 // accessible to non-privileged applications.
                 if ((status.gid == 1007)           // AID_LOG
                           || (status.gid == 1015)  // AID_SDCARD_RW
@@ -713,9 +729,6 @@
                             || status.hasModeFlag(FileUtils.S_IWGRP)
                             || status.hasModeFlag(FileUtils.S_IXGRP))
                     {
-
-                        // non-privileged GIDs should not be able to access
-                        // any block device.
                         retval.add(f);
                     }
                 }
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java
index 88db884..271588f 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java
@@ -16,34 +16,42 @@
 
 package android.provider.cts;
 
-import android.app.Instrumentation;
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentUris;
+import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
+import android.os.SystemClock;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.Contacts;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
-import android.test.InstrumentationTestCase;
+import android.provider.cts.contacts.ContactUtil;
+import android.provider.cts.contacts.DatabaseAsserts;
+import android.provider.cts.contacts.RawContactUtil;
+import android.test.AndroidTestCase;
 
 import java.util.List;
 
-public class ContactsContract_ContactsTest extends InstrumentationTestCase {
-    private ContentResolver mContentResolver;
+public class ContactsContract_ContactsTest extends AndroidTestCase {
+
+    private StaticAccountAuthenticator mAuthenticator;
+    private ContentResolver mResolver;
     private ContactsContract_TestDataBuilder mBuilder;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mContentResolver = getInstrumentation().getTargetContext().getContentResolver();
+        mResolver = getContext().getContentResolver();
         ContentProviderClient provider =
-                mContentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY);
+                mResolver.acquireContentProviderClient(ContactsContract.AUTHORITY);
         mBuilder = new ContactsContract_TestDataBuilder(provider);
+
+        mAuthenticator = new StaticAccountAuthenticator(getContext());
     }
 
     @Override
@@ -57,14 +65,14 @@
         TestContact contact = rawContact.getContact().load();
         long oldLastContacted = contact.getLong(Contacts.LAST_TIME_CONTACTED);
 
-        Contacts.markAsContacted(mContentResolver, contact.getId());
+        Contacts.markAsContacted(mResolver, contact.getId());
         contact.load(); // Reload
 
         long lastContacted = contact.getLong(Contacts.LAST_TIME_CONTACTED);
         assertTrue(oldLastContacted < lastContacted);
         oldLastContacted = lastContacted;
 
-        Contacts.markAsContacted(mContentResolver, contact.getId());
+        Contacts.markAsContacted(mResolver, contact.getId());
         contact.load();
 
         lastContacted = contact.getLong(Contacts.LAST_TIME_CONTACTED);
@@ -72,8 +80,7 @@
     }
 
     public void testContentUri() {
-        Instrumentation instrumentation = getInstrumentation();
-        Context context = instrumentation.getContext();
+        Context context = getContext();
         PackageManager packageManager = context.getPackageManager();
         Intent intent = new Intent(Intent.ACTION_VIEW, ContactsContract.Contacts.CONTENT_URI);
         List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0);
@@ -93,11 +100,79 @@
         assertEquals(ContentUris.withAppendedId(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
                 lookupKey), contactId), lookupUri);
 
-        Uri lookupUri2 = Contacts.getLookupUri(mContentResolver, contactUri);
+        Uri lookupUri2 = Contacts.getLookupUri(mResolver, contactUri);
         assertEquals(lookupUri, lookupUri2);
 
-        Uri contactUri2 = Contacts.lookupContact(mContentResolver, lookupUri);
+        Uri contactUri2 = Contacts.lookupContact(mResolver, lookupUri);
         assertEquals(contactUri, contactUri2);
     }
-}
 
+    public void testInsert_isUnsupported() {
+        DatabaseAsserts.assertInsertIsUnsupported(mResolver, Contacts.CONTENT_URI);
+    }
+
+    public void testContactDelete_removesContactRecord() {
+        assertContactCreateDelete();
+    }
+
+    public void testContactDelete_hasDeleteLog() {
+        long start = System.currentTimeMillis();
+        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
+        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, start);
+
+        // Clean up. Must also remove raw contact.
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+    }
+
+    public void testContactDelete_marksRawContactsForDeletion() {
+        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
+
+        String[] projection = new String[] {
+                ContactsContract.RawContacts.DIRTY,
+                ContactsContract.RawContacts.DELETED
+        };
+        List<String[]> records = RawContactUtil.queryByContactId(mResolver, ids.mContactId,
+                projection);
+        for (String[] arr : records) {
+            assertEquals("1", arr[0]);
+            assertEquals("1", arr[1]);
+        }
+
+        // Clean up
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+    }
+
+    public void testContactUpdate_updatesContactUpdatedTimestamp() {
+        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+
+        ContentValues values = new ContentValues();
+        values.put(ContactsContract.Contacts.STARRED, 1);
+
+        SystemClock.sleep(1);
+        ContactUtil.update(mResolver, ids.mContactId, values);
+
+        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+        assertTrue(newTime > baseTime);
+
+        // Clean up
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+    }
+
+    /**
+     * Create a contact.  Delete it.  And assert that the contact record is no longer present.
+     *
+     * @return The contact id and raw contact id that was created.
+     */
+    private DatabaseAsserts.ContactIdPair assertContactCreateDelete() {
+        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        SystemClock.sleep(1);
+        ContactUtil.delete(mResolver, ids.mContactId);
+
+        assertFalse(ContactUtil.recordExistsForContactId(mResolver, ids.mContactId));
+
+        return ids;
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java
index 0644cb2..612163c 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java
@@ -17,16 +17,23 @@
 package android.provider.cts;
 
 
+import static android.provider.ContactsContract.CommonDataKinds;
+
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
+import android.content.ContentValues;
 import android.net.Uri;
+import android.os.SystemClock;
 import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestData;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
+import android.provider.cts.contacts.ContactUtil;
+import android.provider.cts.contacts.DataUtil;
+import android.provider.cts.contacts.DatabaseAsserts;
+import android.provider.cts.contacts.RawContactUtil;
 import android.test.InstrumentationTestCase;
 
 public class ContactsContract_DataTest extends InstrumentationTestCase {
@@ -57,8 +64,8 @@
 
         // TODO remove this. The method under test is currently broken: it will not
         // work without at least one data row in the raw contact.
-        TestData data = rawContact.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
-                .with(StructuredName.DISPLAY_NAME, "test name")
+        TestData data = rawContact.newDataRow(CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
+                .with(CommonDataKinds.StructuredName.DISPLAY_NAME, "test name")
                 .insert();
 
         Uri lookupUri = Data.getContactLookupUri(mResolver, data.getUri());
@@ -74,8 +81,8 @@
                 .with(RawContacts.ACCOUNT_TYPE, "test_type")
                 .with(RawContacts.ACCOUNT_NAME, "test_name")
                 .insert();
-        TestData data = rawContact.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
-                .with(StructuredName.DISPLAY_NAME, "test name")
+        TestData data = rawContact.newDataRow(CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
+                .with(CommonDataKinds.StructuredName.DISPLAY_NAME, "test name")
                 .insert();
 
         Uri lookupUri = Data.getContactLookupUri(mResolver, data.getUri());
@@ -85,5 +92,64 @@
         assertEquals("Lookup URI matched the wrong contact",
                 lookupContact.getId(), data.load().getRawContact().load().getContactId());
     }
+
+    public void testDataInsert_updatesContactLastUpdatedTimestamp() {
+        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+
+        SystemClock.sleep(1);
+        createData(ids.mRawContactId);
+
+        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+        assertTrue(newTime > baseTime);
+
+        // Clean up
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+    }
+
+    public void testDataDelete_updatesContactLastUpdatedTimestamp() {
+        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        long dataId = createData(ids.mRawContactId);
+
+        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+
+        SystemClock.sleep(1);
+        DataUtil.delete(mResolver, dataId);
+
+        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+        assertTrue(newTime > baseTime);
+
+        // Clean up
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+    }
+
+    public void testDataUpdate_updatesContactLastUpdatedTimestamp() {
+        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        long dataId = createData(ids.mRawContactId);
+
+        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+
+        SystemClock.sleep(1);
+        ContentValues values = new ContentValues();
+        values.put(CommonDataKinds.Phone.NUMBER, "555-5555");
+        DataUtil.update(mResolver, dataId, values);
+
+        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+        assertTrue(newTime > baseTime);
+
+        // Clean up
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+    }
+
+    private long createData(long rawContactId) {
+        ContentValues values = new ContentValues();
+        values.put(Data.MIMETYPE, CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
+        values.put(CommonDataKinds.Phone.NUMBER, "1-800-GOOG-411");
+        values.put(CommonDataKinds.Phone.TYPE, CommonDataKinds.Phone.TYPE_CUSTOM);
+        values.put(CommonDataKinds.Phone.LABEL, "free directory assistance");
+        return DataUtil.insertData(mResolver, rawContactId, values);
+    }
 }
 
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_DeletedContacts.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_DeletedContacts.java
new file mode 100644
index 0000000..542b49e
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_DeletedContacts.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.provider.cts;
+
+import static android.provider.cts.contacts.DatabaseAsserts.ContactIdPair;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.net.Uri;
+import android.os.SystemClock;
+import android.provider.ContactsContract;
+import android.provider.cts.contacts.CommonDatabaseUtils;
+import android.provider.cts.contacts.DatabaseAsserts;
+import android.provider.cts.contacts.DeletedContactUtil;
+import android.provider.cts.contacts.RawContactUtil;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+
+import java.util.HashSet;
+import java.util.List;
+
+public class ContactsContract_DeletedContacts extends AndroidTestCase {
+
+    private static final Uri URI = ContactsContract.DeletedContacts.CONTENT_URI;
+
+    private ContentResolver mResolver;
+
+    @Override
+    public void setUp() {
+        mResolver = getContext().getContentResolver();
+    }
+
+    public void testDelete_isUnsupported() {
+
+        DatabaseAsserts.assertDeleteIsUnsupported(mResolver, URI);
+
+        Uri uri = ContentUris.withAppendedId(URI, 1L);
+        DatabaseAsserts.assertDeleteIsUnsupported(mResolver, uri);
+    }
+
+    public void testInsert_isUnsupported() {
+        DatabaseAsserts.assertInsertIsUnsupported(mResolver, URI);
+    }
+
+    public void testQuery_returnsProperColumns() {
+        long start = System.currentTimeMillis();
+        ContactIdPair ids = createAndDeleteContact();
+
+        String[] projection = new String[] {
+                ContactsContract.DeletedContacts.CONTACT_ID,
+                ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP
+        };
+        List<String[]> records = DeletedContactUtil.query(mResolver, projection);
+        boolean found = false;
+        for (String[] record : records) {
+            if (Long.parseLong(record[0]) == ids.mContactId) {
+                found = true;
+                assertTrue(Long.parseLong(record[1]) > start);
+            }
+        }
+        assertTrue(found);
+    }
+
+    public void testQueryByContactId() {
+        ContactIdPair ids = createAndDeleteContact();
+
+        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND,
+                DeletedContactUtil.queryDeletedTimestampForContactId(mResolver, ids.mContactId));
+    }
+
+    public void testQueryAll() {
+        int numDeletes = 10;
+
+        // Since we cannot clean out delete log from previous tests, we need to account for that
+        // by querying for the count first.
+        long startCount = DeletedContactUtil.getCount(mResolver);
+
+        for (int i = 0; i < numDeletes; i++) {
+            createAndDeleteContact();
+        }
+
+        long endCount = DeletedContactUtil.getCount(mResolver);
+
+        assertEquals(numDeletes, endCount - startCount);
+    }
+
+    public void testQuerySinceTimestamp() {
+
+        // Before
+        HashSet<Long> beforeIds = new HashSet<Long>();
+        beforeIds.add(createAndDeleteContact().mContactId);
+        beforeIds.add(createAndDeleteContact().mContactId);
+
+        long start = System.currentTimeMillis();
+
+        // After
+        HashSet<Long> afterIds = new HashSet<Long>();
+        afterIds.add(createAndDeleteContact().mContactId);
+        afterIds.add(createAndDeleteContact().mContactId);
+        afterIds.add(createAndDeleteContact().mContactId);
+
+        String[] projection = new String[]{
+                ContactsContract.DeletedContacts.CONTACT_ID,
+                ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP
+        };
+        List<String[]> records = DeletedContactUtil.querySinceTimestamp(mResolver, projection,
+                start);
+        for (String[] record : records) {
+            // Check ids to make sure we only have the ones that came after the time.
+            long contactId = Long.parseLong(record[0]);
+            assertFalse(beforeIds.contains(contactId));
+            assertTrue(afterIds.contains(contactId));
+
+            // Check times to make sure they came after
+            assertTrue(Long.parseLong(record[1]) > start);
+        }
+    }
+
+    private ContactIdPair createAndDeleteContact() {
+        ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+        assertEquals(CommonDatabaseUtils.NOT_FOUND,
+                DeletedContactUtil.queryDeletedTimestampForContactId(mResolver, ids.mContactId));
+        SystemClock.sleep(1);
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+        return ids;
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_RawContactsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_RawContactsTest.java
index 02196c0..d9751f4 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_RawContactsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_RawContactsTest.java
@@ -19,22 +19,28 @@
 
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
+import android.content.ContentValues;
 import android.net.Uri;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
-import android.test.InstrumentationTestCase;
+import android.provider.cts.contacts.CommonDatabaseUtils;
+import android.provider.cts.contacts.ContactUtil;
+import android.provider.cts.contacts.DatabaseAsserts;
+import android.provider.cts.contacts.RawContactUtil;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
 
-public class ContactsContract_RawContactsTest extends InstrumentationTestCase {
+public class ContactsContract_RawContactsTest extends AndroidTestCase {
     private ContentResolver mResolver;
     private ContactsContract_TestDataBuilder mBuilder;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mResolver = getInstrumentation().getTargetContext().getContentResolver();
+        mResolver = getContext().getContentResolver();
         ContentProviderClient provider =
                 mResolver.acquireContentProviderClient(ContactsContract.AUTHORITY);
         mBuilder = new ContactsContract_TestDataBuilder(provider);
@@ -83,5 +89,98 @@
         assertEquals("Lookup URI matched the wrong contact",
                 lookupContact.getId(), rawContact.load().getContactId());
     }
-}
 
+    public void testRawContactDelete_setsDeleteFlag() {
+        long rawContactid = RawContactUtil.insertRawContact(mResolver);
+
+        assertTrue(RawContactUtil.rawContactExistsById(mResolver, rawContactid));
+
+        RawContactUtil.delete(mResolver, rawContactid, false);
+
+        String[] projection = new String[]{
+                ContactsContract.RawContacts.CONTACT_ID,
+                ContactsContract.RawContacts.DELETED
+        };
+        String[] result = RawContactUtil.queryByRawContactId(mResolver, rawContactid,
+                projection);
+
+        // Contact id should be null
+        assertNull(result[0]);
+        // Record should be marked deleted.
+        assertEquals("1", result[1]);
+    }
+
+    public void testRawContactDelete_removesRecord() {
+        long rawContactid = RawContactUtil.insertRawContact(mResolver);
+        assertTrue(RawContactUtil.rawContactExistsById(mResolver, rawContactid));
+
+        RawContactUtil.delete(mResolver, rawContactid, true);
+
+        assertFalse(RawContactUtil.rawContactExistsById(mResolver, rawContactid));
+
+        // already clean
+    }
+
+
+    // This implicitly tests the Contact create case.
+    public void testRawContactCreate_updatesContactUpdatedTimestamp() {
+        long startTime = System.currentTimeMillis();
+
+        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
+        long lastUpdated = getContactLastUpdatedTimestampByRawContactId(mResolver, rawContactId);
+
+        assertTrue(lastUpdated > startTime);
+
+        // Clean up
+        RawContactUtil.delete(mResolver, rawContactId, true);
+    }
+
+    public void testRawContactUpdate_updatesContactUpdatedTimestamp() {
+        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+
+        ContentValues values = new ContentValues();
+        values.put(ContactsContract.RawContacts.STARRED, 1);
+        RawContactUtil.update(mResolver, ids.mRawContactId, values);
+
+        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+        assertTrue(newTime > baseTime);
+
+        // Clean up
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+    }
+
+    public void testRawContactPsuedoDelete_hasDeleteLogForContact() {
+        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+
+        RawContactUtil.delete(mResolver, ids.mRawContactId, false);
+
+        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, baseTime);
+
+        // clean up
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+    }
+
+    public void testRawContactDelete_hasDeleteLogForContact() {
+        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
+
+        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
+
+        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
+
+        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, baseTime);
+
+        // already clean
+    }
+
+    private long getContactLastUpdatedTimestampByRawContactId(ContentResolver resolver,
+            long rawContactId) {
+        long contactId = RawContactUtil.queryContactIdByRawContactId(mResolver, rawContactId);
+        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND, contactId);
+
+        return ContactUtil.queryContactLastUpdatedTimestamp(mResolver, contactId);
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/StaticAccountAuthenticator.java b/tests/tests/provider/src/android/provider/cts/StaticAccountAuthenticator.java
new file mode 100644
index 0000000..d3c9e1d
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/StaticAccountAuthenticator.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.provider.cts;
+
+import android.accounts.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.NetworkErrorException;
+import android.content.Context;
+import android.os.Bundle;
+
+/**
+ * Account authenticator with 1 hard coded account.
+ *
+ * Also adds the account to the account manager on instantiation.
+ */
+public class StaticAccountAuthenticator extends AbstractAccountAuthenticator {
+
+    public static final String NAME = "test_account_name";
+    public static final String TYPE = "test_account_type";
+    private static final String LABEL = "test_auth_token_label";
+    private static final String TOKEN = "asdlkjfslkjfdklj";
+
+    private static Bundle sAccountBundle;
+    static {
+        sAccountBundle = new Bundle();
+        sAccountBundle.putString(AccountManager.KEY_ACCOUNT_NAME, NAME);
+        sAccountBundle.putString(AccountManager.KEY_ACCOUNT_TYPE, TYPE);
+        sAccountBundle.putString(AccountManager.KEY_AUTHTOKEN, TOKEN);
+    }
+
+    private Context mContext;
+
+    private static Bundle createResultBundle() {
+        return sAccountBundle;
+    }
+
+    public void addAccount() {
+        AccountManager.get(mContext).addAccount(TYPE, null, null, null, null, null, null);
+    }
+
+    public StaticAccountAuthenticator(Context context) {
+        super(context);
+        this.mContext = context;
+        addAccount();
+    }
+
+    @Override
+    public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
+        return createResultBundle();
+    }
+
+    @Override
+    public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
+            String authTokenType, String[] requiredFeatures, Bundle options)
+            throws NetworkErrorException {
+        return createResultBundle();
+    }
+
+    @Override
+    public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
+            Bundle options) throws NetworkErrorException {
+        Bundle result = new Bundle();
+        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
+        return result;
+    }
+
+    @Override
+    public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
+            String authTokenType, Bundle options) throws NetworkErrorException {
+        return createResultBundle();
+    }
+
+    @Override
+    public String getAuthTokenLabel(String authTokenType) {
+        return LABEL;
+    }
+
+    @Override
+    public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
+            String authTokenType, Bundle options) throws NetworkErrorException {
+        return createResultBundle();
+    }
+
+    @Override
+    public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
+            String[] features) throws NetworkErrorException {
+        Bundle result = new Bundle();
+        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
+        return result;
+    }
+
+}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/CommonDatabaseUtils.java b/tests/tests/provider/src/android/provider/cts/contacts/CommonDatabaseUtils.java
new file mode 100644
index 0000000..833de64
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/contacts/CommonDatabaseUtils.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.provider.cts.contacts;
+
+import android.database.Cursor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Common database methods.
+ */
+public class CommonDatabaseUtils {
+
+    // primitive value used when record is not found.
+    public static final long NOT_FOUND = -1;
+
+    public static String[] singleRecordToArray(Cursor cursor) {
+        String[] result = null;
+        try {
+            if (cursor.moveToNext()) {
+                result = new String[cursor.getColumnCount()];
+                fillArray(cursor, result);
+            }
+        } finally {
+            closeQuietly(cursor);
+        }
+        return result;
+    }
+
+    public static List<String[]> multiRecordToArray(Cursor cursor) {
+        ArrayList<String[]> result = new ArrayList<String[]>();
+        try {
+            while (cursor.moveToNext()) {
+                String[] record = new String[cursor.getColumnCount()];
+                fillArray(cursor, record);
+                result.add(record);
+            }
+        } finally {
+            closeQuietly(cursor);
+        }
+        return result;
+    }
+
+    private static void fillArray(Cursor cursor, String[] array) {
+        for (int i = 0; i < array.length; i++) {
+            array[i] = cursor.getString(i);
+        }
+    }
+
+    public static void closeQuietly(Cursor cursor) {
+        if (cursor != null) {
+            cursor.close();
+        }
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactUtil.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactUtil.java
new file mode 100644
index 0000000..2a53781
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactUtil.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.provider.cts.contacts;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
+
+/**
+ * Convenience methods for operating on the Contacts table.
+ */
+public class ContactUtil {
+
+    private static final Uri URI = ContactsContract.Contacts.CONTENT_URI;
+
+    public static void update(ContentResolver resolver, long contactId,
+            ContentValues values) {
+        Uri uri = ContentUris.withAppendedId(URI, contactId);
+        resolver.update(uri, values, null, null);
+    }
+
+    public static void delete(ContentResolver resolver, long contactId) {
+        Uri uri = ContentUris.withAppendedId(URI, contactId);
+        resolver.delete(uri, null, null);
+    }
+
+    public static boolean recordExistsForContactId(ContentResolver resolver, long contactId) {
+        String[] projection = new String[]{
+                ContactsContract.Contacts._ID
+        };
+        Uri uri = ContentUris.withAppendedId(URI, contactId);
+        Cursor cursor = resolver.query(uri, projection, null, null, null);
+        if (cursor.moveToNext()) {
+            return true;
+        }
+        return false;
+    }
+
+    public static long queryContactLastUpdatedTimestamp(ContentResolver resolver, long contactId) {
+        String[] projection = new String[]{
+                ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP
+        };
+
+        Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
+        Cursor cursor = resolver.query(uri, projection, null, null, null);
+        try {
+            if (cursor.moveToNext()) {
+                return cursor.getLong(0);
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+        return CommonDatabaseUtils.NOT_FOUND;
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/DataUtil.java b/tests/tests/provider/src/android/provider/cts/contacts/DataUtil.java
new file mode 100644
index 0000000..adb253c
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/contacts/DataUtil.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.provider.cts.contacts;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.net.Uri;
+import android.provider.ContactsContract;
+
+/**
+ * Convenience methods for operating on the Data table.
+ */
+public class DataUtil {
+
+    private static final Uri URI = ContactsContract.Data.CONTENT_URI;
+
+    public static void insertName(ContentResolver resolver, long rawContactId) {
+        ContentValues values = new ContentValues();
+        values.put(ContactsContract.Data.MIMETYPE,
+                ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
+        values.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
+                "test raw contact " + rawContactId);
+        insertData(resolver, rawContactId, values);
+    }
+
+    public static long insertData(ContentResolver resolver, long rawContactId,
+            ContentValues values) {
+        // copy
+        ContentValues newValues = new ContentValues(values);
+        newValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
+
+        Uri uri = resolver.insert(URI, newValues);
+        return ContentUris.parseId(uri);
+    }
+
+    public static void delete(ContentResolver resolver, long dataId) {
+        Uri uri = ContentUris.withAppendedId(URI, dataId);
+        resolver.delete(uri, null, null);
+    }
+
+    public static void update(ContentResolver resolver, long dataId, ContentValues values) {
+        Uri uri = ContentUris.withAppendedId(URI, dataId);
+        resolver.update(uri, values, null, null);
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/DatabaseAsserts.java b/tests/tests/provider/src/android/provider/cts/contacts/DatabaseAsserts.java
new file mode 100644
index 0000000..a163960
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/contacts/DatabaseAsserts.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.provider.cts.contacts;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.net.Uri;
+import android.test.MoreAsserts;
+
+import junit.framework.Assert;
+
+/**
+ * Common methods for asserting database related operations.
+ */
+public class DatabaseAsserts {
+
+    public static void assertDeleteIsUnsupported(ContentResolver resolver, Uri uri) {
+        try {
+            resolver.delete(uri, null, null);
+            Assert.fail("delete operation should have failed with UnsupportedOperationException on"
+                    + uri);
+        } catch (UnsupportedOperationException e) {
+            // pass
+        }
+    }
+
+    public static void assertInsertIsUnsupported(ContentResolver resolver, Uri  uri) {
+        try {
+            ContentValues values = new ContentValues();
+            resolver.insert(uri, values);
+            Assert.fail("insert operation should have failed with UnsupportedOperationException on"
+                    + uri);
+        } catch (UnsupportedOperationException e) {
+            // pass
+        }
+    }
+
+    /**
+     * Create a contact and assert that the record exists.
+     *
+     * @return The created contact id pair.
+     */
+    public static ContactIdPair assertAndCreateContact(ContentResolver resolver) {
+        long rawContactId = RawContactUtil.createRawContactWithName(resolver);
+
+        long contactId = RawContactUtil.queryContactIdByRawContactId(resolver, rawContactId);
+        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND, contactId);
+
+        return new ContactIdPair(contactId, rawContactId);
+    }
+
+    /**
+     * Asserts that a contact id was deleted, has a delete log, and that log has a timestamp greater
+     * than the given timestamp.
+     *
+     * @param contactId The contact id to check.
+     * @param start The timestamp that the delete log should be greater than.
+     */
+    public static void assertHasDeleteLogGreaterThan(ContentResolver resolver, long contactId,
+            long start) {
+        Assert.assertFalse(ContactUtil.recordExistsForContactId(resolver, contactId));
+
+        long deletedTimestamp = DeletedContactUtil.queryDeletedTimestampForContactId(resolver,
+                contactId);
+        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND, deletedTimestamp);
+        Assert.assertTrue(deletedTimestamp > start);
+    }
+
+    /**
+     * Holds a single contact id and raw contact id relationship.
+     */
+    public static class ContactIdPair {
+        public long mContactId;
+        public long mRawContactId;
+
+        public ContactIdPair(long contactId, long rawContactId) {
+            this.mContactId = contactId;
+            this.mRawContactId = rawContactId;
+        }
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/DeletedContactUtil.java b/tests/tests/provider/src/android/provider/cts/contacts/DeletedContactUtil.java
new file mode 100644
index 0000000..692570a
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/contacts/DeletedContactUtil.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.provider.cts.contacts;
+
+import static android.provider.ContactsContract.DeletedContacts;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.database.Cursor;
+import android.net.Uri;
+
+import java.util.List;
+
+/**
+ * Convenience methods for operating on the DeletedContacts table.
+ */
+public class DeletedContactUtil {
+
+    private static final Uri URI = DeletedContacts.CONTENT_URI;
+
+    public static long queryDeletedTimestampForContactId(ContentResolver resolver, long contactId) {
+        String[] projection = new String[]{
+                DeletedContacts.CONTACT_DELETED_TIMESTAMP
+        };
+        Uri uri = ContentUris.withAppendedId(URI, contactId);
+        Cursor cursor = resolver.query(uri, projection, null, null, null);
+        if (cursor.moveToNext()) {
+            return cursor.getLong(0);
+        }
+        return CommonDatabaseUtils.NOT_FOUND;
+    }
+
+    public static long getCount(ContentResolver resolver) {
+        String[] projection = new String[] {
+                DeletedContacts.CONTACT_ID
+        };
+        Cursor cursor = resolver.query(URI, projection, null, null, null);
+        try {
+            return cursor.getCount();
+        } finally {
+            CommonDatabaseUtils.closeQuietly(cursor);
+        }
+    }
+
+    /**
+     * Queries all records.
+     *
+     * @return A list of records.  Where each record is represented as an array of strings.
+     */
+    public static List<String[]> query(ContentResolver resolver, String[] projection) {
+        Cursor cursor = resolver.query(URI, projection, null, null, null);
+        return CommonDatabaseUtils.multiRecordToArray(cursor);
+    }
+
+    /**
+     * Queries all records after a given timestamp.
+     *
+     * @return A list of records.  Where each record is represented as an array of strings.
+     */
+    public static List<String[]> querySinceTimestamp(ContentResolver resolver, String[] projection,
+            long timestamp) {
+        String selection = DeletedContacts.CONTACT_DELETED_TIMESTAMP + ">?";
+        String[] args = new String[] {timestamp + ""};
+        Cursor cursor = resolver.query(URI, projection, selection, args, null);
+        return CommonDatabaseUtils.multiRecordToArray(cursor);
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/RawContactUtil.java b/tests/tests/provider/src/android/provider/cts/contacts/RawContactUtil.java
new file mode 100644
index 0000000..8f9e7bd
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/contacts/RawContactUtil.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.provider.cts.contacts;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.cts.StaticAccountAuthenticator;
+
+import java.util.List;
+
+/**
+ * Convenience methods for operating on the RawContacts table.
+ */
+public class RawContactUtil {
+
+    private static final Uri URI = ContactsContract.RawContacts.CONTENT_URI;
+
+    public static void update(ContentResolver resolver, long rawContactId,
+            ContentValues values) {
+        Uri uri = ContentUris.withAppendedId(URI, rawContactId);
+        resolver.update(uri, values, null, null);
+    }
+
+    public static long createRawContactWithName(ContentResolver resolver) {
+        Long rawContactId = insertRawContact(resolver);
+        DataUtil.insertName(resolver, rawContactId);
+        return rawContactId;
+    }
+
+    public static long insertRawContact(ContentResolver resolver) {
+        ContentValues values = new ContentValues();
+        values.put(ContactsContract.RawContacts.ACCOUNT_NAME, StaticAccountAuthenticator.NAME);
+        values.put(ContactsContract.RawContacts.ACCOUNT_TYPE, StaticAccountAuthenticator.TYPE);
+        Uri uri = resolver.insert(ContactsContract.RawContacts.CONTENT_URI, values);
+        return ContentUris.parseId(uri);
+    }
+
+    public static String[] queryByRawContactId(ContentResolver resolver,
+            long rawContactId, String[] projection) {
+        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
+                rawContactId);
+        Cursor cursor = resolver.query(uri, projection, null, null, null);
+        return CommonDatabaseUtils.singleRecordToArray(cursor);
+    }
+
+    /**
+     * Returns a list of raw contact records.
+     *
+     * @return A list of records.  Where each record is represented as an array of strings.
+     */
+    public static List<String[]> queryByContactId(ContentResolver resolver, long contactId,
+            String[] projection) {
+        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, contactId);
+        Cursor cursor = resolver.query(uri, projection, null, null, null);
+        return CommonDatabaseUtils.multiRecordToArray(cursor);
+    }
+
+    public static void delete(ContentResolver resolver, long rawContactId,
+            boolean isSyncAdapter) {
+        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId)
+                .buildUpon()
+                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, isSyncAdapter + "")
+                .build();
+        resolver.delete(uri, null, null);
+    }
+
+    public static long queryContactIdByRawContactId(ContentResolver resolver, long rawContactid) {
+        String[] projection = new String[]{
+                ContactsContract.RawContacts.CONTACT_ID
+        };
+        String[] result = RawContactUtil.queryByRawContactId(resolver, rawContactid,
+                projection);
+        if (result == null) {
+            return CommonDatabaseUtils.NOT_FOUND;
+        }
+        return Long.parseLong(result[0]);
+    }
+
+    public static boolean rawContactExistsById(ContentResolver resolver, long rawContactid) {
+        long contactId = queryContactIdByRawContactId(resolver, rawContactid);
+        return contactId != CommonDatabaseUtils.NOT_FOUND;
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/BaseObjTest.java b/tests/tests/renderscript/src/android/renderscript/cts/BaseObjTest.java
new file mode 100644
index 0000000..6a7a3e4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/BaseObjTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.BaseObj;
+import android.renderscript.Element;
+import android.renderscript.RSIllegalArgumentException;
+import android.renderscript.Type;
+
+public class BaseObjTest extends RSBaseCompute {
+
+    public void testBaseObj() {
+        Element E = Element.I32(mRS);
+        Type.Builder TB = new Type.Builder(mRS, E);
+        Type T = TB.setX(1).create();
+        assertTrue(T != null);
+        BaseObj B = T;
+        B.setName("int32_t");
+        try {
+            B.setName("int32_t");
+            fail("set name twice for a BaseObj");
+        } catch (RSIllegalArgumentException e) {
+        }
+        T.destroy();
+
+        T = TB.setX(2).create();
+        assertTrue(T != null);
+        B = T;
+        try {
+            B.setName("");
+            fail("set empty name for a BaseObj");
+        } catch (RSIllegalArgumentException e) {
+        }
+
+        try {
+            B.setName(null);
+            fail("set name as null string reference for a BaseObj");
+        } catch (RSIllegalArgumentException e) {
+        }
+        B.setName("int32_t");
+
+        assertTrue(B.getName().compareTo("int32_t") == 0);
+        B.destroy();
+    }
+}
+
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 0af3f21..6313f7c 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -2768,7 +2768,8 @@
         final MockView scrollView = (MockView) mActivity.findViewById(R.id.scroll_view);
         Bitmap bitmap = Bitmap.createBitmap(200, 300, Bitmap.Config.RGB_565);
         final BitmapDrawable d = new BitmapDrawable(bitmap);
-        final InputMethodManager imm = InputMethodManager.getInstance(getActivity());
+        final InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(
+                Context.INPUT_METHOD_SERVICE);
         final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(300, 500);
         runTestOnUiThread(new Runnable() {
             public void run() {
@@ -3110,7 +3111,8 @@
     }
 
     public void testInputConnection() throws Throwable {
-        final InputMethodManager imm = InputMethodManager.getInstance(getActivity());
+        final InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(
+                Context.INPUT_METHOD_SERVICE);
         final MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
         final ViewGroup viewGroup = (ViewGroup) mActivity.findViewById(R.id.viewlayout_root);
         final MockEditText editText = new MockEditText(mActivity);
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 95d60ac..38f1ef4 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -122,22 +122,18 @@
     self.__WritePlan(plan, 'Android')
 
     plan = tools.TestPlan(packages)
-    plan.Exclude(ptsPattern)
     plan.Include(r'android\.core\.tests.*')
     self.__WritePlan(plan, 'Java')
 
     plan = tools.TestPlan(packages)
-    plan.Exclude(ptsPattern)
     plan.Include(r'android\.core\.vm-tests-tf')
     self.__WritePlan(plan, 'VM-TF')
 
     plan = tools.TestPlan(packages)
-    plan.Exclude(ptsPattern)
     plan.Include(r'android\.tests\.sigtest')
     self.__WritePlan(plan, 'Signature')
 
     plan = tools.TestPlan(packages)
-    plan.Exclude(ptsPattern)
     plan.Include(r'android\.tests\.appsecurity')
     self.__WritePlan(plan, 'AppSecurity')