Make storage and StrictMode tests more robust.

Many of the AppSecurity tests verify cross-user interactions by
creating and starting temporary users on multi-user devices.  Since
user creation adds significant overhead, this change creates a
secondary and tertiary user only once for the entire module, which
individual tests can then efficiently reuse.

Quietly skip testFullDisk() when we're unable to free up more than
90% of disk space, since that's a prerequisite for that test.

Rewrite StrictModeTest to use explicit listener for observing
violations, since reading back raw logcat data recently became
very flaky.

Test: cts-tradefed run commandAndExit cts-dev -m CtsOsTestCases -t android.os.cts.StrictModeTest
Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases
Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.StorageHostTest
Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.ExternalStorageHostTest
Bug: 38234598, 37486230, 37915178, 62018992
Change-Id: I97182aaa8c82cdc0a1169d5b4adac053c84a1b11
diff --git a/hostsidetests/appsecurity/AndroidTest.xml b/hostsidetests/appsecurity/AndroidTest.xml
index d1989e6..418d363 100644
--- a/hostsidetests/appsecurity/AndroidTest.xml
+++ b/hostsidetests/appsecurity/AndroidTest.xml
@@ -14,6 +14,7 @@
      limitations under the License.
 -->
 <configuration description="Config for the CTS App Security host tests">
+    <target_preparer class="android.appsecurity.cts.AppSecurityPreparer" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsAppSecurityHostTestCases.jar" />
         <option name="runtime-hint" value="20m" />
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
index 16e2765..a1bcc30 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
@@ -55,6 +55,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        Utils.prepareSingleUser(getDevice());
         assertNotNull(mAbi);
         assertNotNull(mCtsBuild);
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityPreparer.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityPreparer.java
new file mode 100644
index 0000000..b1ac744
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityPreparer.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 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.appsecurity.cts;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetCleaner;
+import com.android.tradefed.targetprep.ITargetPreparer;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+/**
+ * Creates secondary and tertiary users for use during a test suite.
+ */
+public class AppSecurityPreparer implements ITargetPreparer, ITargetCleaner {
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo)
+            throws TargetSetupError, BuildError, DeviceNotAvailableException {
+        // Clean up any lingering users from other tests to ensure that we have
+        // best shot at creating the users we need below.
+        removeSecondaryUsers(device);
+
+        final int maxUsers = device.getMaxNumberOfUsersSupported();
+        if (maxUsers > 1) {
+            CLog.logAndDisplay(LogLevel.INFO,
+                    "Created secondary user " + device.createUser("CTS_" + System.nanoTime()));
+        }
+        if (maxUsers > 2) {
+            CLog.logAndDisplay(LogLevel.INFO,
+                    "Created secondary user " + device.createUser("CTS_" + System.nanoTime()));
+        }
+    }
+
+    @Override
+    public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable throwable)
+            throws DeviceNotAvailableException {
+        removeSecondaryUsers(device);
+    }
+
+    private void removeSecondaryUsers(ITestDevice device) throws DeviceNotAvailableException {
+        final int[] userIds = Utils.getAllUsers(device);
+        for (int i = 1; i < userIds.length; i++) {
+            device.removeUser(userIds[i]);
+            CLog.logAndDisplay(LogLevel.INFO, "Destroyed secondary user " + userIds[i]);
+        }
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
index 36b0921..390064d 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
@@ -110,7 +110,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        // ensure build has been set before test is run
+
+        Utils.prepareSingleUser(getDevice());
         assertNotNull(mCtsBuild);
     }
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
index 69ff55e..920e0a5 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
@@ -17,29 +17,17 @@
 package android.appsecurity.cts;
 
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.TestIdentifier;
-import com.android.ddmlib.testrunner.TestResult;
-import com.android.ddmlib.testrunner.TestRunResult;
-import com.android.ddmlib.testrunner.TestResult.TestStatus;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IBuildReceiver;
 
 import java.util.ArrayList;
-import java.util.Map;
 
 /**
  * Base class.
  */
 public class BaseAppSecurityTest extends DeviceTestCase implements IBuildReceiver {
-    protected static final int USER_SYSTEM = 0; // From the UserHandle class.
-
-    private static final String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
-
     protected IBuildInfo mBuildInfo;
 
     /** Whether multi-user is supported. */
@@ -62,49 +50,12 @@
         mSupportsMultiUser = getDevice().getMaxNumberOfUsersSupported() > 1;
         mIsSplitSystemUser = checkIfSplitSystemUser();
         mPrimaryUserId = getDevice().getPrimaryUserId();
-        mFixedUsers = new ArrayList();
+        mFixedUsers = new ArrayList<>();
         mFixedUsers.add(mPrimaryUserId);
-        if (mPrimaryUserId != USER_SYSTEM) {
-            mFixedUsers.add(USER_SYSTEM);
+        if (mPrimaryUserId != Utils.USER_SYSTEM) {
+            mFixedUsers.add(Utils.USER_SYSTEM);
         }
         getDevice().switchUser(mPrimaryUserId);
-        removeTestUsers();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        removeTestUsers();
-        super.tearDown();
-    }
-
-    /**
-     * @return the userid of the created user
-     */
-    protected int createUser() throws DeviceNotAvailableException, IllegalStateException {
-        final String command = "pm create-user "
-                + "TestUser_" + System.currentTimeMillis();
-        CLog.d("Starting command: " + command);
-        final String output = getDevice().executeShellCommand(command);
-        CLog.d("Output for command " + command + ": " + output);
-
-        if (output.startsWith("Success")) {
-            try {
-                return Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim());
-            } catch (NumberFormatException e) {
-                CLog.e("Failed to parse result: %s", output);
-            }
-        } else {
-            CLog.e("Failed to create user: %s", output);
-        }
-        throw new IllegalStateException();
-    }
-
-    private void removeTestUsers() throws Exception {
-        for (int userId : getDevice().listUsers()) {
-            if (!mFixedUsers.contains(userId)) {
-                getDevice().removeUser(userId);
-            }
-        }
     }
 
     private boolean checkIfSplitSystemUser() throws DeviceNotAvailableException {
@@ -131,37 +82,4 @@
         String output = getDevice().executeShellCommand(command);
         return output.contains(packageName);
     }
-
-    private void printTestResult(TestRunResult runResult) {
-        for (Map.Entry<TestIdentifier, TestResult> testEntry :
-                runResult.getTestResults().entrySet()) {
-            TestResult testResult = testEntry.getValue();
-            CLog.d("Test " + testEntry.getKey() + ": " + testResult.getStatus());
-            if (testResult.getStatus() != TestStatus.PASSED) {
-                CLog.d(testResult.getStackTrace());
-            }
-        }
-    }
-
-    protected boolean runDeviceTestsAsUser(String packageName,
-            String testClassName, String testMethodName, int userId) throws Exception {
-        if (testClassName != null && testClassName.startsWith(".")) {
-            testClassName = packageName + testClassName;
-        }
-
-        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
-                packageName, RUNNER, getDevice().getIDevice());
-        if (testClassName != null && testMethodName != null) {
-            testRunner.setMethodName(testClassName, testMethodName);
-        } else if (testClassName != null) {
-            testRunner.setClassName(testClassName);
-        }
-
-        CollectingTestListener listener = new CollectingTestListener();
-        assertTrue(getDevice().runInstrumentationTestsAsUser(testRunner, userId, listener));
-
-        TestRunResult runResult = listener.getCurrentRunResults();
-        printTestResult(runResult);
-        return !runResult.hasFailedTests() && runResult.getNumTestsInState(TestStatus.PASSED) > 0;
-    }
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
index 6a6c27d..2174fa0 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DirectBootHostTest.java
@@ -54,6 +54,7 @@
 
     private String mFeatureList = null;
 
+    private int[] mUsers;
     private IAbi mAbi;
     private IBuildInfo mCtsBuild;
 
@@ -71,6 +72,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        mUsers = Utils.prepareSingleUser(getDevice());
         assertNotNull(mAbi);
         assertNotNull(mCtsBuild);
 
@@ -148,11 +150,8 @@
     }
 
     public void doDirectBootTest(String mode) throws Exception {
-        int[] users = {};
         boolean doTest = true;
         try {
-            users = createUsersForTest();
-
             // Set up test app and secure lock screens
             new InstallMultiple().addApk(APK).run();
             new InstallMultiple().addApk(OTHER_APK).run();
@@ -164,7 +163,7 @@
             // Give enough time for PackageManager to persist stopped state
             Thread.sleep(15000);
 
-            runDeviceTests(PKG, CLASS, "testSetUp", users);
+            runDeviceTests(PKG, CLASS, "testSetUp", mUsers);
 
             // Give enough time for vold to update keys
             Thread.sleep(15000);
@@ -184,19 +183,18 @@
 
             if (doTest) {
                 if (MODE_NONE.equals(mode)) {
-                    runDeviceTests(PKG, CLASS, "testVerifyUnlockedAndDismiss", users);
+                    runDeviceTests(PKG, CLASS, "testVerifyUnlockedAndDismiss", mUsers);
                 } else {
-                    runDeviceTests(PKG, CLASS, "testVerifyLockedAndDismiss", users);
+                    runDeviceTests(PKG, CLASS, "testVerifyLockedAndDismiss", mUsers);
                 }
             }
 
         } finally {
             try {
                 // Remove secure lock screens and tear down test app
-                runDeviceTests(PKG, CLASS, "testTearDown", users);
+                runDeviceTests(PKG, CLASS, "testTearDown", mUsers);
             } finally {
                 getDevice().uninstallPackage(PKG);
-                removeUsersForTest(users);
 
                 // Get ourselves back into a known-good state
                 if (MODE_EMULATED.equals(mode)) {
@@ -211,16 +209,6 @@
         }
     }
 
-    private int[] createUsersForTest() throws DeviceNotAvailableException {
-        // TODO: enable test for multiple users
-        return new int[] { 0 };
-//        return Utils.createUsersForTest(getDevice());
-    }
-
-    private void removeUsersForTest(int[] users) throws DeviceNotAvailableException {
-        Utils.removeUsersForTest(getDevice(), users);
-    }
-
     private void runDeviceTests(String packageName, String testClassName, String testMethodName,
             int... users) throws DeviceNotAvailableException {
         for (int user : users) {
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
index ceb7539..7bdd128 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTestCase.java
@@ -48,6 +48,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        Utils.prepareSingleUser(getDevice());
         assertNotNull(mAbi);
         assertNotNull(mCtsBuild);
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
index 915f147..8397f54 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/EphemeralTest.java
@@ -70,6 +70,7 @@
     public void setUp() throws Exception {
         super.setUp();
 
+        Utils.prepareSingleUser(getDevice());
         assertNotNull(mAbi);
         assertNotNull(mBuildInfo);
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
index e8dca57..87d8bd6 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
@@ -52,6 +52,7 @@
     private static final String MULTIUSER_PKG = "com.android.cts.multiuserstorageapp";
     private static final String MULTIUSER_CLASS = ".MultiUserStorageTest";
 
+    private int[] mUsers;
     private IAbi mAbi;
     private IBuildInfo mCtsBuild;
 
@@ -74,6 +75,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        mUsers = Utils.prepareMultipleUsers(getDevice());
         assertNotNull(mAbi);
         assertNotNull(mCtsBuild);
     }
@@ -87,7 +89,6 @@
      * Verify that app with no external storage permissions works correctly.
      */
     public void testExternalStorageNone() throws Exception {
-        final int[] users = createUsersForTest();
         try {
             wipePrimaryExternalStorage();
 
@@ -95,13 +96,12 @@
             String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
             assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options));
 
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(NONE_PKG, COMMON_CLASS, user);
                 runDeviceTests(NONE_PKG, NONE_CLASS, user);
             }
         } finally {
             getDevice().uninstallPackage(NONE_PKG);
-            removeUsersForTest(users);
         }
     }
 
@@ -111,7 +111,6 @@
      * correctly.
      */
     public void testExternalStorageRead() throws Exception {
-        final int[] users = createUsersForTest();
         try {
             wipePrimaryExternalStorage();
 
@@ -119,13 +118,12 @@
             String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
             assertNull(getDevice().installPackage(getTestAppFile(READ_APK), false, options));
 
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(READ_PKG, COMMON_CLASS, user);
                 runDeviceTests(READ_PKG, READ_CLASS, user);
             }
         } finally {
             getDevice().uninstallPackage(READ_PKG);
-            removeUsersForTest(users);
         }
     }
 
@@ -135,7 +133,6 @@
      * correctly.
      */
     public void testExternalStorageWrite() throws Exception {
-        final int[] users = createUsersForTest();
         try {
             wipePrimaryExternalStorage();
 
@@ -143,13 +140,12 @@
             String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
             assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options));
 
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(WRITE_PKG, COMMON_CLASS, user);
                 runDeviceTests(WRITE_PKG, WRITE_CLASS, user);
             }
         } finally {
             getDevice().uninstallPackage(WRITE_PKG);
-            removeUsersForTest(users);
         }
     }
 
@@ -158,7 +154,6 @@
      * directories belonging to other apps, and those apps can read.
      */
     public void testExternalStorageGifts() throws Exception {
-        final int[] users = createUsersForTest();
         try {
             wipePrimaryExternalStorage();
 
@@ -170,13 +165,13 @@
             // We purposefully delay the installation of the reading apps to
             // verify that the daemon correctly invalidates any caches.
             assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options));
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(WRITE_PKG, ".WriteGiftTest", user);
             }
 
             assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options));
             assertNull(getDevice().installPackage(getTestAppFile(READ_APK), false, options));
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(READ_PKG, ".ReadGiftTest", user);
                 runDeviceTests(NONE_PKG, ".GiftTest", user);
             }
@@ -184,7 +179,6 @@
             getDevice().uninstallPackage(NONE_PKG);
             getDevice().uninstallPackage(READ_PKG);
             getDevice().uninstallPackage(WRITE_PKG);
-            removeUsersForTest(users);
         }
     }
 
@@ -193,15 +187,14 @@
      * isolated storage.
      */
     public void testMultiUserStorageIsolated() throws Exception {
-        final int[] users = createUsersForTest();
         try {
-            if (users.length == 1) {
+            if (mUsers.length == 1) {
                 Log.d(TAG, "Single user device; skipping isolated storage tests");
                 return;
             }
 
-            final int owner = users[0];
-            final int secondary = users[1];
+            final int owner = mUsers[0];
+            final int secondary = mUsers[1];
 
             // Install our test app
             getDevice().uninstallPackage(MULTIUSER_PKG);
@@ -231,7 +224,6 @@
             runDeviceTests(MULTIUSER_PKG, MULTIUSER_CLASS, "testMediaProviderUserIsolation", secondary);
         } finally {
             getDevice().uninstallPackage(MULTIUSER_PKG);
-            removeUsersForTest(users);
         }
     }
 
@@ -240,7 +232,6 @@
      * when apps with r/w permission levels move around their files.
      */
     public void testMultiViewMoveConsistency() throws Exception {
-        final int[] users = createUsersForTest();
         try {
             wipePrimaryExternalStorage();
 
@@ -252,37 +243,35 @@
             assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options));
             assertNull(getDevice().installPackage(getTestAppFile(READ_APK), false, options));
 
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(READ_PKG, ".ReadMultiViewTest", "testFolderSetup", user);
             }
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(READ_PKG, ".ReadMultiViewTest", "testRWAccess", user);
             }
 
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(WRITE_PKG, ".WriteMultiViewTest", "testMoveAway", user);
             }
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(READ_PKG, ".ReadMultiViewTest", "testROAccess", user);
             }
 
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(WRITE_PKG, ".WriteMultiViewTest", "testMoveBack", user);
             }
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(READ_PKG, ".ReadMultiViewTest", "testRWAccess", user);
             }
         } finally {
             getDevice().uninstallPackage(NONE_PKG);
             getDevice().uninstallPackage(READ_PKG);
             getDevice().uninstallPackage(WRITE_PKG);
-            removeUsersForTest(users);
         }
     }
 
     /** Verify that app without READ_EXTERNAL can play default URIs in external storage. */
     public void testExternalStorageReadDefaultUris() throws Exception {
-        final int[] users = createUsersForTest();
         try {
             wipePrimaryExternalStorage();
 
@@ -293,7 +282,7 @@
             assertNull(getDevice().installPackage(getTestAppFile(WRITE_APK), false, options));
             assertNull(getDevice().installPackage(getTestAppFile(NONE_APK), false, options));
 
-            for (int user : users) {
+            for (int user : mUsers) {
                 enableWriteSettings(WRITE_PKG, user);
                 runDeviceTests(
                         WRITE_PKG, WRITE_PKG + ".ChangeDefaultUris", "testChangeDefaultUris", user);
@@ -303,13 +292,12 @@
             }
         } finally {
             // Make sure the provider and uris are reset on failure.
-            for (int user : users) {
+            for (int user : mUsers) {
                 runDeviceTests(
                         WRITE_PKG, WRITE_PKG + ".ChangeDefaultUris", "testResetDefaultUris", user);
             }
             getDevice().uninstallPackage(NONE_PKG);
             getDevice().uninstallPackage(WRITE_PKG);
-            removeUsersForTest(users);
         }
     }
 
@@ -334,14 +322,6 @@
         getDevice().executeShellCommand("rm -rf /sdcard/MUST_*");
     }
 
-    private int[] createUsersForTest() throws DeviceNotAvailableException {
-        return Utils.createUsersForTest(getDevice());
-    }
-
-    private void removeUsersForTest(int[] users) throws DeviceNotAvailableException {
-        Utils.removeUsersForTest(getDevice(), users);
-    }
-
     private void runDeviceTests(String packageName, String testClassName, int userId)
             throws DeviceNotAvailableException {
         Utils.runDeviceTests(getDevice(), packageName, testClassName, userId);
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java
index fb5dffa..4609e8a 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantAppUserTest.java
@@ -19,8 +19,6 @@
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IAbi;
 import com.android.tradefed.testtype.IAbiReceiver;
@@ -73,8 +71,9 @@
         assertNotNull(mAbi);
         assertNotNull(mBuildInfo);
 
-        mSupportsMultiUser =
-                getDevice().getMaxNumberOfUsersSupported() - getDevice().listUsers().size() >= 2;
+        // This test only runs when we have at least 3 users to work with
+        final int[] users = Utils.prepareMultipleUsers(getDevice(), 3);
+        mSupportsMultiUser = (users.length == 3);
         if (mSupportsMultiUser) {
             mPrimaryUserId = getDevice().getPrimaryUserId();
             mFixedUsers = new ArrayList<>();
@@ -83,8 +82,9 @@
                 mFixedUsers.add(USER_SYSTEM);
             }
             getDevice().switchUser(mPrimaryUserId);
-            removeTestUsers();
-            createTestUsers();
+
+            mTestUser[0] = users[1];
+            mTestUser[1] = users[2];
 
             uninstallTestPackages();
             installTestPackages();
@@ -93,7 +93,6 @@
 
     public void tearDown() throws Exception {
         if (mSupportsMultiUser) {
-            removeTestUsers();
             uninstallTestPackages();
         }
         super.tearDown();
@@ -180,19 +179,6 @@
         getDevice().uninstallPackage(USER_PKG);
     }
 
-    private void createTestUsers() throws Exception {
-        mTestUser[0] = getDevice().createUser("TestUser_" + System.currentTimeMillis());
-        mTestUser[1] = getDevice().createUser("TestUser_" + System.currentTimeMillis());
-    }
-
-    private void removeTestUsers() throws Exception {
-        for (int userId : getDevice().listUsers()) {
-            if (!mFixedUsers.contains(userId)) {
-                getDevice().removeUser(userId);
-            }
-        }
-    }
-
     private void runDeviceTests(String packageName, String testClassName, String testMethodName)
             throws DeviceNotAvailableException {
         Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java
index e5a483c..fd599ea 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/InstantCookieHostTest.java
@@ -39,6 +39,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+
+        Utils.prepareSingleUser(getDevice());
         uninstallPackage(INSTANT_COOKIE_APP_PKG);
         clearUserData(INSTANT_COOKIE_APP_PKG);
     }
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/IsolatedSplitsTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/IsolatedSplitsTests.java
index ed05837..8795fe8 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/IsolatedSplitsTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/IsolatedSplitsTests.java
@@ -43,6 +43,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+
+        Utils.prepareSingleUser(getDevice());
         getDevice().uninstallPackage(PKG);
     }
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/KeySetHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/KeySetHostTest.java
index 1f7c6be..3574191 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/KeySetHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/KeySetHostTest.java
@@ -236,10 +236,13 @@
     }
 
     @Override
-        protected void setUp() throws Exception {
+    protected void setUp() throws Exception {
         super.setUp();
-        mDevice = getDevice();
+
+        Utils.prepareSingleUser(getDevice());
         assertNotNull(mCtsBuild);
+
+        mDevice = getDevice();
     }
 
     /**
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java
index 115ebf4..fde9f10 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java
@@ -32,10 +32,13 @@
     private static final boolean MATCH_UNINSTALLED = true;
     private static final boolean MATCH_NORMAL = false;
 
+    private int[] mUsers;
     private String mOldVerifierValue;
 
     public void setUp() throws Exception {
         super.setUp();
+
+        mUsers = Utils.prepareMultipleUsers(getDevice());
         mOldVerifierValue =
                 getDevice().executeShellCommand("settings get global package_verifier_enable");
         getDevice().executeShellCommand("settings put global package_verifier_enable 0");
@@ -54,7 +57,7 @@
             return;
         }
 
-        int userId = createUser();
+        int userId = mUsers[1];
         assertTrue(userId > 0);
         getDevice().startUser(userId);
         installTestAppForUser(TEST_APK, userId);
@@ -67,23 +70,23 @@
         assertTrue(isAppVisibleForUser(TINY_PKG, mPrimaryUserId, MATCH_UNINSTALLED));
 
         // Try the same from an app
-        assertTrue(runDeviceTestsAsUser(TEST_PKG,
-                ".PackageAccessTest", "testPackageAccess_inUser", mPrimaryUserId));
-        assertTrue(runDeviceTestsAsUser(TEST_PKG,
-                ".PackageAccessTest", "testPackageAccess_inUserUninstalled", mPrimaryUserId));
+        Utils.runDeviceTests(getDevice(), TEST_PKG,
+                ".PackageAccessTest", "testPackageAccess_inUser", mPrimaryUserId);
+        Utils.runDeviceTests(getDevice(), TEST_PKG,
+                ".PackageAccessTest", "testPackageAccess_inUserUninstalled", mPrimaryUserId);
 
         // It is not visible for the other user using shell commands
         assertFalse(isAppVisibleForUser(TINY_PKG, userId, MATCH_NORMAL));
         assertFalse(isAppVisibleForUser(TINY_PKG, userId, MATCH_UNINSTALLED));
 
         // Try the same from an app
-        assertTrue(runDeviceTestsAsUser(TEST_PKG,
-                ".PackageAccessTest", "testPackageAccess_notInOtherUser", userId));
-        assertTrue(runDeviceTestsAsUser(TEST_PKG,
-                ".PackageAccessTest", "testPackageAccess_notInOtherUserUninstalled", userId));
+        Utils.runDeviceTests(getDevice(), TEST_PKG,
+                ".PackageAccessTest", "testPackageAccess_notInOtherUser", userId);
+        Utils.runDeviceTests(getDevice(), TEST_PKG,
+                ".PackageAccessTest", "testPackageAccess_notInOtherUserUninstalled", userId);
 
-        assertTrue(runDeviceTestsAsUser(TEST_PKG,
-                ".PackageAccessTest", "testPackageAccess_getPackagesCantSeeTiny", userId));
+        Utils.runDeviceTests(getDevice(), TEST_PKG,
+                ".PackageAccessTest", "testPackageAccess_getPackagesCantSeeTiny", userId);
 
         getDevice().uninstallPackage(TINY_PKG);
 
@@ -105,14 +108,14 @@
         assertFalse(isAppVisibleForUser(TINY_PKG, userId, MATCH_NORMAL));
         assertTrue(isAppVisibleForUser(TINY_PKG, userId, MATCH_UNINSTALLED));
 
-        assertTrue(runDeviceTestsAsUser(TEST_PKG,
-                ".PackageAccessTest", "testPackageAccess_getPackagesCanSeeTiny", userId));
+        Utils.runDeviceTests(getDevice(), TEST_PKG,
+                ".PackageAccessTest", "testPackageAccess_getPackagesCanSeeTiny", userId);
 
-        assertTrue(runDeviceTestsAsUser(TEST_PKG,
+        Utils.runDeviceTests(getDevice(), TEST_PKG,
                 ".PackageAccessTest", "testPackageAccess_notInOtherUserUninstalled",
-                mPrimaryUserId));
-        assertTrue(runDeviceTestsAsUser(TEST_PKG,
-                ".PackageAccessTest", "testPackageAccess_getPackagesCantSeeTiny", mPrimaryUserId));
+                mPrimaryUserId);
+        Utils.runDeviceTests(getDevice(), TEST_PKG,
+                ".PackageAccessTest", "testPackageAccess_getPackagesCantSeeTiny", mPrimaryUserId);
 
         getDevice().uninstallPackage(TINY_PKG);
         getDevice().uninstallPackage(TEST_PKG);
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
index b7f7f88..9ba3c82 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PermissionsHostTest.java
@@ -58,6 +58,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        Utils.prepareSingleUser(getDevice());
         assertNotNull(mAbi);
         assertNotNull(mBuildHelper);
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
index 93d683f..e87c390 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PkgInstallSignatureVerificationTest.java
@@ -16,6 +16,11 @@
 
 package android.appsecurity.cts;
 
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -24,12 +29,6 @@
 import java.io.OutputStream;
 import java.util.Locale;
 
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IBuildReceiver;
-
 /**
  * Tests for APK signature verification during installation.
  */
@@ -44,10 +43,6 @@
     private static final String[] RSA_KEY_NAMES_2048_AND_LARGER =
             {"2048", "3072", "4096", "8192", "16384"};
 
-
-    /** Device under test. */
-    private ITestDevice mDevice;
-
     private IBuildInfo mCtsBuild;
 
     @Override
@@ -58,7 +53,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mDevice = getDevice();
+
+        Utils.prepareSingleUser(getDevice());
         assertNotNull(mCtsBuild);
         uninstallPackage();
     }
@@ -582,9 +578,9 @@
                 }
             }
             if (ephemeral) {
-                return mDevice.installPackage(apkFile, true, "--ephemeral");
+                return getDevice().installPackage(apkFile, true, "--ephemeral");
             } else {
-                return mDevice.installPackage(apkFile, true);
+                return getDevice().installPackage(apkFile, true);
             }
         } finally {
             apkFile.delete();
@@ -602,6 +598,6 @@
     }
 
     private String uninstallPackage() throws DeviceNotAvailableException {
-        return mDevice.uninstallPackage(TEST_PKG);
+        return getDevice().uninstallPackage(TEST_PKG);
     }
 }
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
index ca218ef..630f351 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
@@ -63,6 +63,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        Utils.prepareSingleUser(getDevice());
         assertNotNull(mAbi);
         assertNotNull(mBuildHelper);
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/SplitTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/SplitTests.java
index 21bfca1..9474ba8 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/SplitTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/SplitTests.java
@@ -96,6 +96,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        Utils.prepareSingleUser(getDevice());
         assertNotNull(mAbi);
         assertNotNull(mCtsBuild);
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/StorageHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/StorageHostTest.java
index f679e83..f08e4fe 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/StorageHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/StorageHostTest.java
@@ -16,18 +16,22 @@
 
 package android.appsecurity.cts;
 
-import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
+import com.android.compatibility.common.tradefed.testtype.CompatibilityHostTestBase;
 import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IAbi;
-import com.android.tradefed.testtype.IAbiReceiver;
-import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import junit.framework.AssertionFailedError;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 /**
  * Tests that exercise various storage APIs.
  */
-public class StorageHostTest extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class StorageHostTest extends CompatibilityHostTestBase {
     private static final String PKG_STATS = "com.android.cts.storagestatsapp";
     private static final String PKG_A = "com.android.cts.storageapp_a";
     private static final String PKG_B = "com.android.cts.storageapp_b";
@@ -37,49 +41,15 @@
     private static final String CLASS_STATS = "com.android.cts.storagestatsapp.StorageStatsTest";
     private static final String CLASS = "com.android.cts.storageapp.StorageTest";
 
-    private IAbi mAbi;
-    private IBuildInfo mCtsBuild;
-
     private int[] mUsers;
 
-    @Override
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
+    @Before
+    public void setUp() throws Exception {
+        mUsers = Utils.prepareMultipleUsers(getDevice());
 
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = buildInfo;
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mUsers = Utils.createUsersForTest(getDevice());
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        getDevice().uninstallPackage(PKG_STATS);
-        getDevice().uninstallPackage(PKG_A);
-        getDevice().uninstallPackage(PKG_B);
-
-        Utils.removeUsersForTest(getDevice(), mUsers);
-        mUsers = null;
-    }
-
-    private void prepareTestApps() throws Exception {
-        getDevice().uninstallPackage(PKG_STATS);
-        getDevice().uninstallPackage(PKG_A);
-        getDevice().uninstallPackage(PKG_B);
-
-        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
-        assertNull(getDevice().installPackage(buildHelper.getTestFile(APK_STATS), false));
-        assertNull(getDevice().installPackage(buildHelper.getTestFile(APK_A), false));
-        assertNull(getDevice().installPackage(buildHelper.getTestFile(APK_B), false));
+        installPackage(APK_STATS);
+        installPackage(APK_A);
+        installPackage(APK_B);
 
         for (int user : mUsers) {
             getDevice().executeShellCommand("appops set --user " + user + " " + PKG_STATS
@@ -87,26 +57,20 @@
         }
     }
 
-    public void testEverything() throws Exception {
-        prepareTestApps(); doVerifyQuota();
-        prepareTestApps(); doVerifyAppStats();
-        prepareTestApps(); doVerifyAppQuota();
-        prepareTestApps(); doVerifyAppAllocate();
-        prepareTestApps(); doVerifySummary();
-        prepareTestApps(); doVerifyStats();
-        prepareTestApps(); doVerifyStatsMultiple();
-        prepareTestApps(); doVerifyStatsExternal();
-        prepareTestApps(); doVerifyStatsExternalConsistent();
-        prepareTestApps(); doVerifyCategory();
-        prepareTestApps(); doCache();
-        prepareTestApps(); doFullDisk();
+    @After
+    public void tearDown() throws Exception {
+        getDevice().uninstallPackage(PKG_STATS);
+        getDevice().uninstallPackage(PKG_A);
+        getDevice().uninstallPackage(PKG_B);
     }
 
-    public void doVerifyQuota() throws Exception {
-        runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyQuota", Utils.USER_OWNER);
+    @Test
+    public void testVerifyQuota() throws Exception {
+        Utils.runDeviceTests(getDevice(), PKG_STATS, CLASS_STATS, "testVerifyQuota");
     }
 
-    public void doVerifyAppStats() throws Exception {
+    @Test
+    public void testVerifyAppStats() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_A, CLASS, "testAllocate", user);
         }
@@ -120,31 +84,36 @@
         }
     }
 
-    public void doVerifyAppQuota() throws Exception {
+    @Test
+    public void testVerifyAppQuota() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_A, CLASS, "testVerifyQuotaApi", user);
         }
     }
 
-    public void doVerifyAppAllocate() throws Exception {
+    @Test
+    public void testVerifyAppAllocate() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_A, CLASS, "testVerifyAllocateApi", user);
         }
     }
 
-    public void doVerifySummary() throws Exception {
+    @Test
+    public void testVerifySummary() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifySummary", user);
         }
     }
 
-    public void doVerifyStats() throws Exception {
+    @Test
+    public void testVerifyStats() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyStats", user);
         }
     }
 
-    public void doVerifyStatsMultiple() throws Exception {
+    @Test
+    public void testVerifyStatsMultiple() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_A, CLASS, "testAllocate", user);
             runDeviceTests(PKG_A, CLASS, "testAllocate", user);
@@ -157,25 +126,29 @@
         }
     }
 
-    public void doVerifyStatsExternal() throws Exception {
+    @Test
+    public void testVerifyStatsExternal() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyStatsExternal", user);
         }
     }
 
-    public void doVerifyStatsExternalConsistent() throws Exception {
+    @Test
+    public void testVerifyStatsExternalConsistent() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyStatsExternalConsistent", user);
         }
     }
 
-    public void doVerifyCategory() throws Exception {
+    @Test
+    public void testVerifyCategory() throws Exception {
         for (int user : mUsers) {
             runDeviceTests(PKG_STATS, CLASS_STATS, "testVerifyCategory", user);
         }
     }
 
-    public void doCache() throws Exception {
+    @Test
+    public void testCache() throws Exception {
         // To make the cache clearing logic easier to verify, ignore any cache
         // and low space reserved space.
         getDevice().executeShellCommand("settings put global sys_storage_threshold_max_bytes 0");
@@ -197,7 +170,8 @@
         }
     }
 
-    public void doFullDisk() throws Exception {
+    @Test
+    public void testFullDisk() throws Exception {
         waitForIdle();
 
         // Clear all other cached and external storage data to give ourselves a
@@ -209,9 +183,18 @@
         final String lastEvent = getDevice().executeShellCommand("logcat -d -b events -t 1");
         final String sinceTime = lastEvent.trim().substring(0, 18);
 
-        // Try our hardest to fill up the entire disk
-        runDeviceTests(PKG_A, CLASS, "testFullDisk", Utils.USER_OWNER);
-        runDeviceTests(PKG_A, CLASS, "testTweakComponent", Utils.USER_OWNER);
+        try {
+            // Try our hardest to fill up the entire disk
+            Utils.runDeviceTests(getDevice(), PKG_A, CLASS, "testFullDisk");
+        } catch (Throwable t) {
+            // If we had trouble filling the disk, don't bother going any
+            // further; we failed because we either don't have quota support, or
+            // because disk was more than 10% full.
+            return;
+        }
+
+        // Tweak something that causes PackageManager to persist data
+        Utils.runDeviceTests(getDevice(), PKG_A, CLASS, "testTweakComponent");
 
         // Try poking around a couple of settings apps
         getDevice().executeShellCommand("input keyevent KEY_HOME");
@@ -234,7 +217,7 @@
         troubleLogs = troubleLogs.trim().replaceAll("\\-+ beginning of [a-z]+", "");
 
         if (troubleLogs.length() > 4) {
-            fail("Unexpected crashes while disk full: " + troubleLogs);
+            throw new AssertionFailedError("Unexpected crashes while disk full: " + troubleLogs);
         }
     }
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/UsesLibraryHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/UsesLibraryHostTest.java
index cf8a354..4afeb9bf 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/UsesLibraryHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/UsesLibraryHostTest.java
@@ -51,6 +51,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        Utils.prepareSingleUser(getDevice());
         assertNotNull(mAbi);
         assertNotNull(mBuildHelper);
 
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java
index 37aaeaf..8e83c87 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java
@@ -16,7 +16,6 @@
 
 package android.appsecurity.cts;
 
-import com.android.ddmlib.Log;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.ddmlib.testrunner.TestResult;
@@ -26,16 +25,15 @@
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.result.CollectingTestListener;
 
+import java.util.Arrays;
 import java.util.Map;
 
 public class Utils {
-    private static final String TAG = "AppSecurity";
-
-    public static final int USER_OWNER = 0;
+    public static final int USER_SYSTEM = 0;
 
     public static void runDeviceTests(ITestDevice device, String packageName)
             throws DeviceNotAvailableException {
-        runDeviceTests(device, packageName, null, null, USER_OWNER);
+        runDeviceTests(device, packageName, null, null, USER_SYSTEM);
     }
 
     public static void runDeviceTests(ITestDevice device, String packageName, int userId)
@@ -45,7 +43,7 @@
 
     public static void runDeviceTests(ITestDevice device, String packageName, String testClassName)
             throws DeviceNotAvailableException {
-        runDeviceTests(device, packageName, testClassName, null, USER_OWNER);
+        runDeviceTests(device, packageName, testClassName, null, USER_SYSTEM);
     }
 
     public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
@@ -55,7 +53,7 @@
 
     public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
             String testMethodName) throws DeviceNotAvailableException {
-        runDeviceTests(device, packageName, testClassName, testMethodName, USER_OWNER);
+        runDeviceTests(device, packageName, testClassName, testMethodName, USER_SYSTEM);
     }
 
     public static void runDeviceTests(ITestDevice device, String packageName, String testClassName,
@@ -72,13 +70,8 @@
             testRunner.setClassName(testClassName);
         }
 
-        if (userId != USER_OWNER) {
-            // TODO: move this to RemoteAndroidTestRunner once it supports users
-            testRunner.addInstrumentationArg("hack_key", "hack_value --user " + userId);
-        }
-
         final CollectingTestListener listener = new CollectingTestListener();
-        device.runInstrumentationTests(testRunner, listener);
+        device.runInstrumentationTestsAsUser(testRunner, userId, listener);
 
         final TestRunResult result = listener.getCurrentRunResults();
         if (result.isRunFailure()) {
@@ -103,65 +96,55 @@
         }
     }
 
-    private static boolean isMultiUserSupportedOnDevice(ITestDevice device)
+    /**
+     * Prepare and return a single user relevant for testing.
+     */
+    public static int[] prepareSingleUser(ITestDevice device)
             throws DeviceNotAvailableException {
-        // TODO: move this to ITestDevice once it supports users
-        final String output = device.executeShellCommand("pm get-max-users");
-        try {
-            return Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim()) > 1;
-        } catch (NumberFormatException e) {
-            throw new AssertionError("Failed to parse result: " + output);
-        }
+        return prepareMultipleUsers(device, 1);
     }
 
     /**
-     * Return set of users that test should be run for, creating a secondary
-     * user if the device supports it. Always call
-     * {@link #removeUsersForTest(ITestDevice, int[])} when finished.
+     * Prepare and return two users relevant for testing.
      */
-    public static int[] createUsersForTest(ITestDevice device) throws DeviceNotAvailableException {
-        if (isMultiUserSupportedOnDevice(device)) {
-            return new int[] { USER_OWNER, createUserOnDevice(device) };
-        } else {
-            Log.d(TAG, "Single user device; skipping isolated storage tests");
-            return new int[] { USER_OWNER };
-        }
+    public static int[] prepareMultipleUsers(ITestDevice device)
+            throws DeviceNotAvailableException {
+        return prepareMultipleUsers(device, 2);
     }
 
-    public static void removeUsersForTest(ITestDevice device, int[] users)
+    /**
+     * Prepare and return multiple users relevant for testing.
+     */
+    public static int[] prepareMultipleUsers(ITestDevice device, int maxUsers)
             throws DeviceNotAvailableException {
-        for (int user : users) {
-            if (user != USER_OWNER) {
-                removeUserOnDevice(device, user);
+        final int[] userIds = getAllUsers(device);
+        for (int i = 1; i < userIds.length; i++) {
+            if (i < maxUsers) {
+                device.startUser(userIds[i]);
+            } else {
+                device.stopUser(userIds[i]);
             }
         }
-    }
-
-    private static int createUserOnDevice(ITestDevice device) throws DeviceNotAvailableException {
-        // TODO: move this to ITestDevice once it supports users
-        final String name = "CTS_" + System.currentTimeMillis();
-        final String output = device.executeShellCommand("pm create-user " + name);
-        if (output.startsWith("Success")) {
-            try {
-                final int userId = Integer.parseInt(
-                        output.substring(output.lastIndexOf(" ")).trim());
-                device.executeShellCommand("am start-user " + userId);
-                return userId;
-            } catch (NumberFormatException e) {
-                throw new AssertionError("Failed to parse result: " + output);
-            }
+        if (userIds.length > maxUsers) {
+            return Arrays.copyOf(userIds, maxUsers);
         } else {
-            throw new AssertionError("Failed to create user: " + output);
+            return userIds;
         }
     }
 
-    private static void removeUserOnDevice(ITestDevice device, int userId)
+    public static int[] getAllUsers(ITestDevice device)
             throws DeviceNotAvailableException {
-        // TODO: move this to ITestDevice once it supports users
-        final String output = device.executeShellCommand("pm remove-user " + userId);
-        if (output.startsWith("Error")) {
-            throw new AssertionError("Failed to remove user: " + output);
+        Integer primary = device.getPrimaryUserId();
+        if (primary == null) {
+            primary = USER_SYSTEM;
         }
+        int[] users = new int[] { primary };
+        for (Integer user : device.listUsers()) {
+            if ((user != USER_SYSTEM) && (user != primary)) {
+                users = Arrays.copyOf(users, users.length + 1);
+                users[users.length - 1] = user;
+            }
+        }
+        return users;
     }
-
 }
diff --git a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
index 4a4eef1..9d0dec6 100644
--- a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
@@ -23,7 +23,6 @@
 import static com.android.cts.storageapp.Utils.DATA_INT;
 import static com.android.cts.storageapp.Utils.MB_IN_BYTES;
 import static com.android.cts.storageapp.Utils.PKG_B;
-import static com.android.cts.storageapp.Utils.TAG;
 import static com.android.cts.storageapp.Utils.assertMostlyEquals;
 import static com.android.cts.storageapp.Utils.getSizeManual;
 import static com.android.cts.storageapp.Utils.makeUniqueFile;
@@ -42,7 +41,6 @@
 import android.os.storage.StorageManager;
 import android.system.Os;
 import android.test.InstrumentationTestCase;
-import android.util.Log;
 
 import java.io.File;
 import java.io.IOException;
@@ -62,9 +60,19 @@
 
     public void testFullDisk() throws Exception {
         if (shouldHaveQuota(Os.uname())) {
-            Hoarder.doBlocks(getContext().getDataDir(), true);
+            final File dataDir = getContext().getDataDir();
+
+            // Pre-flight to see if we have enough disk space to test with
+            final long total = dataDir.getTotalSpace();
+            final long free = dataDir.getFreeSpace();
+            final long required = ((total * 9) / 10) + MB_IN_BYTES;
+            if (free < required) {
+                fail("Skipping full disk test; only found " + free + " free out of " + total);
+            }
+
+            Hoarder.doBlocks(dataDir, true);
         } else {
-            Log.d(TAG, "Skipping full disk test due to missing quota support");
+            fail("Skipping full disk test due to missing quota support");
         }
     }
 
diff --git a/tests/tests/os/src/android/os/cts/StrictModeTest.java b/tests/tests/os/src/android/os/cts/StrictModeTest.java
index fecc067..21730c6 100644
--- a/tests/tests/os/src/android/os/cts/StrictModeTest.java
+++ b/tests/tests/os/src/android/os/cts/StrictModeTest.java
@@ -22,15 +22,12 @@
 import android.net.TrafficStats;
 import android.net.Uri;
 import android.os.StrictMode;
-import android.os.SystemClock;
+import android.os.StrictMode.ViolationListener;
 import android.system.Os;
 import android.system.OsConstants;
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
-import libcore.io.Streams;
-
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -38,8 +35,8 @@
 import java.net.HttpURLConnection;
 import java.net.Socket;
 import java.net.URL;
-import java.text.SimpleDateFormat;
-import java.util.Date;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Tests for {@link StrictMode}
@@ -66,6 +63,10 @@
         StrictMode.setVmPolicy(mVmPolicy);
     }
 
+    public interface ThrowingRunnable {
+        public void run() throws Exception;
+    }
+
     /**
      * Insecure connection should be detected
      */
@@ -80,10 +81,10 @@
                 .penaltyLog()
                 .build());
 
-        long mark = System.currentTimeMillis();
-        ((HttpURLConnection) new URL("http://example.com/").openConnection()).getResponseCode();
-        assertLogged("Detected cleartext network traffic from UID "
-                + android.os.Process.myUid(), mark, 5000);
+        assertViolation("Detected cleartext network traffic from UID", () -> {
+            ((HttpURLConnection) new URL("http://example.com/").openConnection())
+                    .getResponseCode();
+        });
     }
 
     /**
@@ -100,10 +101,10 @@
                 .penaltyLog()
                 .build());
 
-        long mark = System.currentTimeMillis();
-        ((HttpURLConnection) new URL("https://example.com/").openConnection()).getResponseCode();
-        assertNotLogged("Detected cleartext network traffic from UID "
-                + android.os.Process.myUid(), mark, 5000);
+        assertNoViolation(() -> {
+            ((HttpURLConnection) new URL("https://example.com/").openConnection())
+                    .getResponseCode();
+        });
     }
 
     public void testFileUriExposure() throws Exception {
@@ -112,19 +113,21 @@
                 .penaltyLog()
                 .build());
 
-        long mark = System.currentTimeMillis();
-        Uri uri = Uri.fromFile(new File("/sdcard/meow.jpg"));
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setDataAndType(uri, "image/jpeg");
-        getContext().startActivity(intent);
-        assertLogged(uri + " exposed beyond app", mark);
+        final Uri badUri = Uri.fromFile(new File("/sdcard/meow.jpg"));
+        assertViolation(badUri + " exposed beyond app", () -> {
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.setDataAndType(badUri, "image/jpeg");
+            getContext().startActivity(intent);
+        });
 
-        mark = System.currentTimeMillis();
-        uri = Uri.parse("content://com.example/foobar");
-        intent = new Intent(Intent.ACTION_VIEW);
-        intent.setDataAndType(uri, "image/jpeg");
-        getContext().startActivity(intent);
-        assertNotLogged(uri + " exposed beyond app", mark);
+        final Uri goodUri = Uri.parse("content://com.example/foobar");
+        assertNoViolation(() -> {
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.setDataAndType(goodUri, "image/jpeg");
+            getContext().startActivity(intent);
+        });
     }
 
     public void testContentUriWithoutPermission() throws Exception {
@@ -133,19 +136,21 @@
                 .penaltyLog()
                 .build());
 
-        long mark = System.currentTimeMillis();
         final Uri uri = Uri.parse("content://com.example/foobar");
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setDataAndType(uri, "image/jpeg");
-        getContext().startActivity(intent);
-        assertLogged(uri + " exposed beyond app", mark);
+        assertViolation(uri + " exposed beyond app", () -> {
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.setDataAndType(uri, "image/jpeg");
+            getContext().startActivity(intent);
+        });
 
-        mark = System.currentTimeMillis();
-        intent = new Intent(Intent.ACTION_VIEW);
-        intent.setDataAndType(uri, "image/jpeg");
-        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-        getContext().startActivity(intent);
-        assertNotLogged(uri + " exposed beyond app", mark);
+        assertNoViolation(() -> {
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.setDataAndType(uri, "image/jpeg");
+            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            getContext().startActivity(intent);
+        });
     }
 
     public void testUntaggedSocketsHttp() throws Exception {
@@ -159,18 +164,20 @@
                 .penaltyLog()
                 .build());
 
-        long mark = System.currentTimeMillis();
-        ((HttpURLConnection) new URL("http://example.com/").openConnection()).getResponseCode();
-        assertLogged("Untagged socket detected", mark);
+        assertViolation("Untagged socket detected", () -> {
+            ((HttpURLConnection) new URL("http://example.com/").openConnection())
+                    .getResponseCode();
+        });
 
-        mark = System.currentTimeMillis();
-        TrafficStats.setThreadStatsTag(0xDECAFBAD);
-        try {
-            ((HttpURLConnection) new URL("http://example.com/").openConnection()).getResponseCode();
-        } finally {
-            TrafficStats.clearThreadStatsTag();
-        }
-        assertNotLogged("Untagged socket detected", mark);
+        assertNoViolation(() -> {
+            TrafficStats.setThreadStatsTag(0xDECAFBAD);
+            try {
+                ((HttpURLConnection) new URL("http://example.com/").openConnection())
+                        .getResponseCode();
+            } finally {
+                TrafficStats.clearThreadStatsTag();
+            }
+        });
     }
 
     public void testUntaggedSocketsRaw() throws Exception {
@@ -184,99 +191,95 @@
                 .penaltyLog()
                 .build());
 
-        long mark = System.currentTimeMillis();
-        TrafficStats.setThreadStatsTag(0xDECAFBAD);
-        try (Socket socket = new Socket("example.com", 80)) {
-            socket.getOutputStream().close();
-        } finally {
-            TrafficStats.clearThreadStatsTag();
-        }
-        assertNotLogged("Untagged socket detected", mark);
+        assertNoViolation(() -> {
+            TrafficStats.setThreadStatsTag(0xDECAFBAD);
+            try (Socket socket = new Socket("example.com", 80)) {
+                socket.getOutputStream().close();
+            } finally {
+                TrafficStats.clearThreadStatsTag();
+            }
+        });
 
-        mark = System.currentTimeMillis();
-        try (Socket socket = new Socket("example.com", 80)) {
-            socket.getOutputStream().close();
-        }
-        assertLogged("Untagged socket detected", mark);
+        assertViolation("Untagged socket detected", () -> {
+            try (Socket socket = new Socket("example.com", 80)) {
+                socket.getOutputStream().close();
+            }
+        });
     }
 
     public void testRead() throws Exception {
         final File test = File.createTempFile("foo", "bar");
         final File dir = test.getParentFile();
 
-        FileInputStream is = null;
-        FileDescriptor fd = null;
+        final FileInputStream is = new FileInputStream(test);
+        final FileDescriptor fd = Os.open(test.getAbsolutePath(), OsConstants.O_RDONLY, 0600);
 
         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectDiskReads()
                 .penaltyLog()
                 .build());
 
-        SystemClock.sleep(1500);
-
-        try (AssertDiskReadLogged l = new AssertDiskReadLogged()) {
+        assertViolation("StrictModeDiskReadViolation", () -> {
             test.exists();
-        }
-        try (AssertDiskReadLogged l = new AssertDiskReadLogged()) {
+        });
+        assertViolation("StrictModeDiskReadViolation", () -> {
             test.length();
-        }
-        try (AssertDiskReadLogged l = new AssertDiskReadLogged()) {
+        });
+        assertViolation("StrictModeDiskReadViolation", () -> {
             dir.list();
-        }
-        try (AssertDiskReadLogged l = new AssertDiskReadLogged()) {
-            is = new FileInputStream(test);
-        }
-        try (AssertDiskReadLogged l = new AssertDiskReadLogged()) {
+        });
+        assertViolation("StrictModeDiskReadViolation", () -> {
+            new FileInputStream(test);
+        });
+        assertViolation("StrictModeDiskReadViolation", () -> {
             is.read();
-        }
-        try (AssertDiskReadLogged l = new AssertDiskReadLogged()) {
-            fd = Os.open(test.getAbsolutePath(), OsConstants.O_RDONLY, 0600);
-        }
-        try (AssertDiskReadLogged l = new AssertDiskReadLogged()) {
+        });
+        assertViolation("StrictModeDiskReadViolation", () -> {
+            Os.open(test.getAbsolutePath(), OsConstants.O_RDONLY, 0600);
+        });
+        assertViolation("StrictModeDiskReadViolation", () -> {
             Os.read(fd, new byte[10], 0, 1);
-        }
+        });
     }
 
     public void testWrite() throws Exception {
-        File file = null;
+        File file = File.createTempFile("foo", "bar");
 
-        FileOutputStream os = null;
-        FileDescriptor fd = null;
+        final FileOutputStream os = new FileOutputStream(file);
+        final FileDescriptor fd = Os.open(file.getAbsolutePath(), OsConstants.O_RDWR, 0600);
 
         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectDiskWrites()
                 .penaltyLog()
                 .build());
 
-        SystemClock.sleep(1500);
-
-        try (AssertDiskWriteLogged l = new AssertDiskWriteLogged()) {
-            file = File.createTempFile("foo", "bar");
-        }
-        try (AssertDiskWriteLogged l = new AssertDiskWriteLogged()) {
+        assertViolation("StrictModeDiskWriteViolation", () -> {
+            File.createTempFile("foo", "bar");
+        });
+        assertViolation("StrictModeDiskWriteViolation", () -> {
             file.delete();
-        }
-        try (AssertDiskWriteLogged l = new AssertDiskWriteLogged()) {
+        });
+        assertViolation("StrictModeDiskWriteViolation", () -> {
             file.createNewFile();
-        }
-        try (AssertDiskWriteLogged l = new AssertDiskWriteLogged()) {
-            os = new FileOutputStream(file);
-        }
-        try (AssertDiskWriteLogged l = new AssertDiskWriteLogged()) {
+        });
+        assertViolation("StrictModeDiskWriteViolation", () -> {
+            new FileOutputStream(file);
+        });
+        assertViolation("StrictModeDiskWriteViolation", () -> {
             os.write(32);
-        }
-        try (AssertDiskWriteLogged l = new AssertDiskWriteLogged()) {
-            fd = Os.open(file.getAbsolutePath(), OsConstants.O_RDWR, 0600);
-        }
-        try (AssertDiskWriteLogged l = new AssertDiskWriteLogged()) {
+        });
+        assertViolation("StrictModeDiskWriteViolation", () -> {
+            Os.open(file.getAbsolutePath(), OsConstants.O_RDWR, 0600);
+        });
+        assertViolation("StrictModeDiskWriteViolation", () -> {
             Os.write(fd, new byte[10], 0, 1);
-        }
-        try (AssertDiskWriteLogged l = new AssertDiskWriteLogged()) {
+        });
+        assertViolation("StrictModeDiskWriteViolation", () -> {
             Os.fsync(fd);
-        }
-        try (AssertDiskWriteLogged l = new AssertDiskWriteLogged()) {
+        });
+        assertViolation("StrictModeDiskWriteViolation", () -> {
             file.renameTo(new File(file.getParent(), "foobar"));
-        }
+        });
     }
 
     public void testNetwork() throws Exception {
@@ -290,75 +293,66 @@
                 .penaltyLog()
                 .build());
 
-        long mark = System.currentTimeMillis();
-        try (Socket socket = new Socket("example.com", 80)) {
-            socket.getOutputStream().close();
-        }
-        assertLogged("StrictModeNetworkViolation", mark);
+        assertViolation("StrictModeNetworkViolation", () -> {
+            try (Socket socket = new Socket("example.com", 80)) {
+                socket.getOutputStream().close();
+            }
+        });
 
-        mark = System.currentTimeMillis();
-        ((HttpURLConnection) new URL("http://example.com/").openConnection()).getResponseCode();
-        assertLogged("StrictModeNetworkViolation", mark);
+        assertViolation("StrictModeNetworkViolation", () -> {
+            ((HttpURLConnection) new URL("http://example.com/").openConnection())
+                    .getResponseCode();
+        });
     }
 
-    private static class AssertLogged implements AutoCloseable {
-        private final String mMessage;
-        private final long mStart;
+    private static void assertViolation(String expected, ThrowingRunnable r) throws Exception {
+        final LinkedBlockingQueue<String> violations = new LinkedBlockingQueue<>();
+        StrictMode.setViolationListener(new ViolationListener() {
+            @Override
+            public void onViolation(String message) {
+                violations.add(message);
+            }
+        });
 
-        public AssertLogged(String message) {
-            mMessage = message;
-            mStart = System.currentTimeMillis();
-        }
-
-        @Override
-        public void close() throws Exception {
-            assertLogged(mMessage, mStart);
+        try {
+            r.run();
+            while (true) {
+                final String violation = violations.poll(5, TimeUnit.SECONDS);
+                if (violation == null) {
+                    fail("Expected violation not found: " + expected);
+                } else if (violation.contains(expected)) {
+                    return;
+                }
+            }
+        } finally {
+            StrictMode.setViolationListener(null);
         }
     }
 
-    private static class AssertDiskReadLogged extends AssertLogged {
-        public AssertDiskReadLogged() {
-            super("StrictModeDiskReadViolation");
+    private static void assertNoViolation(ThrowingRunnable r) throws Exception {
+        final LinkedBlockingQueue<String> violations = new LinkedBlockingQueue<>();
+        StrictMode.setViolationListener(new ViolationListener() {
+            @Override
+            public void onViolation(String message) {
+                violations.add(message);
+            }
+        });
+
+        try {
+            r.run();
+            while (true) {
+                final String violation = violations.poll(5, TimeUnit.SECONDS);
+                if (violation == null) {
+                    return;
+                } else {
+                    fail("Unexpected violation found: " + violation);
+                }
+            }
+        } finally {
+            StrictMode.setViolationListener(null);
         }
     }
 
-    private static class AssertDiskWriteLogged extends AssertLogged {
-        public AssertDiskWriteLogged() {
-            super("StrictModeDiskWriteViolation");
-        }
-    }
-
-    private static void assertLogged(String msg, long since) throws Exception {
-        assertLogged(msg, since, 1100);
-    }
-
-    private static void assertLogged(String msg, long since, long wait) throws Exception {
-        SystemClock.sleep(wait);
-        assertTrue("Expected message not found: " + msg, readLogSince(since).contains(msg));
-    }
-
-    private static void assertNotLogged(String msg, long since) throws Exception {
-        assertNotLogged(msg, since, 1100);
-    }
-
-    private static void assertNotLogged(String msg, long since, long wait) throws Exception {
-        SystemClock.sleep(wait);
-        assertFalse("Unexpected message found: " + msg, readLogSince(since).contains(msg));
-    }
-
-    private static String readLogSince(long millis) throws Exception {
-        final SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
-        final Process proc = new ProcessBuilder("logcat", "-t", format.format(new Date(millis)))
-                .redirectErrorStream(true).start();
-
-        final ByteArrayOutputStream buf = new ByteArrayOutputStream();
-        Streams.copy(proc.getInputStream(), buf);
-        final int res = proc.waitFor();
-
-        Log.d(TAG, "Log output was " + buf.size() + " bytes, exit code " + res);
-        return new String(buf.toByteArray());
-    }
-
     private boolean hasInternetConnection() {
         final PackageManager pm = getContext().getPackageManager();
         return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)