Merge "Merge "Always clone golden files before editing them." into qt-dev am: 8be3ae5838 am: d6db09d156" into qt-r1-dev-plus-aosp
am: 5455f6d3ba

Change-Id: I92440bdf578653d34871b4e0ac2fcac3709cb444
diff --git a/.gitignore b/.gitignore
index 33bfd97..ff66172 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,6 @@
 *.iml
 *.class
 *.sw*
+
+# Jars added by Idea's "Konfigure kotlin in project" action
+**/lib/kotlin-*.jar
\ No newline at end of file
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index b5af652..08f52f1 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1305,6 +1305,16 @@
                 android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
         </activity>
 
+        <activity android:name=".security.ProtectedConfirmationTest"
+            android:label="@string/sec_protected_confirmation_test"
+            android:configChanges="keyboardHidden|orientation|screenSize" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_security" />
+        </activity>
+
         <activity android:name=".security.ScreenLockBoundKeysTest"
                 android:label="@string/sec_lock_bound_key_test"
                 android:configChanges="keyboardHidden|orientation|screenSize" >
diff --git a/apps/CtsVerifier/res/layout/sec_protected_confirmation_main.xml b/apps/CtsVerifier/res/layout/sec_protected_confirmation_main.xml
new file mode 100644
index 0000000..ffa8d46
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/sec_protected_confirmation_main.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="10dip"
+        >
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:id="@+id/sec_protected_confirmation_tee_layout"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:padding="10dp"
+                  android:orientation="horizontal"
+                  android:layout_centerInParent="true"
+                  android:gravity="center"
+                  >
+
+        <Button android:id="@+id/sec_start_test_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/sec_protected_confirmation_tee_test"
+        />
+
+        <ImageView android:id="@+id/sec_protected_confirmation_tee_test_success"
+                   android:layout_width="wrap_content"
+                   android:layout_height="wrap_content"
+                   android:src="@drawable/fs_good"
+        />
+
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:id="@+id/sec_protected_confirmation_strongbox_layout"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:padding="10dp"
+                  android:orientation="horizontal"
+                  android:layout_centerHorizontal="true"
+                  android:layout_below="@id/sec_protected_confirmation_tee_layout"
+                  android:gravity="center"
+                  >
+
+        <Button android:id="@+id/sec_start_test_strongbox_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/sec_protected_confirmation_strongbox_test"
+        />
+
+        <ImageView android:id="@+id/sec_protected_confirmation_strongbox_test_success"
+                   android:layout_width="wrap_content"
+                   android:layout_height="wrap_content"
+                   android:src="@drawable/fs_good"
+        />
+
+    </LinearLayout>
+
+    <include android:layout_width="match_parent"
+             android:layout_height="wrap_content"
+             android:layout_alignParentBottom="true"
+             layout="@layout/pass_fail_buttons"
+    />
+
+</RelativeLayout>
+
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 4bf8b9f..4a3a08f 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -211,6 +211,23 @@
         are unusable without an authentication.
     </string>
 
+    <!-- Strings for protected confirmation test -->
+    <string name="sec_protected_confirmation_test">Android Protected Confirmation Test</string>
+    <string name="sec_protected_confirmation_test_info">
+        This test ensures that - if Android Protected Confirmation is supported by the device under
+        test - the user is able to see the confirmation message and confirm it. It also assures that
+        Keymaster signs a message with a confirmation key only if the message was previously
+        confirmed by the user.
+    </string>
+    <string name="sec_protected_confirmation_not_supported_title">Android Protected Confirmation not supported</string>
+    <string name="sec_protected_confirmation_not_supported_info">
+        Android Protected Confirmation is not implemented by this device. This is okay because this
+        is an optional feature. Set this test to passed and continue.
+    </string>
+    <string name="sec_protected_confirmation_message">This is a CtsVerifier test message!</string>
+    <string name="sec_protected_confirmation_tee_test">Start Tee Test</string>
+    <string name="sec_protected_confirmation_strongbox_test">Start Strongbox Test</string>
+
     <!-- Strings for BluetoothActivity -->
     <string name="bluetooth_test">Bluetooth Test</string>
     <string name="bluetooth_test_info">
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/ProtectedConfirmationTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/ProtectedConfirmationTest.java
new file mode 100644
index 0000000..62c7772
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/ProtectedConfirmationTest.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2019 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 com.android.cts.verifier.security;
+
+import android.content.pm.PackageManager;
+import android.icu.util.Calendar;
+import android.os.Bundle;
+import android.security.ConfirmationAlreadyPresentingException;
+import android.security.ConfirmationCallback;
+import android.security.ConfirmationNotAvailableException;
+import android.security.ConfirmationPrompt;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.UnrecoverableEntryException;
+import java.security.cert.CertificateException;
+import java.util.Date;
+
+public class ProtectedConfirmationTest extends PassFailButtons.Activity {
+
+    /**
+     * Alias for our key in the Android Key Store.
+     */
+    private static final String KEY_NAME = "my_confirmation_key";
+    private boolean teeTestSuccess = false;
+    private boolean strongboxTestSuccess = false;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.sec_protected_confirmation_main);
+        setPassFailButtonClickListeners();
+
+        boolean protectedConfirmationSupported =
+                ConfirmationPrompt.isSupported(getApplicationContext());
+        if (protectedConfirmationSupported) {
+            setInfoResources(R.string.sec_protected_confirmation_test,
+                    R.string.sec_protected_confirmation_test_info, -1);
+            getPassButton().setEnabled(false);
+        } else {
+            setInfoResources(R.string.sec_protected_confirmation_not_supported_title,
+                    R.string.sec_protected_confirmation_not_supported_info, -1);
+            getPassButton().setEnabled(true);
+            return;
+        }
+        boolean hasStrongbox = this.getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_STRONGBOX_KEYSTORE);
+
+        findViewById(R.id.sec_protected_confirmation_tee_test_success)
+                .setVisibility(View.INVISIBLE);
+        findViewById(R.id.sec_protected_confirmation_strongbox_test_success)
+                .setVisibility(View.INVISIBLE);
+        Button startTestButton = (Button) findViewById(R.id.sec_start_test_button);
+        startTestButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showToast("Test running...");
+                v.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        createKey(false /* useStrongbox */);
+                        if (trySign(getString(R.string.sec_protected_confirmation_message)
+                                .getBytes())) {
+                            showToast("Test failed. Key could sign without confirmation.");
+                        } else {
+                            showConfirmationPrompt(
+                                    getString(R.string.sec_protected_confirmation_message),
+                                    false  /* useStrongbox */);
+                        }
+                    }
+                });
+            }
+
+        });
+
+        Button startStrongboxTestButton =
+                (Button) findViewById(R.id.sec_start_test_strongbox_button);
+        if (hasStrongbox) {
+            startStrongboxTestButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    showToast("Test running...");
+                    v.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            createKey(true /* useStrongbox */);
+                            if (trySign(getString(R.string.sec_protected_confirmation_message)
+                                    .getBytes())) {
+                                showToast("Test failed. Key could sign without confirmation.");
+                            } else {
+                                showConfirmationPrompt(
+                                        getString(R.string.sec_protected_confirmation_message),
+                                                  true /* useStrongbox */);
+                            }
+                        }
+                    });
+                }
+
+            });
+        } else {
+            startStrongboxTestButton.setVisibility(View.GONE);
+            // since strongbox is available we mark the strongbox test as passed so that the tee
+            // test alone can make the test pass.
+            strongboxTestSuccess = true;
+        }
+
+    }
+
+    /**
+     * Creates an asymmetric signing key in AndroidKeyStore which can only be used for signing
+     * user confirmed messages.
+     */
+    private void createKey(boolean useStrongbox) {
+        Calendar calendar = Calendar.getInstance();
+        Date validityStart = calendar.getTime();
+        calendar.add(Calendar.YEAR, 1);
+        Date validityEnd = calendar.getTime();
+        try {
+            KeyPairGenerator kpg = KeyPairGenerator.getInstance(
+                    KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
+            KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(
+                    KEY_NAME,
+                    KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY);
+            builder.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512);
+            builder.setAttestationChallenge("CtsVerifierTest".getBytes());
+            builder.setUserConfirmationRequired(true);
+            builder.setIsStrongBoxBacked(useStrongbox);
+            builder.setKeyValidityStart(validityStart);
+            builder.setKeyValidityEnd(validityEnd);
+            kpg.initialize(builder.build());
+            kpg.generateKeyPair();
+        } catch (NoSuchAlgorithmException | NoSuchProviderException |
+                 InvalidAlgorithmParameterException e) {
+            throw new RuntimeException("Failed to create confirmation key", e);
+        }
+    }
+
+    private boolean trySign(byte[] dataThatWasConfirmed) {
+        try {
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            KeyStore.Entry key = keyStore.getEntry(KEY_NAME, null);
+            Signature s = Signature.getInstance("SHA256withECDSA");
+            s.initSign(((KeyStore.PrivateKeyEntry) key).getPrivateKey());
+            s.update(dataThatWasConfirmed);
+            s.sign();
+        } catch (CertificateException | KeyStoreException | IOException | NoSuchAlgorithmException |
+                UnrecoverableEntryException | InvalidKeyException e) {
+            throw new RuntimeException("Failed to load confirmation key", e);
+        } catch (SignatureException e) {
+            return false;
+        }
+        return true;
+    }
+
+    private void showConfirmationPrompt(String confirmationMessage, boolean useStrongbox) {
+        ConfirmationPrompt.Builder builder = new ConfirmationPrompt.Builder(this);
+        builder.setPromptText(confirmationMessage);
+        builder.setExtraData(new byte[]{0x1, 0x02, 0x03});
+        ConfirmationPrompt prompt = builder.build();
+        try {
+            prompt.presentPrompt(getMainExecutor(),
+                    new ConfirmationCallback() {
+                        @Override
+                        public void onConfirmed(byte[] dataThatWasConfirmed) {
+                            super.onConfirmed(dataThatWasConfirmed);
+                            if (trySign(dataThatWasConfirmed)) {
+                                markTestSuccess(useStrongbox);
+                            } else {
+                                showToast("Failed to sign confirmed message");
+                            }
+                        }
+
+                        @Override
+                        public void onDismissed() {
+                            super.onDismissed();
+                            showToast("User dismissed the dialog.");
+                        }
+
+                        @Override
+                        public void onCanceled() {
+                            super.onCanceled();
+                            showToast("Confirmation dialog was canceled.");
+                        }
+
+                        @Override
+                        public void onError(Throwable e) {
+                            super.onError(e);
+                            throw new RuntimeException("Confirmation Callback encountered an error",
+                                                       e);
+                        }
+                    });
+        } catch (ConfirmationAlreadyPresentingException | ConfirmationNotAvailableException e) {
+            throw new RuntimeException("Error trying to present the confirmation prompt", e);
+        }
+    }
+
+    private void showToast(String message) {
+        Toast.makeText(this, message, Toast.LENGTH_LONG)
+                .show();
+    }
+
+    private void markTestSuccess(boolean strongbox) {
+        if (strongbox) {
+            if (!strongboxTestSuccess) {
+                findViewById(R.id.sec_protected_confirmation_strongbox_test_success)
+                        .setVisibility(View.VISIBLE);
+            }
+            strongboxTestSuccess = true;
+        } else {
+            if (!teeTestSuccess) {
+                findViewById(R.id.sec_protected_confirmation_tee_test_success)
+                        .setVisibility(View.VISIBLE);
+            }
+            teeTestSuccess = true;
+        }
+        if (strongboxTestSuccess && teeTestSuccess) {
+            showToast("Test passed.");
+            getPassButton().setEnabled(true);
+        }
+    }
+}
+
diff --git a/apps/VpnApp/latest/Android.mk b/apps/VpnApp/latest/Android.mk
index 0431bef..02da681 100755
--- a/apps/VpnApp/latest/Android.mk
+++ b/apps/VpnApp/latest/Android.mk
@@ -30,6 +30,6 @@
 LOCAL_PRIVATE_PLATFORM_APIS := true
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := arcts cts vts general-tests
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/common/device-side/test-app/Android.bp b/common/device-side/test-app/Android.bp
index 14e711a..74f549d 100644
--- a/common/device-side/test-app/Android.bp
+++ b/common/device-side/test-app/Android.bp
@@ -30,7 +30,7 @@
         "compatibility-common-util-devicesidelib",
         "compatibility-device-info-tests",
         "compatibility-device-info",
-        "compatibility-device-util-tests",
+        "compatibility-device-util-tests-axt",
         "compatibility-device-util-axt",
     ],
 
diff --git a/common/device-side/util-axt/Android.bp b/common/device-side/util-axt/Android.bp
index fe2b1b7..169184a 100644
--- a/common/device-side/util-axt/Android.bp
+++ b/common/device-side/util-axt/Android.bp
@@ -12,14 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// temporary compatibility-device-util variant that brings in androidx.test transitively, instead
-// of android.support.test target. Will be removed after androidx.test CTS conversion is complete.
 java_library_static {
     name: "compatibility-device-util-axt",
     sdk_version: "test_current",
 
     srcs: [
         "src/**/*.java",
+        "src/**/*.kt",
         "src/**/*.aidl",
     ],
 
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/ExceptionUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/ExceptionUtils.java
new file mode 100644
index 0000000..0899966
--- /dev/null
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/ExceptionUtils.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2019 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 com.android.compatibility.common.util;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.function.Function;
+
+/**
+ * Utilities to deal with exceptions
+ */
+public class ExceptionUtils {
+    private ExceptionUtils() {}
+
+    /**
+     * Rethrow a given exception, optionally wrapping it in a {@link RuntimeException}
+     */
+    public static RuntimeException propagate(@NonNull Throwable t) {
+        if (t == null) {
+            throw new NullPointerException();
+        }
+        propagateIfInstanceOf(t, Error.class);
+        propagateIfInstanceOf(t, RuntimeException.class);
+        throw new RuntimeException(t);
+    }
+
+    /**
+     * Rethrow a given exception, if it's of type {@code E}
+     */
+    public static <E extends Throwable> void propagateIfInstanceOf(
+            @Nullable Throwable t, Class<E> c) throws E {
+        if (t != null && c.isInstance(t)) {
+            throw c.cast(t);
+        }
+    }
+
+    /**
+     * Gets the root {@link Throwable#getCause() cause} of {@code t}
+     */
+    public static @NonNull Throwable getRootCause(@NonNull Throwable t) {
+        while (t.getCause() != null) t = t.getCause();
+        return t;
+    }
+
+    /**
+     * Appends {@code cause} at the end of the causal chain of {@code t}
+     *
+     * @return {@code t} for convenience
+     */
+    public static @NonNull Throwable appendCause(@NonNull Throwable t, @Nullable Throwable cause) {
+        if (cause != null) {
+            getRootCause(t).initCause(cause);
+        }
+        return t;
+    }
+
+    /**
+     * Runs the given {@code action}, and if any exceptions are thrown in the process, applies
+     * given {@code exceptionTransformer}, rethrowing the result.
+     */
+    public static <R> R wrappingExceptions(
+            Function<Throwable, Throwable> exceptionTransformer, ThrowingSupplier<R> action) {
+        try {
+            return action.get();
+        } catch (Throwable t) {
+            Throwable transformed;
+            try {
+                transformed = exceptionTransformer.apply(t);
+            } catch (Throwable t2) {
+                transformed = new RuntimeException("Failed to apply exception transformation",
+                        ExceptionUtils.appendCause(t2, t));
+            }
+            throw ExceptionUtils.propagate(transformed);
+        }
+    }
+
+    /**
+     * @see #wrappingExceptions(Function, ThrowingSupplier)
+     */
+    public static void wrappingExceptions(
+            Function<Throwable, Throwable> exceptionTransformer, ThrowingRunnable action) {
+        wrappingExceptions(exceptionTransformer, () -> {
+            action.run();
+            return null;
+        });
+    }
+}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/FutureResultActivity.kt b/common/device-side/util-axt/src/com/android/compatibility/common/util/FutureResultActivity.kt
new file mode 100644
index 0000000..49397a5
--- /dev/null
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/FutureResultActivity.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 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 com.android.compatibility.common.util
+
+import android.app.Activity
+import android.content.Intent
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.ConcurrentHashMap
+import java.util.concurrent.atomic.AtomicInteger
+
+/**
+ * An [Activity] that exposes a special [startActivityForResult],
+ * returning future resultCode as a [CompletableFuture]
+ */
+class FutureResultActivity : Activity() {
+
+    companion object {
+
+        /** requestCode -> Future<resultCode> */
+        private val requests = ConcurrentHashMap<Int, CompletableFuture<Int>>()
+        private val nextRequestCode = AtomicInteger(0)
+
+        fun doAndAwaitStart(act: () -> Unit): CompletableFuture<Int> {
+            val requestCode = nextRequestCode.get()
+            act()
+            PollingCheck.waitFor(60_000) {
+                nextRequestCode.get() >= requestCode + 1
+            }
+            return requests[requestCode]!!
+        }
+    }
+
+    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+        requests[requestCode]!!.complete(resultCode)
+    }
+
+    fun startActivityForResult(intent: Intent): CompletableFuture<Int> {
+        val requestCode = nextRequestCode.getAndIncrement()
+        val future = CompletableFuture<Int>()
+        requests[requestCode] = future
+        startActivityForResult(intent, requestCode)
+        return future
+    }
+}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ThrowingRunnable.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/ThrowingSupplier.java
similarity index 65%
rename from common/device-side/util/src/com/android/compatibility/common/util/ThrowingRunnable.java
rename to common/device-side/util-axt/src/com/android/compatibility/common/util/ThrowingSupplier.java
index 0588cff..f1e0006 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/ThrowingRunnable.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/ThrowingSupplier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -15,12 +15,16 @@
  */
 package com.android.compatibility.common.util;
 
+import java.util.function.Supplier;
+
 /**
- * Similar to {@link Runnable} but has {@code throws Exception}.
+ * Similar to {@link Supplier} but has {@code throws Exception}.
+ *
+ * @param <T> type of the value produced
  */
-public interface ThrowingRunnable {
+public interface ThrowingSupplier<T> {
     /**
-     * Similar to {@link Runnable#run} but has {@code throws Exception}.
+     * Similar to {@link Supplier#get} but has {@code throws Exception}.
      */
-    void run() throws Exception;
+    T get() throws Exception;
 }
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/UiDumpUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/UiDumpUtils.java
new file mode 100644
index 0000000..a36c1eb
--- /dev/null
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/UiDumpUtils.java
@@ -0,0 +1,566 @@
+/*
+ * Copyright (C) 2019 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 com.android.compatibility.common.util;
+
+import static android.text.TextUtils.isEmpty;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.view.accessibility.AccessibilityWindowInfo;
+
+import androidx.test.InstrumentationRegistry;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.ToIntFunction;
+import java.util.stream.Stream;
+
+/**
+ * Utilities to dump the view hierrarchy as an indented tree
+ *
+ * @see #dumpNodes(AccessibilityNodeInfo, StringBuilder)
+ * @see #wrapWithUiDump(Throwable)
+ */
+@SuppressWarnings({"PointlessBitwiseExpression"})
+public class UiDumpUtils {
+    private UiDumpUtils() {}
+
+    private static final boolean CONCISE = false;
+    private static final boolean SHOW_ACTIONS = false;
+    private static final boolean IGNORE_INVISIBLE = false;
+
+    private static final int IGNORED_ACTIONS = 0
+            | AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS
+            | AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS
+            | AccessibilityNodeInfo.ACTION_FOCUS
+            | AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY
+            | AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
+            | AccessibilityNodeInfo.ACTION_SELECT
+            | AccessibilityNodeInfo.ACTION_SET_SELECTION
+            | AccessibilityNodeInfo.ACTION_CLEAR_SELECTION
+            | AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT
+            | AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT
+            ;
+
+    private static final int SPECIALLY_HANDLED_ACTIONS = 0
+            | AccessibilityNodeInfo.ACTION_CLICK
+            | AccessibilityNodeInfo.ACTION_LONG_CLICK
+            | AccessibilityNodeInfo.ACTION_EXPAND
+            | AccessibilityNodeInfo.ACTION_COLLAPSE
+            | AccessibilityNodeInfo.ACTION_FOCUS
+            | AccessibilityNodeInfo.ACTION_CLEAR_FOCUS
+            | AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
+            | AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD
+            | AccessibilityNodeInfo.ACTION_SET_TEXT
+            ;
+
+    /** name -> typical_value */
+    private static Map<String, Boolean> sNodeFlags = new LinkedHashMap<>();
+    static {
+        sNodeFlags.put("focused", false);
+        sNodeFlags.put("selected", false);
+        sNodeFlags.put("contextClickable", false);
+        sNodeFlags.put("dismissable", false);
+        sNodeFlags.put("enabled", true);
+        sNodeFlags.put("password", false);
+        sNodeFlags.put("visibleToUser", true);
+        sNodeFlags.put("contentInvalid", false);
+        sNodeFlags.put("heading", false);
+        sNodeFlags.put("showingHintText", false);
+
+        // Less important flags below
+        // Too spammy to report all, but can uncomment what's necessary
+
+//        sNodeFlags.put("focusable", true);
+//        sNodeFlags.put("accessibilityFocused", false);
+//        sNodeFlags.put("screenReaderFocusable", true);
+//        sNodeFlags.put("clickable", false);
+//        sNodeFlags.put("longClickable", false);
+//        sNodeFlags.put("checkable", false);
+//        sNodeFlags.put("checked", false);
+//        sNodeFlags.put("editable", false);
+//        sNodeFlags.put("scrollable", false);
+//        sNodeFlags.put("importantForAccessibility", true);
+//        sNodeFlags.put("multiLine", false);
+    }
+
+    /** action -> pictogram */
+    private static Map<AccessibilityAction, String> sNodeActions = new LinkedHashMap<>();
+    static {
+        sNodeActions.put(AccessibilityAction.ACTION_PASTE, "\uD83D\uDCCB");
+        sNodeActions.put(AccessibilityAction.ACTION_CUT, "✂");
+        sNodeActions.put(AccessibilityAction.ACTION_COPY, "⎘");
+        sNodeActions.put(AccessibilityAction.ACTION_SCROLL_BACKWARD, "←");
+        sNodeActions.put(AccessibilityAction.ACTION_SCROLL_LEFT, "←");
+        sNodeActions.put(AccessibilityAction.ACTION_SCROLL_FORWARD, "→");
+        sNodeActions.put(AccessibilityAction.ACTION_SCROLL_RIGHT, "→");
+        sNodeActions.put(AccessibilityAction.ACTION_SCROLL_DOWN, "↓");
+        sNodeActions.put(AccessibilityAction.ACTION_SCROLL_UP, "↑");
+    }
+
+    private static Instrumentation sInstrumentation = InstrumentationRegistry.getInstrumentation();
+    private static UiAutomation sUiAutomation = sInstrumentation.getUiAutomation();
+
+    private static int sScreenArea;
+    static {
+        Point displaySize = new Point();
+        sInstrumentation.getContext()
+                .getSystemService(WindowManager.class)
+                .getDefaultDisplay()
+                .getRealSize(displaySize);
+        sScreenArea = displaySize.x * displaySize.y;
+    }
+
+
+    /**
+     * Wraps the given exception, with one containing UI hierrarchy {@link #dumpNodes dump}
+     * in its message.
+     *
+     * <p>
+     * Can be used together with {@link ExceptionUtils#wrappingExceptions}, e.g:
+     * {@code
+     *     ExceptionUtils.wrappingExceptions(UiDumpUtils::wrapWithUiDump, () -> {
+     *         // UI-testing code
+     *     });
+     * }
+     */
+    public static UiDumpWrapperException wrapWithUiDump(Throwable cause) {
+        return (cause instanceof UiDumpWrapperException)
+                ? (UiDumpWrapperException) cause
+                : new UiDumpWrapperException(cause);
+    }
+
+    /**
+     * Dumps UI hierarchy with a given {@code root} as indented text tree into {@code out}.
+     */
+    public static void dumpNodes(AccessibilityNodeInfo root, StringBuilder out) {
+        if (root == null) {
+            appendNode(out, root);
+            return;
+        }
+
+        out.append("--- ").append(root.getPackageName()).append(" ---\n|");
+
+        recursively(root, AccessibilityNodeInfo::getChildCount, AccessibilityNodeInfo::getChild,
+                node -> {
+                    if (appendNode(out, node)) {
+                        out.append("\n|");
+                    }
+                },
+                action -> node -> {
+                    out.append("  ");
+                    action.accept(node);
+                });
+    }
+
+    private static <T> void recursively(T node,
+            ToIntFunction<T> getChildCount, BiFunction<T, Integer, T> getChildAt,
+            Consumer<T> action, Function<Consumer<T>, Consumer<T>> actionChange) {
+        if (node == null) return;
+
+        action.accept(node);
+        Consumer<T> childAction = actionChange.apply(action);
+
+        int size = getChildCount.applyAsInt(node);
+        for (int i = 0; i < size; i++) {
+            recursively(getChildAt.apply(node, i),
+                    getChildCount, getChildAt, childAction, actionChange);
+        }
+    }
+
+    private static StringBuilder appendWindow(AccessibilityWindowInfo window, StringBuilder out) {
+        if (window == null) {
+            out.append("<null window>");
+        } else {
+            if (!isEmpty(window.getTitle())) {
+                out.append(window.getTitle());
+                if (CONCISE) return out;
+                out.append(" ");
+            }
+            out.append(valueToString(
+                    AccessibilityWindowInfo.class, "TYPE_", window.getType())).append(" ");
+            if (CONCISE) return out;
+            appendArea(out, window::getBoundsInScreen);
+
+            Rect bounds = new Rect();
+            window.getBoundsInScreen(bounds);
+            out.append(bounds.width()).append("x").append(bounds.height()).append(" ");
+            if (window.isInPictureInPictureMode()) out.append("#PIP ");
+        }
+        return out;
+    }
+
+    private static void appendArea(StringBuilder out, Consumer<Rect> getBoundsInScreen) {
+        Rect rect = new Rect();
+        getBoundsInScreen.accept(rect);
+        out.append("size:");
+        out.append(toStringRounding((float) area(rect) * 100 / sScreenArea)).append("% ");
+    }
+
+    private static boolean appendNode(StringBuilder out, AccessibilityNodeInfo node) {
+        if (node == null) {
+            out.append("<null node>");
+            return true;
+        }
+
+        if (IGNORE_INVISIBLE && !node.isVisibleToUser()) return false;
+
+        boolean markedClickable = false;
+        boolean markedNonFocusable = false;
+
+        try {
+            if (node.isFocused() || node.isAccessibilityFocused()) {
+                out.append(">");
+            }
+
+            if ((node.getActions() & AccessibilityNodeInfo.ACTION_EXPAND) != 0) {
+                out.append("[+] ");
+            }
+            if ((node.getActions() & AccessibilityNodeInfo.ACTION_COLLAPSE) != 0) {
+                out.append("[-] ");
+            }
+
+            CharSequence txt = node.getText();
+            if (node.isCheckable()) {
+                out.append("[").append(node.isChecked() ? "X" : "_").append("] ");
+            } else if (node.isEditable()) {
+                if (txt == null) txt = "";
+                out.append("[");
+                appendTextWithCursor(out, node, txt);
+                out.append("] ");
+            } else if (node.isClickable()) {
+                markedClickable = true;
+                out.append("[");
+            } else if (!node.isImportantForAccessibility()) {
+                markedNonFocusable = true;
+                out.append("(");
+            }
+
+            if (appendNodeText(out, node)) return true;
+        } finally {
+            backspaceIf(' ', out);
+            if (markedClickable) {
+                out.append("]");
+                if (node.isLongClickable()) out.append("+");
+                out.append(" ");
+            }
+            if (markedNonFocusable) out.append(") ");
+
+            if (CONCISE) out.append(" ");
+
+            for (Map.Entry<String, Boolean> prop : sNodeFlags.entrySet()) {
+                boolean value = call(node, boolGetter(prop.getKey()));
+                if (value != prop.getValue()) {
+                    out.append("#");
+                    if (!value) out.append("not_");
+                    out.append(prop.getKey()).append(" ");
+                }
+            }
+
+            if (SHOW_ACTIONS) {
+                LinkedHashSet<String> symbols = new LinkedHashSet<>();
+                for (AccessibilityAction accessibilityAction : node.getActionList()) {
+                    String symbol = sNodeActions.get(accessibilityAction);
+                    if (symbol != null) symbols.add(symbol);
+                }
+                merge(symbols, "←", "→", "↔");
+                merge(symbols, "↑", "↓", "↕");
+                symbols.forEach(out::append);
+                if (!symbols.isEmpty()) out.append(" ");
+
+                getActions(node)
+                        .map(a -> "[" + actionToString(a) + "] ")
+                        .forEach(out::append);
+            }
+
+            Bundle extras = node.getExtras();
+            for (String extra : extras.keySet()) {
+                if (extra.equals("AccessibilityNodeInfo.chromeRole")) continue;
+                if (extra.equals("AccessibilityNodeInfo.roleDescription")) continue;
+                String value = "" + extras.get(extra);
+                if (value.isEmpty()) continue;
+                out.append(extra).append(":").append(value).append(" ");
+            }
+        }
+        return true;
+    }
+
+    private static StringBuilder appendTextWithCursor(StringBuilder out, AccessibilityNodeInfo node,
+            CharSequence txt) {
+        out.append(txt);
+        insertAtEnd(out, txt.length() - 1 - node.getTextSelectionStart(), "ꕯ");
+        if (node.getTextSelectionEnd() != node.getTextSelectionStart()) {
+            insertAtEnd(out, txt.length() - 1 - node.getTextSelectionEnd(), "ꕯ");
+        }
+        return out;
+    }
+
+    private static boolean appendNodeText(StringBuilder out, AccessibilityNodeInfo node) {
+        CharSequence txt = node.getText();
+
+        Bundle extras = node.getExtras();
+        if (extras.containsKey("AccessibilityNodeInfo.roleDescription")) {
+            out.append("<").append(extras.getString("AccessibilityNodeInfo.chromeRole"))
+                    .append("> ");
+        } else if (extras.containsKey("AccessibilityNodeInfo.chromeRole")) {
+            out.append("<").append(extras.getString("AccessibilityNodeInfo.chromeRole"))
+                    .append("> ");
+        }
+
+        if (CONCISE) {
+            if (!isEmpty(node.getContentDescription())) {
+                out.append(escape(node.getContentDescription()));
+                return true;
+            }
+            if (!isEmpty(node.getPaneTitle())) {
+                out.append(escape(node.getPaneTitle()));
+                return true;
+            }
+            if (!isEmpty(txt) && !node.isEditable()) {
+                out.append('"');
+                if (node.getTextSelectionStart() > 0 || node.getTextSelectionEnd() > 0) {
+                    appendTextWithCursor(out, node, txt);
+                } else {
+                    out.append(escape(txt));
+                }
+                out.append('"');
+                return true;
+            }
+            if (!isEmpty(node.getViewIdResourceName())) {
+                out.append("@").append(fromLast("/", node.getViewIdResourceName()));
+                return true;
+            }
+        }
+
+        if (node.getParent() == null && node.getWindow() != null) {
+            appendWindow(node.getWindow(), out);
+            if (CONCISE) return true;
+            out.append(" ");
+        }
+
+        if (!extras.containsKey("AccessibilityNodeInfo.chromeRole")) {
+            out.append(fromLast(".", node.getClassName())).append(" ");
+        }
+        ifNotEmpty(node.getViewIdResourceName(),
+                s -> out.append("@").append(fromLast("/", s)).append(" "));
+        ifNotEmpty(node.getPaneTitle(), s -> out.append("## ").append(s).append(" "));
+        ifNotEmpty(txt, s -> out.append("\"").append(s).append("\" "));
+
+        ifNotEmpty(node.getContentDescription(), s -> out.append("//").append(s).append(" "));
+
+        appendArea(out, node::getBoundsInScreen);
+        return false;
+    }
+
+    private static <T> String valueToString(Class<?> clazz, String prefix, T value) {
+        String s = flagsToString(clazz, prefix, value, Objects::equals);
+        if (s.isEmpty()) s = "" + value;
+        return s;
+    }
+
+    private static <T> String flagsToString(Class<?> clazz, String prefix, T flags,
+            BiPredicate<T, T> test) {
+        return mkStr(sb -> {
+            consts(clazz, prefix)
+                    .filter(f -> box(f.getType()).isInstance(flags))
+                    .forEach(c -> {
+                        try {
+                            if (test.test(flags, read(null, c))) {
+                                sb.append(c.getName().substring(prefix.length())).append("|");
+                            }
+                        } catch (Exception e) {
+                            throw new RuntimeException("Error while dealing with " + c, e);
+                        }
+                    });
+            backspace(sb);
+        });
+    }
+
+    private static Class box(Class c) {
+        return c == int.class ? Integer.class : c;
+    }
+
+    private static Stream<Field> consts(Class<?> clazz, String prefix) {
+        return Arrays.stream(clazz.getDeclaredFields())
+                .filter(f -> isConst(f) && f.getName().startsWith(prefix));
+    }
+
+    private static boolean isConst(Field f) {
+        return Modifier.isStatic(f.getModifiers()) && Modifier.isFinal(f.getModifiers());
+    }
+
+    private static Character last(StringBuilder sb) {
+        return sb.length() == 0 ? null : sb.charAt(sb.length() - 1);
+    }
+
+    private static StringBuilder backspaceIf(char c, StringBuilder sb) {
+        if (Objects.equals(last(sb), c)) backspace(sb);
+        return sb;
+    }
+
+    private static StringBuilder backspace(StringBuilder sb) {
+        if (sb.length() != 0) {
+            sb.deleteCharAt(sb.length() - 1);
+        }
+        return sb;
+    }
+
+    private static String toStringRounding(float f) {
+        return f >= 5.0 ? "" + (int) f : String.format("%.1f", f);
+    }
+
+    private static int area(Rect r) {
+        return Math.abs((r.right - r.left) * (r.bottom - r.top));
+    }
+
+    private static String escape(CharSequence s) {
+        return mkStr(out -> {
+            for (int i = 0; i < s.length(); i++) {
+                char c = s.charAt(i);
+                if (c < 127 || c == 0xa0 || c >= 0x2000 && c < 0x2070) {
+                    out.append(c);
+                } else {
+                    out.append("\\u").append(Integer.toHexString(c));
+                }
+            }
+        });
+    }
+
+    private static Stream<AccessibilityAction> getActions(
+            AccessibilityNodeInfo node) {
+        if (node == null) return Stream.empty();
+        return node.getActionList().stream()
+                .filter(a -> !AccessibilityAction.ACTION_SHOW_ON_SCREEN.equals(a)
+                        && (a.getId()
+                                & ~IGNORED_ACTIONS
+                                & ~SPECIALLY_HANDLED_ACTIONS
+                            ) != 0);
+    }
+
+    private static String actionToString(AccessibilityAction a) {
+        if (!isEmpty(a.getLabel())) return a.getLabel().toString();
+        return valueToString(AccessibilityAction.class, "ACTION_", a);
+    }
+
+    private static void merge(Set<String> symbols, String a, String b, String ab) {
+        if (symbols.contains(a) && symbols.contains(b)) {
+            symbols.add(ab);
+            symbols.remove(a);
+            symbols.remove(b);
+        }
+    }
+
+    private static String fromLast(String substr, CharSequence whole) {
+        String wholeStr = whole.toString();
+        int idx = wholeStr.lastIndexOf(substr);
+        if (idx < 0) return wholeStr;
+        return wholeStr.substring(idx + substr.length());
+    }
+
+    private static String boolGetter(String propName) {
+        return "is" + Character.toUpperCase(propName.charAt(0)) + propName.substring(1);
+    }
+
+    private static <T> T read(Object o, Field f) {
+        try {
+            f.setAccessible(true);
+            return (T) f.get(o);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static <T> T call(Object o, String methodName, Object... args) {
+        Class clazz = o instanceof Class ? (Class) o : o.getClass();
+        try {
+            Method method = clazz.getDeclaredMethod(methodName, mapToTypes(args));
+            method.setAccessible(true);
+            //noinspection unchecked
+            return (T) method.invoke(o, args);
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException(
+                    newlineSeparated(Arrays.asList(clazz.getDeclaredMethods())), e);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static Class[] mapToTypes(Object[] args) {
+        return Arrays.stream(args).map(Object::getClass).toArray(Class[]::new);
+    }
+
+    private static void ifNotEmpty(CharSequence t, Consumer<CharSequence> f) {
+        if (!isEmpty(t)) {
+            f.accept(t);
+        }
+    }
+
+    private static StringBuilder insertAtEnd(StringBuilder sb, int pos, String s) {
+        return sb.insert(sb.length() - 1 - pos, s);
+    }
+
+    private static <T, R> R fold(List<T> l, R init, BiFunction<R, T, R> combine) {
+        R result = init;
+        for (T t : l) {
+            result = combine.apply(result, t);
+        }
+        return result;
+    }
+
+    private static <T> String toString(List<T> l, String sep, Function<T, String> elemToStr) {
+        return fold(l, "", (a, b) -> a + sep + elemToStr.apply(b));
+    }
+
+    private static <T> String toString(List<T> l, String sep) {
+        return toString(l, sep, String::valueOf);
+    }
+
+    private static String newlineSeparated(List<?> l) {
+        return toString(l, "\n");
+    }
+
+    private static String mkStr(Consumer<StringBuilder> build) {
+        StringBuilder t = new StringBuilder();
+        build.accept(t);
+        return t.toString();
+    }
+
+    private static class UiDumpWrapperException extends RuntimeException {
+        private UiDumpWrapperException(Throwable cause) {
+            super(cause.getMessage() + "\n\nWhile displaying the following UI:\n"
+                    + mkStr(sb -> dumpNodes(sUiAutomation.getRootInActiveWindow(), sb)), cause);
+        }
+    }
+}
diff --git a/common/device-side/util/Android.bp b/common/device-side/util/Android.bp
deleted file mode 100644
index e1552b6..0000000
--- a/common/device-side/util/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (C) 2018 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.
-
-java_library_static {
-    name: "compatibility-device-util",
-    sdk_version: "test_current",
-
-    srcs: [
-        "src/**/*.java",
-        "src/**/*.aidl",
-    ],
-
-    static_libs: [
-        "androidx.test.rules",
-        "compatibility-common-util-devicesidelib",
-        "android-support-test",
-        "ub-uiautomator",
-        "mockito-target-minus-junit4",
-        "androidx.annotation_annotation",
-        "truth-prebuilt",
-    ],
-
-    libs: [
-        "android.test.runner.stubs",
-        "android.test.base.stubs",
-    ],
-
-    jarjar_rules: "protobuf-jarjar-rules.txt",
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ActivitiesWatcher.java b/common/device-side/util/src/com/android/compatibility/common/util/ActivitiesWatcher.java
deleted file mode 100644
index a2b0152..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ActivitiesWatcher.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import android.app.Activity;
-import android.app.Application.ActivityLifecycleCallbacks;
-import android.os.Bundle;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Helper object used to watch for activities lifecycle events.
- *
- * <p><b>NOTE:</b> currently it's limited to just one occurrence of each event.
- *
- * <p>These limitations will be fixed as needed (A.K.A. K.I.S.S. :-)
- */
-public final class ActivitiesWatcher implements ActivityLifecycleCallbacks {
-
-    private static final String TAG = ActivitiesWatcher.class.getSimpleName();
-
-    private final Map<String, ActivityWatcher> mWatchers = new ArrayMap<>();
-    private final long mTimeoutMs;
-
-    /**
-     * Default constructor.
-     *
-     * @param timeoutMs how long to wait for given lifecycle event before timing out.
-     */
-    public ActivitiesWatcher(long timeoutMs) {
-        mTimeoutMs = timeoutMs;
-    }
-
-    @Override
-    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
-        Log.v(TAG, "onActivityCreated(): " + activity);
-        notifyWatcher(activity, ActivityLifecycle.CREATED);
-    }
-
-    @Override
-    public void onActivityStarted(Activity activity) {
-        Log.v(TAG, "onActivityStarted(): " + activity);
-        notifyWatcher(activity, ActivityLifecycle.STARTED);
-    }
-
-    @Override
-    public void onActivityResumed(Activity activity) {
-        Log.v(TAG, "onActivityResumed(): " + activity);
-        notifyWatcher(activity, ActivityLifecycle.RESUMED);
-    }
-
-    @Override
-    public void onActivityPaused(Activity activity) {
-        Log.v(TAG, "onActivityPaused(): " + activity);
-        notifyWatcher(activity, ActivityLifecycle.PAUSED);
-    }
-
-    @Override
-    public void onActivityStopped(Activity activity) {
-        Log.v(TAG, "onActivityStopped(): " + activity);
-        notifyWatcher(activity, ActivityLifecycle.STOPPED);
-    }
-
-    @Override
-    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
-        Log.v(TAG, "onActivitySaveInstanceState(): " + activity);
-        notifyWatcher(activity, ActivityLifecycle.SAVE_INSTANCE);
-    }
-
-    @Override
-    public void onActivityDestroyed(Activity activity) {
-        Log.v(TAG, "onActivityDestroyed(): " + activity);
-        notifyWatcher(activity, ActivityLifecycle.DESTROYED);
-    }
-
-    /**
-     * Gets a watcher for the given activity.
-     *
-     * @throws IllegalStateException if already registered.
-     */
-    public ActivityWatcher watch(@NonNull Class<? extends Activity> clazz) {
-        return watch(clazz.getName());
-    }
-
-    @Override
-    public String toString() {
-        return "[ActivitiesWatcher: activities=" + mWatchers.keySet() + "]";
-    }
-
-    /**
-     * Gets a watcher for the given activity.
-     *
-     * @throws IllegalStateException if already registered.
-     */
-    public ActivityWatcher watch(@NonNull String className) {
-        if (mWatchers.containsKey(className)) {
-            throw new IllegalStateException("Already watching " + className);
-        }
-        Log.d(TAG, "Registering watcher for " + className);
-        final ActivityWatcher watcher = new ActivityWatcher(mTimeoutMs);
-        mWatchers.put(className,  watcher);
-        return watcher;
-    }
-
-    private void notifyWatcher(@NonNull Activity activity, @NonNull ActivityLifecycle lifecycle) {
-        final String className = activity.getComponentName().getClassName();
-        final ActivityWatcher watcher = mWatchers.get(className);
-        if (watcher != null) {
-            Log.d(TAG, "notifying watcher of " + className + " of " + lifecycle);
-            watcher.notify(lifecycle);
-        } else {
-            Log.v(TAG, lifecycle + ": no watcher for " + className);
-        }
-    }
-
-    /**
-     * Object used to watch for acitivity lifecycle events.
-     *
-     * <p><b>NOTE: </b>currently it only supports one occurrence for each event.
-     */
-    public static final class ActivityWatcher {
-        private final CountDownLatch mCreatedLatch = new CountDownLatch(1);
-        private final CountDownLatch mStartedLatch = new CountDownLatch(1);
-        private final CountDownLatch mResumedLatch = new CountDownLatch(1);
-        private final CountDownLatch mPausedLatch = new CountDownLatch(1);
-        private final CountDownLatch mStoppedLatch = new CountDownLatch(1);
-        private final CountDownLatch mSaveInstanceLatch = new CountDownLatch(1);
-        private final CountDownLatch mDestroyedLatch = new CountDownLatch(1);
-        private final long mTimeoutMs;
-
-        private ActivityWatcher(long timeoutMs) {
-            mTimeoutMs = timeoutMs;
-        }
-
-        /**
-         * Blocks until the given lifecycle event happens.
-         *
-         * @throws IllegalStateException if it times out while waiting.
-         * @throws InterruptedException if interrupted while waiting.
-         */
-        public void waitFor(@NonNull ActivityLifecycle lifecycle) throws InterruptedException {
-            final CountDownLatch latch = getLatch(lifecycle);
-            final boolean called = latch.await(mTimeoutMs, TimeUnit.MILLISECONDS);
-            if (!called) {
-                throw new IllegalStateException(lifecycle + " not called in " + mTimeoutMs + " ms");
-            }
-        }
-
-        private CountDownLatch getLatch(@NonNull ActivityLifecycle lifecycle) {
-            switch (lifecycle) {
-                case CREATED:
-                    return mCreatedLatch;
-                case STARTED:
-                    return mStartedLatch;
-                case RESUMED:
-                    return mResumedLatch;
-                case PAUSED:
-                    return mPausedLatch;
-                case STOPPED:
-                    return mStoppedLatch;
-                case SAVE_INSTANCE:
-                    return mSaveInstanceLatch;
-                case DESTROYED:
-                    return mDestroyedLatch;
-                default:
-                    throw new IllegalArgumentException("unsupported lifecycle: " + lifecycle);
-            }
-        }
-
-        private void notify(@NonNull ActivityLifecycle lifecycle) {
-            getLatch(lifecycle).countDown();
-        }
-    }
-
-    /**
-     * Supported activity lifecycle.
-     */
-    public enum ActivityLifecycle {
-        CREATED,
-        STARTED,
-        RESUMED,
-        PAUSED,
-        STOPPED,
-        SAVE_INSTANCE,
-        DESTROYED
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ActivityLauncher.java b/common/device-side/util/src/com/android/compatibility/common/util/ActivityLauncher.java
deleted file mode 100644
index 20d9331..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ActivityLauncher.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.compatibility.common.util;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.support.test.rule.ActivityTestRule;
-
-import androidx.annotation.NonNull;
-
-import com.android.compatibility.common.util.ActivitiesWatcher.ActivityWatcher;
-
-/**
- * Helper used to launch an activity and watch for its lifecycle events.
- *
- * @param <A> activity type
- */
-public final class ActivityLauncher<A extends Activity> {
-
-    private final ActivityWatcher mWatcher;
-    private final ActivityTestRule<A> mActivityTestRule;
-    private final Intent mLaunchIntent;
-
-    public ActivityLauncher(@NonNull Context context, @NonNull ActivitiesWatcher watcher,
-            @NonNull Class<A> activityClass) {
-        mWatcher = watcher.watch(activityClass);
-        mActivityTestRule = new ActivityTestRule<>(activityClass);
-        mLaunchIntent = new Intent(context, activityClass);
-    }
-
-    /**
-     * Gets a watcher for the activity lifecycle events.
-     */
-    @NonNull
-    public ActivityWatcher getWatcher() {
-        return mWatcher;
-    }
-
-    /**
-     * Launches the activity.
-     */
-    @NonNull
-    public A launchActivity() {
-        return mActivityTestRule.launchActivity(mLaunchIntent);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/AdoptShellPermissionsRule.java b/common/device-side/util/src/com/android/compatibility/common/util/AdoptShellPermissionsRule.java
deleted file mode 100644
index f7b50b4..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/AdoptShellPermissionsRule.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import android.app.UiAutomation;
-import android.support.test.InstrumentationRegistry;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-/**
- * Custom JUnit4 rule that runs a test adopting Shell's permissions, revoking them at the end.
- *
- * <p>NOTE: should only be used in the cases where *every* test in a class requires the permission.
- * For a more fine-grained access, use
- * {@link SystemUtil#runWithShellPermissionIdentity(ThrowingRunnable)}
- * or {@link SystemUtil#callWithShellPermissionIdentity(java.util.concurrent.Callable)} instead.
- */
-public class AdoptShellPermissionsRule implements TestRule {
-
-    private final UiAutomation mUiAutomation;
-
-    private final String[] mPermissions;
-
-    public AdoptShellPermissionsRule() {
-        this(InstrumentationRegistry.getInstrumentation().getUiAutomation());
-    }
-
-    public AdoptShellPermissionsRule(@NonNull UiAutomation uiAutomation) {
-        this(uiAutomation, (String[]) null);
-    }
-
-    public AdoptShellPermissionsRule(@NonNull UiAutomation uiAutomation,
-            @Nullable String... permissions) {
-        mUiAutomation = uiAutomation;
-        mPermissions = permissions;
-    }
-
-    @Override
-    public Statement apply(Statement base, Description description) {
-        return new Statement() {
-
-            @Override
-            public void evaluate() throws Throwable {
-                if (mPermissions != null) {
-                    mUiAutomation.adoptShellPermissionIdentity(mPermissions);
-                } else {
-                    mUiAutomation.adoptShellPermissionIdentity();
-                }
-                try {
-                    base.evaluate();
-                } finally {
-                    mUiAutomation.dropShellPermissionIdentity();
-                }
-            }
-        };
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/AmUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/AmUtils.java
deleted file mode 100644
index f3e178b..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/AmUtils.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-public class AmUtils {
-    private static final String TAG = "CtsAmUtils";
-
-    private static final String DUMPSYS_ACTIVITY_PROCESSES = "dumpsys activity --proto processes";
-
-    private AmUtils() {
-    }
-
-    /** Run "adb shell am make-uid-idle PACKAGE" */
-    public static void runMakeUidIdle(String packageName) {
-        SystemUtil.runShellCommandForNoOutput("am make-uid-idle " + packageName);
-    }
-
-    /** Run "adb shell am kill PACKAGE" */
-    public static void runKill(String packageName) throws Exception {
-        runKill(packageName, false /* wait */);
-    }
-
-    public static void runKill(String packageName, boolean wait) throws Exception {
-        SystemUtil.runShellCommandForNoOutput("am kill --user cur " + packageName);
-
-        if (!wait) {
-            return;
-        }
-
-        TestUtils.waitUntil("package process was not killed:" + packageName,
-                () -> !isProcessRunning(packageName));
-    }
-
-    private static boolean isProcessRunning(String packageName) {
-        final String output = SystemUtil.runShellCommand("ps -A -o NAME");
-        String[] packages = output.split("\\n");
-        for (int i = packages.length -1; i >=0; --i) {
-            if (packages[i].equals(packageName)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /** Run "adb shell am set-standby-bucket" */
-    public static void setStandbyBucket(String packageName, int value) {
-        SystemUtil.runShellCommandForNoOutput("am set-standby-bucket " + packageName
-                + " " + value);
-    }
-
-    /** Wait until all broad queues are idle. */
-    public static void waitForBroadcastIdle() {
-        SystemUtil.runCommandAndPrintOnLogcat(TAG, "am wait-for-broadcast-idle");
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ApiLevelUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/ApiLevelUtil.java
deleted file mode 100644
index 943ebc7..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ApiLevelUtil.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.os.Build;
-
-import java.lang.reflect.Field;
-
-/**
- * Device-side compatibility utility class for reading device API level.
- */
-public class ApiLevelUtil {
-
-    public static boolean isBefore(int version) {
-        return Build.VERSION.SDK_INT < version;
-    }
-
-    public static boolean isBefore(String version) {
-        return Build.VERSION.SDK_INT < resolveVersionString(version);
-    }
-
-    public static boolean isAfter(int version) {
-        return Build.VERSION.SDK_INT > version;
-    }
-
-    public static boolean isAfter(String version) {
-        return Build.VERSION.SDK_INT > resolveVersionString(version);
-    }
-
-    public static boolean isAtLeast(int version) {
-        return Build.VERSION.SDK_INT >= version;
-    }
-
-    public static boolean isAtLeast(String version) {
-        return Build.VERSION.SDK_INT >= resolveVersionString(version);
-    }
-
-    public static boolean isAtMost(int version) {
-        return Build.VERSION.SDK_INT <= version;
-    }
-
-    public static boolean isAtMost(String version) {
-        return Build.VERSION.SDK_INT <= resolveVersionString(version);
-    }
-
-    public static int getApiLevel() {
-        return Build.VERSION.SDK_INT;
-    }
-
-    public static boolean codenameEquals(String name) {
-        return Build.VERSION.CODENAME.equalsIgnoreCase(name.trim());
-    }
-
-    public static boolean codenameStartsWith(String prefix) {
-        return Build.VERSION.CODENAME.startsWith(prefix);
-    }
-
-    public static String getCodename() {
-        return Build.VERSION.CODENAME;
-    }
-
-    protected static int resolveVersionString(String versionString) {
-        // Attempt 1: Parse version string as an integer, e.g. "23" for M
-        try {
-            return Integer.parseInt(versionString);
-        } catch (NumberFormatException e) { /* ignore for alternate approaches below */ }
-        // Attempt 2: Find matching field in VersionCodes utility class, return value
-        try {
-            Field versionField = VersionCodes.class.getField(versionString.toUpperCase());
-            return versionField.getInt(null); // no instance for VERSION_CODES, use null
-        } catch (IllegalAccessException | NoSuchFieldException e) { /* ignore */ }
-        // Attempt 3: Find field within android.os.Build.VERSION_CODES
-        try {
-            Field versionField = Build.VERSION_CODES.class.getField(versionString.toUpperCase());
-            return versionField.getInt(null); // no instance for VERSION_CODES, use null
-        } catch (IllegalAccessException | NoSuchFieldException e) {
-            throw new RuntimeException(
-                    String.format("Failed to parse version string %s", versionString), e);
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/AppOpsUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/AppOpsUtils.java
deleted file mode 100644
index 939d6da..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/AppOpsUtils.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2018 Google Inc.
- *
- * 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 com.android.compatibility.common.util;
-
-import static android.app.AppOpsManager.MODE_ALLOWED;
-import static android.app.AppOpsManager.MODE_DEFAULT;
-import static android.app.AppOpsManager.MODE_ERRORED;
-import static android.app.AppOpsManager.MODE_IGNORED;
-
-import android.app.AppOpsManager;
-import android.support.test.InstrumentationRegistry;
-
-import java.io.IOException;
-
-/**
- * Utilities for controlling App Ops settings, and testing whether ops are logged.
- */
-public class AppOpsUtils {
-
-    /**
-     * Resets a package's app ops configuration to the device default. See AppOpsManager for the
-     * default op settings.
-     *
-     * <p>
-     * It's recommended to call this in setUp() and tearDown() of your test so the test starts and
-     * ends with a reproducible default state, and so doesn't affect other tests.
-     *
-     * <p>
-     * Some app ops are configured to be non-resettable, which means that the state of these will
-     * not be reset even when calling this method.
-     */
-    public static String reset(String packageName) throws IOException {
-        return runCommand("appops reset " + packageName);
-    }
-
-    /**
-     * Sets the app op mode (e.g. allowed, denied) for a single package and operation.
-     */
-    public static String setOpMode(String packageName, String opStr, int mode)
-            throws IOException {
-        String modeStr;
-        switch (mode) {
-            case MODE_ALLOWED:
-                modeStr = "allow";
-                break;
-            case MODE_ERRORED:
-                modeStr = "deny";
-                break;
-            case MODE_IGNORED:
-                modeStr = "ignore";
-                break;
-            case MODE_DEFAULT:
-                modeStr = "default";
-                break;
-            default:
-                throw new IllegalArgumentException("Unexpected app op type");
-        }
-        String command = "appops set " + packageName + " " + opStr + " " + modeStr;
-        return runCommand(command);
-    }
-
-    /**
-     * Get the app op mode (e.g. MODE_ALLOWED, MODE_DEFAULT) for a single package and operation.
-     */
-    public static int getOpMode(String packageName, String opStr)
-            throws IOException {
-        String opState = getOpState(packageName, opStr);
-        if (opState.contains(" allow")) {
-            return MODE_ALLOWED;
-        } else if (opState.contains(" deny")) {
-            return MODE_ERRORED;
-        } else if (opState.contains(" ignore")) {
-            return MODE_IGNORED;
-        } else if (opState.contains(" default")) {
-            return MODE_DEFAULT;
-        } else {
-            throw new IllegalStateException("Unexpected app op mode returned " + opState);
-        }
-    }
-
-    /**
-     * Returns whether an allowed operation has been logged by the AppOpsManager for a
-     * package. Operations are noted when the app attempts to perform them and calls e.g.
-     * {@link AppOpsManager#noteOperation}.
-     *
-     * @param opStr The public string constant of the operation (e.g. OPSTR_READ_SMS).
-     */
-    public static boolean allowedOperationLogged(String packageName, String opStr)
-            throws IOException {
-        return getOpState(packageName, opStr).contains(" time=");
-    }
-
-    /**
-     * Returns whether a rejected operation has been logged by the AppOpsManager for a
-     * package. Operations are noted when the app attempts to perform them and calls e.g.
-     * {@link AppOpsManager#noteOperation}.
-     *
-     * @param opStr The public string constant of the operation (e.g. OPSTR_READ_SMS).
-     */
-    public static boolean rejectedOperationLogged(String packageName, String opStr)
-            throws IOException {
-        return getOpState(packageName, opStr).contains(" rejectTime=");
-    }
-
-    /**
-     * Returns the app op state for a package. Includes information on when the operation was last
-     * attempted to be performed by the package.
-     *
-     * Format: "SEND_SMS: allow; time=+23h12m54s980ms ago; rejectTime=+1h10m23s180ms"
-     */
-    private static String getOpState(String packageName, String opStr) throws IOException {
-        return runCommand("appops get " + packageName + " " + opStr);
-    }
-
-    private static String runCommand(String command) throws IOException {
-        return SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/AppStandbyUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/AppStandbyUtils.java
deleted file mode 100644
index 6eeaae2..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/AppStandbyUtils.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import android.util.Log;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class AppStandbyUtils {
-    private static final String TAG = "CtsAppStandbyUtils";
-
-    /**
-     * Returns if app standby is enabled.
-     *
-     * @return true if enabled; or false if disabled.
-     */
-    public static boolean isAppStandbyEnabled() {
-        final String result = SystemUtil.runShellCommand(
-                "dumpsys usagestats is-app-standby-enabled").trim();
-        return Boolean.parseBoolean(result);
-    }
-
-    /**
-     * Sets enabled state for app standby feature for runtime switch.
-     *
-     * App standby feature has 2 switches. This one affects the switch at runtime. If the build
-     * switch is off, enabling the runtime switch will not enable App standby.
-     *
-     * @param enabled if App standby is enabled.
-     */
-    public static void setAppStandbyEnabledAtRuntime(boolean enabled) {
-        final String value = enabled ? "1" : "0";
-        Log.d(TAG, "Setting AppStandby " + (enabled ? "enabled" : "disabled") + " at runtime.");
-        SettingsUtils.putGlobalSetting("app_standby_enabled", value);
-    }
-
-    /**
-     * Returns if app standby is enabled at runtime. Note {@link #isAppStandbyEnabled()} may still
-     * return {@code false} if this method returns {@code true}, because app standby can be disabled
-     * at build time as well.
-     *
-     * @return true if enabled at runtime; or false if disabled at runtime.
-     */
-    public static boolean isAppStandbyEnabledAtRuntime() {
-        final String result =
-                SystemUtil.runShellCommand("settings get global app_standby_enabled").trim();
-        final boolean boolResult = result.equals("1") || result.equals("null");
-        Log.d(TAG, "AppStandby is " + (boolResult ? "enabled" : "disabled") + " at runtime.");
-        return boolResult;
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BatteryUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/BatteryUtils.java
deleted file mode 100644
index 272bc67..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BatteryUtils.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import static com.android.compatibility.common.util.SettingsUtils.putGlobalSetting;
-import static com.android.compatibility.common.util.TestUtils.waitUntil;
-
-import android.content.pm.PackageManager;
-import android.os.BatteryManager;
-import android.os.PowerManager;
-import android.provider.Settings.Global;
-import android.support.test.InstrumentationRegistry;
-import android.util.Log;
-
-import org.junit.Assume;
-
-public class BatteryUtils {
-    private static final String TAG = "CtsBatteryUtils";
-
-    private BatteryUtils() {
-    }
-
-    public static BatteryManager getBatteryManager() {
-        return InstrumentationRegistry.getContext().getSystemService(BatteryManager.class);
-    }
-
-    public static PowerManager getPowerManager() {
-        return InstrumentationRegistry.getContext().getSystemService(PowerManager.class);
-    }
-
-    /** Make the target device think it's off charger. */
-    public static void runDumpsysBatteryUnplug() {
-        SystemUtil.runShellCommandForNoOutput("cmd battery unplug");
-
-        Log.d(TAG, "Battery UNPLUGGED");
-    }
-
-    /**
-     * Set the battery level to {@code level} percent. The valid range is [0, 100].
-     */
-    public static void runDumpsysBatterySetLevel(int level) throws Exception {
-        SystemUtil.runShellCommandForNoOutput(("cmd battery set level " + level));
-
-        Log.d(TAG, "Battery level set to " + level);
-    }
-
-    /**
-     * Set whether the device is plugged in to a charger or not.
-     */
-    public static void runDumpsysBatterySetPluggedIn(boolean pluggedIn) throws Exception {
-        SystemUtil.runShellCommandForNoOutput(("cmd battery set ac " + (pluggedIn ? "1" : "0")));
-
-        Log.d(TAG, "Battery AC set to " + pluggedIn);
-    }
-
-    /** Reset the effect of all the previous {@code runDumpsysBattery*} call  */
-    public static void runDumpsysBatteryReset() {
-        SystemUtil.runShellCommandForNoOutput(("cmd battery reset"));
-
-        Log.d(TAG, "Battery RESET");
-    }
-
-    /**
-     * Enable / disable battery saver. Note {@link #runDumpsysBatteryUnplug} must have been
-     * executed before enabling BS.
-     */
-    public static void enableBatterySaver(boolean enabled) throws Exception {
-        if (enabled) {
-            SystemUtil.runShellCommandForNoOutput("cmd power set-mode 1");
-            putGlobalSetting(Global.LOW_POWER_MODE, "1");
-            waitUntil("Battery saver still off", () -> getPowerManager().isPowerSaveMode());
-            waitUntil("Location mode still " + getPowerManager().getLocationPowerSaveMode(),
-                    () -> (PowerManager.LOCATION_MODE_NO_CHANGE
-                            != getPowerManager().getLocationPowerSaveMode()));
-
-            Thread.sleep(500);
-            waitUntil("Force all apps standby still off",
-                    () -> SystemUtil.runShellCommand("dumpsys alarm")
-                            .contains(" Force all apps standby: true\n"));
-
-        } else {
-            SystemUtil.runShellCommandForNoOutput("cmd power set-mode 0");
-            putGlobalSetting(Global.LOW_POWER_MODE, "0");
-            putGlobalSetting(Global.LOW_POWER_MODE_STICKY, "0");
-            waitUntil("Battery saver still on", () -> !getPowerManager().isPowerSaveMode());
-            waitUntil("Location mode still " + getPowerManager().getLocationPowerSaveMode(),
-                    () -> (PowerManager.LOCATION_MODE_NO_CHANGE
-                            == getPowerManager().getLocationPowerSaveMode()));
-
-            Thread.sleep(500);
-            waitUntil("Force all apps standby still on",
-                    () -> SystemUtil.runShellCommand("dumpsys alarm")
-                            .contains(" Force all apps standby: false\n"));
-        }
-
-        AmUtils.waitForBroadcastIdle();
-        Log.d(TAG, "Battery saver turned " + (enabled ? "ON" : "OFF"));
-    }
-
-    /**
-     * Turn on/off screen.
-     */
-    public static void turnOnScreen(boolean on) throws Exception {
-        if (on) {
-            SystemUtil.runShellCommandForNoOutput("input keyevent KEYCODE_WAKEUP");
-            waitUntil("Device still not interactive", () -> getPowerManager().isInteractive());
-
-        } else {
-            SystemUtil.runShellCommandForNoOutput("input keyevent KEYCODE_SLEEP");
-            waitUntil("Device still interactive", () -> !getPowerManager().isInteractive());
-        }
-        AmUtils.waitForBroadcastIdle();
-        Log.d(TAG, "Screen turned " + (on ? "ON" : "OFF"));
-    }
-
-    /** @return true if the device supports battery saver. */
-    public static boolean isBatterySaverSupported() {
-        final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
-        return !pm.hasSystemFeature(PackageManager.FEATURE_WATCH);
-    }
-
-    /** "Assume" the current device supports battery saver. */
-    public static void assumeBatterySaverFeature() {
-        Assume.assumeTrue("Device doesn't support battery saver", isBatterySaverSupported());
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BeforeAfterRule.java b/common/device-side/util/src/com/android/compatibility/common/util/BeforeAfterRule.java
deleted file mode 100644
index be75671..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BeforeAfterRule.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-/**
- * Custom JUnit4 rule that provides "before" / "after" callbacks, which is useful to use with
- * {@link org.junit.rules.RuleChain}.
- */
-public class BeforeAfterRule implements TestRule {
-    @Override
-    public Statement apply(Statement base, Description description) {
-        return new Statement() {
-
-            @Override
-            public void evaluate() throws Throwable {
-                onBefore(base, description);
-                try {
-                    base.evaluate();
-                } finally {
-                    onAfter(base, description);
-                }
-            }
-        };
-    }
-
-    protected void onBefore(Statement base, Description description) throws Throwable {
-    }
-
-    protected void onAfter(Statement base, Description description) throws Throwable {
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BitmapUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/BitmapUtils.java
deleted file mode 100644
index 7f94d6f..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BitmapUtils.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.compatibility.common.util;
-
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.CompressFormat;
-import android.graphics.Color;
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.lang.reflect.Method;
-import java.util.Random;
-
-public class BitmapUtils {
-    private static final String TAG = "BitmapUtils";
-
-    private BitmapUtils() {}
-
-    // Compares two bitmaps by pixels.
-    public static boolean compareBitmaps(Bitmap bmp1, Bitmap bmp2) {
-        if (bmp1 == bmp2) {
-            return true;
-        }
-
-        if (bmp1 == null || bmp2 == null) {
-            return false;
-        }
-
-        if ((bmp1.getWidth() != bmp2.getWidth()) || (bmp1.getHeight() != bmp2.getHeight())) {
-            return false;
-        }
-
-        for (int i = 0; i < bmp1.getWidth(); i++) {
-            for (int j = 0; j < bmp1.getHeight(); j++) {
-                if (bmp1.getPixel(i, j) != bmp2.getPixel(i, j)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    public static Bitmap generateRandomBitmap(int width, int height) {
-        final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        final Random generator = new Random();
-        for (int x = 0; x < width; x++) {
-            for (int y = 0; y < height; y++) {
-                bmp.setPixel(x, y, generator.nextInt(Integer.MAX_VALUE));
-            }
-        }
-        return bmp;
-    }
-
-    public static Bitmap generateWhiteBitmap(int width, int height) {
-        final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        bmp.eraseColor(Color.WHITE);
-        return bmp;
-    }
-
-    public static Bitmap getWallpaperBitmap(Context context) throws Exception {
-        WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
-        Class<?> noparams[] = {};
-        Class<?> wmClass = wallpaperManager.getClass();
-        Method methodGetBitmap = wmClass.getDeclaredMethod("getBitmap", noparams);
-        return (Bitmap) methodGetBitmap.invoke(wallpaperManager, null);
-    }
-
-    public static ByteArrayInputStream bitmapToInputStream(Bitmap bmp) {
-        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        bmp.compress(CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
-        byte[] bitmapData = bos.toByteArray();
-        return new ByteArrayInputStream(bitmapData);
-    }
-
-    private static void logIfBitmapSolidColor(String fileName, Bitmap bitmap) {
-        int firstColor = bitmap.getPixel(0, 0);
-        for (int x = 0; x < bitmap.getWidth(); x++) {
-            for (int y = 0; y < bitmap.getHeight(); y++) {
-                if (bitmap.getPixel(x, y) != firstColor) {
-                    return;
-                }
-            }
-        }
-
-        Log.w(TAG, String.format("%s entire bitmap color is %x", fileName, firstColor));
-    }
-
-    public static void saveBitmap(Bitmap bitmap, String directoryName, String fileName) {
-        new File(directoryName).mkdirs(); // create dirs if needed
-
-        Log.d(TAG, "Saving file: " + fileName + " in directory: " + directoryName);
-
-        if (bitmap == null) {
-            Log.d(TAG, "File not saved, bitmap was null");
-            return;
-        }
-
-        logIfBitmapSolidColor(fileName, bitmap);
-
-        File file = new File(directoryName, fileName);
-        try (FileOutputStream fileStream = new FileOutputStream(file)) {
-            bitmap.compress(Bitmap.CompressFormat.PNG, 0 /* ignored for PNG */, fileStream);
-            fileStream.flush();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberService.java b/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberService.java
deleted file mode 100644
index 360c078..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberService.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.compatibility.common.util;
-
-import static android.provider.BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER;
-import static android.provider.BlockedNumberContract.BlockedNumbers.CONTENT_URI;
-
-import android.app.IntentService;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-import android.util.Log;
-
-/**
- * A service to handle interactions with the BlockedNumberProvider. The BlockedNumberProvider
- * can only be accessed by the primary user. This service can be run as a singleton service
- * which will then be able to access the BlockedNumberProvider from a test running in a
- * secondary user.
- */
-public class BlockedNumberService extends IntentService {
-
-    static final String INSERT_ACTION = "android.telecom.cts.InsertBlockedNumber";
-    static final String DELETE_ACTION = "android.telecom.cts.DeleteBlockedNumber";
-    static final String PHONE_NUMBER_EXTRA = "number";
-    static final String URI_EXTRA = "uri";
-    static final String ROWS_EXTRA = "rows";
-    static final String RESULT_RECEIVER_EXTRA = "resultReceiver";
-
-    private static final String TAG = "CtsBlockNumberSvc";
-
-    private ContentResolver mContentResolver;
-
-    public BlockedNumberService() {
-        super(BlockedNumberService.class.getName());
-    }
-
-    @Override
-    public void onHandleIntent(Intent intent) {
-        Log.i(TAG, "Starting BlockedNumberService service: " + intent);
-        if (intent == null) {
-            return;
-        }
-        Bundle bundle;
-        mContentResolver = getContentResolver();
-        switch (intent.getAction()) {
-            case INSERT_ACTION:
-                bundle = insertBlockedNumber(intent.getStringExtra(PHONE_NUMBER_EXTRA));
-                break;
-            case DELETE_ACTION:
-                bundle = deleteBlockedNumber(Uri.parse(intent.getStringExtra(URI_EXTRA)));
-                break;
-            default:
-                bundle = new Bundle();
-                break;
-        }
-        ResultReceiver receiver = intent.getParcelableExtra(RESULT_RECEIVER_EXTRA);
-        receiver.send(0, bundle);
-    }
-
-    private Bundle insertBlockedNumber(String number) {
-        Log.i(TAG, "insertBlockedNumber: " + number);
-
-        ContentValues cv = new ContentValues();
-        cv.put(COLUMN_ORIGINAL_NUMBER, number);
-        Uri uri = mContentResolver.insert(CONTENT_URI, cv);
-        Bundle bundle = new Bundle();
-        bundle.putString(URI_EXTRA, uri.toString());
-        return bundle;
-    }
-
-    private Bundle deleteBlockedNumber(Uri uri) {
-        Log.i(TAG, "deleteBlockedNumber: " + uri);
-
-        int rows = mContentResolver.delete(uri, null, null);
-        Bundle bundle = new Bundle();
-        bundle.putInt(ROWS_EXTRA, rows);
-        return bundle;
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberUtil.java
deleted file mode 100644
index e5a0ce4..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BlockedNumberUtil.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.compatibility.common.util;
-
-import static com.android.compatibility.common.util.BlockedNumberService.DELETE_ACTION;
-import static com.android.compatibility.common.util.BlockedNumberService.INSERT_ACTION;
-import static com.android.compatibility.common.util.BlockedNumberService.PHONE_NUMBER_EXTRA;
-import static com.android.compatibility.common.util.BlockedNumberService.RESULT_RECEIVER_EXTRA;
-import static com.android.compatibility.common.util.BlockedNumberService.ROWS_EXTRA;
-import static com.android.compatibility.common.util.BlockedNumberService.URI_EXTRA;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.ResultReceiver;
-
-import junit.framework.TestCase;
-
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Utility for starting the blocked number service.
- */
-public class BlockedNumberUtil {
-
-    private static final int TIMEOUT = 2;
-
-    private BlockedNumberUtil() {}
-
-    /** Insert a phone number into the blocked number provider and returns the resulting Uri. */
-    public static Uri insertBlockedNumber(Context context, String phoneNumber) {
-        Intent intent = new Intent(INSERT_ACTION);
-        intent.putExtra(PHONE_NUMBER_EXTRA, phoneNumber);
-
-        return Uri.parse(runBlockedNumberService(context, intent).getString(URI_EXTRA));
-    }
-
-    /** Remove a number from the blocked number provider and returns the number of rows deleted. */
-    public static int deleteBlockedNumber(Context context, Uri uri) {
-        Intent intent = new Intent(DELETE_ACTION);
-        intent.putExtra(URI_EXTRA, uri.toString());
-
-        return runBlockedNumberService(context, intent).getInt(ROWS_EXTRA);
-    }
-
-    /** Start the blocked number service. */
-    static Bundle runBlockedNumberService(Context context, Intent intent) {
-        // Temporarily allow background service
-        SystemUtil.runShellCommand("cmd deviceidle tempwhitelist " + context.getPackageName());
-
-        final Semaphore semaphore = new Semaphore(0);
-        final Bundle result = new Bundle();
-
-        ResultReceiver receiver = new ResultReceiver(new Handler(Looper.getMainLooper())) {
-            @Override
-            protected void onReceiveResult(int resultCode, Bundle resultData) {
-                result.putAll(resultData);
-                semaphore.release();
-            }
-        };
-        intent.putExtra(RESULT_RECEIVER_EXTRA, receiver);
-        intent.setComponent(new ComponentName(context, BlockedNumberService.class));
-
-        context.startService(intent);
-
-        try {
-            TestCase.assertTrue(semaphore.tryAcquire(TIMEOUT, TimeUnit.SECONDS));
-        } catch (InterruptedException e) {
-            TestCase.fail("Timed out waiting for result from BlockedNumberService");
-        }
-        return result;
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BlockingBroadcastReceiver.java b/common/device-side/util/src/com/android/compatibility/common/util/BlockingBroadcastReceiver.java
deleted file mode 100755
index c26ddd0..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BlockingBroadcastReceiver.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import androidx.annotation.Nullable;
-import android.util.Log;
-
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * A receiver that allows caller to wait for the broadcast synchronously. Notice that you should not
- * reuse the instance. Usage is typically like this:
- * <pre>
- *     BlockingBroadcastReceiver receiver = new BlockingBroadcastReceiver(context, "action");
- *     try {
- *         receiver.register();
- *         Intent intent = receiver.awaitForBroadcast();
- *         // assert the intent
- *     } finally {
- *         receiver.unregisterQuietly();
- *     }
- * </pre>
- */
-public class BlockingBroadcastReceiver extends BroadcastReceiver {
-    private static final String TAG = "BlockingBroadcast";
-
-    private static final int DEFAULT_TIMEOUT_SECONDS = 30;
-
-    private final BlockingQueue<Intent> mBlockingQueue;
-    private final String mExpectedAction;
-    private final Context mContext;
-
-    public BlockingBroadcastReceiver(Context context, String expectedAction) {
-        mContext = context;
-        mExpectedAction = expectedAction;
-        mBlockingQueue = new ArrayBlockingQueue<>(1);
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (mExpectedAction.equals(intent.getAction())) {
-            mBlockingQueue.add(intent);
-        }
-    }
-
-    public void register() {
-        mContext.registerReceiver(this, new IntentFilter(mExpectedAction));
-    }
-
-    /**
-     * Wait until the broadcast and return the received broadcast intent. {@code null} is returned
-     * if no broadcast with expected action is received within 30 seconds.
-     */
-    public @Nullable Intent awaitForBroadcast() {
-        try {
-            return mBlockingQueue.poll(DEFAULT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            Log.e(TAG, "waitForBroadcast get interrupted: ", e);
-        }
-        return null;
-    }
-
-    /**
-     * Wait until the broadcast and return the received broadcast intent. {@code null} is returned
-     * if no broadcast with expected action is received within the given timeout.
-     */
-    public @Nullable Intent awaitForBroadcast(long timeoutMillis) {
-        try {
-            return mBlockingQueue.poll(timeoutMillis, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            Log.e(TAG, "waitForBroadcast get interrupted: ", e);
-        }
-        return null;
-    }
-
-    public void unregisterQuietly() {
-        try {
-            mContext.unregisterReceiver(this);
-        } catch (Exception ex) {
-            Log.e(TAG, "Failed to unregister BlockingBroadcastReceiver: ", ex);
-        }
-    }
-}
\ No newline at end of file
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BroadcastRpcBase.java b/common/device-side/util/src/com/android/compatibility/common/util/BroadcastRpcBase.java
deleted file mode 100644
index 772e7d3..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BroadcastRpcBase.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.support.test.InstrumentationRegistry;
-import android.util.Log;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Base class to help broadcast-based RPC.
- */
-public abstract class BroadcastRpcBase<TRequest, TResponse> {
-    private static final String TAG = "BroadcastRpc";
-
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-
-    static final String ACTION_REQUEST = "ACTION_REQUEST";
-    static final String EXTRA_PAYLOAD = "EXTRA_PAYLOAD";
-    static final String EXTRA_EXCEPTION = "EXTRA_EXCEPTION";
-
-    static Handler sMainHandler = new Handler(Looper.getMainLooper());
-
-    /** Implement in a subclass */
-    protected abstract byte[] requestToBytes(TRequest request);
-
-    /** Implement in a subclass */
-    protected abstract TResponse bytesToResponse(byte[] bytes);
-
-    public TResponse invoke(ComponentName targetReceiver, TRequest request) throws Exception {
-        // Create a request intent.
-        Log.i(TAG, "Sending to: " + targetReceiver + (VERBOSE ? "\nRequest: " + request : ""));
-
-        final Intent requestIntent = new Intent(ACTION_REQUEST)
-                .setComponent(targetReceiver)
-                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
-                .putExtra(EXTRA_PAYLOAD, requestToBytes(request));
-
-        // Send it.
-        final CountDownLatch latch = new CountDownLatch(1);
-        final AtomicReference<Bundle> responseBundle = new AtomicReference<>();
-
-        InstrumentationRegistry.getContext().sendOrderedBroadcast(
-                requestIntent, null, new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        responseBundle.set(getResultExtras(false));
-                        latch.countDown();
-                    }
-                }, sMainHandler, 0, null, null);
-
-        // Wait for a reply and check it.
-        final boolean responseArrived = latch.await(60, TimeUnit.SECONDS);
-        assertTrue("Didn't receive broadcast result.", responseArrived);
-
-        // TODO If responseArrived is false, print if the package / component is installed?
-
-        assertNotNull("Didn't receive result extras", responseBundle.get());
-
-        final String exception = responseBundle.get().getString(EXTRA_EXCEPTION);
-        if (exception != null) {
-            fail("Target throw exception: receiver=" + targetReceiver
-                    + "\nException: " + exception);
-        }
-
-        final byte[] resultPayload = responseBundle.get().getByteArray(EXTRA_PAYLOAD);
-        assertNotNull("Didn't receive result payload", resultPayload);
-
-        Log.i(TAG, "Response received: " + (VERBOSE ? resultPayload.toString() : ""));
-
-        return bytesToResponse(resultPayload);
-    }
-
-    /**
-     * Base class for a receiver for a broadcast-based RPC.
-     */
-    public abstract static class ReceiverBase<TRequest, TResponse> extends BroadcastReceiver {
-        @Override
-        public final void onReceive(Context context, Intent intent) {
-            assertEquals(ACTION_REQUEST, intent.getAction());
-
-            // Parse the request.
-            final TRequest request = bytesToRequest(intent.getByteArrayExtra(EXTRA_PAYLOAD));
-
-            Log.i(TAG, "Request received: " + (VERBOSE ? request.toString() : ""));
-
-            Throwable exception = null;
-
-            // Handle it and generate a response.
-            TResponse response = null;
-            try {
-                response = handleRequest(context, request);
-                Log.i(TAG, "Response generated: " + (VERBOSE ? response.toString() : ""));
-            } catch (Throwable e) {
-                exception = e;
-                Log.e(TAG, "Exception thrown: " + e.getMessage(), e);
-            }
-
-            // Send back.
-            final Bundle extras = new Bundle();
-            if (response != null) {
-                extras.putByteArray(EXTRA_PAYLOAD, responseToBytes(response));
-            }
-            if (exception != null) {
-                extras.putString(EXTRA_EXCEPTION,
-                        exception.toString() + "\n" + Log.getStackTraceString(exception));
-            }
-            setResultExtras(extras);
-        }
-
-        /** Implement in a subclass */
-        protected abstract TResponse handleRequest(Context context, TRequest request)
-                throws Exception;
-
-        /** Implement in a subclass */
-        protected abstract byte[] responseToBytes(TResponse response);
-
-        /** Implement in a subclass */
-        protected abstract TRequest bytesToRequest(byte[] bytes);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BroadcastTestBase.java b/common/device-side/util/src/com/android/compatibility/common/util/BroadcastTestBase.java
deleted file mode 100644
index 7500050..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BroadcastTestBase.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2015 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 com.android.compatibility.common.util;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-public class BroadcastTestBase extends ActivityInstrumentationTestCase2<
-                                       BroadcastTestStartActivity> {
-    static final String TAG = "BroadcastTestBase";
-    protected static final int TIMEOUT_MS = 20 * 1000;
-
-    protected Context mContext;
-    protected Bundle mResultExtras;
-    private CountDownLatch mLatch;
-    protected ActivityDoneReceiver mActivityDoneReceiver = null;
-    private BroadcastTestStartActivity mActivity;
-    private BroadcastUtils.TestcaseType mTestCaseType;
-    protected boolean mHasFeature;
-
-    public BroadcastTestBase() {
-        super(BroadcastTestStartActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mHasFeature = false;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        Log.v(TAG, getClass().getSimpleName() + ".tearDown(): hasFeature=" + mHasFeature
-                + " receiver=" + mActivityDoneReceiver);
-        if (mHasFeature && mActivityDoneReceiver != null) {
-            try {
-                mContext.unregisterReceiver(mActivityDoneReceiver);
-            } catch (IllegalArgumentException e) {
-                // This exception is thrown if mActivityDoneReceiver in
-                // the above call to unregisterReceiver is never registered.
-                // If so, no harm done by ignoring this exception.
-            }
-            mActivityDoneReceiver = null;
-        }
-        super.tearDown();
-    }
-
-    protected boolean isIntentSupported(String intentStr) {
-        Intent intent = new Intent(intentStr);
-        final PackageManager manager = mContext.getPackageManager();
-        assertNotNull(manager);
-        if (manager.resolveActivity(intent, 0) == null) {
-            Log.i(TAG, "No Activity found for the intent: " + intentStr);
-            return false;
-        }
-        return true;
-    }
-
-    protected void startTestActivity(String intentSuffix) {
-        Intent intent = new Intent();
-        intent.setAction("android.intent.action.TEST_START_ACTIVITY_" + intentSuffix);
-        intent.setComponent(new ComponentName(getInstrumentation().getContext(),
-                BroadcastTestStartActivity.class));
-        setActivityIntent(intent);
-        mActivity = getActivity();
-    }
-
-    protected void registerBroadcastReceiver(BroadcastUtils.TestcaseType testCaseType) throws Exception {
-        mTestCaseType = testCaseType;
-        mLatch = new CountDownLatch(1);
-        mActivityDoneReceiver = new ActivityDoneReceiver();
-        mContext.registerReceiver(mActivityDoneReceiver,
-                new IntentFilter(BroadcastUtils.BROADCAST_INTENT + testCaseType.toString()));
-    }
-
-    protected boolean startTestAndWaitForBroadcast(BroadcastUtils.TestcaseType testCaseType,
-                                                   String pkg, String cls) throws Exception {
-        Log.i(TAG, "Begin Testing: " + testCaseType);
-        registerBroadcastReceiver(testCaseType);
-        mActivity.startTest(testCaseType.toString(), pkg, cls);
-        if (!mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
-            fail("Failed to receive broadcast in " + TIMEOUT_MS + "msec");
-            return false;
-        }
-        return true;
-    }
-
-    class ActivityDoneReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(
-                    BroadcastUtils.BROADCAST_INTENT +
-                        BroadcastTestBase.this.mTestCaseType.toString())) {
-                Bundle extras = intent.getExtras();
-                Log.i(TAG, "received_broadcast for " + BroadcastUtils.toBundleString(extras));
-                BroadcastTestBase.this.mResultExtras = extras;
-                mLatch.countDown();
-            }
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BroadcastTestStartActivity.java b/common/device-side/util/src/com/android/compatibility/common/util/BroadcastTestStartActivity.java
deleted file mode 100644
index 4b3e85d..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BroadcastTestStartActivity.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2015 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 com.android.compatibility.common.util;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.ComponentName;
-import android.os.Bundle;
-import android.util.Log;
-
-public class BroadcastTestStartActivity extends Activity {
-    static final String TAG = "BroadcastTestStartActivity";
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        Log.i(TAG, " in onCreate");
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        Log.i(TAG, " in onResume");
-    }
-
-    void startTest(String testCaseType, String pkg, String cls) {
-        Intent intent = new Intent();
-        Log.i(TAG, "received_testcasetype = " + testCaseType);
-        intent.putExtra(BroadcastUtils.TESTCASE_TYPE, testCaseType);
-        intent.setAction("android.intent.action.VIMAIN_" + testCaseType);
-        intent.setComponent(new ComponentName(pkg, cls));
-        startActivity(intent);
-    }
-
-    @Override
-    protected void onPause() {
-        Log.i(TAG, " in onPause");
-        super.onPause();
-    }
-
-    @Override
-    protected void onStart() {
-        super.onStart();
-        Log.i(TAG, " in onStart");
-    }
-
-    @Override
-    protected void onRestart() {
-        super.onRestart();
-        Log.i(TAG, " in onRestart");
-    }
-
-    @Override
-    protected void onStop() {
-        Log.i(TAG, " in onStop");
-        super.onStop();
-    }
-
-    @Override
-    protected void onDestroy() {
-        Log.i(TAG, " in onDestroy");
-        super.onDestroy();
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BroadcastUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/BroadcastUtils.java
deleted file mode 100644
index a4661fc..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BroadcastUtils.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2015 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 com.android.compatibility.common.util;
-
-import android.os.Bundle;
-
-public class BroadcastUtils {
-    public enum TestcaseType {
-        ZEN_MODE_ON,
-        ZEN_MODE_OFF,
-        AIRPLANE_MODE_ON,
-        AIRPLANE_MODE_OFF,
-        BATTERYSAVER_MODE_ON,
-        BATTERYSAVER_MODE_OFF,
-        THEATER_MODE_ON,
-        THEATER_MODE_OFF
-    }
-    public static final String TESTCASE_TYPE = "Testcase_type";
-    public static final String BROADCAST_INTENT =
-            "android.intent.action.FROM_UTIL_CTS_TEST_";
-    public static final int NUM_MINUTES_FOR_ZENMODE = 10;
-
-    public static final String toBundleString(Bundle bundle) {
-        if (bundle == null) {
-            return "*** Bundle is null ****";
-        }
-        StringBuilder buf = new StringBuilder();
-        if (bundle != null) {
-            buf.append("extras: ");
-            for (String s : bundle.keySet()) {
-                buf.append("(" + s + " = " + bundle.get(s) + "), ");
-            }
-        }
-        return buf.toString();
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BundleUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/BundleUtils.java
deleted file mode 100644
index eda641d..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BundleUtils.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import android.os.Bundle;
-
-public class BundleUtils {
-    private BundleUtils() {
-    }
-
-    public static Bundle makeBundle(Object... keysAndValues) {
-        if ((keysAndValues.length % 2) != 0) {
-            throw new IllegalArgumentException("Argument count not even.");
-        }
-
-        if (keysAndValues.length == 0) {
-            return null;
-        }
-        final Bundle ret = new Bundle();
-
-        for (int i = keysAndValues.length - 2; i >= 0; i -= 2) {
-            final String key = keysAndValues[i].toString();
-            final Object value = keysAndValues[i + 1];
-
-            if (value == null) {
-                ret.putString(key, null);
-
-            } else if (value instanceof Boolean) {
-                ret.putBoolean(key, (Boolean) value);
-
-            } else if (value instanceof Integer) {
-                ret.putInt(key, (Integer) value);
-
-            } else if (value instanceof String) {
-                ret.putString(key, (String) value);
-
-            } else if (value instanceof Bundle) {
-                ret.putBundle(key, (Bundle) value);
-            } else {
-                throw new IllegalArgumentException(
-                        "Type not supported yet: " + value.getClass().getName());
-            }
-        }
-        return ret;
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BusinessLogicDeviceExecutor.java b/common/device-side/util/src/com/android/compatibility/common/util/BusinessLogicDeviceExecutor.java
deleted file mode 100644
index 7d7aaf0..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BusinessLogicDeviceExecutor.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Execute business logic methods for device side test cases
- */
-public class BusinessLogicDeviceExecutor extends BusinessLogicExecutor {
-
-    private Context mContext;
-    private Object mTestObj;
-
-    public BusinessLogicDeviceExecutor(Context context, Object testObj) {
-        mContext = context;
-        mTestObj = testObj;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected Object getTestObject() {
-        return mTestObj;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void logInfo(String format, Object... args) {
-        Log.i(LOG_TAG, String.format(format, args));
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void logDebug(String format, Object... args) {
-        Log.d(LOG_TAG, String.format(format, args));
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected String formatExecutionString(String method, String... args) {
-        return String.format("%s(%s)", method, TextUtils.join(", ", args));
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected ResolvedMethod getResolvedMethod(Class cls, String methodName, String... args)
-            throws ClassNotFoundException {
-        List<Method> nameMatches = getMethodsWithName(cls, methodName);
-        for (Method m : nameMatches) {
-            ResolvedMethod rm = new ResolvedMethod(m);
-            int paramTypesMatched = 0;
-            int argsUsed = 0;
-            Class[] paramTypes = m.getParameterTypes();
-            for (Class paramType : paramTypes) {
-                if (argsUsed == args.length && paramType.equals(String.class)) {
-                    // We've used up all supplied string args, so this method will not match.
-                    // If paramType is the Context class, we can match a paramType without needing
-                    // more string args. similarly, paramType "String[]" can be matched with zero
-                    // string args. If we add support for more paramTypes, this logic may require
-                    // adjustment.
-                    break;
-                }
-                if (paramType.equals(String.class)) {
-                    // Type "String" -- supply the next available arg
-                    rm.addArg(args[argsUsed++]);
-                } else if (Context.class.isAssignableFrom(paramType)) {
-                    // Type "Context" -- supply the context from the test case
-                    rm.addArg(mContext);
-                } else if (paramType.equals(Class.forName(STRING_ARRAY_CLASS))) {
-                    // Type "String[]" (or "String...") -- supply all remaining args
-                    rm.addArg(Arrays.copyOfRange(args, argsUsed, args.length));
-                    argsUsed += (args.length - argsUsed);
-                } else {
-                    break; // Param type is unrecognized, this method will not match.
-                }
-                paramTypesMatched++; // A param type has been matched when reaching this point.
-            }
-            if (paramTypesMatched == paramTypes.length && argsUsed == args.length) {
-                return rm; // Args match, methods match, so return the first method-args pairing.
-            }
-            // Not a match, try args for next method that matches by name.
-        }
-        throw new RuntimeException(String.format(
-                "BusinessLogic: Failed to invoke action method %s with args: %s", methodName,
-                Arrays.toString(args)));
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/BusinessLogicTestCase.java b/common/device-side/util/src/com/android/compatibility/common/util/BusinessLogicTestCase.java
deleted file mode 100644
index d567a5f..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/BusinessLogicTestCase.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-
-import android.app.Instrumentation;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.support.test.InstrumentationRegistry;
-import android.util.Log;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.rules.TestName;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.lang.reflect.Field;
-import java.util.Map;
-
-/**
- * Device-side base class for tests leveraging the Business Logic service.
- */
-public class BusinessLogicTestCase {
-    private static final String TAG = "BusinessLogicTestCase";
-
-    /* String marking the beginning of the parameter in a test name */
-    private static final String PARAM_START = "[";
-
-    public static final String CONTENT_PROVIDER =
-            String.format("%s://android.tradefed.contentprovider", ContentResolver.SCHEME_CONTENT);
-
-    /* Test name rule that tracks the current test method under execution */
-    @Rule public TestName mTestCase = new TestName();
-
-    protected BusinessLogic mBusinessLogic;
-    protected boolean mCanReadBusinessLogic = true;
-
-    @Before
-    public void handleBusinessLogic() {
-        loadBusinessLogic();
-        executeBusinessLogic();
-    }
-
-    protected void executeBusinessLogic() {
-        String methodName = mTestCase.getMethodName();
-        assertTrue(String.format("Test \"%s\" is unable to execute as it depends on the missing "
-                + "remote configuration.", methodName), mCanReadBusinessLogic);
-        if (methodName.contains(PARAM_START)) {
-            // Strip parameter suffix (e.g. "[0]") from method name
-            methodName = methodName.substring(0, methodName.lastIndexOf(PARAM_START));
-        }
-        String testName = String.format("%s#%s", this.getClass().getName(), methodName);
-        if (mBusinessLogic.hasLogicFor(testName)) {
-            Log.i(TAG, "Finding business logic for test case: " + testName);
-            BusinessLogicExecutor executor = new BusinessLogicDeviceExecutor(getContext(), this);
-            mBusinessLogic.applyLogicFor(testName, executor);
-        }
-    }
-
-    protected void loadBusinessLogic() {
-        String uriPath = String.format("%s/%s", CONTENT_PROVIDER, BusinessLogic.DEVICE_FILE);
-        Uri sdcardUri = Uri.parse(uriPath);
-        Context appContext = InstrumentationRegistry.getTargetContext();
-        try {
-            ContentResolver resolver = appContext.getContentResolver();
-            ParcelFileDescriptor descriptor = resolver.openFileDescriptor(sdcardUri, "r");
-            mBusinessLogic = BusinessLogicFactory.createFromFile(
-                    new ParcelFileDescriptor.AutoCloseInputStream(descriptor));
-            return;
-        } catch (FileNotFoundException e) {
-            // Log the error and use the fallback too
-            Log.e(TAG, "Error while using content provider for config", e);
-        }
-        // Fallback to reading the business logic directly.
-        File businessLogicFile = new File(BusinessLogic.DEVICE_FILE);
-        if (businessLogicFile.canRead()) {
-            mBusinessLogic = BusinessLogicFactory.createFromFile(businessLogicFile);
-        } else {
-            mCanReadBusinessLogic = false;
-        }
-    }
-
-    protected static Instrumentation getInstrumentation() {
-        return InstrumentationRegistry.getInstrumentation();
-    }
-
-    protected static Context getContext() {
-        return getInstrumentation().getTargetContext();
-    }
-
-    public static void skipTest(String message) {
-        assumeTrue(message, false);
-    }
-
-    public static void failTest(String message) {
-        fail(message);
-    }
-
-    public void mapPut(String mapName, String key, String value) {
-        boolean put = false;
-        for (Field f : getClass().getDeclaredFields()) {
-            if (f.getName().equalsIgnoreCase(mapName) && Map.class.isAssignableFrom(f.getType())) {
-                try {
-                    ((Map) f.get(this)).put(key, value);
-                    put = true;
-                } catch (IllegalAccessException e) {
-                    Log.w(String.format("failed to invoke mapPut on field \"%s\". Resuming...",
-                            f.getName()), e);
-                    // continue iterating through fields, throw exception if no other fields match
-                }
-            }
-        }
-        if (!put) {
-            throw new RuntimeException(String.format("Failed to find map %s in class %s", mapName,
-                    getClass().getName()));
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/CTSResult.java b/common/device-side/util/src/com/android/compatibility/common/util/CTSResult.java
deleted file mode 100644
index d60155a..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/CTSResult.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.android.compatibility.common.util;
-
-public interface CTSResult {
-    public static final int RESULT_OK = 1;
-    public static final int RESULT_FAIL = 2;
-    public void setResult(int resultCode);
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/CallbackAsserter.java b/common/device-side/util/src/com/android/compatibility/common/util/CallbackAsserter.java
deleted file mode 100644
index 436161a..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/CallbackAsserter.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import static junit.framework.Assert.fail;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.support.test.InstrumentationRegistry;
-import android.util.Log;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Predicate;
-
-/**
- * CallbackAsserter helps wait until a callback is called.
- */
-public class CallbackAsserter {
-    private static final String TAG = "CallbackAsserter";
-
-    final CountDownLatch mLatch = new CountDownLatch(1);
-
-    CallbackAsserter() {
-    }
-
-    /**
-     * Call this to assert a callback be called within the given timeout.
-     */
-    public final void assertCalled(String message, int timeoutSeconds) throws Exception {
-        try {
-            if (mLatch.await(timeoutSeconds, TimeUnit.SECONDS)) {
-                return;
-            }
-            fail("Didn't receive callback: " + message);
-        } finally {
-            cleanUp();
-        }
-    }
-
-    void cleanUp() {
-    }
-
-    /**
-     * Create an instance for a broadcast.
-     */
-    public static CallbackAsserter forBroadcast(IntentFilter filter) {
-        return forBroadcast(filter, null);
-    }
-
-    /**
-     * Create an instance for a broadcast.
-     */
-    public static CallbackAsserter forBroadcast(IntentFilter filter, Predicate<Intent> checker) {
-        return new BroadcastAsserter(filter, checker);
-    }
-
-    /**
-     * Create an instance for a content changed notification.
-     */
-    public static CallbackAsserter forContentUri(Uri watchUri) {
-        return forContentUri(watchUri, null);
-    }
-
-    /**
-     * Create an instance for a content changed notification.
-     */
-    public static CallbackAsserter forContentUri(Uri watchUri, Predicate<Uri> checker) {
-        return new ContentObserverAsserter(watchUri, checker);
-    }
-
-    private static class BroadcastAsserter extends CallbackAsserter {
-        private final BroadcastReceiver mReceiver;
-
-        BroadcastAsserter(IntentFilter filter, Predicate<Intent> checker) {
-            mReceiver = new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    if (checker != null && !checker.test(intent)) {
-                        Log.v(TAG, "Ignoring intent: " + intent);
-                        return;
-                    }
-                    mLatch.countDown();
-                }
-            };
-            InstrumentationRegistry.getContext().registerReceiver(mReceiver, filter);
-        }
-
-        @Override
-        void cleanUp() {
-            InstrumentationRegistry.getContext().unregisterReceiver(mReceiver);
-        }
-    }
-
-    private static class ContentObserverAsserter extends CallbackAsserter {
-        private final ContentObserver mObserver;
-
-        ContentObserverAsserter(Uri watchUri, Predicate<Uri> checker) {
-            mObserver = new ContentObserver(null) {
-                @Override
-                public void onChange(boolean selfChange, Uri uri) {
-                    if (checker != null && !checker.test(uri)) {
-                        Log.v(TAG, "Ignoring notification on URI: " + uri);
-                        return;
-                    }
-                    mLatch.countDown();
-                }
-            };
-            InstrumentationRegistry.getContext().getContentResolver().registerContentObserver(
-                    watchUri, true, mObserver);
-        }
-
-        @Override
-        void cleanUp() {
-            InstrumentationRegistry.getContext().getContentResolver().unregisterContentObserver(
-                    mObserver);
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java
deleted file mode 100644
index c0da13d..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static org.junit.Assert.fail;
-
-import android.graphics.Color;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.util.function.Function;
-import java.util.function.IntUnaryOperator;
-
-public class ColorUtils {
-    public static void verifyColor(int expected, int observed) {
-        verifyColor(expected, observed, 0);
-    }
-
-    public static void verifyColor(int expected, int observed, int tolerance) {
-        verifyColor("", expected, observed, tolerance);
-    }
-
-    /**
-     * Verify that two colors match within a per-channel tolerance.
-     *
-     * @param s String with extra information about the test with an error.
-     * @param expected Expected color.
-     * @param observed Observed color.
-     * @param tolerance Per-channel tolerance by which the color can mismatch.
-     */
-    public static void verifyColor(@NonNull String s, int expected, int observed, int tolerance) {
-        s += " expected 0x" + Integer.toHexString(expected)
-            + ", observed 0x" + Integer.toHexString(observed)
-            + ", tolerated channel error 0x" + tolerance;
-        String red = verifyChannel("red", expected, observed, tolerance, (i) -> Color.red(i));
-        String green = verifyChannel("green", expected, observed, tolerance, (i) -> Color.green(i));
-        String blue = verifyChannel("blue", expected, observed, tolerance, (i) -> Color.blue(i));
-        String alpha = verifyChannel("alpha", expected, observed, tolerance, (i) -> Color.alpha(i));
-
-        buildErrorString(s, red, green, blue, alpha);
-    }
-
-    private static void buildErrorString(@NonNull String s, @Nullable String red,
-            @Nullable String green, @Nullable String blue, @Nullable String alpha) {
-        String err = null;
-        for (String channel : new String[]{red, green, blue, alpha}) {
-            if (channel == null) continue;
-            if (err == null) err = s;
-            err += "\n\t\t" + channel;
-        }
-        if (err != null) {
-            fail(err);
-        }
-    }
-
-    private static String verifyChannel(String channelName, int expected, int observed,
-            int tolerance, IntUnaryOperator f) {
-        int e = f.applyAsInt(expected);
-        int o = f.applyAsInt(observed);
-        if (Math.abs(e - o) <= tolerance) {
-            return null;
-        }
-        return "Channel " + channelName + " mismatch: expected<0x" + Integer.toHexString(e)
-            + ">, observed: <0x" + Integer.toHexString(o) + ">";
-    }
-
-    /**
-     * Verify that two colors match within a per-channel tolerance.
-     *
-     * @param msg String with extra information about the test with an error.
-     * @param expected Expected color.
-     * @param observed Observed color.
-     * @param tolerance Per-channel tolerance by which the color can mismatch.
-     */
-    public static void verifyColor(@NonNull String msg, Color expected, Color observed,
-            float tolerance) {
-        if (!expected.getColorSpace().equals(observed.getColorSpace())) {
-            fail("Cannot compare Colors with different color spaces! expected: " + expected
-                    + "\tobserved: " + observed);
-        }
-        msg += " expected " + expected + ", observed " + observed + ", tolerated channel error "
-            + tolerance;
-        String red = verifyChannel("red", expected, observed, tolerance, (c) -> c.red());
-        String green = verifyChannel("green", expected, observed, tolerance, (c) -> c.green());
-        String blue = verifyChannel("blue", expected, observed, tolerance, (c) -> c.blue());
-        String alpha = verifyChannel("alpha", expected, observed, tolerance, (c) -> c.alpha());
-
-        buildErrorString(msg, red, green, blue, alpha);
-    }
-
-    private static String verifyChannel(String channelName, Color expected, Color observed,
-            float tolerance, Function<Color, Float> f) {
-        float e = f.apply(expected);
-        float o = f.apply(observed);
-        float diff = Math.abs(e - o);
-        if (diff <= tolerance) {
-            return null;
-        }
-        return "Channel " + channelName + " mismatch: expected<" + e + ">, observed: <" + o
-            + ">, difference: <" + diff + ">";
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ConnectivityUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ConnectivityUtils.java
deleted file mode 100644
index 09a0a85..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ConnectivityUtils.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-
-public class ConnectivityUtils {
-    private ConnectivityUtils() {
-    }
-
-    /** @return true when the device has a network connection. */
-    public static boolean isNetworkConnected(Context context) {
-        final NetworkInfo networkInfo = context.getSystemService(ConnectivityManager.class)
-                .getActiveNetworkInfo();
-        return (networkInfo != null) && networkInfo.isConnected();
-    }
-
-    /** Assert that the device has a network connection. */
-    public static void assertNetworkConnected(Context context) {
-        assertTrue("Network must be connected", isNetworkConnected(context));
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/CpuFeatures.java b/common/device-side/util/src/com/android/compatibility/common/util/CpuFeatures.java
deleted file mode 100644
index 9360942..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/CpuFeatures.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2010 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 com.android.compatibility.common.util;
-
-import android.os.Build;
-
-public class CpuFeatures {
-
-    public static final String ARMEABI_V7 = "armeabi-v7a";
-
-    public static final String ARMEABI = "armeabi";
-
-    public static final String MIPSABI = "mips";
-
-    public static final  String X86ABI = "x86";
-
-    public static final int HWCAP_VFP = (1 << 6);
-
-    public static final int HWCAP_NEON = (1 << 12);
-
-    public static final int HWCAP_VFPv3 = (1 << 13);
-
-    public static final int HWCAP_VFPv4 = (1 << 16);
-
-    public static final int HWCAP_IDIVA = (1 << 17);
-
-    public static final int HWCAP_IDIVT = (1 << 18);
-
-    static {
-        System.loadLibrary("cts_jni");
-    }
-
-    public static native boolean isArmCpu();
-
-    public static native boolean isMipsCpu();
-
-    public static native boolean isX86Cpu();
-
-    public static native boolean isArm64Cpu();
-
-    public static native boolean isMips64Cpu();
-
-    public static native boolean isX86_64Cpu();
-
-    public static native int getHwCaps();
-
-    public static boolean isArm64CpuIn32BitMode() {
-        if (!isArmCpu()) {
-            return false;
-        }
-
-        for (String abi : Build.SUPPORTED_64_BIT_ABIS) {
-            if (abi.equals("arm64-v8a")) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/CtsAndroidTestCase.java b/common/device-side/util/src/com/android/compatibility/common/util/CtsAndroidTestCase.java
deleted file mode 100644
index 1ffad1d..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/CtsAndroidTestCase.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-import android.test.ActivityInstrumentationTestCase2;
-
-/**
- *  This class emulates AndroidTestCase, but internally it is ActivityInstrumentationTestCase2
- *  to access Instrumentation.
- *  DummyActivity is not supposed to be accessed.
- */
-public class CtsAndroidTestCase extends ActivityInstrumentationTestCase2<DummyActivity> {
-    public CtsAndroidTestCase() {
-        super(DummyActivity.class);
-    }
-
-    public Context getContext() {
-        return getInstrumentation().getContext();
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/CtsKeyEventUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/CtsKeyEventUtil.java
deleted file mode 100644
index 97e4310..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/CtsKeyEventUtil.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.compatibility.common.util;
-
-import android.app.Instrumentation;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.inputmethod.InputMethodManager;
-
-import java.lang.reflect.Field;
-
-/**
- * Utility class to send KeyEvents bypassing the IME. The code is similar to functions in
- * {@link Instrumentation} and {@link android.test.InstrumentationTestCase} classes. It uses
- * {@link InputMethodManager#dispatchKeyEventFromInputMethod(View, KeyEvent)} to send the events.
- * After sending the events waits for idle.
- */
-public final class CtsKeyEventUtil {
-
-    private CtsKeyEventUtil() {}
-
-    /**
-     * Sends the key events corresponding to the text to the app being instrumented.
-     *
-     * @param instrumentation the instrumentation used to run the test.
-     * @param targetView View to find the ViewRootImpl and dispatch.
-     * @param text The text to be sent. Null value returns immediately.
-     */
-    public static void sendString(final Instrumentation instrumentation, final View targetView,
-            final String text) {
-        if (text == null) {
-            return;
-        }
-
-        KeyEvent[] events = getKeyEvents(text);
-
-        if (events != null) {
-            for (int i = 0; i < events.length; i++) {
-                // We have to change the time of an event before injecting it because
-                // all KeyEvents returned by KeyCharacterMap.getEvents() have the same
-                // time stamp and the system rejects too old events. Hence, it is
-                // possible for an event to become stale before it is injected if it
-                // takes too long to inject the preceding ones.
-                sendKey(instrumentation, targetView, KeyEvent.changeTimeRepeat(
-                        events[i], SystemClock.uptimeMillis(), 0 /* newRepeat */));
-            }
-        }
-    }
-
-    /**
-     * Sends a series of key events through instrumentation. For instance:
-     * sendKeys(view, KEYCODE_DPAD_LEFT, KEYCODE_DPAD_CENTER).
-     *
-     * @param instrumentation the instrumentation used to run the test.
-     * @param targetView View to find the ViewRootImpl and dispatch.
-     * @param keys The series of key codes.
-     */
-    public static void sendKeys(final Instrumentation instrumentation, final View targetView,
-            final int...keys) {
-        final int count = keys.length;
-
-        for (int i = 0; i < count; i++) {
-            try {
-                sendKeyDownUp(instrumentation, targetView, keys[i]);
-            } catch (SecurityException e) {
-                // Ignore security exceptions that are now thrown
-                // when trying to send to another app, to retain
-                // compatibility with existing tests.
-            }
-        }
-    }
-
-    /**
-     * Sends a series of key events through instrumentation. The sequence of keys is a string
-     * containing the key names as specified in KeyEvent, without the KEYCODE_ prefix. For
-     * instance: sendKeys(view, "DPAD_LEFT A B C DPAD_CENTER"). Each key can be repeated by using
-     * the N* prefix. For instance, to send two KEYCODE_DPAD_LEFT, use the following:
-     * sendKeys(view, "2*DPAD_LEFT").
-     *
-     * @param instrumentation the instrumentation used to run the test.
-     * @param targetView View to find the ViewRootImpl and dispatch.
-     * @param keysSequence The sequence of keys.
-     */
-    public static void sendKeys(final Instrumentation instrumentation, final View targetView,
-            final String keysSequence) {
-        final String[] keys = keysSequence.split(" ");
-        final int count = keys.length;
-
-        for (int i = 0; i < count; i++) {
-            String key = keys[i];
-            int repeater = key.indexOf('*');
-
-            int keyCount;
-            try {
-                keyCount = repeater == -1 ? 1 : Integer.parseInt(key.substring(0, repeater));
-            } catch (NumberFormatException e) {
-                Log.w("ActivityTestCase", "Invalid repeat count: " + key);
-                continue;
-            }
-
-            if (repeater != -1) {
-                key = key.substring(repeater + 1);
-            }
-
-            for (int j = 0; j < keyCount; j++) {
-                try {
-                    final Field keyCodeField = KeyEvent.class.getField("KEYCODE_" + key);
-                    final int keyCode = keyCodeField.getInt(null);
-                    try {
-                        sendKeyDownUp(instrumentation, targetView, keyCode);
-                    } catch (SecurityException e) {
-                        // Ignore security exceptions that are now thrown
-                        // when trying to send to another app, to retain
-                        // compatibility with existing tests.
-                    }
-                } catch (NoSuchFieldException e) {
-                    Log.w("ActivityTestCase", "Unknown keycode: KEYCODE_" + key);
-                    break;
-                } catch (IllegalAccessException e) {
-                    Log.w("ActivityTestCase", "Unknown keycode: KEYCODE_" + key);
-                    break;
-                }
-            }
-        }
-    }
-
-    /**
-     * Sends an up and down key events.
-     *
-     * @param instrumentation the instrumentation used to run the test.
-     * @param targetView View to find the ViewRootImpl and dispatch.
-     * @param key The integer keycode for the event to be sent.
-     */
-    public static void sendKeyDownUp(final Instrumentation instrumentation, final View targetView,
-            final int key) {
-        sendKey(instrumentation, targetView, new KeyEvent(KeyEvent.ACTION_DOWN, key));
-        sendKey(instrumentation, targetView, new KeyEvent(KeyEvent.ACTION_UP, key));
-    }
-
-    /**
-     * Sends a key event.
-     *
-     * @param instrumentation the instrumentation used to run the test.
-     * @param targetView View to find the ViewRootImpl and dispatch.
-     * @param event KeyEvent to be send.
-     */
-    public static void sendKey(final Instrumentation instrumentation, final View targetView,
-            final KeyEvent event) {
-        validateNotAppThread();
-
-        long downTime = event.getDownTime();
-        long eventTime = event.getEventTime();
-        int action = event.getAction();
-        int code = event.getKeyCode();
-        int repeatCount = event.getRepeatCount();
-        int metaState = event.getMetaState();
-        int deviceId = event.getDeviceId();
-        int scanCode = event.getScanCode();
-        int source = event.getSource();
-        int flags = event.getFlags();
-        if (source == InputDevice.SOURCE_UNKNOWN) {
-            source = InputDevice.SOURCE_KEYBOARD;
-        }
-        if (eventTime == 0) {
-            eventTime = SystemClock.uptimeMillis();
-        }
-        if (downTime == 0) {
-            downTime = eventTime;
-        }
-
-        final KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount,
-                metaState, deviceId, scanCode, flags, source);
-
-        InputMethodManager imm = targetView.getContext().getSystemService(InputMethodManager.class);
-        imm.dispatchKeyEventFromInputMethod(null, newEvent);
-        instrumentation.waitForIdleSync();
-    }
-
-    /**
-     * Sends a key event while holding another modifier key down, then releases both keys and
-     * waits for idle sync. Useful for sending combinations like shift + tab.
-     *
-     * @param instrumentation the instrumentation used to run the test.
-     * @param targetView View to find the ViewRootImpl and dispatch.
-     * @param keyCodeToSend The integer keycode for the event to be sent.
-     * @param modifierKeyCodeToHold The integer keycode of the modifier to be held.
-     */
-    public static void sendKeyWhileHoldingModifier(final Instrumentation instrumentation,
-            final View targetView, final int keyCodeToSend,
-            final int modifierKeyCodeToHold) {
-        final int metaState = getMetaStateForModifierKeyCode(modifierKeyCodeToHold);
-        final long downTime = SystemClock.uptimeMillis();
-
-        final KeyEvent holdKeyDown = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
-                modifierKeyCodeToHold, 0 /* repeat */);
-        sendKey(instrumentation ,targetView, holdKeyDown);
-
-        final KeyEvent keyDown = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
-                keyCodeToSend, 0 /* repeat */, metaState);
-        sendKey(instrumentation, targetView, keyDown);
-
-        final KeyEvent keyUp = new KeyEvent(downTime, downTime, KeyEvent.ACTION_UP,
-                keyCodeToSend, 0 /* repeat */, metaState);
-        sendKey(instrumentation, targetView, keyUp);
-
-        final KeyEvent holdKeyUp = new KeyEvent(downTime, downTime, KeyEvent.ACTION_UP,
-                modifierKeyCodeToHold, 0 /* repeat */);
-        sendKey(instrumentation, targetView, holdKeyUp);
-
-        instrumentation.waitForIdleSync();
-    }
-
-    private static int getMetaStateForModifierKeyCode(int modifierKeyCode) {
-        if (!KeyEvent.isModifierKey(modifierKeyCode)) {
-            throw new IllegalArgumentException("Modifier key expected, but got: "
-                    + KeyEvent.keyCodeToString(modifierKeyCode));
-        }
-
-        int metaState;
-        switch (modifierKeyCode) {
-            case KeyEvent.KEYCODE_SHIFT_LEFT:
-                metaState = KeyEvent.META_SHIFT_LEFT_ON;
-                break;
-            case KeyEvent.KEYCODE_SHIFT_RIGHT:
-                metaState = KeyEvent.META_SHIFT_RIGHT_ON;
-                break;
-            case KeyEvent.KEYCODE_ALT_LEFT:
-                metaState = KeyEvent.META_ALT_LEFT_ON;
-                break;
-            case KeyEvent.KEYCODE_ALT_RIGHT:
-                metaState = KeyEvent.META_ALT_RIGHT_ON;
-                break;
-            case KeyEvent.KEYCODE_CTRL_LEFT:
-                metaState = KeyEvent.META_CTRL_LEFT_ON;
-                break;
-            case KeyEvent.KEYCODE_CTRL_RIGHT:
-                metaState = KeyEvent.META_CTRL_RIGHT_ON;
-                break;
-            case KeyEvent.KEYCODE_META_LEFT:
-                metaState = KeyEvent.META_META_LEFT_ON;
-                break;
-            case KeyEvent.KEYCODE_META_RIGHT:
-                metaState = KeyEvent.META_META_RIGHT_ON;
-                break;
-            case KeyEvent.KEYCODE_SYM:
-                metaState = KeyEvent.META_SYM_ON;
-                break;
-            case KeyEvent.KEYCODE_NUM:
-                metaState = KeyEvent.META_NUM_LOCK_ON;
-                break;
-            case KeyEvent.KEYCODE_FUNCTION:
-                metaState = KeyEvent.META_FUNCTION_ON;
-                break;
-            default:
-                // Safety net: all modifier keys need to have at least one meta state associated.
-                throw new UnsupportedOperationException("No meta state associated with "
-                        + "modifier key: " + KeyEvent.keyCodeToString(modifierKeyCode));
-        }
-
-        return KeyEvent.normalizeMetaState(metaState);
-    }
-
-    private static KeyEvent[] getKeyEvents(final String text) {
-        KeyCharacterMap keyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
-        return keyCharacterMap.getEvents(text.toCharArray());
-    }
-
-    private static void validateNotAppThread() {
-        if (Looper.myLooper() == Looper.getMainLooper()) {
-            throw new RuntimeException(
-                    "This method can not be called from the main application thread");
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/CtsMockitoUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/CtsMockitoUtils.java
deleted file mode 100644
index 54985dc..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/CtsMockitoUtils.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.compatibility.common.util;
-
-import org.mockito.verification.VerificationMode;
-
-public class CtsMockitoUtils {
-    private CtsMockitoUtils() {}
-
-    public static VerificationMode within(long timeout) {
-        return new Within(timeout);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/CtsMouseUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/CtsMouseUtil.java
deleted file mode 100644
index e53eb08..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/CtsMouseUtil.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-
-import android.app.Instrumentation;
-import android.app.UiAutomation;
-import android.os.SystemClock;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-import android.view.View;
-
-import org.mockito.ArgumentMatcher;
-import org.mockito.InOrder;
-
-public final class CtsMouseUtil {
-
-    private CtsMouseUtil() {}
-
-    public static View.OnHoverListener installHoverListener(View view) {
-        return installHoverListener(view, true);
-    }
-
-    public static View.OnHoverListener installHoverListener(View view, boolean result) {
-        final View.OnHoverListener mockListener = mock(View.OnHoverListener.class);
-        view.setOnHoverListener((v, event) -> {
-            // Clone the event to work around event instance reuse in the framework.
-            mockListener.onHover(v, MotionEvent.obtain(event));
-            return result;
-        });
-        return mockListener;
-    }
-
-    public static void clearHoverListener(View view) {
-        view.setOnHoverListener(null);
-    }
-
-    public static MotionEvent obtainMouseEvent(int action, View anchor, int offsetX, int offsetY) {
-        final long eventTime = SystemClock.uptimeMillis();
-        final int[] screenPos = new int[2];
-        anchor.getLocationOnScreen(screenPos);
-        final int x = screenPos[0] + offsetX;
-        final int y = screenPos[1] + offsetY;
-        MotionEvent event = MotionEvent.obtain(eventTime, eventTime, action, x, y, 0);
-        event.setSource(InputDevice.SOURCE_MOUSE);
-        return event;
-    }
-
-    /**
-     * Emulates a hover move on a point relative to the top-left corner of the passed {@link View}.
-     * Offset parameters are used to compute the final screen coordinates of the tap point.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param anchor the anchor view to determine the tap location on the screen
-     * @param offsetX extra X offset for the move
-     * @param offsetY extra Y offset for the move
-     */
-    public static void emulateHoverOnView(Instrumentation instrumentation, View anchor, int offsetX,
-            int offsetY) {
-        final long downTime = SystemClock.uptimeMillis();
-        final UiAutomation uiAutomation = instrumentation.getUiAutomation();
-        final int[] screenPos = new int[2];
-        anchor.getLocationOnScreen(screenPos);
-        final int x = screenPos[0] + offsetX;
-        final int y = screenPos[1] + offsetY;
-
-        injectHoverEvent(uiAutomation, downTime, x, y);
-    }
-
-    private static void injectHoverEvent(UiAutomation uiAutomation, long downTime, int xOnScreen,
-            int yOnScreen) {
-        MotionEvent event = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_HOVER_MOVE,
-                xOnScreen, yOnScreen, 0);
-        event.setSource(InputDevice.SOURCE_MOUSE);
-        uiAutomation.injectInputEvent(event, true);
-        event.recycle();
-    }
-
-    public static class ActionMatcher implements ArgumentMatcher<MotionEvent> {
-        private final int mAction;
-
-        public ActionMatcher(int action) {
-            mAction = action;
-        }
-
-        @Override
-        public boolean matches(MotionEvent actual) {
-            return actual.getAction() == mAction;
-        }
-
-        @Override
-        public String toString() {
-            return "action=" + MotionEvent.actionToString(mAction);
-        }
-    }
-
-    public static class PositionMatcher extends ActionMatcher {
-        private final int mX;
-        private final int mY;
-
-        public PositionMatcher(int action, int x, int y) {
-            super(action);
-            mX = x;
-            mY = y;
-        }
-
-        @Override
-        public boolean matches(MotionEvent actual) {
-            return super.matches(actual)
-                    && ((int) actual.getX()) == mX
-                    && ((int) actual.getY()) == mY;
-        }
-
-        @Override
-        public String toString() {
-            return super.toString() + "@(" + mX + "," + mY + ")";
-        }
-    }
-
-    public static void verifyEnterMove(View.OnHoverListener listener, View view, int moveCount) {
-        final InOrder inOrder = inOrder(listener);
-        verifyEnterMoveInternal(listener, view, moveCount, inOrder);
-        inOrder.verifyNoMoreInteractions();
-    }
-
-    public static void verifyEnterMoveExit(
-            View.OnHoverListener listener, View view, int moveCount) {
-        final InOrder inOrder = inOrder(listener);
-        verifyEnterMoveInternal(listener, view, moveCount, inOrder);
-        inOrder.verify(listener, times(1)).onHover(eq(view),
-                argThat(new ActionMatcher(MotionEvent.ACTION_HOVER_EXIT)));
-        inOrder.verifyNoMoreInteractions();
-    }
-
-    private static void verifyEnterMoveInternal(
-            View.OnHoverListener listener, View view, int moveCount, InOrder inOrder) {
-        inOrder.verify(listener, times(1)).onHover(eq(view),
-                argThat(new ActionMatcher(MotionEvent.ACTION_HOVER_ENTER)));
-        inOrder.verify(listener, times(moveCount)).onHover(eq(view),
-                argThat(new ActionMatcher(MotionEvent.ACTION_HOVER_MOVE)));
-    }
-}
-
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/CtsTouchUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/CtsTouchUtils.java
deleted file mode 100644
index bd53549..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/CtsTouchUtils.java
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.compatibility.common.util;
-
-import android.app.Instrumentation;
-import android.app.UiAutomation;
-import android.graphics.Point;
-import android.os.SystemClock;
-import android.support.test.rule.ActivityTestRule;
-import android.util.SparseArray;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-
-/**
- * Test utilities for touch emulation.
- */
-public final class CtsTouchUtils {
-    /**
-     * Interface definition for a callback to be invoked when an event has been injected.
-     */
-    public interface EventInjectionListener {
-        /**
-         * Callback method to be invoked when a {MotionEvent#ACTION_DOWN} has been injected.
-         * @param xOnScreen X coordinate of the injected event.
-         * @param yOnScreen Y coordinate of the injected event.
-         */
-        public void onDownInjected(int xOnScreen, int yOnScreen);
-
-        /**
-         * Callback method to be invoked when a {MotionEvent#ACTION_MOVE} has been injected.
-         * @param xOnScreen X coordinates of the injected event.
-         * @param yOnScreen Y coordinates of the injected event.
-         */
-        public void onMoveInjected(int[] xOnScreen, int[] yOnScreen);
-
-        /**
-         * Callback method to be invoked when a {MotionEvent#ACTION_UP} has been injected.
-         * @param xOnScreen X coordinate of the injected event.
-         * @param yOnScreen Y coordinate of the injected event.
-         */
-        public void onUpInjected(int xOnScreen, int yOnScreen);
-    }
-
-    private CtsTouchUtils() {}
-
-    /**
-     * Emulates a tap in the center of the passed {@link View}.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param view the view to "tap"
-     */
-    public static void emulateTapOnViewCenter(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule, View view) {
-        emulateTapOnView(instrumentation, activityTestRule, view, view.getWidth() / 2,
-                view.getHeight() / 2);
-    }
-
-    /**
-     * Emulates a tap on a point relative to the top-left corner of the passed {@link View}. Offset
-     * parameters are used to compute the final screen coordinates of the tap point.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param anchorView the anchor view to determine the tap location on the screen
-     * @param offsetX extra X offset for the tap
-     * @param offsetY extra Y offset for the tap
-     */
-    public static void emulateTapOnView(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule, View anchorView,
-            int offsetX, int offsetY) {
-        final int touchSlop = ViewConfiguration.get(anchorView.getContext()).getScaledTouchSlop();
-        // Get anchor coordinates on the screen
-        final int[] viewOnScreenXY = new int[2];
-        anchorView.getLocationOnScreen(viewOnScreenXY);
-        int xOnScreen = viewOnScreenXY[0] + offsetX;
-        int yOnScreen = viewOnScreenXY[1] + offsetY;
-        final UiAutomation uiAutomation = instrumentation.getUiAutomation();
-        final long downTime = SystemClock.uptimeMillis();
-
-        injectDownEvent(uiAutomation, downTime, xOnScreen, yOnScreen, null);
-        injectMoveEventForTap(uiAutomation, downTime, touchSlop, xOnScreen, yOnScreen);
-        injectUpEvent(uiAutomation, downTime, false, xOnScreen, yOnScreen, null);
-
-        // Wait for the system to process all events in the queue
-        if (activityTestRule != null) {
-            WidgetTestUtils.runOnMainAndDrawSync(activityTestRule,
-                    activityTestRule.getActivity().getWindow().getDecorView(), null);
-        } else {
-            instrumentation.waitForIdleSync();
-        }
-    }
-
-    /**
-     * Emulates a double tap in the center of the passed {@link View}.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param view the view to "double tap"
-     */
-    public static void emulateDoubleTapOnViewCenter(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule, View view) {
-        emulateDoubleTapOnView(instrumentation, activityTestRule, view, view.getWidth() / 2,
-                view.getHeight() / 2);
-    }
-
-    /**
-     * Emulates a double tap on a point relative to the top-left corner of the passed {@link View}.
-     * Offset parameters are used to compute the final screen coordinates of the tap points.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param anchorView the anchor view to determine the tap location on the screen
-     * @param offsetX extra X offset for the taps
-     * @param offsetY extra Y offset for the taps
-     */
-    public static void emulateDoubleTapOnView(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule, View anchorView,
-            int offsetX, int offsetY) {
-        final int touchSlop = ViewConfiguration.get(anchorView.getContext()).getScaledTouchSlop();
-        // Get anchor coordinates on the screen
-        final int[] viewOnScreenXY = new int[2];
-        anchorView.getLocationOnScreen(viewOnScreenXY);
-        int xOnScreen = viewOnScreenXY[0] + offsetX;
-        int yOnScreen = viewOnScreenXY[1] + offsetY;
-        final UiAutomation uiAutomation = instrumentation.getUiAutomation();
-        final long downTime = SystemClock.uptimeMillis();
-
-        injectDownEvent(uiAutomation, downTime, xOnScreen, yOnScreen, null);
-        injectMoveEventForTap(uiAutomation, downTime, touchSlop, xOnScreen, yOnScreen);
-        injectUpEvent(uiAutomation, downTime, false, xOnScreen, yOnScreen, null);
-        injectDownEvent(uiAutomation, downTime, xOnScreen, yOnScreen, null);
-        injectMoveEventForTap(uiAutomation, downTime, touchSlop, xOnScreen, yOnScreen);
-        injectUpEvent(uiAutomation, downTime, false, xOnScreen, yOnScreen, null);
-
-        // Wait for the system to process all events in the queue
-        if (activityTestRule != null) {
-            WidgetTestUtils.runOnMainAndDrawSync(activityTestRule,
-                    activityTestRule.getActivity().getWindow().getDecorView(), null);
-        } else {
-            instrumentation.waitForIdleSync();
-        }
-    }
-
-    /**
-     * Emulates a linear drag gesture between 2 points across the screen.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param dragStartX Start X of the emulated drag gesture
-     * @param dragStartY Start Y of the emulated drag gesture
-     * @param dragAmountX X amount of the emulated drag gesture
-     * @param dragAmountY Y amount of the emulated drag gesture
-     */
-    public static void emulateDragGesture(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule,
-            int dragStartX, int dragStartY, int dragAmountX, int dragAmountY) {
-        emulateDragGesture(instrumentation, activityTestRule,
-                dragStartX, dragStartY, dragAmountX, dragAmountY,
-                2000, 20, null);
-    }
-
-    private static void emulateDragGesture(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule,
-            int dragStartX, int dragStartY, int dragAmountX, int dragAmountY,
-            int dragDurationMs, int moveEventCount) {
-        emulateDragGesture(instrumentation, activityTestRule,
-                dragStartX, dragStartY, dragAmountX, dragAmountY,
-                dragDurationMs, moveEventCount, null);
-    }
-
-    private static void emulateDragGesture(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule,
-            int dragStartX, int dragStartY, int dragAmountX, int dragAmountY,
-            int dragDurationMs, int moveEventCount,
-            EventInjectionListener eventInjectionListener) {
-        // We are using the UiAutomation object to inject events so that drag works
-        // across view / window boundaries (such as for the emulated drag and drop
-        // sequences)
-        final UiAutomation uiAutomation = instrumentation.getUiAutomation();
-        final long downTime = SystemClock.uptimeMillis();
-
-        injectDownEvent(uiAutomation, downTime, dragStartX, dragStartY, eventInjectionListener);
-
-        // Inject a sequence of MOVE events that emulate the "move" part of the gesture
-        injectMoveEventsForDrag(uiAutomation, downTime, true, dragStartX, dragStartY,
-                dragStartX + dragAmountX, dragStartY + dragAmountY, moveEventCount, dragDurationMs,
-            eventInjectionListener);
-
-        injectUpEvent(uiAutomation, downTime, true, dragStartX + dragAmountX,
-                dragStartY + dragAmountY, eventInjectionListener);
-
-        // Wait for the system to process all events in the queue
-        if (activityTestRule != null) {
-            WidgetTestUtils.runOnMainAndDrawSync(activityTestRule,
-                    activityTestRule.getActivity().getWindow().getDecorView(), null);
-        } else {
-            instrumentation.waitForIdleSync();
-        }
-    }
-
-    /**
-     * Emulates a series of linear drag gestures across the screen between multiple points without
-     * lifting the finger. Note that this function does not support curve movements between the
-     * points.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param coordinates the ordered list of points for the drag gesture
-     */
-    public static void emulateDragGesture(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule, SparseArray<Point> coordinates) {
-        emulateDragGesture(instrumentation, activityTestRule, coordinates, 2000, 20);
-    }
-
-    private static void emulateDragGesture(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule,
-            SparseArray<Point> coordinates, int dragDurationMs, int moveEventCount) {
-        final int coordinatesSize = coordinates.size();
-        if (coordinatesSize < 2) {
-            throw new IllegalArgumentException("Need at least 2 points for emulating drag");
-        }
-        // We are using the UiAutomation object to inject events so that drag works
-        // across view / window boundaries (such as for the emulated drag and drop
-        // sequences)
-        final UiAutomation uiAutomation = instrumentation.getUiAutomation();
-        final long downTime = SystemClock.uptimeMillis();
-
-        injectDownEvent(uiAutomation, downTime, coordinates.get(0).x, coordinates.get(0).y, null);
-
-        // Move to each coordinate.
-        for (int i = 0; i < coordinatesSize - 1; i++) {
-            // Inject a sequence of MOVE events that emulate the "move" part of the gesture.
-            injectMoveEventsForDrag(uiAutomation,
-                    downTime,
-                    true,
-                    coordinates.get(i).x,
-                    coordinates.get(i).y,
-                    coordinates.get(i + 1).x,
-                    coordinates.get(i + 1).y,
-                    moveEventCount,
-                    dragDurationMs,
-                    null);
-        }
-
-        injectUpEvent(uiAutomation,
-                downTime,
-                true,
-                coordinates.get(coordinatesSize - 1).x,
-                coordinates.get(coordinatesSize - 1).y,
-                null);
-
-        // Wait for the system to process all events in the queue
-        if (activityTestRule != null) {
-            WidgetTestUtils.runOnMainAndDrawSync(activityTestRule,
-                    activityTestRule.getActivity().getWindow().getDecorView(), null);
-        } else {
-            instrumentation.waitForIdleSync();
-        }
-    }
-
-    private static long injectDownEvent(UiAutomation uiAutomation, long downTime, int xOnScreen,
-            int yOnScreen, EventInjectionListener eventInjectionListener) {
-        MotionEvent eventDown = MotionEvent.obtain(
-                downTime, downTime, MotionEvent.ACTION_DOWN, xOnScreen, yOnScreen, 1);
-        eventDown.setSource(InputDevice.SOURCE_TOUCHSCREEN);
-        uiAutomation.injectInputEvent(eventDown, true);
-        if (eventInjectionListener != null) {
-            eventInjectionListener.onDownInjected(xOnScreen, yOnScreen);
-        }
-        eventDown.recycle();
-        return downTime;
-    }
-
-    private static void injectMoveEventForTap(UiAutomation uiAutomation, long downTime,
-            int touchSlop, int xOnScreen, int yOnScreen) {
-        MotionEvent eventMove = MotionEvent.obtain(downTime, downTime, MotionEvent.ACTION_MOVE,
-                xOnScreen + (touchSlop / 2.0f), yOnScreen + (touchSlop / 2.0f), 1);
-        eventMove.setSource(InputDevice.SOURCE_TOUCHSCREEN);
-        uiAutomation.injectInputEvent(eventMove, true);
-        eventMove.recycle();
-    }
-
-    private static void injectMoveEventsForDrag(UiAutomation uiAutomation, long downTime,
-            boolean useCurrentEventTime, int dragStartX, int dragStartY, int dragEndX, int dragEndY,
-            int moveEventCount, int dragDurationMs, EventInjectionListener eventInjectionListener) {
-        final int dragAmountX = dragEndX - dragStartX;
-        final int dragAmountY = dragEndY - dragStartY;
-        final int sleepTime = dragDurationMs / moveEventCount;
-
-        // sleep for a bit to emulate the overall drag gesture.
-        long prevEventTime = downTime;
-        SystemClock.sleep(sleepTime);
-        for (int i = 0; i < moveEventCount; i++) {
-            // Note that the first MOVE event is generated "away" from the coordinates
-            // of the start / DOWN event, and the last MOVE event is generated
-            // at the same coordinates as the subsequent UP event.
-            final int moveX = dragStartX + dragAmountX * (i  + 1) / moveEventCount;
-            final int moveY = dragStartY + dragAmountY * (i  + 1) / moveEventCount;
-            long eventTime = useCurrentEventTime ? SystemClock.uptimeMillis() : downTime;
-
-            // If necessary, generate history for our next MOVE event. The history is generated
-            // to be spaced at 10 millisecond intervals, interpolating the coordinates from the
-            // last generated MOVE event to our current one.
-            int historyEventCount = (int) ((eventTime - prevEventTime) / 10);
-            int[] xCoordsForListener = (eventInjectionListener == null) ? null :
-                    new int[Math.max(1, historyEventCount)];
-            int[] yCoordsForListener = (eventInjectionListener == null) ? null :
-                    new int[Math.max(1, historyEventCount)];
-            MotionEvent eventMove = null;
-            if (historyEventCount == 0) {
-                eventMove = MotionEvent.obtain(
-                        downTime, eventTime, MotionEvent.ACTION_MOVE, moveX, moveY, 1);
-                if (eventInjectionListener != null) {
-                    xCoordsForListener[0] = moveX;
-                    yCoordsForListener[0] = moveY;
-                }
-            } else {
-                final int prevMoveX = dragStartX + dragAmountX * i / moveEventCount;
-                final int prevMoveY = dragStartY + dragAmountY * i / moveEventCount;
-                final int deltaMoveX = moveX - prevMoveX;
-                final int deltaMoveY = moveY - prevMoveY;
-                final long deltaTime = (eventTime - prevEventTime);
-                for (int historyIndex = 0; historyIndex < historyEventCount; historyIndex++) {
-                    int stepMoveX = prevMoveX + deltaMoveX * (historyIndex + 1) / historyEventCount;
-                    int stepMoveY = prevMoveY + deltaMoveY * (historyIndex + 1) / historyEventCount;
-                    long stepEventTime = useCurrentEventTime
-                            ? prevEventTime + deltaTime * (historyIndex + 1) / historyEventCount
-                            : downTime;
-                    if (historyIndex == 0) {
-                        // Generate the first event in our sequence
-                        eventMove = MotionEvent.obtain(downTime, stepEventTime,
-                                MotionEvent.ACTION_MOVE, stepMoveX, stepMoveY, 1);
-                    } else {
-                        // and then add to it
-                        eventMove.addBatch(stepEventTime, stepMoveX, stepMoveY, 1.0f, 1.0f, 1);
-                    }
-                    if (eventInjectionListener != null) {
-                        xCoordsForListener[historyIndex] = stepMoveX;
-                        yCoordsForListener[historyIndex] = stepMoveY;
-                    }
-                }
-            }
-
-            eventMove.setSource(InputDevice.SOURCE_TOUCHSCREEN);
-            uiAutomation.injectInputEvent(eventMove, true);
-            if (eventInjectionListener != null) {
-                eventInjectionListener.onMoveInjected(xCoordsForListener, yCoordsForListener);
-            }
-            eventMove.recycle();
-            prevEventTime = eventTime;
-
-            // sleep for a bit to emulate the overall drag gesture.
-            SystemClock.sleep(sleepTime);
-        }
-    }
-
-    private static void injectUpEvent(UiAutomation uiAutomation, long downTime,
-            boolean useCurrentEventTime, int xOnScreen, int yOnScreen,
-            EventInjectionListener eventInjectionListener) {
-        long eventTime = useCurrentEventTime ? SystemClock.uptimeMillis() : downTime;
-        MotionEvent eventUp = MotionEvent.obtain(
-                downTime, eventTime, MotionEvent.ACTION_UP, xOnScreen, yOnScreen, 1);
-        eventUp.setSource(InputDevice.SOURCE_TOUCHSCREEN);
-        uiAutomation.injectInputEvent(eventUp, true);
-        if (eventInjectionListener != null) {
-            eventInjectionListener.onUpInjected(xOnScreen, yOnScreen);
-        }
-        eventUp.recycle();
-    }
-
-    /**
-     * Emulates a fling gesture across the horizontal center of the passed view.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param view the view to fling
-     * @param isDownwardsFlingGesture if <code>true</code>, the emulated fling will
-     *      be a downwards gesture
-     * @return The vertical amount of emulated fling in pixels
-     */
-    public static int emulateFlingGesture(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule, View view, boolean isDownwardsFlingGesture) {
-        return emulateFlingGesture(instrumentation, activityTestRule,
-                view, isDownwardsFlingGesture, null);
-    }
-
-    /**
-     * Emulates a fling gesture across the horizontal center of the passed view.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param view the view to fling
-     * @param isDownwardsFlingGesture if <code>true</code>, the emulated fling will
-     *      be a downwards gesture
-     * @param eventInjectionListener optional listener to notify about the injected events
-     * @return The vertical amount of emulated fling in pixels
-     */
-    public static int emulateFlingGesture(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule, View view, boolean isDownwardsFlingGesture,
-            EventInjectionListener eventInjectionListener) {
-        final ViewConfiguration configuration = ViewConfiguration.get(view.getContext());
-        final int flingVelocity = (configuration.getScaledMinimumFlingVelocity() +
-                configuration.getScaledMaximumFlingVelocity()) / 2;
-        // Get view coordinates on the screen
-        final int[] viewOnScreenXY = new int[2];
-        view.getLocationOnScreen(viewOnScreenXY);
-
-        // Our fling gesture will be from 25% height of the view to 75% height of the view
-        // for downwards fling gesture, and the other way around for upwards fling gesture
-        final int viewHeight = view.getHeight();
-        final int x = viewOnScreenXY[0] + view.getWidth() / 2;
-        final int startY = isDownwardsFlingGesture ? viewOnScreenXY[1] + viewHeight / 4
-                : viewOnScreenXY[1] + 3 * viewHeight / 4;
-        final int amountY = isDownwardsFlingGesture ? viewHeight / 2 : -viewHeight / 2;
-
-        // Compute fling gesture duration based on the distance (50% height of the view) and
-        // fling velocity
-        final int durationMs = (1000 * viewHeight) / (2 * flingVelocity);
-
-        // And do the same event injection sequence as our generic drag gesture
-        emulateDragGesture(instrumentation, activityTestRule,
-                x, startY, 0, amountY, durationMs, durationMs / 16,
-            eventInjectionListener);
-
-        return amountY;
-    }
-
-    private static class ViewStateSnapshot {
-        final View mFirst;
-        final View mLast;
-        final int mFirstTop;
-        final int mLastBottom;
-        final int mChildCount;
-        private ViewStateSnapshot(ViewGroup viewGroup) {
-            mChildCount = viewGroup.getChildCount();
-            if (mChildCount == 0) {
-                mFirst = mLast = null;
-                mFirstTop = mLastBottom = Integer.MIN_VALUE;
-            } else {
-                mFirst = viewGroup.getChildAt(0);
-                mLast = viewGroup.getChildAt(mChildCount - 1);
-                mFirstTop = mFirst.getTop();
-                mLastBottom = mLast.getBottom();
-            }
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
-
-            final ViewStateSnapshot that = (ViewStateSnapshot) o;
-            return mFirstTop == that.mFirstTop &&
-                    mLastBottom == that.mLastBottom &&
-                    mFirst == that.mFirst &&
-                    mLast == that.mLast &&
-                    mChildCount == that.mChildCount;
-        }
-
-        @Override
-        public int hashCode() {
-            int result = mFirst != null ? mFirst.hashCode() : 0;
-            result = 31 * result + (mLast != null ? mLast.hashCode() : 0);
-            result = 31 * result + mFirstTop;
-            result = 31 * result + mLastBottom;
-            result = 31 * result + mChildCount;
-            return result;
-        }
-    }
-
-    /**
-     * Emulates a scroll to the bottom of the specified {@link ViewGroup}.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param viewGroup View group
-     */
-    public static void emulateScrollToBottom(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule, ViewGroup viewGroup) {
-        final int[] viewGroupOnScreenXY = new int[2];
-        viewGroup.getLocationOnScreen(viewGroupOnScreenXY);
-
-        final int emulatedX = viewGroupOnScreenXY[0] + viewGroup.getWidth() / 2;
-        final int emulatedStartY = viewGroupOnScreenXY[1] + 3 * viewGroup.getHeight() / 4;
-        final int swipeAmount = viewGroup.getHeight() / 2;
-
-        ViewStateSnapshot prev;
-        ViewStateSnapshot next = new ViewStateSnapshot(viewGroup);
-        do {
-            prev = next;
-            emulateDragGesture(instrumentation, activityTestRule,
-                    emulatedX, emulatedStartY, 0, -swipeAmount, 300, 10);
-            next = new ViewStateSnapshot(viewGroup);
-        } while (!prev.equals(next));
-    }
-
-    /**
-     * Emulates a long press in the center of the passed {@link View}.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param view the view to "long press"
-     */
-    public static void emulateLongPressOnViewCenter(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule, View view) {
-        emulateLongPressOnViewCenter(instrumentation, activityTestRule, view, 0);
-    }
-
-    /**
-     * Emulates a long press in the center of the passed {@link View}.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param view the view to "long press"
-     * @param extraWaitMs the duration of emulated "long press" in milliseconds starting
-     *      after system-level long press timeout.
-     */
-    public static void emulateLongPressOnViewCenter(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule, View view, long extraWaitMs) {
-        final int touchSlop = ViewConfiguration.get(view.getContext()).getScaledTouchSlop();
-        // Use instrumentation to emulate a tap on the spinner to bring down its popup
-        final int[] viewOnScreenXY = new int[2];
-        view.getLocationOnScreen(viewOnScreenXY);
-        int xOnScreen = viewOnScreenXY[0] + view.getWidth() / 2;
-        int yOnScreen = viewOnScreenXY[1] + view.getHeight() / 2;
-
-        emulateLongPressOnScreen(instrumentation, activityTestRule,
-                xOnScreen, yOnScreen, touchSlop, extraWaitMs, true);
-    }
-
-    /**
-     * Emulates a long press confirmed on a point relative to the top-left corner of the passed
-     * {@link View}. Offset parameters are used to compute the final screen coordinates of the
-     * press point.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param view the view to "long press"
-     * @param offsetX extra X offset for the tap
-     * @param offsetY extra Y offset for the tap
-     */
-    public static void emulateLongPressOnView(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule, View view, int offsetX, int offsetY) {
-        final int touchSlop = ViewConfiguration.get(view.getContext()).getScaledTouchSlop();
-        final int[] viewOnScreenXY = new int[2];
-        view.getLocationOnScreen(viewOnScreenXY);
-        int xOnScreen = viewOnScreenXY[0] + offsetX;
-        int yOnScreen = viewOnScreenXY[1] + offsetY;
-
-        emulateLongPressOnScreen(instrumentation, activityTestRule,
-                xOnScreen, yOnScreen, touchSlop, 0, true);
-    }
-
-    /**
-     * Emulates a long press then a linear drag gesture between 2 points across the screen.
-     * This is used for drag selection.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param dragStartX Start X of the emulated drag gesture
-     * @param dragStartY Start Y of the emulated drag gesture
-     * @param dragAmountX X amount of the emulated drag gesture
-     * @param dragAmountY Y amount of the emulated drag gesture
-     */
-    public static void emulateLongPressAndDragGesture(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule,
-            int dragStartX, int dragStartY, int dragAmountX, int dragAmountY) {
-        emulateLongPressOnScreen(instrumentation, activityTestRule, dragStartX, dragStartY,
-                0 /* touchSlop */, 0 /* extraWaitMs */, false /* upGesture */);
-        emulateDragGesture(instrumentation, activityTestRule, dragStartX, dragStartY, dragAmountX,
-                dragAmountY);
-    }
-
-    /**
-     * Emulates a long press on the screen.
-     *
-     * @param instrumentation the instrumentation used to run the test
-     * @param xOnScreen X position on screen for the "long press"
-     * @param yOnScreen Y position on screen for the "long press"
-     * @param extraWaitMs extra duration of emulated long press in milliseconds added
-     *        after the system-level "long press" timeout.
-     * @param upGesture whether to include an up event.
-     */
-    private static void emulateLongPressOnScreen(Instrumentation instrumentation,
-            ActivityTestRule<?> activityTestRule,
-            int xOnScreen, int yOnScreen, int touchSlop, long extraWaitMs, boolean upGesture) {
-        final UiAutomation uiAutomation = instrumentation.getUiAutomation();
-        final long downTime = SystemClock.uptimeMillis();
-
-        injectDownEvent(uiAutomation, downTime, xOnScreen, yOnScreen, null);
-        injectMoveEventForTap(uiAutomation, downTime, touchSlop, xOnScreen, yOnScreen);
-        SystemClock.sleep((long) (ViewConfiguration.getLongPressTimeout() * 1.5f) + extraWaitMs);
-        if (upGesture) {
-            injectUpEvent(uiAutomation, downTime, false, xOnScreen, yOnScreen, null);
-        }
-
-        // Wait for the system to process all events in the queue
-        if (activityTestRule != null) {
-            WidgetTestUtils.runOnMainAndDrawSync(activityTestRule,
-                    activityTestRule.getActivity().getWindow().getDecorView(), null);
-        } else {
-            instrumentation.waitForIdleSync();
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateChangerRule.java b/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateChangerRule.java
deleted file mode 100644
index a13da52..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateChangerRule.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-import android.provider.DeviceConfig;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * JUnit rule used to set a {@link DeviceConfig} preference before the test is run.
- *
- * <p>It stores the current value before the test, changes it (if necessary), then restores it after
- * the test (if necessary).
- */
-public class DeviceConfigStateChangerRule extends StateChangerRule<String> {
-
-    /**
-     * Default constructor.
-     *
-     * @param context context used to retrieve the {@link DeviceConfig} provider.
-     * @param namespace {@code DeviceConfig} namespace.
-     * @param key prefence key.
-     * @param value value to be set before the test is run.
-     */
-    public DeviceConfigStateChangerRule(@NonNull Context context, @NonNull String namespace,
-            @NonNull String key, @Nullable String value) {
-        this(new DeviceConfigStateManager(context, namespace, key), value);
-    }
-
-    /**
-     * Alternative constructor used when then test case already defines a
-     * {@link DeviceConfigStateManager}.
-     */
-    public DeviceConfigStateChangerRule(@NonNull DeviceConfigStateManager dcsm,
-            @Nullable String value) {
-        super(dcsm, value);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateKeeperRule.java b/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateKeeperRule.java
deleted file mode 100644
index 6f186de..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateKeeperRule.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-import android.provider.DeviceConfig;
-
-import androidx.annotation.NonNull;
-
-/**
- * JUnit rule used to restore a {@link DeviceConfig} preference after the test is run.
- *
- * <p>It stores the current value before the test, and restores it after the test (if necessary).
- */
-public class DeviceConfigStateKeeperRule extends StateKeeperRule<String> {
-
-    /**
-     * Default constructor.
-     *
-     * @param context context used to retrieve the {@link DeviceConfig} provider.
-     * @param namespace {@code DeviceConfig} namespace.
-     * @param key prefence key.
-     */
-    public DeviceConfigStateKeeperRule(@NonNull Context context, @NonNull String namespace,
-            @NonNull String key) {
-        super(new DeviceConfigStateManager(context, namespace, key));
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateManager.java b/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateManager.java
deleted file mode 100644
index c85fc1b..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/DeviceConfigStateManager.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.compatibility.common.util;
-
-import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
-
-import android.content.Context;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.google.common.base.Preconditions;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Manages the state of a preference backed by {@link DeviceConfig}.
- */
-public final class DeviceConfigStateManager implements StateManager<String> {
-
-    private static final String TAG = DeviceConfigStateManager.class.getSimpleName();
-
-    private final Context mContext;
-    private final String mNamespace;
-    private final String mKey;
-
-    /**
-     * Default constructor.
-     *
-     * @param context context used to retrieve the {@link Settings} provider.
-     * @param namespace settings namespace.
-     * @param key prefence key.
-     */
-    public DeviceConfigStateManager(@NonNull Context context, @NonNull String namespace,
-            @NonNull String key) {
-        debug("DeviceConfigStateManager", "namespace=%s, key=%s", namespace, key);
-
-        mContext = Preconditions.checkNotNull(context);
-        mNamespace = Preconditions.checkNotNull(namespace);
-        mKey = Preconditions.checkNotNull(key);
-    }
-
-    @Override
-    public void set(@Nullable String value) {
-        debug("set", value);
-        runWithShellPermissionIdentity(() -> setWithPermissionsGranted(value),
-                "android.permission.READ_DEVICE_CONFIG", "android.permission.WRITE_DEVICE_CONFIG");
-    }
-
-    private void setWithPermissionsGranted(@Nullable String value) {
-        final OneTimeDeviceConfigListener listener = new OneTimeDeviceConfigListener(mNamespace,
-                mKey);
-        DeviceConfig.addOnPropertiesChangedListener(mNamespace, mContext.getMainExecutor(),
-                listener);
-
-        DeviceConfig.setProperty(mNamespace, mKey, value, /* makeDefault= */ false);
-        listener.assertCalled();
-    }
-
-    @Override
-    @Nullable
-    public String get() {
-        final AtomicReference<String> reference = new AtomicReference<>();
-        runWithShellPermissionIdentity(()
-                -> reference.set(DeviceConfig.getProperty(mNamespace, mKey)),
-                "android.permission.READ_DEVICE_CONFIG");
-        debug("get", reference.get());
-
-        return reference.get();
-    }
-
-    private void debug(@NonNull String methodName, @NonNull String msg, Object...args) {
-        if (!Log.isLoggable(TAG, Log.DEBUG)) return;
-
-        final String prefix = String.format("%s(%s:%s): ", methodName, mNamespace, mKey);
-        Log.d(TAG, prefix + String.format(msg, args));
-    }
-
-    @Override
-    public String toString() {
-        return "DeviceConfigStateManager[namespace=" + mNamespace + ", key=" + mKey + "]";
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DeviceInfoStore.java b/common/device-side/util/src/com/android/compatibility/common/util/DeviceInfoStore.java
deleted file mode 100644
index 03f69fa..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/DeviceInfoStore.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.compatibility.common.util;
-
-import android.util.JsonWriter;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.List;
-
-public class DeviceInfoStore extends InfoStore {
-
-    protected File mJsonFile;
-    protected JsonWriter mJsonWriter = null;
-
-    public DeviceInfoStore() {
-        mJsonFile = null;
-    }
-
-    public DeviceInfoStore(File file) throws Exception {
-        mJsonFile = file;
-    }
-
-    /**
-     * Opens the file for storage and creates the writer.
-     */
-    @Override
-    public void open() throws IOException {
-        FileOutputStream out = new FileOutputStream(mJsonFile);
-        mJsonWriter = new JsonWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
-        // TODO(agathaman): remove to make json output less pretty
-        mJsonWriter.setIndent("  ");
-        mJsonWriter.beginObject();
-    }
-
-    /**
-     * Closes the writer.
-     */
-    @Override
-    public void close() throws Exception {
-        mJsonWriter.endObject();
-        mJsonWriter.flush();
-        mJsonWriter.close();
-    }
-
-    /**
-     * Start a new group of result.
-     */
-    @Override
-    public void startGroup() throws IOException {
-        mJsonWriter.beginObject();
-    }
-
-    /**
-     * Start a new group of result with specified name.
-     */
-    @Override
-    public void startGroup(String name) throws IOException {
-        mJsonWriter.name(name);
-        mJsonWriter.beginObject();
-    }
-
-    /**
-     * Complete adding result to the last started group.
-     */
-    @Override
-    public void endGroup() throws IOException {
-        mJsonWriter.endObject();
-    }
-
-    /**
-     * Start a new array of result.
-     */
-    @Override
-    public void startArray() throws IOException {
-        mJsonWriter.beginArray();
-    }
-
-    /**
-     * Start a new array of result with specified name.
-     */
-    @Override
-    public void startArray(String name) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-    }
-
-    /**
-     * Complete adding result to the last started array.
-     */
-    @Override
-    public void endArray() throws IOException {
-        mJsonWriter.endArray();
-    }
-
-    /**
-     * Adds a int value to the InfoStore
-     */
-    @Override
-    public void addResult(String name, int value) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(value);
-    }
-
-    /**
-     * Adds a long value to the InfoStore
-     */
-    @Override
-    public void addResult(String name, long value) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(value);
-    }
-
-    /**
-     * Adds a float value to the InfoStore
-     */
-    @Override
-    public void addResult(String name, float value) throws IOException {
-        addResult(name, (double) value);
-    }
-
-    /**
-     * Adds a double value to the InfoStore
-     */
-    @Override
-    public void addResult(String name, double value) throws IOException {
-        checkName(name);
-        if (isDoubleNaNOrInfinite(value)) {
-            return;
-        } else {
-            mJsonWriter.name(name);
-            mJsonWriter.value(value);
-        }
-    }
-
-    /**
-     * Adds a boolean value to the InfoStore
-     */
-    @Override
-    public void addResult(String name, boolean value) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(value);
-    }
-
-    /**
-     * Adds a String value to the InfoStore
-     */
-    @Override
-    public void addResult(String name, String value) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.value(checkString(value));
-    }
-
-    /**
-     * Adds a int array to the InfoStore
-     */
-    @Override
-    public void addArrayResult(String name, int[] array) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (int value : checkArray(array)) {
-            mJsonWriter.value(value);
-        }
-        mJsonWriter.endArray();
-    }
-
-    /**
-     * Adds a long array to the InfoStore
-     */
-    @Override
-    public void addArrayResult(String name, long[] array) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (long value : checkArray(array)) {
-            mJsonWriter.value(value);
-        }
-        mJsonWriter.endArray();
-    }
-
-    /**
-     * Adds a float array to the InfoStore
-     */
-    @Override
-    public void addArrayResult(String name, float[] array) throws IOException {
-        double[] doubleArray = new double[array.length];
-        for (int i = 0; i < array.length; i++) {
-            doubleArray[i] = array[i];
-        }
-        addArrayResult(name, doubleArray);
-    }
-
-    /**
-     * Adds a double array to the InfoStore
-     */
-    @Override
-    public void addArrayResult(String name, double[] array) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (double value : checkArray(array)) {
-            if (isDoubleNaNOrInfinite(value)) {
-                continue;
-            }
-            mJsonWriter.value(value);
-        }
-        mJsonWriter.endArray();
-    }
-
-    /**
-     * Adds a boolean array to the InfoStore
-     */
-    @Override
-    public void addArrayResult(String name, boolean[] array) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (boolean value : checkArray(array)) {
-            mJsonWriter.value(value);
-        }
-        mJsonWriter.endArray();
-    }
-
-    /**
-     * Adds a List of String to the InfoStore
-     */
-    @Override
-    public void addListResult(String name, List<String> list) throws IOException {
-        checkName(name);
-        mJsonWriter.name(name);
-        mJsonWriter.beginArray();
-        for (String value : checkStringList(list)) {
-            mJsonWriter.value(checkString(value));
-        }
-        mJsonWriter.endArray();
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DeviceReportLog.java b/common/device-side/util/src/com/android/compatibility/common/util/DeviceReportLog.java
deleted file mode 100644
index 12c9f1a..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/DeviceReportLog.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.compatibility.common.util;
-
-import android.app.Instrumentation;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-/**
- * Handles adding results to the report for device side tests.
- *
- * NOTE: tests MUST call {@link #submit(Instrumentation)} if and only if the test passes in order to
- * send the results to the runner.
- */
-public class DeviceReportLog extends ReportLog {
-    private static final String TAG = DeviceReportLog.class.getSimpleName();
-    private static final String RESULT = "COMPATIBILITY_TEST_RESULT";
-    private static final int INST_STATUS_ERROR = -1;
-    private static final int INST_STATUS_IN_PROGRESS = 2;
-
-    private ReportLogDeviceInfoStore store;
-
-    public DeviceReportLog(String reportLogName, String streamName) {
-        this(reportLogName, streamName, new File(InstrumentationRegistry
-                .getInstrumentation().getTargetContext()
-                .getExternalFilesDir(null).getPath(),
-                "report-log-files"));
-    }
-
-    public DeviceReportLog(String reportLogName, String streamName, File logDirectory) {
-        super(reportLogName, streamName);
-        try {
-            // dir value must match the src-dir value configured in ReportLogCollector target
-            // preparer in cts/harness/tools/cts-tradefed/res/config/cts-preconditions.xml
-            if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-                throw new IOException("External storage is not mounted");
-            } else if ((!logDirectory.exists() && !logDirectory.mkdirs())
-                    || (logDirectory.exists() && !logDirectory.isDirectory())) {
-                throw new IOException("Cannot create directory for device info files");
-            } else {
-                File jsonFile = new File(logDirectory, mReportLogName + ".reportlog.json");
-                store = new ReportLogDeviceInfoStore(jsonFile, mStreamName);
-                store.open();
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "Could not create report log file.", e);
-        }
-    }
-
-    /**
-     * Adds a double metric to the report.
-     */
-    @Override
-    public void addValue(String source, String message, double value, ResultType type,
-            ResultUnit unit) {
-        super.addValue(source, message, value, type, unit);
-        try {
-            store.addResult(message, value);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds a double metric to the report.
-     */
-    @Override
-    public void addValue(String message, double value, ResultType type, ResultUnit unit) {
-        super.addValue(message, value, type, unit);
-        try {
-            store.addResult(message, value);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds a double array of metrics to the report.
-     */
-    @Override
-    public void addValues(String source, String message, double[] values, ResultType type,
-            ResultUnit unit) {
-        super.addValues(source, message, values, type, unit);
-        try {
-            store.addArrayResult(message, values);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds a double array of metrics to the report.
-     */
-    @Override
-    public void addValues(String message, double[] values, ResultType type, ResultUnit unit) {
-        super.addValues(message, values, type, unit);
-        try {
-            store.addArrayResult(message, values);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds an int metric to the report.
-     */
-    @Override
-    public void addValue(String message, int value, ResultType type, ResultUnit unit) {
-        try {
-            store.addResult(message, value);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds a long metric to the report.
-     */
-    @Override
-    public void addValue(String message, long value, ResultType type, ResultUnit unit) {
-        try {
-            store.addResult(message, value);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds a float metric to the report.
-     */
-    @Override
-    public void addValue(String message, float value, ResultType type, ResultUnit unit) {
-        try {
-            store.addResult(message, value);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds a boolean metric to the report.
-     */
-    @Override
-    public void addValue(String message, boolean value, ResultType type, ResultUnit unit) {
-        try {
-            store.addResult(message, value);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds a String metric to the report.
-     */
-    @Override
-    public void addValue(String message, String value, ResultType type, ResultUnit unit) {
-        try {
-            store.addResult(message, value);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds an int array of metrics to the report.
-     */
-    @Override
-    public void addValues(String message, int[] values, ResultType type, ResultUnit unit) {
-        try {
-            store.addArrayResult(message, values);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds a long array of metrics to the report.
-     */
-    @Override
-    public void addValues(String message, long[] values, ResultType type, ResultUnit unit) {
-        try {
-            store.addArrayResult(message, values);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds a float array of metrics to the report.
-     */
-    @Override
-    public void addValues(String message, float[] values, ResultType type, ResultUnit unit) {
-        try {
-            store.addArrayResult(message, values);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds a boolean array of metrics to the report.
-     */
-    @Override
-    public void addValues(String message, boolean[] values, ResultType type, ResultUnit unit) {
-        try {
-            store.addArrayResult(message, values);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Adds a String List of metrics to the report.
-     */
-    @Override
-    public void addValues(String message, List<String> values, ResultType type, ResultUnit unit) {
-        try {
-            store.addListResult(message, values);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Sets the summary double metric of the report.
-     *
-     * NOTE: messages over {@value Metric#MAX_MESSAGE_LENGTH} chars will be trimmed.
-     */
-    @Override
-    public void setSummary(String message, double value, ResultType type, ResultUnit unit) {
-        super.setSummary(message, value, type, unit);
-        try {
-            store.addResult(message, value);
-        } catch (Exception e) {
-            Log.e(TAG, "Could not log metric.", e);
-        }
-    }
-
-    /**
-     * Closes report file and submits report to instrumentation.
-     */
-    public void submit(Instrumentation instrumentation) {
-        try {
-            store.close();
-            Bundle output = new Bundle();
-            output.putString(RESULT, serialize(this));
-            instrumentation.sendStatus(INST_STATUS_IN_PROGRESS, output);
-        } catch (Exception e) {
-            Log.e(TAG, "ReportLog Submit Failed", e);
-            instrumentation.sendStatus(INST_STATUS_ERROR, null);
-        }
-    }
-
-    /**
-     * Closes report file. Static functions that do not have access to instrumentation can
-     * use this to close report logs. Summary, if present, is not reported to instrumentation, hence
-     * does not appear in the result XML.
-     */
-    public void submit() {
-        try {
-            store.close();
-        } catch (Exception e) {
-            Log.e(TAG, "ReportLog Submit Failed", e);
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DoubleVisitor.java b/common/device-side/util/src/com/android/compatibility/common/util/DoubleVisitor.java
deleted file mode 100644
index 96fb3bb..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/DoubleVisitor.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import androidx.annotation.NonNull;
-
-/**
- * Implements the Visitor design pattern to visit 2 related objects (like a view and the activity
- * hosting it).
- *
- * @param <V1> 1st visited object
- * @param <V2> 2nd visited object
- */
-public interface DoubleVisitor<V1, V2> {
-
-    /**
-     * Visit those objects.
-     */
-    void visit(@NonNull V1 visited1, @NonNull V2 visited2);
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DummyActivity.java b/common/device-side/util/src/com/android/compatibility/common/util/DummyActivity.java
deleted file mode 100644
index 672106c..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/DummyActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.app.Activity;
-
-public class DummyActivity extends Activity {
-
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/DynamicConfigDeviceSide.java b/common/device-side/util/src/com/android/compatibility/common/util/DynamicConfigDeviceSide.java
deleted file mode 100644
index 0e443fb..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/DynamicConfigDeviceSide.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2015 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 com.android.compatibility.common.util;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import android.support.test.InstrumentationRegistry;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.FileNotFoundException;
-
-/**
- * Load dynamic config for device side test cases
- */
-public class DynamicConfigDeviceSide extends DynamicConfig {
-
-    public static final String CONTENT_PROVIDER =
-            String.format("%s://android.tradefed.contentprovider", ContentResolver.SCHEME_CONTENT);
-
-    public DynamicConfigDeviceSide(String moduleName) throws XmlPullParserException, IOException {
-        this(moduleName, new File(CONFIG_FOLDER_ON_DEVICE));
-    }
-
-    public DynamicConfigDeviceSide(String moduleName, File configFolder)
-            throws XmlPullParserException, IOException {
-        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-            throw new IOException("External storage is not mounted");
-        }
-        // Use the content provider to get the config:
-        String uriPath = String.format("%s/%s/%s.dynamic", CONTENT_PROVIDER, configFolder.getAbsolutePath(), moduleName);
-        Uri sdcardUri = Uri.parse(uriPath);
-        Context appContext = InstrumentationRegistry.getTargetContext();
-        try {
-            ContentResolver resolver = appContext.getContentResolver();
-            ParcelFileDescriptor descriptor = resolver.openFileDescriptor(sdcardUri,"r");
-
-            initializeConfig(new ParcelFileDescriptor.AutoCloseInputStream(descriptor));
-            return;
-        } catch (FileNotFoundException e) {
-            // Log the error and use the fallback too
-            Log.e("DynamicConfigDeviceSide", "Error while using content provider for config", e);
-        }
-        // Fallback to the direct search
-        File configFile = getConfigFile(configFolder, moduleName);
-        initializeConfig(configFile);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/FakeKeys.java b/common/device-side/util/src/com/android/compatibility/common/util/FakeKeys.java
deleted file mode 100644
index 85e06ea..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/FakeKeys.java
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.compatibility.common.util;
-
-// Copied from cts/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java
-
-public class FakeKeys {
-    /*
-     * The keys and certificates below are generated with:
-     *
-     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
-     * openssl req -newkey rsa:1024 -keyout userkey.pem -nodes -days 3650 -out userkey.req
-     * mkdir -p demoCA/newcerts
-     * touch demoCA/index.txt
-     * echo "01" > demoCA/serial
-     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
-     */
-    public static class FAKE_RSA_1 {
-        /**
-         * Generated from above and converted with:
-         *
-         * openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
-         */
-        public static final byte[] privateKey = {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
-            (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
-            (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
-            (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
-            (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
-            (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
-            (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
-            (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
-            (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
-            (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
-            (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
-            (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
-            (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
-            (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
-            (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
-            (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
-            (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
-            (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
-            (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
-            (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
-            (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
-            (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
-            (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
-            (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
-            (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
-            (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
-            (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
-            (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
-            (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
-            (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
-            (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
-            (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
-            (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
-            (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
-            (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
-            (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
-            (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
-            (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
-            (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
-            (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
-            (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
-            (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
-            (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
-            (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
-            (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
-            (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
-            (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
-            (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
-            (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
-            (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
-            (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
-            (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
-            (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
-            (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
-            (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
-            (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
-            (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
-            (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
-            (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
-            (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
-            (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
-            (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
-            (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
-            (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
-            (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
-            (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
-            (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
-            (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
-            (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
-            (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
-            (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
-            (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
-            (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
-            (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
-            (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
-            (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
-            (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
-            (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
-            (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
-            (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
-            (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
-            (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
-            (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
-            (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
-            (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
-            (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
-            (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
-            (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
-            (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
-            (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
-            (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
-            (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
-            (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
-            (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
-            (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
-            (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
-            (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
-            (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
-            (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
-            (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
-            (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
-            (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
-            (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
-            (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
-            (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
-        };
-
-        /**
-         * Generated from above and converted with:
-         *
-         * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
-         */
-        public static final byte[] caCertificate = {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xce, (byte) 0x30, (byte) 0x82,
-            (byte) 0x02, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-            (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xe1, (byte) 0x6a,
-            (byte) 0xa2, (byte) 0xf4, (byte) 0x2e, (byte) 0x55, (byte) 0x48, (byte) 0x0a,
-            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31,
-            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53,
-            (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43,
-            (byte) 0x41, (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d,
-            (byte) 0x4d, (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61,
-            (byte) 0x69, (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65,
-            (byte) 0x77, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12,
-            (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69,
-            (byte) 0x64, (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74,
-            (byte) 0x20, (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73,
-            (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32,
-            (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x34, (byte) 0x31, (byte) 0x36,
-            (byte) 0x35, (byte) 0x35, (byte) 0x34, (byte) 0x34, (byte) 0x5a, (byte) 0x17,
-            (byte) 0x0d, (byte) 0x32, (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31,
-            (byte) 0x32, (byte) 0x31, (byte) 0x36, (byte) 0x35, (byte) 0x35, (byte) 0x34,
-            (byte) 0x34, (byte) 0x5a, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b,
-            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31,
-            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41,
-            (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d,
-            (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69,
-            (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77,
-            (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41,
-            (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64,
-            (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20,
-            (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30,
-            (byte) 0x81, (byte) 0x9f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
-            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
-            (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03,
-            (byte) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
-            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa3, (byte) 0x72,
-            (byte) 0xab, (byte) 0xd0, (byte) 0xe4, (byte) 0xad, (byte) 0x2f, (byte) 0xe7,
-            (byte) 0xe2, (byte) 0x79, (byte) 0x07, (byte) 0x36, (byte) 0x3d, (byte) 0x0c,
-            (byte) 0x8d, (byte) 0x42, (byte) 0x9a, (byte) 0x0a, (byte) 0x33, (byte) 0x64,
-            (byte) 0xb3, (byte) 0xcd, (byte) 0xb2, (byte) 0xd7, (byte) 0x3a, (byte) 0x42,
-            (byte) 0x06, (byte) 0x77, (byte) 0x45, (byte) 0x29, (byte) 0xe9, (byte) 0xcb,
-            (byte) 0xb7, (byte) 0x4a, (byte) 0xd6, (byte) 0xee, (byte) 0xad, (byte) 0x01,
-            (byte) 0x91, (byte) 0x9b, (byte) 0x0c, (byte) 0x59, (byte) 0xa1, (byte) 0x03,
-            (byte) 0xfa, (byte) 0xf0, (byte) 0x5a, (byte) 0x7c, (byte) 0x4f, (byte) 0xf7,
-            (byte) 0x8d, (byte) 0x36, (byte) 0x0f, (byte) 0x1f, (byte) 0x45, (byte) 0x7d,
-            (byte) 0x1b, (byte) 0x31, (byte) 0xa1, (byte) 0x35, (byte) 0x0b, (byte) 0x00,
-            (byte) 0xed, (byte) 0x7a, (byte) 0xb6, (byte) 0xc8, (byte) 0x4e, (byte) 0xa9,
-            (byte) 0x86, (byte) 0x4c, (byte) 0x7b, (byte) 0x99, (byte) 0x57, (byte) 0x41,
-            (byte) 0x12, (byte) 0xef, (byte) 0x6b, (byte) 0xbc, (byte) 0x3d, (byte) 0x60,
-            (byte) 0xf2, (byte) 0x99, (byte) 0x1a, (byte) 0xcd, (byte) 0xed, (byte) 0x56,
-            (byte) 0xa4, (byte) 0xe5, (byte) 0x36, (byte) 0x9f, (byte) 0x24, (byte) 0x1f,
-            (byte) 0xdc, (byte) 0x89, (byte) 0x40, (byte) 0xc8, (byte) 0x99, (byte) 0x92,
-            (byte) 0xab, (byte) 0x4a, (byte) 0xb5, (byte) 0x61, (byte) 0x45, (byte) 0x62,
-            (byte) 0xff, (byte) 0xa3, (byte) 0x45, (byte) 0x65, (byte) 0xaf, (byte) 0xf6,
-            (byte) 0x27, (byte) 0x30, (byte) 0x51, (byte) 0x0e, (byte) 0x0e, (byte) 0xeb,
-            (byte) 0x79, (byte) 0x0c, (byte) 0xbe, (byte) 0xb3, (byte) 0x0a, (byte) 0x6f,
-            (byte) 0x29, (byte) 0x06, (byte) 0xdc, (byte) 0x2f, (byte) 0x6b, (byte) 0x51,
-            (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
-            (byte) 0x81, (byte) 0xb1, (byte) 0x30, (byte) 0x81, (byte) 0xae, (byte) 0x30,
-            (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e,
-            (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x33, (byte) 0x05,
-            (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60, (byte) 0xc7, (byte) 0xf9,
-            (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c, (byte) 0x8f, (byte) 0x6d,
-            (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e, (byte) 0x5d, (byte) 0x51,
-            (byte) 0x30, (byte) 0x7f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
-            (byte) 0x23, (byte) 0x04, (byte) 0x78, (byte) 0x30, (byte) 0x76, (byte) 0x80,
-            (byte) 0x14, (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f,
-            (byte) 0x60, (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73,
-            (byte) 0x5c, (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97,
-            (byte) 0x8e, (byte) 0x5d, (byte) 0x51, (byte) 0xa1, (byte) 0x53, (byte) 0xa4,
-            (byte) 0x51, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
-            (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
-            (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
-            (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
-            (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
-            (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
-            (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
-            (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
-            (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
-            (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
-            (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x82, (byte) 0x09,
-            (byte) 0x00, (byte) 0xe1, (byte) 0x6a, (byte) 0xa2, (byte) 0xf4, (byte) 0x2e,
-            (byte) 0x55, (byte) 0x48, (byte) 0x0a, (byte) 0x30, (byte) 0x0c, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05,
-            (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30,
-            (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
-            (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05,
-            (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00,
-            (byte) 0x8c, (byte) 0x30, (byte) 0x42, (byte) 0xfa, (byte) 0xeb, (byte) 0x1a,
-            (byte) 0x26, (byte) 0xeb, (byte) 0xda, (byte) 0x56, (byte) 0x32, (byte) 0xf2,
-            (byte) 0x9d, (byte) 0xa5, (byte) 0x24, (byte) 0xd8, (byte) 0x3a, (byte) 0xda,
-            (byte) 0x30, (byte) 0xa6, (byte) 0x8b, (byte) 0x46, (byte) 0xfe, (byte) 0xfe,
-            (byte) 0xdb, (byte) 0xf1, (byte) 0xe6, (byte) 0xe1, (byte) 0x7c, (byte) 0x1b,
-            (byte) 0xe7, (byte) 0x77, (byte) 0x00, (byte) 0xa1, (byte) 0x1c, (byte) 0x19,
-            (byte) 0x17, (byte) 0x73, (byte) 0xb0, (byte) 0xf0, (byte) 0x9d, (byte) 0xf3,
-            (byte) 0x4f, (byte) 0xb6, (byte) 0xbc, (byte) 0xc7, (byte) 0x47, (byte) 0x85,
-            (byte) 0x2a, (byte) 0x4a, (byte) 0xa1, (byte) 0xa5, (byte) 0x58, (byte) 0xf5,
-            (byte) 0xc5, (byte) 0x1a, (byte) 0x51, (byte) 0xb1, (byte) 0x04, (byte) 0x80,
-            (byte) 0xee, (byte) 0x3a, (byte) 0xec, (byte) 0x2f, (byte) 0xe1, (byte) 0xfd,
-            (byte) 0x58, (byte) 0xeb, (byte) 0xed, (byte) 0x82, (byte) 0x9e, (byte) 0x38,
-            (byte) 0xa3, (byte) 0x24, (byte) 0x75, (byte) 0xf7, (byte) 0x3e, (byte) 0xc2,
-            (byte) 0xc5, (byte) 0x27, (byte) 0xeb, (byte) 0x6f, (byte) 0x7b, (byte) 0x50,
-            (byte) 0xda, (byte) 0x43, (byte) 0xdc, (byte) 0x3b, (byte) 0x0b, (byte) 0x6f,
-            (byte) 0x78, (byte) 0x8f, (byte) 0xb0, (byte) 0x66, (byte) 0xe1, (byte) 0x12,
-            (byte) 0x87, (byte) 0x5f, (byte) 0x97, (byte) 0x7b, (byte) 0xca, (byte) 0x14,
-            (byte) 0x79, (byte) 0xf7, (byte) 0xe8, (byte) 0x6c, (byte) 0x72, (byte) 0xdb,
-            (byte) 0x91, (byte) 0x65, (byte) 0x17, (byte) 0x54, (byte) 0xe0, (byte) 0x74,
-            (byte) 0x1d, (byte) 0xac, (byte) 0x47, (byte) 0x04, (byte) 0x12, (byte) 0xe0,
-            (byte) 0xc3, (byte) 0x66, (byte) 0x19, (byte) 0x05, (byte) 0x2e, (byte) 0x7e,
-            (byte) 0xf1, (byte) 0x61
-        };
-    }
-
-    /*
-     * The keys and certificates below are generated with:
-     *
-     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
-     * openssl dsaparam -out dsaparam.pem 1024
-     * openssl req -newkey dsa:dsaparam.pem -keyout userkey.pem -nodes -days 3650 -out userkey.req
-     * mkdir -p demoCA/newcerts
-     * touch demoCA/index.txt
-     * echo "01" > demoCA/serial
-     * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
-     */
-    public static class FAKE_DSA_1 {
-        /**
-         * Generated from above and converted with: openssl pkcs8 -topk8 -outform d
-         * -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
-         */
-        public static final byte[] privateKey = {
-            (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x4c, (byte) 0x02, (byte) 0x01,
-            (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x2c, (byte) 0x06,
-            (byte) 0x07, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38,
-            (byte) 0x04, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1f,
-            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xb3, (byte) 0x23,
-            (byte) 0xf7, (byte) 0x86, (byte) 0xbd, (byte) 0x3b, (byte) 0x86, (byte) 0xcc,
-            (byte) 0xc3, (byte) 0x91, (byte) 0xc0, (byte) 0x30, (byte) 0x32, (byte) 0x02,
-            (byte) 0x47, (byte) 0x35, (byte) 0x01, (byte) 0xef, (byte) 0xee, (byte) 0x98,
-            (byte) 0x13, (byte) 0x56, (byte) 0x49, (byte) 0x47, (byte) 0xb5, (byte) 0x20,
-            (byte) 0xa8, (byte) 0x60, (byte) 0xcb, (byte) 0xc0, (byte) 0xd5, (byte) 0x77,
-            (byte) 0xc1, (byte) 0x69, (byte) 0xcd, (byte) 0x18, (byte) 0x34, (byte) 0x92,
-            (byte) 0xf2, (byte) 0x6a, (byte) 0x2a, (byte) 0x10, (byte) 0x59, (byte) 0x1c,
-            (byte) 0x91, (byte) 0x20, (byte) 0x51, (byte) 0xca, (byte) 0x37, (byte) 0xb2,
-            (byte) 0x87, (byte) 0xa6, (byte) 0x8a, (byte) 0x02, (byte) 0xfd, (byte) 0x45,
-            (byte) 0x46, (byte) 0xf9, (byte) 0x76, (byte) 0xb1, (byte) 0x35, (byte) 0x38,
-            (byte) 0x8d, (byte) 0xff, (byte) 0x4c, (byte) 0x5d, (byte) 0x75, (byte) 0x8f,
-            (byte) 0x66, (byte) 0x15, (byte) 0x7d, (byte) 0x7b, (byte) 0xda, (byte) 0xdb,
-            (byte) 0x57, (byte) 0x39, (byte) 0xff, (byte) 0x91, (byte) 0x3f, (byte) 0xdd,
-            (byte) 0xe2, (byte) 0xb4, (byte) 0x22, (byte) 0x60, (byte) 0x4c, (byte) 0x32,
-            (byte) 0x3b, (byte) 0x9d, (byte) 0x34, (byte) 0x9f, (byte) 0xb9, (byte) 0x5d,
-            (byte) 0x75, (byte) 0xb9, (byte) 0xd3, (byte) 0x7f, (byte) 0x11, (byte) 0xba,
-            (byte) 0xb7, (byte) 0xc8, (byte) 0x32, (byte) 0xc6, (byte) 0xce, (byte) 0x71,
-            (byte) 0x91, (byte) 0xd3, (byte) 0x32, (byte) 0xaf, (byte) 0x4d, (byte) 0x7e,
-            (byte) 0x7c, (byte) 0x15, (byte) 0xf7, (byte) 0x71, (byte) 0x2c, (byte) 0x52,
-            (byte) 0x65, (byte) 0x4d, (byte) 0xa9, (byte) 0x81, (byte) 0x25, (byte) 0x35,
-            (byte) 0xce, (byte) 0x0b, (byte) 0x5b, (byte) 0x56, (byte) 0xfe, (byte) 0xf1,
-            (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xeb, (byte) 0x4e, (byte) 0x7f,
-            (byte) 0x7a, (byte) 0x31, (byte) 0xb3, (byte) 0x7d, (byte) 0x8d, (byte) 0xb2,
-            (byte) 0xf7, (byte) 0xaf, (byte) 0xad, (byte) 0xb1, (byte) 0x42, (byte) 0x92,
-            (byte) 0xf3, (byte) 0x6c, (byte) 0xe4, (byte) 0xed, (byte) 0x8b, (byte) 0x02,
-            (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x81, (byte) 0xc8, (byte) 0x36,
-            (byte) 0x48, (byte) 0xdb, (byte) 0x71, (byte) 0x2b, (byte) 0x91, (byte) 0xce,
-            (byte) 0x6d, (byte) 0xbc, (byte) 0xb8, (byte) 0xf9, (byte) 0xcb, (byte) 0x50,
-            (byte) 0x91, (byte) 0x10, (byte) 0x8a, (byte) 0xf8, (byte) 0x37, (byte) 0x50,
-            (byte) 0xda, (byte) 0x4f, (byte) 0xc8, (byte) 0x4d, (byte) 0x73, (byte) 0xcb,
-            (byte) 0x4d, (byte) 0xb0, (byte) 0x19, (byte) 0x54, (byte) 0x5a, (byte) 0xf3,
-            (byte) 0x6c, (byte) 0xc9, (byte) 0xd8, (byte) 0x96, (byte) 0xd9, (byte) 0xb0,
-            (byte) 0x54, (byte) 0x7e, (byte) 0x7d, (byte) 0xe2, (byte) 0x58, (byte) 0x0e,
-            (byte) 0x5f, (byte) 0xc0, (byte) 0xce, (byte) 0xb9, (byte) 0x5c, (byte) 0xe3,
-            (byte) 0xd3, (byte) 0xdf, (byte) 0xcf, (byte) 0x45, (byte) 0x74, (byte) 0xfb,
-            (byte) 0xe6, (byte) 0x20, (byte) 0xe7, (byte) 0xfc, (byte) 0x0f, (byte) 0xca,
-            (byte) 0xdb, (byte) 0xc0, (byte) 0x0b, (byte) 0xe1, (byte) 0x5a, (byte) 0x16,
-            (byte) 0x1d, (byte) 0xb3, (byte) 0x2e, (byte) 0xe5, (byte) 0x5f, (byte) 0x89,
-            (byte) 0x17, (byte) 0x73, (byte) 0x50, (byte) 0xd1, (byte) 0x4a, (byte) 0x60,
-            (byte) 0xb7, (byte) 0xaa, (byte) 0xf0, (byte) 0xc7, (byte) 0xc5, (byte) 0x03,
-            (byte) 0x4e, (byte) 0x36, (byte) 0x51, (byte) 0x9e, (byte) 0x2f, (byte) 0xfa,
-            (byte) 0xf3, (byte) 0xd6, (byte) 0x58, (byte) 0x14, (byte) 0x02, (byte) 0xb4,
-            (byte) 0x41, (byte) 0xd6, (byte) 0x72, (byte) 0x6f, (byte) 0x58, (byte) 0x5b,
-            (byte) 0x2d, (byte) 0x23, (byte) 0xc0, (byte) 0x75, (byte) 0x4f, (byte) 0x39,
-            (byte) 0xa8, (byte) 0x6a, (byte) 0xdf, (byte) 0x79, (byte) 0x21, (byte) 0xf2,
-            (byte) 0x77, (byte) 0x91, (byte) 0x3f, (byte) 0x1c, (byte) 0x4d, (byte) 0x48,
-            (byte) 0x78, (byte) 0xcd, (byte) 0xed, (byte) 0x79, (byte) 0x23, (byte) 0x04,
-            (byte) 0x17, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xc7, (byte) 0xe7,
-            (byte) 0xe2, (byte) 0x6b, (byte) 0x14, (byte) 0xe6, (byte) 0x31, (byte) 0x12,
-            (byte) 0xb2, (byte) 0x1e, (byte) 0xd4, (byte) 0xf2, (byte) 0x9b, (byte) 0x2c,
-            (byte) 0xf6, (byte) 0x54, (byte) 0x4c, (byte) 0x12, (byte) 0xe8, (byte) 0x22
-
-        };
-
-        /**
-         * Generated from above and converted with:
-         *
-         * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
-         */
-        public static final byte[] caCertificate = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x8a, (byte) 0x30, (byte) 0x82,
-            (byte) 0x01, (byte) 0xf3, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-            (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0x87, (byte) 0xc0,
-            (byte) 0x68, (byte) 0x7f, (byte) 0x42, (byte) 0x92, (byte) 0x0b, (byte) 0x7a,
-            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x5e, (byte) 0x31,
-            (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x41, (byte) 0x55,
-            (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x0a, (byte) 0x53,
-            (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d, (byte) 0x53, (byte) 0x74,
-            (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31, (byte) 0x21, (byte) 0x30,
-            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
-            (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57,
-            (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73,
-            (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c,
-            (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x17, (byte) 0x30, (byte) 0x15,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c,
-            (byte) 0x0e, (byte) 0x63, (byte) 0x61, (byte) 0x2e, (byte) 0x65, (byte) 0x78,
-            (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e,
-            (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17,
-            (byte) 0x0d, (byte) 0x31, (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32,
-            (byte) 0x37, (byte) 0x32, (byte) 0x33, (byte) 0x33, (byte) 0x31, (byte) 0x32,
-            (byte) 0x39, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x33,
-            (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x35, (byte) 0x32, (byte) 0x33,
-            (byte) 0x33, (byte) 0x31, (byte) 0x32, (byte) 0x39, (byte) 0x5a, (byte) 0x30,
-            (byte) 0x5e, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02,
-            (byte) 0x41, (byte) 0x55, (byte) 0x31, (byte) 0x13, (byte) 0x30, (byte) 0x11,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c,
-            (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x6d, (byte) 0x65, (byte) 0x2d,
-            (byte) 0x53, (byte) 0x74, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x31,
-            (byte) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e,
-            (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74,
-            (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69,
-            (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79,
-            (byte) 0x20, (byte) 0x4c, (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x17,
-            (byte) 0x30, (byte) 0x15, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x03, (byte) 0x0c, (byte) 0x0e, (byte) 0x63, (byte) 0x61, (byte) 0x2e,
-            (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c,
-            (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30,
-            (byte) 0x81, (byte) 0x9f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
-            (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
-            (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03,
-            (byte) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
-            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa4, (byte) 0xc7,
-            (byte) 0x06, (byte) 0xba, (byte) 0xdf, (byte) 0x2b, (byte) 0xee, (byte) 0xd2,
-            (byte) 0xb9, (byte) 0xe4, (byte) 0x52, (byte) 0x21, (byte) 0x68, (byte) 0x2b,
-            (byte) 0x83, (byte) 0xdf, (byte) 0xe3, (byte) 0x9c, (byte) 0x08, (byte) 0x73,
-            (byte) 0xdd, (byte) 0x90, (byte) 0xea, (byte) 0x97, (byte) 0x0c, (byte) 0x96,
-            (byte) 0x20, (byte) 0xb1, (byte) 0xee, (byte) 0x11, (byte) 0xd5, (byte) 0xd4,
-            (byte) 0x7c, (byte) 0x44, (byte) 0x96, (byte) 0x2e, (byte) 0x6e, (byte) 0xa2,
-            (byte) 0xb2, (byte) 0xa3, (byte) 0x4b, (byte) 0x0f, (byte) 0x32, (byte) 0x90,
-            (byte) 0xaf, (byte) 0x5c, (byte) 0x6f, (byte) 0x00, (byte) 0x88, (byte) 0x45,
-            (byte) 0x4e, (byte) 0x9b, (byte) 0x26, (byte) 0xc1, (byte) 0x94, (byte) 0x3c,
-            (byte) 0xfe, (byte) 0x10, (byte) 0xbd, (byte) 0xda, (byte) 0xf2, (byte) 0x8d,
-            (byte) 0x03, (byte) 0x52, (byte) 0x32, (byte) 0x11, (byte) 0xff, (byte) 0xf6,
-            (byte) 0xf9, (byte) 0x6e, (byte) 0x8f, (byte) 0x0f, (byte) 0xc8, (byte) 0x0a,
-            (byte) 0x48, (byte) 0x39, (byte) 0x33, (byte) 0xb9, (byte) 0x0c, (byte) 0xb3,
-            (byte) 0x2b, (byte) 0xab, (byte) 0x7d, (byte) 0x79, (byte) 0x6f, (byte) 0x57,
-            (byte) 0x5b, (byte) 0xb8, (byte) 0x84, (byte) 0xb6, (byte) 0xcc, (byte) 0xe8,
-            (byte) 0x30, (byte) 0x78, (byte) 0xff, (byte) 0x92, (byte) 0xe5, (byte) 0x43,
-            (byte) 0x2e, (byte) 0xef, (byte) 0x66, (byte) 0x98, (byte) 0xb4, (byte) 0xfe,
-            (byte) 0xa2, (byte) 0x40, (byte) 0xf2, (byte) 0x1f, (byte) 0xd0, (byte) 0x86,
-            (byte) 0x16, (byte) 0xc8, (byte) 0x45, (byte) 0xc4, (byte) 0x52, (byte) 0xcb,
-            (byte) 0x31, (byte) 0x5c, (byte) 0x9f, (byte) 0x32, (byte) 0x3b, (byte) 0xf7,
-            (byte) 0x19, (byte) 0x08, (byte) 0xc7, (byte) 0x00, (byte) 0x21, (byte) 0x7d,
-            (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
-            (byte) 0x50, (byte) 0x30, (byte) 0x4e, (byte) 0x30, (byte) 0x1d, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16,
-            (byte) 0x04, (byte) 0x14, (byte) 0x47, (byte) 0x82, (byte) 0xa3, (byte) 0xf1,
-            (byte) 0xc2, (byte) 0x7e, (byte) 0x3a, (byte) 0xde, (byte) 0x4f, (byte) 0x30,
-            (byte) 0x4c, (byte) 0x7f, (byte) 0x72, (byte) 0x81, (byte) 0x15, (byte) 0x32,
-            (byte) 0xda, (byte) 0x7f, (byte) 0x58, (byte) 0x18, (byte) 0x30, (byte) 0x1f,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04,
-            (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x47,
-            (byte) 0x82, (byte) 0xa3, (byte) 0xf1, (byte) 0xc2, (byte) 0x7e, (byte) 0x3a,
-            (byte) 0xde, (byte) 0x4f, (byte) 0x30, (byte) 0x4c, (byte) 0x7f, (byte) 0x72,
-            (byte) 0x81, (byte) 0x15, (byte) 0x32, (byte) 0xda, (byte) 0x7f, (byte) 0x58,
-            (byte) 0x18, (byte) 0x30, (byte) 0x0c, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05, (byte) 0x30, (byte) 0x03,
-            (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
-            (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7,
-            (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00,
-            (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x08, (byte) 0x7f,
-            (byte) 0x6a, (byte) 0x48, (byte) 0x90, (byte) 0x7b, (byte) 0x9b, (byte) 0x72,
-            (byte) 0x13, (byte) 0xa7, (byte) 0xef, (byte) 0x6b, (byte) 0x0b, (byte) 0x59,
-            (byte) 0xe5, (byte) 0x49, (byte) 0x72, (byte) 0x3a, (byte) 0xc8, (byte) 0x84,
-            (byte) 0xcc, (byte) 0x23, (byte) 0x18, (byte) 0x4c, (byte) 0xec, (byte) 0xc7,
-            (byte) 0xef, (byte) 0xcb, (byte) 0xa7, (byte) 0xbe, (byte) 0xe4, (byte) 0xef,
-            (byte) 0x8f, (byte) 0xc6, (byte) 0x06, (byte) 0x8c, (byte) 0xc0, (byte) 0xe4,
-            (byte) 0x2f, (byte) 0x2a, (byte) 0xc0, (byte) 0x35, (byte) 0x7d, (byte) 0x5e,
-            (byte) 0x19, (byte) 0x29, (byte) 0x8c, (byte) 0xb9, (byte) 0xf1, (byte) 0x1e,
-            (byte) 0xaf, (byte) 0x82, (byte) 0xd8, (byte) 0xe3, (byte) 0x88, (byte) 0xe1,
-            (byte) 0x31, (byte) 0xc8, (byte) 0x82, (byte) 0x1f, (byte) 0x83, (byte) 0xa9,
-            (byte) 0xde, (byte) 0xfe, (byte) 0x4b, (byte) 0xe2, (byte) 0x78, (byte) 0x64,
-            (byte) 0xed, (byte) 0xa4, (byte) 0x7b, (byte) 0xee, (byte) 0x8d, (byte) 0x71,
-            (byte) 0x1b, (byte) 0x44, (byte) 0xe6, (byte) 0xb7, (byte) 0xe8, (byte) 0xc5,
-            (byte) 0x9a, (byte) 0x93, (byte) 0x92, (byte) 0x6f, (byte) 0x6f, (byte) 0xdb,
-            (byte) 0xbd, (byte) 0xd7, (byte) 0x03, (byte) 0x85, (byte) 0xa9, (byte) 0x5f,
-            (byte) 0x53, (byte) 0x5f, (byte) 0x5d, (byte) 0x30, (byte) 0xc6, (byte) 0xd9,
-            (byte) 0xce, (byte) 0x34, (byte) 0xa8, (byte) 0xbe, (byte) 0x31, (byte) 0x47,
-            (byte) 0x1c, (byte) 0xa4, (byte) 0x7f, (byte) 0xc0, (byte) 0x2c, (byte) 0xbc,
-            (byte) 0xfe, (byte) 0x1a, (byte) 0x31, (byte) 0xd8, (byte) 0x77, (byte) 0x4d,
-            (byte) 0xfc, (byte) 0x45, (byte) 0x84, (byte) 0xfc, (byte) 0x45, (byte) 0x12,
-            (byte) 0xab, (byte) 0x50, (byte) 0xe4, (byte) 0x45, (byte) 0xe5, (byte) 0x11
-        };
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/FeatureUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/FeatureUtil.java
deleted file mode 100644
index c9681d2..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/FeatureUtil.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-import android.content.pm.FeatureInfo;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.os.Build;
-import android.support.test.InstrumentationRegistry;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Device-side utility class for detecting system features
- */
-public class FeatureUtil {
-
-    public static final String AUTOMOTIVE_FEATURE = "android.hardware.type.automotive";
-    public static final String LEANBACK_FEATURE = "android.software.leanback";
-    public static final String LOW_RAM_FEATURE = "android.hardware.ram.low";
-    public static final String TELEPHONY_FEATURE = "android.hardware.telephony";
-    public static final String TV_FEATURE = "android.hardware.type.television";
-    public static final String WATCH_FEATURE = "android.hardware.type.watch";
-
-
-    /** Returns true if the device has a given system feature */
-    public static boolean hasSystemFeature(String feature) {
-        return getPackageManager().hasSystemFeature(feature);
-    }
-
-    /** Returns true if the device has any feature in a given collection of system features */
-    public static boolean hasAnySystemFeature(String... features) {
-        PackageManager pm = getPackageManager();
-        for (String feature : features) {
-            if (pm.hasSystemFeature(feature)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /** Returns true if the device has all features in a given collection of system features */
-    public static boolean hasAllSystemFeatures(String... features) {
-        PackageManager pm = getPackageManager();
-        for (String feature : features) {
-            if (!pm.hasSystemFeature(feature)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /** Returns all system features of the device */
-    public static Set<String> getAllFeatures() {
-        Set<String> allFeatures = new HashSet<String>();
-        for (FeatureInfo fi : getPackageManager().getSystemAvailableFeatures()) {
-            allFeatures.add(fi.name);
-        }
-        return allFeatures;
-    }
-
-    /** Returns true if the device has feature TV_FEATURE or feature LEANBACK_FEATURE */
-    public static boolean isTV() {
-        return hasAnySystemFeature(TV_FEATURE, LEANBACK_FEATURE);
-    }
-
-    /** Returns true if the device has feature WATCH_FEATURE */
-    public static boolean isWatch() {
-        return hasSystemFeature(WATCH_FEATURE);
-    }
-
-    /** Returns true if the device has feature AUTOMOTIVE_FEATURE */
-    public static boolean isAutomotive() {
-        return hasSystemFeature(AUTOMOTIVE_FEATURE);
-    }
-
-    public static boolean isVrHeadset() {
-        int maskedUiMode = (getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK);
-        return (maskedUiMode == Configuration.UI_MODE_TYPE_VR_HEADSET);
-    }
-
-    /** Returns true if the device is a low ram device:
-     *  1. API level &gt;= O_MR1
-     *  2. device has feature LOW_RAM_FEATURE
-     */
-    public static boolean isLowRam() {
-        return ApiLevelUtil.isAtLeast(Build.VERSION_CODES.O_MR1) &&
-                hasSystemFeature(LOW_RAM_FEATURE);
-    }
-
-    private static Context getContext() {
-        return InstrumentationRegistry.getInstrumentation().getTargetContext();
-    }
-
-    private static PackageManager getPackageManager() {
-        return getContext().getPackageManager();
-    }
-
-    private static Configuration getConfiguration() {
-        return getContext().getResources().getConfiguration();
-    }
-
-    /** Returns true if the device has feature TELEPHONY_FEATURE */
-    public static boolean hasTelephony() {
-        return hasSystemFeature(TELEPHONY_FEATURE);
-    }
-
-    /** Returns true if the device has feature FEATURE_MICROPHONE */
-    public static boolean hasMicrophone() {
-        return hasSystemFeature(getPackageManager().FEATURE_MICROPHONE);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/FileCopyHelper.java b/common/device-side/util/src/com/android/compatibility/common/util/FileCopyHelper.java
deleted file mode 100644
index f58dbd0..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/FileCopyHelper.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2009 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-
-/**
- * FileCopyHelper is used to copy files from resources to the
- * application directory and responsible for deleting the files.
- *
- * @see MediaStore_VideoTest
- * @see MediaStore_Images_MediaTest
- * @see MediaStore_Images_ThumbnailsTest
- */
-public class FileCopyHelper {
-    /** The context. */
-    private Context mContext;
-
-    /** The files added. */
-    private ArrayList<String> mFilesList;
-
-    /**
-     * Instantiates a new file copy helper.
-     *
-     * @param context the context
-     */
-    public FileCopyHelper(Context context) {
-        mContext = context;
-        mFilesList = new ArrayList<String>();
-    }
-
-    /**
-     * Copy the file from the resources with a filename.
-     *
-     * @param resId the res id
-     * @param fileName the file name
-     *
-     * @return the absolute path of the destination file
-     * @throws IOException
-     */
-    public String copy(int resId, String fileName) throws IOException {
-        InputStream source = mContext.getResources().openRawResource(resId);
-        OutputStream target = mContext.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
-        copyFile(source, target);
-        mFilesList.add(fileName);
-        return mContext.getFileStreamPath(fileName).getAbsolutePath();
-    }
-
-    public void copyToExternalStorage(int resId, File path) throws IOException {
-        InputStream source = mContext.getResources().openRawResource(resId);
-        OutputStream target = new FileOutputStream(path);
-        copyFile(source, target);
-    }
-
-    private void copyFile(InputStream source, OutputStream target) throws IOException {
-        try {
-            byte[] buffer = new byte[1024];
-            for (int len = source.read(buffer); len > 0; len = source.read(buffer)) {
-                target.write(buffer, 0, len);
-            }
-        } finally {
-            if (source != null) {
-                source.close();
-            }
-            if (target != null) {
-                target.close();
-            }
-        }
-    }
-
-    /**
-     * Delete all the files copied by the helper.
-     */
-    public void clear(){
-        for (String path : mFilesList) {
-            mContext.deleteFile(path);
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/FileUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/FileUtils.java
deleted file mode 100644
index ceada01..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/FileUtils.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.compatibility.common.util;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/** Bits and pieces copied from hidden API of android.os.FileUtils. */
-public class FileUtils {
-
-    public static final int S_IFMT  = 0170000;
-    public static final int S_IFSOCK = 0140000;
-    public static final int S_IFLNK = 0120000;
-    public static final int S_IFREG = 0100000;
-    public static final int S_IFBLK = 0060000;
-    public static final int S_IFDIR = 0040000;
-    public static final int S_IFCHR = 0020000;
-    public static final int S_IFIFO = 0010000;
-
-    public static final int S_ISUID = 0004000;
-    public static final int S_ISGID = 0002000;
-    public static final int S_ISVTX = 0001000;
-
-    public static final int S_IRWXU = 00700;
-    public static final int S_IRUSR = 00400;
-    public static final int S_IWUSR = 00200;
-    public static final int S_IXUSR = 00100;
-
-    public static final int S_IRWXG = 00070;
-    public static final int S_IRGRP = 00040;
-    public static final int S_IWGRP = 00020;
-    public static final int S_IXGRP = 00010;
-
-    public static final int S_IRWXO = 00007;
-    public static final int S_IROTH = 00004;
-    public static final int S_IWOTH = 00002;
-    public static final int S_IXOTH = 00001;
-
-    static {
-        System.loadLibrary("cts_jni");
-    }
-
-    public static class FileStatus {
-
-        public int dev;
-        public int ino;
-        public int mode;
-        public int nlink;
-        public int uid;
-        public int gid;
-        public int rdev;
-        public long size;
-        public int blksize;
-        public long blocks;
-        public long atime;
-        public long mtime;
-        public long ctime;
-
-        public boolean hasModeFlag(int flag) {
-            if (((S_IRWXU | S_IRWXG | S_IRWXO) & flag) != flag) {
-                throw new IllegalArgumentException("Inappropriate flag " + flag);
-            }
-            return (mode & flag) == flag;
-        }
-
-        public boolean isOfType(int type) {
-            if ((type & S_IFMT) != type) {
-                throw new IllegalArgumentException("Unknown type " + type);
-            }
-            return (mode & S_IFMT) == type;
-        }
-    }
-
-    /**
-     * @param path of the file to stat
-     * @param status object to set the fields on
-     * @param statLinks or don't stat links (lstat vs stat)
-     * @return whether or not we were able to stat the file
-     */
-    public native static boolean getFileStatus(String path, FileStatus status, boolean statLinks);
-
-    public native static String getUserName(int uid);
-
-    public native static String getGroupName(int gid);
-
-    public native static int setPermissions(String file, int mode);
-
-    /**
-     * Copy data from a source stream to destFile.
-     * Return true if succeed, return false if failed.
-     */
-    public static boolean copyToFile(InputStream inputStream, File destFile) {
-        try {
-            if (destFile.exists()) {
-                destFile.delete();
-            }
-            FileOutputStream out = new FileOutputStream(destFile);
-            try {
-                byte[] buffer = new byte[4096];
-                int bytesRead;
-                while ((bytesRead = inputStream.read(buffer)) >= 0) {
-                    out.write(buffer, 0, bytesRead);
-                }
-            } finally {
-                out.flush();
-                try {
-                    out.getFD().sync();
-                } catch (IOException e) {
-                }
-                out.close();
-            }
-            return true;
-        } catch (IOException e) {
-            return false;
-        }
-    }
-
-    public static void createFile(File file, int numBytes) throws IOException {
-        File parentFile = file.getParentFile();
-        if (parentFile != null) {
-            parentFile.mkdirs();
-        }
-        byte[] buffer = new byte[numBytes];
-        FileOutputStream output = new FileOutputStream(file);
-        try {
-            output.write(buffer);
-        } finally {
-            output.close();
-        }
-    }
-
-    public static byte[] readInputStreamFully(InputStream is) {
-        ByteArrayOutputStream os = new ByteArrayOutputStream();
-        byte[] buffer = new byte[32768];
-        int count;
-        try {
-            while ((count = is.read(buffer)) != -1) {
-                os.write(buffer, 0, count);
-            }
-            is.close();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-        return os.toByteArray();
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/IBinderParcelable.java b/common/device-side/util/src/com/android/compatibility/common/util/IBinderParcelable.java
deleted file mode 100644
index f3c53fe..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/IBinderParcelable.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 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 com.android.compatibility.common.util;
-
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class IBinderParcelable implements Parcelable {
-    public IBinder binder;
-
-    public IBinderParcelable(IBinder source) {
-        binder = source;
-    }
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeStrongBinder(binder);
-    }
-
-    public static final Parcelable.Creator<IBinderParcelable>
-        CREATOR = new Parcelable.Creator<IBinderParcelable>() {
-
-        public IBinderParcelable createFromParcel(Parcel source) {
-            return new IBinderParcelable(source);
-        }
-
-        public IBinderParcelable[] newArray(int size) {
-            return new IBinderParcelable[size];
-        }
-    };
-
-    private IBinderParcelable(Parcel source) {
-        binder = source.readStrongBinder();
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ImeAwareEditText.java b/common/device-side/util/src/com/android/compatibility/common/util/ImeAwareEditText.java
deleted file mode 100644
index db148bf..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ImeAwareEditText.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-
-public class ImeAwareEditText extends EditText {
-    private boolean mHasPendingShowSoftInputRequest;
-    final Runnable mRunShowSoftInputIfNecessary = () -> showSoftInputIfNecessary();
-
-    public ImeAwareEditText(Context context) {
-        super(context, null);
-    }
-
-    public ImeAwareEditText(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public ImeAwareEditText(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public ImeAwareEditText(Context context, AttributeSet attrs, int defStyleAttr,
-            int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    /**
-     * This method is called back by the system when the system is about to establish a connection
-     * to the current input method.
-     *
-     * <p>This is a good and reliable signal to schedule a pending task to call
-     * {@link InputMethodManager#showSoftInput(View, int)}.</p>
-     *
-     * @param editorInfo context about the text input field.
-     * @return {@link InputConnection} to be passed to the input method.
-     */
-    @Override
-    public InputConnection onCreateInputConnection(EditorInfo editorInfo) {
-        final InputConnection ic = super.onCreateInputConnection(editorInfo);
-        if (mHasPendingShowSoftInputRequest) {
-            removeCallbacks(mRunShowSoftInputIfNecessary);
-            post(mRunShowSoftInputIfNecessary);
-        }
-        return ic;
-    }
-
-    private void showSoftInputIfNecessary() {
-        if (mHasPendingShowSoftInputRequest) {
-            final InputMethodManager imm =
-                    getContext().getSystemService(InputMethodManager.class);
-            imm.showSoftInput(this, 0);
-            mHasPendingShowSoftInputRequest = false;
-        }
-    }
-
-    public void scheduleShowSoftInput() {
-        final InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
-        if (imm.isActive(this)) {
-            // This means that ImeAwareEditText is already connected to the IME.
-            // InputMethodManager#showSoftInput() is guaranteed to pass client-side focus check.
-            mHasPendingShowSoftInputRequest = false;
-            removeCallbacks(mRunShowSoftInputIfNecessary);
-            imm.showSoftInput(this, 0);
-            return;
-        }
-
-        // Otherwise, InputMethodManager#showSoftInput() should be deferred after
-        // onCreateInputConnection().
-        mHasPendingShowSoftInputRequest = true;
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/LocationUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/LocationUtils.java
deleted file mode 100644
index f233851..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/LocationUtils.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 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 com.android.compatibility.common.util;
-
-import android.app.Instrumentation;
-import android.util.Log;
-
-import java.io.IOException;
-
-public class LocationUtils {
-    private static String TAG = "LocationUtils";
-
-    public static void registerMockLocationProvider(Instrumentation instrumentation,
-            boolean enable) {
-        StringBuilder command = new StringBuilder();
-        command.append("appops set ");
-        command.append(instrumentation.getContext().getPackageName());
-        command.append(" android:mock_location ");
-        command.append(enable ? "allow" : "deny");
-        try {
-            SystemUtil.runShellCommand(instrumentation, command.toString());
-        } catch (IOException e) {
-            Log.e(TAG, "Error managing mock location app. Command: " + command, e);
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/MediaPerfUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/MediaPerfUtils.java
deleted file mode 100644
index 469e99a..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/MediaPerfUtils.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2016 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 com.android.compatibility.common.util;
-
-import android.media.MediaFormat;
-import android.util.Range;
-
-import com.android.compatibility.common.util.DeviceReportLog;
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-
-import java.util.Arrays;
-import android.util.Log;
-
-public class MediaPerfUtils {
-    private static final String TAG = "MediaPerfUtils";
-
-    private static final int MOVING_AVERAGE_NUM_FRAMES = 10;
-    private static final int MOVING_AVERAGE_WINDOW_MS = 1000;
-
-    // allow a variance of 2x for measured frame rates (e.g. half of lower-limit to double of
-    // upper-limit of the published values). Also allow an extra 10% margin. This also acts as
-    // a limit for the size of the published rates (e.g. upper-limit / lower-limit <= tolerance).
-    private static final double FRAMERATE_TOLERANCE = 2.0 * 1.1;
-
-    /*
-     *  ------------------ HELPER METHODS FOR ACHIEVABLE FRAME RATES ------------------
-     */
-
-    /** removes brackets from format to be included in JSON. */
-    private static String formatForReport(MediaFormat format) {
-        String asString = "" + format;
-        return asString.substring(1, asString.length() - 1);
-    }
-
-    /**
-     * Adds performance header info to |log| for |codecName|, |round|, |configFormat|, |inputFormat|
-     * and |outputFormat|. Also appends same to |message| and returns the resulting base message
-     * for logging purposes.
-     */
-    public static String addPerformanceHeadersToLog(
-            DeviceReportLog log, String message, int round, String codecName,
-            MediaFormat configFormat, MediaFormat inputFormat, MediaFormat outputFormat) {
-        String mime = configFormat.getString(MediaFormat.KEY_MIME);
-        int width = configFormat.getInteger(MediaFormat.KEY_WIDTH);
-        int height = configFormat.getInteger(MediaFormat.KEY_HEIGHT);
-
-        log.addValue("round", round, ResultType.NEUTRAL, ResultUnit.NONE);
-        log.addValue("codec_name", codecName, ResultType.NEUTRAL, ResultUnit.NONE);
-        log.addValue("mime_type", mime, ResultType.NEUTRAL, ResultUnit.NONE);
-        log.addValue("width", width, ResultType.NEUTRAL, ResultUnit.NONE);
-        log.addValue("height", height, ResultType.NEUTRAL, ResultUnit.NONE);
-        log.addValue("config_format", formatForReport(configFormat),
-                ResultType.NEUTRAL, ResultUnit.NONE);
-        log.addValue("input_format", formatForReport(inputFormat),
-                ResultType.NEUTRAL, ResultUnit.NONE);
-        log.addValue("output_format", formatForReport(outputFormat),
-                ResultType.NEUTRAL, ResultUnit.NONE);
-
-        message += " codec=" + codecName + " round=" + round + " configFormat=" + configFormat
-                + " inputFormat=" + inputFormat + " outputFormat=" + outputFormat;
-
-        Range<Double> reported =
-            MediaUtils.getVideoCapabilities(codecName, mime)
-                    .getAchievableFrameRatesFor(width, height);
-        if (reported != null) {
-            log.addValue("reported_low", reported.getLower(), ResultType.NEUTRAL, ResultUnit.FPS);
-            log.addValue("reported_high", reported.getUpper(), ResultType.NEUTRAL, ResultUnit.FPS);
-            message += " reported=" + reported.getLower() + "-" + reported.getUpper();
-        }
-
-        return message;
-    }
-
-    /**
-     * Adds performance statistics based on the raw |stats| to |log|. Also prints the same into
-     * logcat. Returns the "final fps" value.
-     */
-    public static double addPerformanceStatsToLog(
-            DeviceReportLog log, MediaUtils.Stats durationsUsStats, String message) {
-
-        MediaUtils.Stats frameAvgUsStats =
-            durationsUsStats.movingAverage(MOVING_AVERAGE_NUM_FRAMES);
-        log.addValue(
-                "window_frames", MOVING_AVERAGE_NUM_FRAMES, ResultType.NEUTRAL, ResultUnit.COUNT);
-        logPerformanceStats(log, frameAvgUsStats, "frame_avg_stats",
-                message + " window=" + MOVING_AVERAGE_NUM_FRAMES);
-
-        MediaUtils.Stats timeAvgUsStats =
-            durationsUsStats.movingAverageOverSum(MOVING_AVERAGE_WINDOW_MS * 1000);
-        log.addValue("window_time", MOVING_AVERAGE_WINDOW_MS, ResultType.NEUTRAL, ResultUnit.MS);
-        double fps = logPerformanceStats(log, timeAvgUsStats, "time_avg_stats",
-                message + " windowMs=" + MOVING_AVERAGE_WINDOW_MS);
-
-        log.setSummary("fps", fps, ResultType.HIGHER_BETTER, ResultUnit.FPS);
-        return fps;
-    }
-
-    /**
-     * Adds performance statistics based on the processed |stats| to |log| using |prefix|.
-     * Also prints the same into logcat using |message| as the base message. Returns the fps value
-     * for |stats|. |prefix| must be lowercase alphanumeric underscored format.
-     */
-    private static double logPerformanceStats(
-            DeviceReportLog log, MediaUtils.Stats statsUs, String prefix, String message) {
-        final String[] labels = {
-            "min", "p5", "p10", "p20", "p30", "p40", "p50", "p60", "p70", "p80", "p90", "p95", "max"
-        };
-        final double[] points = {
-             0,     5,    10,    20,    30,    40,    50,    60,    70,    80,    90,    95,    100
-        };
-
-        int num = statsUs.getNum();
-        long avg = Math.round(statsUs.getAverage());
-        long stdev = Math.round(statsUs.getStdev());
-        log.addValue(prefix + "_num", num, ResultType.NEUTRAL, ResultUnit.COUNT);
-        log.addValue(prefix + "_avg", avg / 1000., ResultType.LOWER_BETTER, ResultUnit.MS);
-        log.addValue(prefix + "_stdev", stdev / 1000., ResultType.LOWER_BETTER, ResultUnit.MS);
-        message += " num=" + num + " avg=" + avg + " stdev=" + stdev;
-        final double[] percentiles = statsUs.getPercentiles(points);
-        for (int i = 0; i < labels.length; ++i) {
-            long p = Math.round(percentiles[i]);
-            message += " " + labels[i] + "=" + p;
-            log.addValue(prefix + "_" + labels[i], p / 1000., ResultType.NEUTRAL, ResultUnit.MS);
-        }
-
-        // print result to logcat in case test aborts before logs are written
-        Log.i(TAG, message);
-
-        return 1e6 / percentiles[points.length - 2];
-    }
-
-    /** Verifies |measuredFps| against reported achievable rates. Returns null if at least
-     *  one measurement falls within the margins of the reported range. Otherwise, returns
-     *  an error message to display.*/
-    public static String verifyAchievableFrameRates(
-            String name, String mime, int w, int h, double... measuredFps) {
-        Range<Double> reported =
-            MediaUtils.getVideoCapabilities(name, mime).getAchievableFrameRatesFor(w, h);
-        String kind = "achievable frame rates for " + name + " " + mime + " " + w + "x" + h;
-        if (reported == null) {
-            return "Failed to get " + kind;
-        }
-        double lowerBoundary1 = reported.getLower() / FRAMERATE_TOLERANCE;
-        double upperBoundary1 = reported.getUpper() * FRAMERATE_TOLERANCE;
-        double lowerBoundary2 = reported.getUpper() / Math.pow(FRAMERATE_TOLERANCE, 2);
-        double upperBoundary2 = reported.getLower() * Math.pow(FRAMERATE_TOLERANCE, 2);
-        Log.d(TAG, name + " " + mime + " " + w + "x" + h +
-                " lowerBoundary1 " + lowerBoundary1 + " upperBoundary1 " + upperBoundary1 +
-                " lowerBoundary2 " + lowerBoundary2 + " upperBoundary2 " + upperBoundary2 +
-                " measured " + Arrays.toString(measuredFps));
-
-        for (double measured : measuredFps) {
-            if (measured >= lowerBoundary1 && measured <= upperBoundary1
-                    && measured >= lowerBoundary2 && measured <= upperBoundary2) {
-                return null;
-            }
-        }
-
-        return "Expected " + kind + ": " + reported + ".\n"
-                + "Measured frame rate: " + Arrays.toString(measuredFps) + ".\n";
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java
deleted file mode 100644
index 3ea6b63..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/MediaUtils.java
+++ /dev/null
@@ -1,1232 +0,0 @@
-/*
- * Copyright 2014 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.drm.DrmConvertedStatus;
-import android.drm.DrmManagerClient;
-import android.graphics.ImageFormat;
-import android.media.Image;
-import android.media.Image.Plane;
-import android.media.MediaCodec;
-import android.media.MediaCodec.BufferInfo;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.MediaCodecInfo.VideoCapabilities;
-import android.media.MediaCodecList;
-import android.media.MediaExtractor;
-import android.media.MediaFormat;
-import android.net.Uri;
-import android.util.Log;
-import android.util.Range;
-
-import com.android.compatibility.common.util.DeviceReportLog;
-import com.android.compatibility.common.util.ResultType;
-import com.android.compatibility.common.util.ResultUnit;
-
-import java.lang.reflect.Method;
-import java.nio.ByteBuffer;
-import java.security.MessageDigest;
-
-import static java.lang.reflect.Modifier.isPublic;
-import static java.lang.reflect.Modifier.isStatic;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import static junit.framework.Assert.assertTrue;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.RandomAccessFile;
-
-public class MediaUtils {
-    private static final String TAG = "MediaUtils";
-
-    /*
-     *  ----------------------- HELPER METHODS FOR SKIPPING TESTS -----------------------
-     */
-    private static final int ALL_AV_TRACKS = -1;
-
-    private static final MediaCodecList sMCL = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-
-    /**
-     * Returns the test name (heuristically).
-     *
-     * Since it uses heuristics, this method has only been verified for media
-     * tests. This centralizes the way to signal errors during a test.
-     */
-    public static String getTestName() {
-        return getTestName(false /* withClass */);
-    }
-
-    /**
-     * Returns the test name with the full class (heuristically).
-     *
-     * Since it uses heuristics, this method has only been verified for media
-     * tests. This centralizes the way to signal errors during a test.
-     */
-    public static String getTestNameWithClass() {
-        return getTestName(true /* withClass */);
-    }
-
-    private static String getTestName(boolean withClass) {
-        int bestScore = -1;
-        String testName = "test???";
-        Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
-        for (Map.Entry<Thread, StackTraceElement[]> entry : traces.entrySet()) {
-            StackTraceElement[] stack = entry.getValue();
-            for (int index = 0; index < stack.length; ++index) {
-                // method name must start with "test"
-                String methodName = stack[index].getMethodName();
-                if (!methodName.startsWith("test")) {
-                    continue;
-                }
-
-                int score = 0;
-                // see if there is a public non-static void method that takes no argument
-                Class<?> clazz;
-                try {
-                    clazz = Class.forName(stack[index].getClassName());
-                    ++score;
-                    for (final Method method : clazz.getDeclaredMethods()) {
-                        if (method.getName().equals(methodName)
-                                && isPublic(method.getModifiers())
-                                && !isStatic(method.getModifiers())
-                                && method.getParameterTypes().length == 0
-                                && method.getReturnType().equals(Void.TYPE)) {
-                            ++score;
-                            break;
-                        }
-                    }
-                    if (score == 1) {
-                        // if we could read the class, but method is not public void, it is
-                        // not a candidate
-                        continue;
-                    }
-                } catch (ClassNotFoundException e) {
-                }
-
-                // even if we cannot verify the method signature, there are signals in the stack
-
-                // usually test method is invoked by reflection
-                int depth = 1;
-                while (index + depth < stack.length
-                        && stack[index + depth].getMethodName().equals("invoke")
-                        && stack[index + depth].getClassName().equals(
-                                "java.lang.reflect.Method")) {
-                    ++depth;
-                }
-                if (depth > 1) {
-                    ++score;
-                    // and usually test method is run by runMethod method in android.test package
-                    if (index + depth < stack.length) {
-                        if (stack[index + depth].getClassName().startsWith("android.test.")) {
-                            ++score;
-                        }
-                        if (stack[index + depth].getMethodName().equals("runMethod")) {
-                            ++score;
-                        }
-                    }
-                }
-
-                if (score > bestScore) {
-                    bestScore = score;
-                    testName = methodName;
-                    if (withClass) {
-                        testName = stack[index].getClassName() + "." + testName;
-                    }
-                }
-            }
-        }
-        return testName;
-    }
-
-    /**
-     * Finds test name (heuristically) and prints out standard skip message.
-     *
-     * Since it uses heuristics, this method has only been verified for media
-     * tests. This centralizes the way to signal a skipped test.
-     */
-    public static void skipTest(String tag, String reason) {
-        Log.i(tag, "SKIPPING " + getTestName() + "(): " + reason);
-        DeviceReportLog log = new DeviceReportLog("CtsMediaSkippedTests", "test_skipped");
-        try {
-            log.addValue("reason", reason, ResultType.NEUTRAL, ResultUnit.NONE);
-            log.addValue(
-                    "test", getTestNameWithClass(), ResultType.NEUTRAL, ResultUnit.NONE);
-            log.submit();
-        } catch (NullPointerException e) { }
-    }
-
-    /**
-     * Finds test name (heuristically) and prints out standard skip message.
-     *
-     * Since it uses heuristics, this method has only been verified for media
-     * tests.  This centralizes the way to signal a skipped test.
-     */
-    public static void skipTest(String reason) {
-        skipTest(TAG, reason);
-    }
-
-    public static boolean check(boolean result, String message) {
-        if (!result) {
-            skipTest(message);
-        }
-        return result;
-    }
-
-    /*
-     *  ------------------- HELPER METHODS FOR CHECKING CODEC SUPPORT -------------------
-     */
-
-    public static boolean isGoogle(String codecName) {
-        codecName = codecName.toLowerCase();
-        return codecName.startsWith("omx.google.")
-                || codecName.startsWith("c2.android.")
-                || codecName.startsWith("c2.google.");
-    }
-
-    // returns the list of codecs that support any one of the formats
-    private static String[] getCodecNames(
-            boolean isEncoder, Boolean isGoog, MediaFormat... formats) {
-        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        ArrayList<String> result = new ArrayList<>();
-        for (MediaCodecInfo info : mcl.getCodecInfos()) {
-            if (info.isEncoder() != isEncoder) {
-                continue;
-            }
-            if (isGoog != null && isGoogle(info.getName()) != isGoog) {
-                continue;
-            }
-
-            for (MediaFormat format : formats) {
-                String mime = format.getString(MediaFormat.KEY_MIME);
-
-                CodecCapabilities caps = null;
-                try {
-                    caps = info.getCapabilitiesForType(mime);
-                } catch (IllegalArgumentException e) {  // mime is not supported
-                    continue;
-                }
-                if (caps.isFormatSupported(format)) {
-                    result.add(info.getName());
-                    break;
-                }
-            }
-        }
-        return result.toArray(new String[result.size()]);
-    }
-
-    /* Use isGoog = null to query all decoders */
-    public static String[] getDecoderNames(/* Nullable */ Boolean isGoog, MediaFormat... formats) {
-        return getCodecNames(false /* isEncoder */, isGoog, formats);
-    }
-
-    public static String[] getDecoderNames(MediaFormat... formats) {
-        return getCodecNames(false /* isEncoder */, null /* isGoog */, formats);
-    }
-
-    /* Use isGoog = null to query all decoders */
-    public static String[] getEncoderNames(/* Nullable */ Boolean isGoog, MediaFormat... formats) {
-        return getCodecNames(true /* isEncoder */, isGoog, formats);
-    }
-
-    public static String[] getEncoderNames(MediaFormat... formats) {
-        return getCodecNames(true /* isEncoder */, null /* isGoog */, formats);
-    }
-
-    public static String[] getDecoderNamesForMime(String mime) {
-        MediaFormat format = new MediaFormat();
-        format.setString(MediaFormat.KEY_MIME, mime);
-        return getCodecNames(false /* isEncoder */, null /* isGoog */, format);
-    }
-
-    public static String[] getEncoderNamesForMime(String mime) {
-        MediaFormat format = new MediaFormat();
-        format.setString(MediaFormat.KEY_MIME, mime);
-        return getCodecNames(true /* isEncoder */, null /* isGoog */, format);
-    }
-
-    public static void verifyNumCodecs(
-            int count, boolean isEncoder, Boolean isGoog, MediaFormat... formats) {
-        String desc = (isEncoder ? "encoders" : "decoders") + " for "
-                + (formats.length == 1 ? formats[0].toString() : Arrays.toString(formats));
-        if (isGoog != null) {
-            desc = (isGoog ? "Google " : "non-Google ") + desc;
-        }
-
-        String[] codecs = getCodecNames(isEncoder, isGoog, formats);
-        assertTrue("test can only verify " + count + " " + desc + "; found " + codecs.length + ": "
-                + Arrays.toString(codecs), codecs.length <= count);
-    }
-
-    public static MediaCodec getDecoder(MediaFormat format) {
-        String decoder = sMCL.findDecoderForFormat(format);
-        if (decoder != null) {
-            try {
-                return MediaCodec.createByCodecName(decoder);
-            } catch (IOException e) {
-            }
-        }
-        return null;
-    }
-
-    public static boolean canEncode(MediaFormat format) {
-        if (sMCL.findEncoderForFormat(format) == null) {
-            Log.i(TAG, "no encoder for " + format);
-            return false;
-        }
-        return true;
-    }
-
-    public static boolean canDecode(MediaFormat format) {
-        if (sMCL.findDecoderForFormat(format) == null) {
-            Log.i(TAG, "no decoder for " + format);
-            return false;
-        }
-        return true;
-    }
-
-    public static boolean supports(String codecName, String mime, int w, int h) {
-        // While this could be simply written as such, give more graceful feedback.
-        // MediaFormat format = MediaFormat.createVideoFormat(mime, w, h);
-        // return supports(codecName, format);
-
-        VideoCapabilities vidCap = getVideoCapabilities(codecName, mime);
-        if (vidCap == null) {
-            return false;
-        } else if (vidCap.isSizeSupported(w, h)) {
-            return true;
-        }
-
-        Log.w(TAG, "unsupported size " + w + "x" + h);
-        return false;
-    }
-
-    public static boolean supports(String codecName, MediaFormat format) {
-        MediaCodec codec;
-        try {
-            codec = MediaCodec.createByCodecName(codecName);
-        } catch (IOException e) {
-            Log.w(TAG, "codec not found: " + codecName);
-            return false;
-        }
-
-        String mime = format.getString(MediaFormat.KEY_MIME);
-        CodecCapabilities cap = null;
-        try {
-            cap = codec.getCodecInfo().getCapabilitiesForType(mime);
-            return cap.isFormatSupported(format);
-        } catch (IllegalArgumentException e) {
-            Log.w(TAG, "not supported mime: " + mime);
-            return false;
-        } finally {
-            codec.release();
-        }
-    }
-
-    public static boolean hasCodecForTrack(MediaExtractor ex, int track) {
-        int count = ex.getTrackCount();
-        if (track < 0 || track >= count) {
-            throw new IndexOutOfBoundsException(track + " not in [0.." + (count - 1) + "]");
-        }
-        return canDecode(ex.getTrackFormat(track));
-    }
-
-    /**
-     * return true iff all audio and video tracks are supported
-     */
-    public static boolean hasCodecsForMedia(MediaExtractor ex) {
-        for (int i = 0; i < ex.getTrackCount(); ++i) {
-            MediaFormat format = ex.getTrackFormat(i);
-            // only check for audio and video codecs
-            String mime = format.getString(MediaFormat.KEY_MIME).toLowerCase();
-            if (!mime.startsWith("audio/") && !mime.startsWith("video/")) {
-                continue;
-            }
-            if (!canDecode(format)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * return true iff any track starting with mimePrefix is supported
-     */
-    public static boolean hasCodecForMediaAndDomain(MediaExtractor ex, String mimePrefix) {
-        mimePrefix = mimePrefix.toLowerCase();
-        for (int i = 0; i < ex.getTrackCount(); ++i) {
-            MediaFormat format = ex.getTrackFormat(i);
-            String mime = format.getString(MediaFormat.KEY_MIME);
-            if (mime.toLowerCase().startsWith(mimePrefix)) {
-                if (canDecode(format)) {
-                    return true;
-                }
-                Log.i(TAG, "no decoder for " + format);
-            }
-        }
-        return false;
-    }
-
-    private static boolean hasCodecsForResourceCombo(
-            Context context, int resourceId, int track, String mimePrefix) {
-        try {
-            AssetFileDescriptor afd = null;
-            MediaExtractor ex = null;
-            try {
-                afd = context.getResources().openRawResourceFd(resourceId);
-                ex = new MediaExtractor();
-                ex.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
-                if (mimePrefix != null) {
-                    return hasCodecForMediaAndDomain(ex, mimePrefix);
-                } else if (track == ALL_AV_TRACKS) {
-                    return hasCodecsForMedia(ex);
-                } else {
-                    return hasCodecForTrack(ex, track);
-                }
-            } finally {
-                if (ex != null) {
-                    ex.release();
-                }
-                if (afd != null) {
-                    afd.close();
-                }
-            }
-        } catch (IOException e) {
-            Log.i(TAG, "could not open resource");
-        }
-        return false;
-    }
-
-    /**
-     * return true iff all audio and video tracks are supported
-     */
-    public static boolean hasCodecsForResource(Context context, int resourceId) {
-        return hasCodecsForResourceCombo(context, resourceId, ALL_AV_TRACKS, null /* mimePrefix */);
-    }
-
-    public static boolean checkCodecsForResource(Context context, int resourceId) {
-        return check(hasCodecsForResource(context, resourceId), "no decoder found");
-    }
-
-    /**
-     * return true iff track is supported.
-     */
-    public static boolean hasCodecForResource(Context context, int resourceId, int track) {
-        return hasCodecsForResourceCombo(context, resourceId, track, null /* mimePrefix */);
-    }
-
-    public static boolean checkCodecForResource(Context context, int resourceId, int track) {
-        return check(hasCodecForResource(context, resourceId, track), "no decoder found");
-    }
-
-    /**
-     * return true iff any track starting with mimePrefix is supported
-     */
-    public static boolean hasCodecForResourceAndDomain(
-            Context context, int resourceId, String mimePrefix) {
-        return hasCodecsForResourceCombo(context, resourceId, ALL_AV_TRACKS, mimePrefix);
-    }
-
-    /**
-     * return true iff all audio and video tracks are supported
-     */
-    public static boolean hasCodecsForPath(Context context, String path) {
-        MediaExtractor ex = null;
-        try {
-            ex = getExtractorForPath(context, path);
-            return hasCodecsForMedia(ex);
-        } catch (IOException e) {
-            Log.i(TAG, "could not open path " + path);
-        } finally {
-            if (ex != null) {
-                ex.release();
-            }
-        }
-        return true;
-    }
-
-    private static MediaExtractor getExtractorForPath(Context context, String path)
-            throws IOException {
-        Uri uri = Uri.parse(path);
-        String scheme = uri.getScheme();
-        MediaExtractor ex = new MediaExtractor();
-        try {
-            if (scheme == null) { // file
-                ex.setDataSource(path);
-            } else if (scheme.equalsIgnoreCase("file")) {
-                ex.setDataSource(uri.getPath());
-            } else {
-                ex.setDataSource(context, uri, null);
-            }
-        } catch (IOException e) {
-            ex.release();
-            throw e;
-        }
-        return ex;
-    }
-
-    public static boolean checkCodecsForPath(Context context, String path) {
-        return check(hasCodecsForPath(context, path), "no decoder found");
-    }
-
-    public static boolean hasCodecForDomain(boolean encoder, String domain) {
-        for (MediaCodecInfo info : sMCL.getCodecInfos()) {
-            if (encoder != info.isEncoder()) {
-                continue;
-            }
-
-            for (String type : info.getSupportedTypes()) {
-                if (type.toLowerCase().startsWith(domain.toLowerCase() + "/")) {
-                    Log.i(TAG, "found codec " + info.getName() + " for mime " + type);
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    public static boolean checkCodecForDomain(boolean encoder, String domain) {
-        return check(hasCodecForDomain(encoder, domain),
-                "no " + domain + (encoder ? " encoder" : " decoder") + " found");
-    }
-
-    private static boolean hasCodecForMime(boolean encoder, String mime) {
-        for (MediaCodecInfo info : sMCL.getCodecInfos()) {
-            if (encoder != info.isEncoder()) {
-                continue;
-            }
-
-            for (String type : info.getSupportedTypes()) {
-                if (type.equalsIgnoreCase(mime)) {
-                    Log.i(TAG, "found codec " + info.getName() + " for mime " + mime);
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private static boolean hasCodecForMimes(boolean encoder, String[] mimes) {
-        for (String mime : mimes) {
-            if (!hasCodecForMime(encoder, mime)) {
-                Log.i(TAG, "no " + (encoder ? "encoder" : "decoder") + " for mime " + mime);
-                return false;
-            }
-        }
-        return true;
-    }
-
-
-    public static boolean hasEncoder(String... mimes) {
-        return hasCodecForMimes(true /* encoder */, mimes);
-    }
-
-    public static boolean hasDecoder(String... mimes) {
-        return hasCodecForMimes(false /* encoder */, mimes);
-    }
-
-    public static boolean checkDecoder(String... mimes) {
-        return check(hasCodecForMimes(false /* encoder */, mimes), "no decoder found");
-    }
-
-    public static boolean checkEncoder(String... mimes) {
-        return check(hasCodecForMimes(true /* encoder */, mimes), "no encoder found");
-    }
-
-    public static boolean canDecodeVideo(String mime, int width, int height, float rate) {
-        MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
-        format.setFloat(MediaFormat.KEY_FRAME_RATE, rate);
-        return canDecode(format);
-    }
-
-    public static boolean canDecodeVideo(
-            String mime, int width, int height, float rate,
-            Integer profile, Integer level, Integer bitrate) {
-        MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
-        format.setFloat(MediaFormat.KEY_FRAME_RATE, rate);
-        if (profile != null) {
-            format.setInteger(MediaFormat.KEY_PROFILE, profile);
-            if (level != null) {
-                format.setInteger(MediaFormat.KEY_LEVEL, level);
-            }
-        }
-        if (bitrate != null) {
-            format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
-        }
-        return canDecode(format);
-    }
-
-    public static boolean checkEncoderForFormat(MediaFormat format) {
-        return check(canEncode(format), "no encoder for " + format);
-    }
-
-    public static boolean checkDecoderForFormat(MediaFormat format) {
-        return check(canDecode(format), "no decoder for " + format);
-    }
-
-    /*
-     *  ----------------------- HELPER METHODS FOR MEDIA HANDLING -----------------------
-     */
-
-    public static VideoCapabilities getVideoCapabilities(String codecName, String mime) {
-        for (MediaCodecInfo info : sMCL.getCodecInfos()) {
-            if (!info.getName().equalsIgnoreCase(codecName)) {
-                continue;
-            }
-            CodecCapabilities caps;
-            try {
-                caps = info.getCapabilitiesForType(mime);
-            } catch (IllegalArgumentException e) {
-                // mime is not supported
-                Log.w(TAG, "not supported mime: " + mime);
-                return null;
-            }
-            VideoCapabilities vidCaps = caps.getVideoCapabilities();
-            if (vidCaps == null) {
-                Log.w(TAG, "not a video codec: " + codecName);
-            }
-            return vidCaps;
-        }
-        Log.w(TAG, "codec not found: " + codecName);
-        return null;
-    }
-
-    public static MediaFormat getTrackFormatForResource(
-            Context context,
-            int resourceId,
-            String mimeTypePrefix) throws IOException {
-        MediaExtractor extractor = new MediaExtractor();
-        AssetFileDescriptor afd = context.getResources().openRawResourceFd(resourceId);
-        try {
-            extractor.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
-        } finally {
-            afd.close();
-        }
-        return getTrackFormatForExtractor(extractor, mimeTypePrefix);
-    }
-
-    public static MediaFormat getTrackFormatForPath(
-            Context context, String path, String mimeTypePrefix)
-            throws IOException {
-      MediaExtractor extractor = getExtractorForPath(context, path);
-      return getTrackFormatForExtractor(extractor, mimeTypePrefix);
-    }
-
-    private static MediaFormat getTrackFormatForExtractor(
-            MediaExtractor extractor,
-            String mimeTypePrefix) {
-      int trackIndex;
-      MediaFormat format = null;
-      for (trackIndex = 0; trackIndex < extractor.getTrackCount(); trackIndex++) {
-          MediaFormat trackMediaFormat = extractor.getTrackFormat(trackIndex);
-          if (trackMediaFormat.getString(MediaFormat.KEY_MIME).startsWith(mimeTypePrefix)) {
-              format = trackMediaFormat;
-              break;
-          }
-      }
-      extractor.release();
-      if (format == null) {
-          throw new RuntimeException("couldn't get a track for " + mimeTypePrefix);
-      }
-
-      return format;
-    }
-
-    public static MediaExtractor createMediaExtractorForMimeType(
-            Context context, int resourceId, String mimeTypePrefix)
-            throws IOException {
-        MediaExtractor extractor = new MediaExtractor();
-        AssetFileDescriptor afd = context.getResources().openRawResourceFd(resourceId);
-        try {
-            extractor.setDataSource(
-                    afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
-        } finally {
-            afd.close();
-        }
-        int trackIndex;
-        for (trackIndex = 0; trackIndex < extractor.getTrackCount(); trackIndex++) {
-            MediaFormat trackMediaFormat = extractor.getTrackFormat(trackIndex);
-            if (trackMediaFormat.getString(MediaFormat.KEY_MIME).startsWith(mimeTypePrefix)) {
-                extractor.selectTrack(trackIndex);
-                break;
-            }
-        }
-        if (trackIndex == extractor.getTrackCount()) {
-            extractor.release();
-            throw new IllegalStateException("couldn't get a track for " + mimeTypePrefix);
-        }
-
-        return extractor;
-    }
-
-    /*
-     *  ---------------------- HELPER METHODS FOR CODEC CONFIGURATION
-     */
-
-    /** Format must contain mime, width and height.
-     *  Throws Exception if encoder does not support this width and height */
-    public static void setMaxEncoderFrameAndBitrates(
-            MediaCodec encoder, MediaFormat format, int maxFps) {
-        String mime = format.getString(MediaFormat.KEY_MIME);
-
-        VideoCapabilities vidCaps =
-            encoder.getCodecInfo().getCapabilitiesForType(mime).getVideoCapabilities();
-        setMaxEncoderFrameAndBitrates(vidCaps, format, maxFps);
-    }
-
-    public static void setMaxEncoderFrameAndBitrates(
-            VideoCapabilities vidCaps, MediaFormat format, int maxFps) {
-        int width = format.getInteger(MediaFormat.KEY_WIDTH);
-        int height = format.getInteger(MediaFormat.KEY_HEIGHT);
-
-        int maxWidth = vidCaps.getSupportedWidths().getUpper();
-        int maxHeight = vidCaps.getSupportedHeightsFor(maxWidth).getUpper();
-        int frameRate = Math.min(
-                maxFps, vidCaps.getSupportedFrameRatesFor(width, height).getUpper().intValue());
-        format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
-
-        int bitrate = vidCaps.getBitrateRange().clamp(
-            (int)(vidCaps.getBitrateRange().getUpper() /
-                  Math.sqrt((double)maxWidth * maxHeight / width / height)));
-        format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
-    }
-
-    /*
-     *  ------------------ HELPER METHODS FOR STATISTICS AND REPORTING ------------------
-     */
-
-    // TODO: migrate this into com.android.compatibility.common.util.Stat
-    public static class Stats {
-        /** does not support NaN or Inf in |data| */
-        public Stats(double[] data) {
-            mData = data;
-            if (mData != null) {
-                mNum = mData.length;
-            }
-        }
-
-        public int getNum() {
-            return mNum;
-        }
-
-        /** calculate mSumX and mSumXX */
-        private void analyze() {
-            if (mAnalyzed) {
-                return;
-            }
-
-            if (mData != null) {
-                for (double x : mData) {
-                    if (!(x >= mMinX)) { // mMinX may be NaN
-                        mMinX = x;
-                    }
-                    if (!(x <= mMaxX)) { // mMaxX may be NaN
-                        mMaxX = x;
-                    }
-                    mSumX += x;
-                    mSumXX += x * x;
-                }
-            }
-            mAnalyzed = true;
-        }
-
-        /** returns the maximum or NaN if it does not exist */
-        public double getMin() {
-            analyze();
-            return mMinX;
-        }
-
-        /** returns the minimum or NaN if it does not exist */
-        public double getMax() {
-            analyze();
-            return mMaxX;
-        }
-
-        /** returns the average or NaN if it does not exist. */
-        public double getAverage() {
-            analyze();
-            if (mNum == 0) {
-                return Double.NaN;
-            } else {
-                return mSumX / mNum;
-            }
-        }
-
-        /** returns the standard deviation or NaN if it does not exist. */
-        public double getStdev() {
-            analyze();
-            if (mNum == 0) {
-                return Double.NaN;
-            } else {
-                double average = mSumX / mNum;
-                return Math.sqrt(mSumXX / mNum - average * average);
-            }
-        }
-
-        /** returns the statistics for the moving average over n values */
-        public Stats movingAverage(int n) {
-            if (n < 1 || mNum < n) {
-                return new Stats(null);
-            } else if (n == 1) {
-                return this;
-            }
-
-            double[] avgs = new double[mNum - n + 1];
-            double sum = 0;
-            for (int i = 0; i < mNum; ++i) {
-                sum += mData[i];
-                if (i >= n - 1) {
-                    avgs[i - n + 1] = sum / n;
-                    sum -= mData[i - n + 1];
-                }
-            }
-            return new Stats(avgs);
-        }
-
-        /** returns the statistics for the moving average over a window over the
-         *  cumulative sum. Basically, moves a window from: [0, window] to
-         *  [sum - window, sum] over the cumulative sum, over ((sum - window) / average)
-         *  steps, and returns the average value over each window.
-         *  This method is used to average time-diff data over a window of a constant time.
-         */
-        public Stats movingAverageOverSum(double window) {
-            if (window <= 0 || mNum < 1) {
-                return new Stats(null);
-            }
-
-            analyze();
-            double average = mSumX / mNum;
-            if (window >= mSumX) {
-                return new Stats(new double[] { average });
-            }
-            int samples = (int)Math.ceil((mSumX - window) / average);
-            double[] avgs = new double[samples];
-
-            // A somewhat brute force approach to calculating the moving average.
-            // TODO: add support for weights in Stats, so we can do a more refined approach.
-            double sum = 0; // sum of elements in the window
-            int num = 0; // number of elements in the moving window
-            int bi = 0; // index of the first element in the moving window
-            int ei = 0; // index of the last element in the moving window
-            double space = window; // space at the end of the window
-            double foot = 0; // space at the beginning of the window
-
-            // invariants: foot + sum + space == window
-            //             bi + num == ei
-            //
-            //  window:             |-------------------------------|
-            //                      |    <-----sum------>           |
-            //                      <foot>               <---space-->
-            //                           |               |
-            //  intervals:   |-----------|-------|-------|--------------------|--------|
-            //                           ^bi             ^ei
-
-            int ix = 0; // index in the result
-            while (ix < samples) {
-                // add intervals while there is space in the window
-                while (ei < mData.length && mData[ei] <= space) {
-                    space -= mData[ei];
-                    sum += mData[ei];
-                    num++;
-                    ei++;
-                }
-
-                // calculate average over window and deal with odds and ends (e.g. if there are no
-                // intervals in the current window: pick whichever element overlaps the window
-                // most.
-                if (num > 0) {
-                    avgs[ix++] = sum / num;
-                } else if (bi > 0 && foot > space) {
-                    // consider previous
-                    avgs[ix++] = mData[bi - 1];
-                } else if (ei == mData.length) {
-                    break;
-                } else {
-                    avgs[ix++] = mData[ei];
-                }
-
-                // move the window to the next position
-                foot -= average;
-                space += average;
-
-                // remove intervals that are now partially or wholly outside of the window
-                while (bi < ei && foot < 0) {
-                    foot += mData[bi];
-                    sum -= mData[bi];
-                    num--;
-                    bi++;
-                }
-            }
-            return new Stats(Arrays.copyOf(avgs, ix));
-        }
-
-        /** calculate mSortedData */
-        private void sort() {
-            if (mSorted || mNum == 0) {
-                return;
-            }
-            mSortedData = Arrays.copyOf(mData, mNum);
-            Arrays.sort(mSortedData);
-            mSorted = true;
-        }
-
-        /** returns an array of percentiles for the points using nearest rank */
-        public double[] getPercentiles(double... points) {
-            sort();
-            double[] res = new double[points.length];
-            for (int i = 0; i < points.length; ++i) {
-                if (mNum < 1 || points[i] < 0 || points[i] > 100) {
-                    res[i] = Double.NaN;
-                } else {
-                    res[i] = mSortedData[(int)Math.round(points[i] / 100 * (mNum - 1))];
-                }
-            }
-            return res;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (o instanceof Stats) {
-                Stats other = (Stats)o;
-                if (other.mNum != mNum) {
-                    return false;
-                } else if (mNum == 0) {
-                    return true;
-                }
-                return Arrays.equals(mData, other.mData);
-            }
-            return false;
-        }
-
-        private double[] mData;
-        private double mSumX = 0;
-        private double mSumXX = 0;
-        private double mMinX = Double.NaN;
-        private double mMaxX = Double.NaN;
-        private int mNum = 0;
-        private boolean mAnalyzed = false;
-        private double[] mSortedData;
-        private boolean mSorted = false;
-    }
-
-    /**
-     * Convert a forward lock .dm message stream to a .fl file
-     * @param context Context to use
-     * @param dmStream The .dm message
-     * @param flFile The output file to be written
-     * @return success
-     */
-    public static boolean convertDmToFl(
-            Context context,
-            InputStream dmStream,
-            RandomAccessFile flFile) {
-        final String MIMETYPE_DRM_MESSAGE = "application/vnd.oma.drm.message";
-        byte[] dmData = new byte[10000];
-        int totalRead = 0;
-        int numRead;
-        while (true) {
-            try {
-                numRead = dmStream.read(dmData, totalRead, dmData.length - totalRead);
-            } catch (IOException e) {
-                Log.w(TAG, "Failed to read from input file");
-                return false;
-            }
-            if (numRead == -1) {
-                break;
-            }
-            totalRead += numRead;
-            if (totalRead == dmData.length) {
-                // grow array
-                dmData = Arrays.copyOf(dmData, dmData.length + 10000);
-            }
-        }
-        byte[] fileData = Arrays.copyOf(dmData, totalRead);
-
-        DrmManagerClient drmClient = null;
-        try {
-            drmClient = new DrmManagerClient(context);
-        } catch (IllegalArgumentException e) {
-            Log.w(TAG, "DrmManagerClient instance could not be created, context is Illegal.");
-            return false;
-        } catch (IllegalStateException e) {
-            Log.w(TAG, "DrmManagerClient didn't initialize properly.");
-            return false;
-        }
-
-        try {
-            int convertSessionId = -1;
-            try {
-                convertSessionId = drmClient.openConvertSession(MIMETYPE_DRM_MESSAGE);
-            } catch (IllegalArgumentException e) {
-                Log.w(TAG, "Conversion of Mimetype: " + MIMETYPE_DRM_MESSAGE
-                        + " is not supported.", e);
-                return false;
-            } catch (IllegalStateException e) {
-                Log.w(TAG, "Could not access Open DrmFramework.", e);
-                return false;
-            }
-
-            if (convertSessionId < 0) {
-                Log.w(TAG, "Failed to open session.");
-                return false;
-            }
-
-            DrmConvertedStatus convertedStatus = null;
-            try {
-                convertedStatus = drmClient.convertData(convertSessionId, fileData);
-            } catch (IllegalArgumentException e) {
-                Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: "
-                        + convertSessionId, e);
-                return false;
-            } catch (IllegalStateException e) {
-                Log.w(TAG, "Could not convert data. Convertsession: " + convertSessionId, e);
-                return false;
-            }
-
-            if (convertedStatus == null ||
-                    convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK ||
-                    convertedStatus.convertedData == null) {
-                Log.w(TAG, "Error in converting data. Convertsession: " + convertSessionId);
-                try {
-                    DrmConvertedStatus result = drmClient.closeConvertSession(convertSessionId);
-                    if (result.statusCode != DrmConvertedStatus.STATUS_OK) {
-                        Log.w(TAG, "Conversion failed with status: " + result.statusCode);
-                        return false;
-                    }
-                } catch (IllegalStateException e) {
-                    Log.w(TAG, "Could not close session. Convertsession: " +
-                           convertSessionId, e);
-                }
-                return false;
-            }
-
-            try {
-                flFile.write(convertedStatus.convertedData, 0, convertedStatus.convertedData.length);
-            } catch (IOException e) {
-                Log.w(TAG, "Failed to write to output file: " + e);
-                return false;
-            }
-
-            try {
-                convertedStatus = drmClient.closeConvertSession(convertSessionId);
-            } catch (IllegalStateException e) {
-                Log.w(TAG, "Could not close convertsession. Convertsession: " +
-                        convertSessionId, e);
-                return false;
-            }
-
-            if (convertedStatus == null ||
-                    convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK ||
-                    convertedStatus.convertedData == null) {
-                Log.w(TAG, "Error in closing session. Convertsession: " + convertSessionId);
-                return false;
-            }
-
-            try {
-                flFile.seek(convertedStatus.offset);
-                flFile.write(convertedStatus.convertedData);
-            } catch (IOException e) {
-                Log.w(TAG, "Could not update file.", e);
-                return false;
-            }
-
-            return true;
-        } finally {
-            drmClient.close();
-        }
-    }
-
-    /**
-     * @param decoder new MediaCodec object
-     * @param ex MediaExtractor after setDataSource and selectTrack
-     * @param frameMD5Sums reference MD5 checksum for decoded frames
-     * @return true if decoded frames checksums matches reference checksums
-     * @throws IOException
-     */
-    public static boolean verifyDecoder(
-            MediaCodec decoder, MediaExtractor ex, List<String> frameMD5Sums)
-            throws IOException {
-
-        int trackIndex = ex.getSampleTrackIndex();
-        MediaFormat format = ex.getTrackFormat(trackIndex);
-        decoder.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
-        decoder.start();
-
-        boolean sawInputEOS = false;
-        boolean sawOutputEOS = false;
-        final long kTimeOutUs = 5000; // 5ms timeout
-        int decodedFrameCount = 0;
-        int expectedFrameCount = frameMD5Sums.size();
-        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
-
-        while (!sawOutputEOS) {
-            // handle input
-            if (!sawInputEOS) {
-                int inIdx = decoder.dequeueInputBuffer(kTimeOutUs);
-                if (inIdx >= 0) {
-                    ByteBuffer buffer = decoder.getInputBuffer(inIdx);
-                    int sampleSize = ex.readSampleData(buffer, 0);
-                    if (sampleSize < 0) {
-                        final int flagEOS = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
-                        decoder.queueInputBuffer(inIdx, 0, 0, 0, flagEOS);
-                        sawInputEOS = true;
-                    } else {
-                        decoder.queueInputBuffer(inIdx, 0, sampleSize, ex.getSampleTime(), 0);
-                        ex.advance();
-                    }
-                }
-            }
-
-            // handle output
-            int outputBufIndex = decoder.dequeueOutputBuffer(info, kTimeOutUs);
-            if (outputBufIndex >= 0) {
-                try {
-                    if (info.size > 0) {
-                        // Disregard 0-sized buffers at the end.
-                        String md5CheckSum = "";
-                        Image image = decoder.getOutputImage(outputBufIndex);
-                        md5CheckSum = getImageMD5Checksum(image);
-
-                        if (!md5CheckSum.equals(frameMD5Sums.get(decodedFrameCount))) {
-                            Log.d(TAG,
-                                    String.format(
-                                            "Frame %d md5sum mismatch: %s(actual) vs %s(expected)",
-                                            decodedFrameCount, md5CheckSum,
-                                            frameMD5Sums.get(decodedFrameCount)));
-                            return false;
-                        }
-
-                        decodedFrameCount++;
-                    }
-                } catch (Exception e) {
-                    Log.e(TAG, "getOutputImage md5CheckSum failed", e);
-                    return false;
-                } finally {
-                    decoder.releaseOutputBuffer(outputBufIndex, false /* render */);
-                }
-                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
-                    sawOutputEOS = true;
-                }
-            } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
-                MediaFormat decOutputFormat = decoder.getOutputFormat();
-                Log.d(TAG, "output format " + decOutputFormat);
-            } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
-                Log.i(TAG, "Skip handling MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED");
-            } else if (outputBufIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
-                continue;
-            } else {
-                Log.w(TAG, "decoder.dequeueOutputBuffer() unrecognized index: " + outputBufIndex);
-                return false;
-            }
-        }
-
-        if (decodedFrameCount != expectedFrameCount) {
-            return false;
-        }
-
-        return true;
-    }
-
-    public static String getImageMD5Checksum(Image image) throws Exception {
-        int format = image.getFormat();
-        if (ImageFormat.YUV_420_888 != format) {
-            Log.w(TAG, "unsupported image format");
-            return "";
-        }
-
-        MessageDigest md = MessageDigest.getInstance("MD5");
-
-        int imageWidth = image.getWidth();
-        int imageHeight = image.getHeight();
-
-        Image.Plane[] planes = image.getPlanes();
-        for (int i = 0; i < planes.length; ++i) {
-            ByteBuffer buf = planes[i].getBuffer();
-
-            int width, height, rowStride, pixelStride, x, y;
-            rowStride = planes[i].getRowStride();
-            pixelStride = planes[i].getPixelStride();
-            if (i == 0) {
-                width = imageWidth;
-                height = imageHeight;
-            } else {
-                width = imageWidth / 2;
-                height = imageHeight /2;
-            }
-            // local contiguous pixel buffer
-            byte[] bb = new byte[width * height];
-            if (buf.hasArray()) {
-                byte b[] = buf.array();
-                int offs = buf.arrayOffset();
-                if (pixelStride == 1) {
-                    for (y = 0; y < height; ++y) {
-                        System.arraycopy(bb, y * width, b, y * rowStride + offs, width);
-                    }
-                } else {
-                    // do it pixel-by-pixel
-                    for (y = 0; y < height; ++y) {
-                        int lineOffset = offs + y * rowStride;
-                        for (x = 0; x < width; ++x) {
-                            bb[y * width + x] = b[lineOffset + x * pixelStride];
-                        }
-                    }
-                }
-            } else { // almost always ends up here due to direct buffers
-                int pos = buf.position();
-                if (pixelStride == 1) {
-                    for (y = 0; y < height; ++y) {
-                        buf.position(pos + y * rowStride);
-                        buf.get(bb, y * width, width);
-                    }
-                } else {
-                    // local line buffer
-                    byte[] lb = new byte[rowStride];
-                    // do it pixel-by-pixel
-                    for (y = 0; y < height; ++y) {
-                        buf.position(pos + y * rowStride);
-                        // we're only guaranteed to have pixelStride * (width - 1) + 1 bytes
-                        buf.get(lb, 0, pixelStride * (width - 1) + 1);
-                        for (x = 0; x < width; ++x) {
-                            bb[y * width + x] = lb[x * pixelStride];
-                        }
-                    }
-                }
-                buf.position(pos);
-            }
-            md.update(bb, 0, width * height);
-        }
-
-        return convertByteArrayToHEXString(md.digest());
-    }
-
-    private static String convertByteArrayToHEXString(byte[] ba) throws Exception {
-        StringBuilder result = new StringBuilder();
-        for (int i = 0; i < ba.length; i++) {
-            result.append(Integer.toString((ba[i] & 0xff) + 0x100, 16).substring(1));
-        }
-        return result.toString();
-    }
-
-
-    /*
-     *  -------------------------------------- END --------------------------------------
-     */
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/MoreMatchers.java b/common/device-side/util/src/com/android/compatibility/common/util/MoreMatchers.java
deleted file mode 100644
index cee610e..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/MoreMatchers.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import org.mockito.ArgumentMatchers;
-
-public class MoreMatchers {
-    private MoreMatchers() {
-    }
-
-    public static <T> T anyOrNull(Class<T> clazz) {
-        return ArgumentMatchers.argThat(value -> true);
-    }
-
-    public static String anyStringOrNull() {
-        return ArgumentMatchers.argThat(value -> true);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/NullWebViewUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/NullWebViewUtils.java
deleted file mode 100644
index 3153adb..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/NullWebViewUtils.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2010 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-
-/**
- * Utilities to enable the android.webkit.* CTS tests (and others that rely on a functioning
- * android.webkit.WebView implementation) to determine whether a functioning WebView is present
- * on the device or not.
- *
- * Test cases that require android.webkit.* classes should wrap their first usage of WebView in a
- * try catch block, and pass any exception that is thrown to
- * NullWebViewUtils.determineIfWebViewAvailable. The return value of
- * NullWebViewUtils.isWebViewAvailable will then determine if the test should expect to be able to
- * use a WebView.
- */
-public class NullWebViewUtils {
-
-    private static boolean sWebViewUnavailable;
-
-    /**
-     * @param context Current Activity context, used to query the PackageManager.
-     * @param t       An exception thrown by trying to invoke android.webkit.* APIs.
-     */
-    public static void determineIfWebViewAvailable(Context context, Throwable t) {
-        sWebViewUnavailable = !hasWebViewFeature(context) && checkCauseWasUnsupportedOperation(t);
-    }
-
-    /**
-     * After calling determineIfWebViewAvailable, this returns whether a WebView is available on the
-     * device and wheter the test can rely on it.
-     * @return True iff. PackageManager determined that there is no WebView on the device and the
-     *         exception thrown from android.webkit.* was UnsupportedOperationException.
-     */
-    public static boolean isWebViewAvailable() {
-        return !sWebViewUnavailable;
-    }
-
-    private static boolean hasWebViewFeature(Context context) {
-        // Query the system property that determins if there is a functional WebView on the device.
-        PackageManager pm = context.getPackageManager();
-        return pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW);
-    }
-
-    private static boolean checkCauseWasUnsupportedOperation(Throwable t) {
-        if (t == null) return false;
-        while (t.getCause() != null) {
-            t = t.getCause();
-        }
-        return t instanceof UnsupportedOperationException;
-    }
-
-    /**
-     * Some CTS tests (by design) first use android.webkit.* from a background thread. This helper
-     * allows the test to catch the UnsupportedOperationException from that background thread, and
-     * then query the result from the test main thread.
-     */
-    public static class NullWebViewFromThreadExceptionHandler
-            implements Thread.UncaughtExceptionHandler {
-        private Throwable mPendingException;
-
-        @Override
-        public void uncaughtException(Thread t, Throwable e) {
-            mPendingException = e;
-        }
-
-        public boolean isWebViewAvailable(Context context) {
-            return hasWebViewFeature(context) ||
-                    !checkCauseWasUnsupportedOperation(mPendingException);
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/OnFailureRule.java b/common/device-side/util/src/com/android/compatibility/common/util/OnFailureRule.java
deleted file mode 100644
index 585c145..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/OnFailureRule.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import android.util.Log;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-/**
- * Custom JUnit4 rule that provides a callback upon test failures.
- */
-public abstract class OnFailureRule implements TestRule {
-    private String mLogTag = "OnFailureRule";
-
-    public OnFailureRule() {
-    }
-
-    public OnFailureRule(String logTag) {
-        mLogTag = logTag;
-    }
-
-    @Override
-    public Statement apply(Statement base, Description description) {
-        return new Statement() {
-
-            @Override
-            public void evaluate() throws Throwable {
-                try {
-                    base.evaluate();
-                } catch (Throwable t) {
-                    Log.e(mLogTag, "Test failed: description=" +  description + "\nThrowable=" + t);
-                    onTestFailure(base, description, t);
-                    throw t;
-                }
-            }
-        };
-    }
-
-    protected abstract void onTestFailure(Statement base, Description description, Throwable t);
-}
\ No newline at end of file
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/OneTimeDeviceConfigListener.java b/common/device-side/util/src/com/android/compatibility/common/util/OneTimeDeviceConfigListener.java
deleted file mode 100644
index e5be3f41..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/OneTimeDeviceConfigListener.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.compatibility.common.util;
-
-import android.os.SystemClock;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.OnPropertiesChangedListener;
-import android.provider.DeviceConfig.Properties;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.google.common.base.Preconditions;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Helper used to block tests until a device config value has been updated.
- */
-public final class OneTimeDeviceConfigListener implements OnPropertiesChangedListener {
-
-    public static final long DEFAULT_TIMEOUT_MS = 5_000;
-
-    private static final String TAG = OneTimeDeviceConfigListener.class.getSimpleName();
-
-    private final String mNamespace;
-    private final String mKey;
-    private final long mTimeoutMs;
-    private final long mStarted = SystemClock.elapsedRealtime();
-
-    private final CountDownLatch mLatch = new CountDownLatch(1);
-
-    public OneTimeDeviceConfigListener(@NonNull String namespace, @NonNull String key) {
-        this(namespace, key, DEFAULT_TIMEOUT_MS);
-    }
-
-    public OneTimeDeviceConfigListener(@NonNull String namespace, @NonNull String key,
-            long timeoutMs) {
-        mNamespace = Preconditions.checkNotNull(namespace);
-        mKey = Preconditions.checkNotNull(key);
-        mTimeoutMs = timeoutMs;
-    }
-
-    @Override
-    public void onPropertiesChanged(@NonNull Properties properties) {
-        if (!properties.getNamespace().equals(mNamespace)
-                || !properties.getKeyset().contains(mKey)) {
-            Log.d(TAG, "ignoring callback for namespace: " + properties.getNamespace());
-            return;
-        }
-        mLatch.countDown();
-        DeviceConfig.removeOnPropertiesChangedListener(this);
-    }
-
-    /**
-     * Blocks for a few seconds until it's called.
-     *
-     * @throws IllegalStateException if it's not called.
-     */
-    public void assertCalled() {
-        try {
-            final boolean updated = mLatch.await(mTimeoutMs, TimeUnit.MILLISECONDS);
-            if (!updated) {
-                throw new RetryableException(
-                        "Settings " + mKey + " not called in " + mTimeoutMs + "ms");
-            }
-            final long delta = SystemClock.elapsedRealtime() - mStarted;
-            Log.v(TAG, TestNameUtils.getCurrentTestName() + "/" + mKey + ": " + delta + "ms");
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new IllegalStateException("Interrupted", e);
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/OneTimeSettingsListener.java b/common/device-side/util/src/com/android/compatibility/common/util/OneTimeSettingsListener.java
deleted file mode 100644
index 79c80c9..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/OneTimeSettingsListener.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static com.android.compatibility.common.util.SettingsUtils.NAMESPACE_GLOBAL;
-import static com.android.compatibility.common.util.SettingsUtils.NAMESPACE_SECURE;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.Log;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Helper used to block tests until a secure settings value has been updated.
- */
-public final class OneTimeSettingsListener extends ContentObserver {
-
-    private static final String TAG = "OneTimeSettingsListener";
-    public static final long DEFAULT_TIMEOUT_MS = 30_000;
-
-    private final CountDownLatch mLatch = new CountDownLatch(1);
-    private final ContentResolver mResolver;
-    private final String mKey;
-    private final long mStarted;
-
-    public OneTimeSettingsListener(Context context, String namespace, String key) {
-        super(new Handler(Looper.getMainLooper()));
-        mStarted = SystemClock.elapsedRealtime();
-        mKey = key;
-        mResolver = context.getContentResolver();
-        final Uri uri;
-        switch (namespace) {
-            case NAMESPACE_SECURE:
-                uri = Settings.Secure.getUriFor(key);
-                break;
-            case NAMESPACE_GLOBAL:
-                uri = Settings.Global.getUriFor(key);
-                break;
-            default:
-                throw new IllegalArgumentException("invalid namespace: " + namespace);
-        }
-        mResolver.registerContentObserver(uri, false, this);
-    }
-
-    @Override
-    public void onChange(boolean selfChange, Uri uri) {
-        mResolver.unregisterContentObserver(this);
-        mLatch.countDown();
-    }
-
-    /**
-     * Blocks for a few seconds until it's called.
-     *
-     * @throws IllegalStateException if it's not called.
-     */
-    public void assertCalled() {
-        try {
-            final boolean updated = mLatch.await(DEFAULT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-            if (!updated) {
-                throw new RetryableException(
-                        "Settings " + mKey + " not called in " + DEFAULT_TIMEOUT_MS + "ms");
-            }
-            final long delta = SystemClock.elapsedRealtime() - mStarted;
-            // TODO: usually it's notified in ~50-150ms, but for some reason it takes ~10s
-            // on some ViewAttributesTest methods, hence the 30s limit
-            Log.v(TAG, TestNameUtils.getCurrentTestName() + "/" + mKey + ": " + delta + "ms");
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new IllegalStateException("Interrupted", e);
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/PackageUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/PackageUtil.java
deleted file mode 100644
index e7b6976..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/PackageUtil.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.support.test.InstrumentationRegistry;
-import android.util.Log;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * Device-side utility class for PackageManager-related operations
- */
-public class PackageUtil {
-
-    private static final String TAG = PackageUtil.class.getSimpleName();
-
-    private static final int SYSTEM_APP_MASK =
-            ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
-    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
-
-    /** Returns true if a package with the given name exists on the device */
-    public static boolean exists(String packageName) {
-        try {
-            return (getPackageManager().getApplicationInfo(packageName,
-                    PackageManager.GET_META_DATA) != null);
-        } catch(PackageManager.NameNotFoundException e) {
-            return false;
-        }
-    }
-
-    /** Returns true if a package with the given name AND SHA digest exists on the device */
-    public static boolean exists(String packageName, String sha) {
-        try {
-            if (getPackageManager().getApplicationInfo(
-                    packageName, PackageManager.GET_META_DATA) == null) {
-                return false;
-            }
-            return sha.equals(computePackageSignatureDigest(packageName));
-        } catch (NoSuchAlgorithmException | PackageManager.NameNotFoundException e) {
-            return false;
-        }
-    }
-
-    /** Returns true if the app for the given package name is a system app for this device */
-    public static boolean isSystemApp(String packageName) {
-        try {
-            ApplicationInfo ai = getPackageManager().getApplicationInfo(packageName,
-                    PackageManager.GET_META_DATA);
-            return ai != null && ((ai.flags & SYSTEM_APP_MASK) != 0);
-        } catch(PackageManager.NameNotFoundException e) {
-            return false;
-        }
-    }
-
-    /** Returns the version string of the package name, or null if the package can't be found */
-    public static String getVersionString(String packageName) {
-        try {
-            PackageInfo info = getPackageManager().getPackageInfo(packageName,
-                    PackageManager.GET_META_DATA);
-            return info.versionName;
-        } catch (PackageManager.NameNotFoundException | NullPointerException e) {
-            Log.w(TAG, "Could not find version string for package " + packageName);
-            return null;
-        }
-    }
-
-    /**
-     * Compute the signature SHA digest for a package.
-     * @param package the name of the package for which the signature SHA digest is requested
-     * @return the signature SHA digest
-     */
-    public static String computePackageSignatureDigest(String packageName)
-            throws NoSuchAlgorithmException, PackageManager.NameNotFoundException {
-        PackageInfo packageInfo = getPackageManager()
-                .getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
-        MessageDigest messageDigest = MessageDigest.getInstance("SHA256");
-        messageDigest.update(packageInfo.signatures[0].toByteArray());
-
-        final byte[] digest = messageDigest.digest();
-        final int digestLength = digest.length;
-        final int charCount = 3 * digestLength - 1;
-
-        final char[] chars = new char[charCount];
-        for (int i = 0; i < digestLength; i++) {
-            final int byteHex = digest[i] & 0xFF;
-            chars[i * 3] = HEX_ARRAY[byteHex >>> 4];
-            chars[i * 3 + 1] = HEX_ARRAY[byteHex & 0x0F];
-            if (i < digestLength - 1) {
-                chars[i * 3 + 2] = ':';
-            }
-        }
-        return new String(chars);
-    }
-
-    private static PackageManager getPackageManager() {
-        return InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager();
-    }
-
-    private static boolean hasDeviceFeature(final String requiredFeature) {
-        return InstrumentationRegistry.getContext()
-                .getPackageManager()
-                .hasSystemFeature(requiredFeature);
-    }
-
-    /**
-     * Rotation support is indicated by explicitly having both landscape and portrait
-     * features or not listing either at all.
-     */
-    public static boolean supportsRotation() {
-        final boolean supportsLandscape = hasDeviceFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE);
-        final boolean supportsPortrait = hasDeviceFeature(PackageManager.FEATURE_SCREEN_PORTRAIT);
-        return (supportsLandscape && supportsPortrait)
-                || (!supportsLandscape && !supportsPortrait);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ParcelUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ParcelUtils.java
deleted file mode 100644
index ecaa722..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ParcelUtils.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import static org.junit.Assert.assertNotNull;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class ParcelUtils {
-    private ParcelUtils() {
-    }
-
-    /** Convert a Parcelable into a byte[]. */
-    public static byte[] toBytes(Parcelable p) {
-        assertNotNull(p);
-
-        final Parcel parcel = Parcel.obtain();
-        parcel.writeParcelable(p, 0);
-        byte[] data = parcel.marshall();
-        parcel.recycle();
-
-        return data;
-    }
-
-    /** Decode a byte[] into a Parcelable. */
-    public static <T extends Parcelable> T fromBytes(byte[] data) {
-        assertNotNull(data);
-
-        final Parcel parcel = Parcel.obtain();
-        parcel.unmarshall(data, 0, data.length);
-        parcel.setDataPosition(0);
-        T ret = parcel.readParcelable(ParcelUtils.class.getClassLoader());
-        parcel.recycle();
-
-        return ret;
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/PollingCheck.java b/common/device-side/util/src/com/android/compatibility/common/util/PollingCheck.java
deleted file mode 100644
index bcc3530..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/PollingCheck.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.compatibility.common.util;
-
-import java.util.concurrent.Callable;
-
-import junit.framework.Assert;
-
-public abstract class PollingCheck {
-    private static final long TIME_SLICE = 50;
-    private long mTimeout = 3000;
-
-    public static interface PollingCheckCondition {
-        boolean canProceed();
-    }
-
-    public PollingCheck() {
-    }
-
-    public PollingCheck(long timeout) {
-        mTimeout = timeout;
-    }
-
-    protected abstract boolean check();
-
-    public void run() {
-        if (check()) {
-            return;
-        }
-
-        long timeout = mTimeout;
-        while (timeout > 0) {
-            try {
-                Thread.sleep(TIME_SLICE);
-            } catch (InterruptedException e) {
-                Assert.fail("unexpected InterruptedException");
-            }
-
-            if (check()) {
-                return;
-            }
-
-            timeout -= TIME_SLICE;
-        }
-
-        Assert.fail("unexpected timeout");
-    }
-
-    public static void check(CharSequence message, long timeout, Callable<Boolean> condition)
-            throws Exception {
-        while (timeout > 0) {
-            if (condition.call()) {
-                return;
-            }
-
-            Thread.sleep(TIME_SLICE);
-            timeout -= TIME_SLICE;
-        }
-
-        Assert.fail(message.toString());
-    }
-
-    public static void waitFor(final PollingCheckCondition condition) {
-        new PollingCheck() {
-            @Override
-            protected boolean check() {
-                return condition.canProceed();
-            }
-        }.run();
-    }
-
-    public static void waitFor(long timeout, final PollingCheckCondition condition) {
-        new PollingCheck(timeout) {
-            @Override
-            protected boolean check() {
-                return condition.canProceed();
-            }
-        }.run();
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/PropertyUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/PropertyUtil.java
deleted file mode 100644
index c95b8df..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/PropertyUtil.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.os.Build;
-import android.support.test.InstrumentationRegistry;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Device-side utility class for reading properties and gathering information for testing
- * Android device compatibility.
- */
-public class PropertyUtil {
-
-    /**
-     * Name of read-only property detailing the first API level for which the product was
-     * shipped. Property should be undefined for factory ROM products.
-     */
-    public static final String FIRST_API_LEVEL = "ro.product.first_api_level";
-    private static final String BUILD_TYPE_PROPERTY = "ro.build.type";
-    private static final String MANUFACTURER_PROPERTY = "ro.product.manufacturer";
-    private static final String TAG_DEV_KEYS = "dev-keys";
-    private static final String VNDK_VERSION = "ro.vndk.version";
-
-    public static final String GOOGLE_SETTINGS_QUERY =
-            "content query --uri content://com.google.settings/partner";
-
-    /** Value to be returned by getPropertyInt() if property is not found */
-    public static int INT_VALUE_IF_UNSET = -1;
-
-    /** Returns whether the device build is a user build */
-    public static boolean isUserBuild() {
-        return propertyEquals(BUILD_TYPE_PROPERTY, "user");
-    }
-
-    /** Returns whether this build is built with dev-keys */
-    public static boolean isDevKeysBuild() {
-        for (String tag : Build.TAGS.split(",")) {
-            if (TAG_DEV_KEYS.equals(tag.trim())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Return the first API level for this product. If the read-only property is unset,
-     * this means the first API level is the current API level, and the current API level
-     * is returned.
-     */
-    public static int getFirstApiLevel() {
-        int firstApiLevel = getPropertyInt(FIRST_API_LEVEL);
-        return (firstApiLevel == INT_VALUE_IF_UNSET) ? Build.VERSION.SDK_INT : firstApiLevel;
-    }
-
-    /**
-     * Return whether the SDK version of the vendor partiton is newer than the given API level.
-     * If the property is set to non-integer value, this means the vendor partition is using
-     * current API level and true is returned.
-     */
-    public static boolean isVendorApiLevelNewerThan(int apiLevel) {
-        int vendorApiLevel = getPropertyInt(VNDK_VERSION);
-        if (vendorApiLevel == INT_VALUE_IF_UNSET) {
-            return true;
-        }
-        return vendorApiLevel > apiLevel;
-    }
-
-    /**
-     * Return the manufacturer of this product. If unset, return null.
-     */
-    public static String getManufacturer() {
-        return getProperty(MANUFACTURER_PROPERTY);
-    }
-
-    /** Returns a mapping from client ID names to client ID values */
-    public static Map<String, String> getClientIds() throws IOException {
-        Map<String,String> clientIds = new HashMap<>();
-        String queryOutput = SystemUtil.runShellCommand(
-                InstrumentationRegistry.getInstrumentation(), GOOGLE_SETTINGS_QUERY);
-        for (String line : queryOutput.split("[\\r?\\n]+")) {
-            // Expected line format: "Row: 1 _id=123, name=<property_name>, value=<property_value>"
-            Pattern pattern = Pattern.compile("name=([a-z_]*), value=(.*)$");
-            Matcher matcher = pattern.matcher(line);
-            if (matcher.find()) {
-                String name = matcher.group(1);
-                String value = matcher.group(2);
-                if (name.contains("client_id")) {
-                    clientIds.put(name, value); // only add name-value pair for client ids
-                }
-            }
-        }
-        return clientIds;
-    }
-
-    /** Returns whether the property exists on this device */
-    public static boolean propertyExists(String property) {
-        return getProperty(property) != null;
-    }
-
-    /** Returns whether the property value is equal to a given string */
-    public static boolean propertyEquals(String property, String value) {
-        if (value == null) {
-            return !propertyExists(property); // null value implies property does not exist
-        }
-        return value.equals(getProperty(property));
-    }
-
-    /**
-     * Returns whether the property value matches a given regular expression. The method uses
-     * String.matches(), requiring a complete match (i.e. expression matches entire value string)
-     */
-    public static boolean propertyMatches(String property, String regex) {
-        if (regex == null || regex.isEmpty()) {
-            // null or empty pattern implies property does not exist
-            return !propertyExists(property);
-        }
-        String value = getProperty(property);
-        return (value == null) ? false : value.matches(regex);
-    }
-
-    /**
-     * Retrieves the desired integer property, returning INT_VALUE_IF_UNSET if not found.
-     */
-    public static int getPropertyInt(String property) {
-        String value = getProperty(property);
-        if (value == null) {
-            return INT_VALUE_IF_UNSET;
-        }
-        try {
-            return Integer.parseInt(value);
-        } catch (NumberFormatException e) {
-            return INT_VALUE_IF_UNSET;
-        }
-    }
-
-    /** Retrieves the desired property value in string form */
-    public static String getProperty(String property) {
-        Scanner scanner = null;
-        try {
-            Process process = new ProcessBuilder("getprop", property).start();
-            scanner = new Scanner(process.getInputStream());
-            String value = scanner.nextLine().trim();
-            return (value.isEmpty()) ? null : value;
-        } catch (IOException e) {
-            return null;
-        } finally {
-            if (scanner != null) {
-                scanner.close();
-            }
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ReadElf.java b/common/device-side/util/src/com/android/compatibility/common/util/ReadElf.java
deleted file mode 100644
index feaa9cd..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ReadElf.java
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.compatibility.common.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A poor man's implementation of the readelf command. This program is designed
- * to parse ELF (Executable and Linkable Format) files.
- */
-public class ReadElf implements AutoCloseable {
-    /** The magic values for the ELF identification. */
-    private static final byte[] ELFMAG = {
-            (byte) 0x7F, (byte) 'E', (byte) 'L', (byte) 'F', };
-
-    private static final int EI_NIDENT = 16;
-
-    private static final int EI_CLASS = 4;
-    private static final int EI_DATA = 5;
-
-    private static final int EM_386 = 3;
-    private static final int EM_MIPS = 8;
-    private static final int EM_ARM = 40;
-    private static final int EM_X86_64 = 62;
-    // http://en.wikipedia.org/wiki/Qualcomm_Hexagon
-    private static final int EM_QDSP6 = 164;
-    private static final int EM_AARCH64 = 183;
-
-    private static final int ELFCLASS32 = 1;
-    private static final int ELFCLASS64 = 2;
-
-    private static final int ELFDATA2LSB = 1;
-    private static final int ELFDATA2MSB = 2;
-
-    private static final int EV_CURRENT = 1;
-
-    private static final long PT_LOAD = 1;
-
-    private static final int SHT_SYMTAB = 2;
-    private static final int SHT_STRTAB = 3;
-    private static final int SHT_DYNAMIC = 6;
-    private static final int SHT_DYNSYM = 11;
-
-    public static class Symbol {
-        public static final int STB_LOCAL = 0;
-        public static final int STB_GLOBAL = 1;
-        public static final int STB_WEAK = 2;
-        public static final int STB_LOPROC = 13;
-        public static final int STB_HIPROC = 15;
-
-        public static final int STT_NOTYPE = 0;
-        public static final int STT_OBJECT = 1;
-        public static final int STT_FUNC = 2;
-        public static final int STT_SECTION = 3;
-        public static final int STT_FILE = 4;
-        public static final int STT_COMMON = 5;
-        public static final int STT_TLS = 6;
-
-        public final String name;
-        public final int bind;
-        public final int type;
-
-        Symbol(String name, int st_info) {
-            this.name = name;
-            this.bind = (st_info >> 4) & 0x0F;
-            this.type = st_info & 0x0F;
-        }
-
-        @Override
-        public String toString() {
-            return "Symbol[" + name + "," + toBind() + "," + toType() + "]";
-        }
-
-        private String toBind() {
-            switch (bind) {
-                case STB_LOCAL:
-                    return "LOCAL";
-                case STB_GLOBAL:
-                    return "GLOBAL";
-                case STB_WEAK:
-                    return "WEAK";
-            }
-            return "STB_??? (" + bind + ")";
-        }
-
-        private String toType() {
-            switch (type) {
-                case STT_NOTYPE:
-                    return "NOTYPE";
-                case STT_OBJECT:
-                    return "OBJECT";
-                case STT_FUNC:
-                    return "FUNC";
-                case STT_SECTION:
-                    return "SECTION";
-                case STT_FILE:
-                    return "FILE";
-                case STT_COMMON:
-                    return "COMMON";
-                case STT_TLS:
-                    return "TLS";
-            }
-            return "STT_??? (" + type + ")";
-        }
-    }
-
-    private final String mPath;
-    private final RandomAccessFile mFile;
-    private final byte[] mBuffer = new byte[512];
-    private int mEndian;
-    private boolean mIsDynamic;
-    private boolean mIsPIE;
-    private int mType;
-    private int mAddrSize;
-
-    /** Symbol Table offset */
-    private long mSymTabOffset;
-
-    /** Symbol Table size */
-    private long mSymTabSize;
-
-    /** Dynamic Symbol Table offset */
-    private long mDynSymOffset;
-
-    /** Dynamic Symbol Table size */
-    private long mDynSymSize;
-
-    /** Section Header String Table offset */
-    private long mShStrTabOffset;
-
-    /** Section Header String Table size */
-    private long mShStrTabSize;
-
-    /** String Table offset */
-    private long mStrTabOffset;
-
-    /** String Table size */
-    private long mStrTabSize;
-
-    /** Dynamic String Table offset */
-    private long mDynStrOffset;
-
-    /** Dynamic String Table size */
-    private long mDynStrSize;
-
-    /** Symbol Table symbol names */
-    private Map<String, Symbol> mSymbols;
-
-    /** Dynamic Symbol Table symbol names */
-    private Map<String, Symbol> mDynamicSymbols;
-
-    public static ReadElf read(File file) throws IOException {
-        return new ReadElf(file);
-    }
-
-    public static void main(String[] args) throws IOException {
-        for (String arg : args) {
-            ReadElf re = new ReadElf(new File(arg));
-            re.getSymbol("x");
-            re.getDynamicSymbol("x");
-            re.close();
-        }
-    }
-
-    public boolean isDynamic() {
-        return mIsDynamic;
-    }
-
-    public int getType() {
-        return mType;
-    }
-
-    public boolean isPIE() {
-        return mIsPIE;
-    }
-
-    private ReadElf(File file) throws IOException {
-        mPath = file.getPath();
-        mFile = new RandomAccessFile(file, "r");
-
-        if (mFile.length() < EI_NIDENT) {
-            throw new IllegalArgumentException("Too small to be an ELF file: " + file);
-        }
-
-        readHeader();
-    }
-
-    @Override
-    public void close() {
-        try {
-            mFile.close();
-        } catch (IOException ignored) {
-        }
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            close();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    private void readHeader() throws IOException {
-        mFile.seek(0);
-        mFile.readFully(mBuffer, 0, EI_NIDENT);
-
-        if (mBuffer[0] != ELFMAG[0] || mBuffer[1] != ELFMAG[1] ||
-                mBuffer[2] != ELFMAG[2] || mBuffer[3] != ELFMAG[3]) {
-            throw new IllegalArgumentException("Invalid ELF file: " + mPath);
-        }
-
-        int elfClass = mBuffer[EI_CLASS];
-        if (elfClass == ELFCLASS32) {
-            mAddrSize = 4;
-        } else if (elfClass == ELFCLASS64) {
-            mAddrSize = 8;
-        } else {
-            throw new IOException("Invalid ELF EI_CLASS: " + elfClass + ": " + mPath);
-        }
-
-        mEndian = mBuffer[EI_DATA];
-        if (mEndian == ELFDATA2LSB) {
-        } else if (mEndian == ELFDATA2MSB) {
-            throw new IOException("Unsupported ELFDATA2MSB file: " + mPath);
-        } else {
-            throw new IOException("Invalid ELF EI_DATA: " + mEndian + ": " + mPath);
-        }
-
-        mType = readHalf();
-
-        int e_machine = readHalf();
-        if (e_machine != EM_386 && e_machine != EM_X86_64 &&
-                e_machine != EM_AARCH64 && e_machine != EM_ARM &&
-                e_machine != EM_MIPS &&
-                e_machine != EM_QDSP6) {
-            throw new IOException("Invalid ELF e_machine: " + e_machine + ": " + mPath);
-        }
-
-        // AbiTest relies on us rejecting any unsupported combinations.
-        if ((e_machine == EM_386 && elfClass != ELFCLASS32) ||
-                (e_machine == EM_X86_64 && elfClass != ELFCLASS64) ||
-                (e_machine == EM_AARCH64 && elfClass != ELFCLASS64) ||
-                (e_machine == EM_ARM && elfClass != ELFCLASS32) ||
-                (e_machine == EM_QDSP6 && elfClass != ELFCLASS32)) {
-            throw new IOException("Invalid e_machine/EI_CLASS ELF combination: " +
-                    e_machine + "/" + elfClass + ": " + mPath);
-        }
-
-        long e_version = readWord();
-        if (e_version != EV_CURRENT) {
-            throw new IOException("Invalid e_version: " + e_version + ": " + mPath);
-        }
-
-        long e_entry = readAddr();
-
-        long ph_off = readOff();
-        long sh_off = readOff();
-
-        long e_flags = readWord();
-        int e_ehsize = readHalf();
-        int e_phentsize = readHalf();
-        int e_phnum = readHalf();
-        int e_shentsize = readHalf();
-        int e_shnum = readHalf();
-        int e_shstrndx = readHalf();
-
-        readSectionHeaders(sh_off, e_shnum, e_shentsize, e_shstrndx);
-        readProgramHeaders(ph_off, e_phnum, e_phentsize);
-    }
-
-    private void readSectionHeaders(long sh_off, int e_shnum, int e_shentsize, int e_shstrndx)
-            throws IOException {
-        // Read the Section Header String Table offset first.
-        {
-            mFile.seek(sh_off + e_shstrndx * e_shentsize);
-
-            long sh_name = readWord();
-            long sh_type = readWord();
-            long sh_flags = readX(mAddrSize);
-            long sh_addr = readAddr();
-            long sh_offset = readOff();
-            long sh_size = readX(mAddrSize);
-            // ...
-
-            if (sh_type == SHT_STRTAB) {
-                mShStrTabOffset = sh_offset;
-                mShStrTabSize = sh_size;
-            }
-        }
-
-        for (int i = 0; i < e_shnum; ++i) {
-            // Don't bother to re-read the Section Header StrTab.
-            if (i == e_shstrndx) {
-                continue;
-            }
-
-            mFile.seek(sh_off + i * e_shentsize);
-
-            long sh_name = readWord();
-            long sh_type = readWord();
-            long sh_flags = readX(mAddrSize);
-            long sh_addr = readAddr();
-            long sh_offset = readOff();
-            long sh_size = readX(mAddrSize);
-
-            if (sh_type == SHT_SYMTAB || sh_type == SHT_DYNSYM) {
-                final String symTabName = readShStrTabEntry(sh_name);
-                if (".symtab".equals(symTabName)) {
-                    mSymTabOffset = sh_offset;
-                    mSymTabSize = sh_size;
-                } else if (".dynsym".equals(symTabName)) {
-                    mDynSymOffset = sh_offset;
-                    mDynSymSize = sh_size;
-                }
-            } else if (sh_type == SHT_STRTAB) {
-                final String strTabName = readShStrTabEntry(sh_name);
-                if (".strtab".equals(strTabName)) {
-                    mStrTabOffset = sh_offset;
-                    mStrTabSize = sh_size;
-                } else if (".dynstr".equals(strTabName)) {
-                    mDynStrOffset = sh_offset;
-                    mDynStrSize = sh_size;
-                }
-            } else if (sh_type == SHT_DYNAMIC) {
-                mIsDynamic = true;
-            }
-        }
-    }
-
-    private void readProgramHeaders(long ph_off, int e_phnum, int e_phentsize) throws IOException {
-        for (int i = 0; i < e_phnum; ++i) {
-            mFile.seek(ph_off + i * e_phentsize);
-
-            long p_type = readWord();
-            if (p_type == PT_LOAD) {
-                if (mAddrSize == 8) {
-                    // Only in Elf64_phdr; in Elf32_phdr p_flags is at the end.
-                    long p_flags = readWord();
-                }
-                long p_offset = readOff();
-                long p_vaddr = readAddr();
-                // ...
-
-                if (p_vaddr == 0) {
-                    mIsPIE = true;
-                }
-            }
-        }
-    }
-
-    private HashMap<String, Symbol> readSymbolTable(long symStrOffset, long symStrSize,
-            long tableOffset, long tableSize) throws IOException {
-        HashMap<String, Symbol> result = new HashMap<String, Symbol>();
-        mFile.seek(tableOffset);
-        while (mFile.getFilePointer() < tableOffset + tableSize) {
-            long st_name = readWord();
-            int st_info;
-            if (mAddrSize == 8) {
-                st_info = readByte();
-                int st_other = readByte();
-                int st_shndx = readHalf();
-                long st_value = readAddr();
-                long st_size = readX(mAddrSize);
-            } else {
-                long st_value = readAddr();
-                long st_size = readWord();
-                st_info = readByte();
-                int st_other = readByte();
-                int st_shndx = readHalf();
-            }
-            if (st_name == 0) {
-                continue;
-            }
-
-            final String symName = readStrTabEntry(symStrOffset, symStrSize, st_name);
-            if (symName != null) {
-                Symbol s = new Symbol(symName, st_info);
-                result.put(symName, s);
-            }
-        }
-        return result;
-    }
-
-    private String readShStrTabEntry(long strOffset) throws IOException {
-        if (mShStrTabOffset == 0 || strOffset < 0 || strOffset >= mShStrTabSize) {
-            return null;
-        }
-        return readString(mShStrTabOffset + strOffset);
-    }
-
-    private String readStrTabEntry(long tableOffset, long tableSize, long strOffset)
-            throws IOException {
-        if (tableOffset == 0 || strOffset < 0 || strOffset >= tableSize) {
-            return null;
-        }
-        return readString(tableOffset + strOffset);
-    }
-
-    private int readHalf() throws IOException {
-        return (int) readX(2);
-    }
-
-    private long readWord() throws IOException {
-        return readX(4);
-    }
-
-    private long readOff() throws IOException {
-        return readX(mAddrSize);
-    }
-
-    private long readAddr() throws IOException {
-        return readX(mAddrSize);
-    }
-
-    private long readX(int byteCount) throws IOException {
-        mFile.readFully(mBuffer, 0, byteCount);
-
-        int answer = 0;
-        if (mEndian == ELFDATA2LSB) {
-            for (int i = byteCount - 1; i >= 0; i--) {
-                answer = (answer << 8) | (mBuffer[i] & 0xff);
-            }
-        } else {
-            final int N = byteCount - 1;
-            for (int i = 0; i <= N; ++i) {
-                answer = (answer << 8) | (mBuffer[i] & 0xff);
-            }
-        }
-
-        return answer;
-    }
-
-    private String readString(long offset) throws IOException {
-        long originalOffset = mFile.getFilePointer();
-        mFile.seek(offset);
-        mFile.readFully(mBuffer, 0, (int) Math.min(mBuffer.length, mFile.length() - offset));
-        mFile.seek(originalOffset);
-
-        for (int i = 0; i < mBuffer.length; ++i) {
-            if (mBuffer[i] == 0) {
-                return new String(mBuffer, 0, i);
-            }
-        }
-
-        return null;
-    }
-
-    private int readByte() throws IOException {
-        return mFile.read() & 0xff;
-    }
-
-    public Symbol getSymbol(String name) {
-        if (mSymbols == null) {
-            try {
-                mSymbols = readSymbolTable(mStrTabOffset, mStrTabSize, mSymTabOffset, mSymTabSize);
-            } catch (IOException e) {
-                return null;
-            }
-        }
-        return mSymbols.get(name);
-    }
-
-    public Symbol getDynamicSymbol(String name) {
-        if (mDynamicSymbols == null) {
-            try {
-                mDynamicSymbols = readSymbolTable(
-                        mDynStrOffset, mDynStrSize, mDynSymOffset, mDynSymSize);
-            } catch (IOException e) {
-                return null;
-            }
-        }
-        return mDynamicSymbols.get(name);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ReportLogDeviceInfoStore.java b/common/device-side/util/src/com/android/compatibility/common/util/ReportLogDeviceInfoStore.java
deleted file mode 100644
index 538881d..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ReportLogDeviceInfoStore.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.compatibility.common.util;
-
-import android.util.JsonWriter;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-
-public class ReportLogDeviceInfoStore extends DeviceInfoStore {
-
-    private final String mStreamName;
-    private File tempJsonFile;
-
-    public ReportLogDeviceInfoStore(File jsonFile, String streamName) throws Exception {
-        mJsonFile = jsonFile;
-        mStreamName = streamName;
-    }
-
-    /**
-     * Creates the writer and starts the JSON Object for the metric stream.
-     */
-    @Override
-    public void open() throws IOException {
-        // Write new metrics to a temp file to avoid invalid JSON files due to failed tests.
-        BufferedWriter formatWriter;
-        tempJsonFile = File.createTempFile(mStreamName, "-temp-report-log");
-        formatWriter = new BufferedWriter(new FileWriter(tempJsonFile));
-        if (mJsonFile.exists()) {
-            BufferedReader jsonReader = new BufferedReader(new FileReader(mJsonFile));
-            String currentLine;
-            String nextLine = jsonReader.readLine();
-            while ((currentLine = nextLine) != null) {
-                nextLine = jsonReader.readLine();
-                if (nextLine == null && currentLine.charAt(currentLine.length() - 1) == '}') {
-                    // Reopen overall JSON object to write new metrics.
-                    currentLine = currentLine.substring(0, currentLine.length() - 1) + ",";
-                }
-                // Copy to temp file directly to avoid large metrics string in memory.
-                formatWriter.write(currentLine, 0, currentLine.length());
-            }
-            jsonReader.close();
-        } else {
-            formatWriter.write("{", 0 , 1);
-        }
-        // Start new JSON object for new metrics.
-        formatWriter.write("\"" + mStreamName + "\":", 0, mStreamName.length() + 3);
-        formatWriter.flush();
-        formatWriter.close();
-        mJsonWriter = new JsonWriter(new FileWriter(tempJsonFile, true));
-        mJsonWriter.beginObject();
-    }
-
-    /**
-     * Closes the writer.
-     */
-    @Override
-    public void close() throws IOException {
-        // Close JSON Writer.
-        mJsonWriter.endObject();
-        mJsonWriter.close();
-        // Close overall JSON Object.
-        try (BufferedWriter formatWriter = new BufferedWriter(new FileWriter(tempJsonFile, true))) {
-            formatWriter.write("}", 0, 1);
-        }
-        // Copy metrics from temp file and delete temp file.
-        mJsonFile.createNewFile();
-        try (
-                BufferedReader jsonReader = new BufferedReader(new FileReader(tempJsonFile));
-                BufferedWriter metricsWriter = new BufferedWriter(new FileWriter(mJsonFile))
-        ) {
-            String line;
-            while ((line = jsonReader.readLine()) != null) {
-                // Copy from temp file directly to avoid large metrics string in memory.
-                metricsWriter.write(line, 0, line.length());
-            }
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/RequiredFeatureRule.java b/common/device-side/util/src/com/android/compatibility/common/util/RequiredFeatureRule.java
deleted file mode 100644
index 0968ddc..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/RequiredFeatureRule.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.support.test.InstrumentationRegistry;
-import android.util.Log;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-/**
- * Custom JUnit4 rule that does not run a test case if the device does not have a given feature.
- */
-public class RequiredFeatureRule implements TestRule {
-    private static final String TAG = "RequiredFeatureRule";
-
-    private final String mFeature;
-    private final boolean mHasFeature;
-
-    public RequiredFeatureRule(String feature) {
-        mFeature = feature;
-        mHasFeature = hasFeature(feature);
-    }
-
-    @Override
-    public Statement apply(Statement base, Description description) {
-        return new Statement() {
-
-            @Override
-            public void evaluate() throws Throwable {
-                if (!mHasFeature) {
-                    Log.d(TAG, "skipping "
-                            + description.getClassName() + "#" + description.getMethodName()
-                            + " because device does not have feature '" + mFeature + "'");
-                    return;
-                }
-                base.evaluate();
-            }
-        };
-    }
-
-    public static boolean hasFeature(String feature) {
-        return InstrumentationRegistry.getContext().getPackageManager().hasSystemFeature(feature);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/RequiredServiceRule.java b/common/device-side/util/src/com/android/compatibility/common/util/RequiredServiceRule.java
deleted file mode 100644
index a4359fd..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/RequiredServiceRule.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import android.support.test.InstrumentationRegistry;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-/**
- * Custom JUnit4 rule that does not run a test case if the device does not have a given service.
- */
-public class RequiredServiceRule implements TestRule {
-    private static final String TAG = "RequiredServiceRule";
-
-    private final String mService;
-    private final boolean mHasService;
-
-    /**
-     * Creates a rule for the given service.
-     */
-    public RequiredServiceRule(@NonNull String service) {
-        mService = service;
-        mHasService = hasService(service);
-    }
-
-    @Override
-    public Statement apply(@NonNull Statement base, @NonNull Description description) {
-        return new Statement() {
-
-            @Override
-            public void evaluate() throws Throwable {
-                if (!mHasService) {
-                    Log.d(TAG, "skipping "
-                            + description.getClassName() + "#" + description.getMethodName()
-                            + " because device does not have service '" + mService + "'");
-                    return;
-                }
-                base.evaluate();
-            }
-        };
-    }
-
-    /**
-     * Checks if the device has the given service.
-     */
-    public static boolean hasService(@NonNull String service) {
-        // TODO: ideally should call SystemServiceManager directly, but we would need to open
-        // some @Testing APIs for that.
-        String command = "service check " + service;
-        try {
-            String commandOutput = SystemUtil.runShellCommand(
-                    InstrumentationRegistry.getInstrumentation(), command);
-            return !commandOutput.contains("not found");
-        } catch (Exception e) {
-            Log.w(TAG, "Exception running '" + command + "': " + e);
-            return false;
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/Result.java b/common/device-side/util/src/com/android/compatibility/common/util/Result.java
deleted file mode 100644
index 0d8a29a..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/Result.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.compatibility.common.util;
-
-/**
- * Represents the result of a test.
- */
-public interface Result {
-    public static final int RESULT_OK = 1;
-    public static final int RESULT_FAIL = 2;
-    /**
-     * Sets the test result of this object.
-     *
-     * @param resultCode The test result, either {@code RESULT_OK} or {@code RESULT_FAIL}.
-     */
-    void setResult(int resultCode);
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/RetryRule.java b/common/device-side/util/src/com/android/compatibility/common/util/RetryRule.java
deleted file mode 100644
index 32dedea..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/RetryRule.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.util.Log;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-/**
- * Custom JUnit4 rule that retry tests when they fail due to a {@link RetryableException}.
- */
-public class RetryRule implements TestRule {
-
-    private static final String TAG = "RetryRule";
-    private final int mMaxAttempts;
-
-    /**
-     * Retries the underlying test when it catches a {@link RetryableException}.
-     *
-     * @param retries number of retries. Use {@code 0} to disable rule.
-     *
-     * @throws IllegalArgumentException if {@code retries} is less than {@code 0}.
-     */
-    public RetryRule(int retries) {
-        if (retries < 0) {
-            throw new IllegalArgumentException("retries must be more than 0");
-        }
-        mMaxAttempts = retries + 1;
-    }
-
-    @Override
-    public Statement apply(Statement base, Description description) {
-        return new Statement() {
-
-            @Override
-            public void evaluate() throws Throwable {
-                if (mMaxAttempts <= 1) {
-                    Log.v(TAG, "Executing " + description.getDisplayName()
-                            + " right away because mMaxAttempts is " + mMaxAttempts);
-                    base.evaluate();
-                    return;
-                }
-
-                final String name = description.getDisplayName();
-                Throwable caught = null;
-                for (int i = 1; i <= mMaxAttempts; i++) {
-                    try {
-                        base.evaluate();
-                        if (i == 1) {
-                            Log.v(TAG, "Good News, Everyone! " + name + " passed right away");
-                        } else {
-                            Log.d(TAG,
-                                    "Better late than never: " + name + " passed at attempt #" + i);
-                        }
-                        return;
-                    } catch (RetryableException e) {
-                        final Timeout timeout = e.getTimeout();
-                        if (timeout != null) {
-                            long before = timeout.ms();
-                            timeout.increase();
-                            Log.d(TAG, "Increased " + timeout.getName() + " from " + before + "ms"
-                                    + " to " + timeout.ms() + "ms");
-                        }
-                        caught = e;
-                    }
-                    Log.w(TAG, "Arrrr! " + name + " failed at attempt " + i + "/" + mMaxAttempts
-                            + ": " + caught);
-                }
-                Log.e(TAG, "D'OH! " + name + ": giving up after " + mMaxAttempts + " attempts");
-                throw caught;
-            }
-        };
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/RetryableException.java b/common/device-side/util/src/com/android/compatibility/common/util/RetryableException.java
deleted file mode 100644
index 1c6c782..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/RetryableException.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import androidx.annotation.Nullable;
-
-/**
- * Exception that cause the {@link RetryRule} to re-try a test.
- */
-public class RetryableException extends RuntimeException {
-
-    @Nullable
-    private final Timeout mTimeout;
-
-    public RetryableException(String msg) {
-        this((Timeout) null, msg);
-    }
-
-    public RetryableException(String format, Object...args) {
-        this((Timeout) null, String.format(format, args));
-    }
-
-    public RetryableException(Throwable cause, String format, Object...args) {
-        this((Timeout) null, cause, String.format(format, args), cause);
-    }
-
-    public RetryableException(@Nullable Timeout timeout, String msg) {
-        super(msg);
-        this.mTimeout = timeout;
-    }
-
-    public RetryableException(@Nullable Timeout timeout, String format, Object...args) {
-        super(String.format(format, args));
-        this.mTimeout = timeout;
-    }
-
-    public RetryableException(@Nullable Timeout timeout, Throwable cause, String format,
-            Object...args) {
-        super(String.format(format, args), cause);
-        this.mTimeout = timeout;
-    }
-
-    @Nullable
-    public Timeout getTimeout() {
-        return mTimeout;
-    }
-
-    @Override
-    public String getMessage() {
-        final String superMessage = super.getMessage();
-        return mTimeout == null ? superMessage : superMessage + " (timeout=" + mTimeout + ")";
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/SafeCleanerRule.java b/common/device-side/util/src/com/android/compatibility/common/util/SafeCleanerRule.java
deleted file mode 100644
index 806884c..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/SafeCleanerRule.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import org.junit.AssumptionViolatedException;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-
-/**
- * Rule used to safely run clean up code after a test is finished, so that exceptions thrown by
- * the cleanup code don't hide exception thrown by the test body
- */
-public final class SafeCleanerRule implements TestRule {
-
-    private static final String TAG = "SafeCleanerRule";
-
-    private final List<ThrowingRunnable> mCleaners = new ArrayList<>();
-    private final List<Callable<List<Throwable>>> mExtraThrowables = new ArrayList<>();
-    private final List<Throwable> mThrowables = new ArrayList<>();
-    private Dumper mDumper;
-
-    /**
-     * Runs {@code cleaner} after the test is finished, catching any {@link Throwable} thrown by it.
-     */
-    public SafeCleanerRule run(@NonNull ThrowingRunnable cleaner) {
-        mCleaners.add(cleaner);
-        return this;
-    }
-
-    /**
-     * Adds exceptions directly.
-     *
-     * <p>Typically used for exceptions caught asychronously during the test execution.
-     */
-    public SafeCleanerRule add(@NonNull Callable<List<Throwable>> exceptions) {
-        mExtraThrowables.add(exceptions);
-        return this;
-    }
-
-    /**
-     * Adds exceptions directly.
-     *
-     * <p>Typically used for exceptions caught during {@code finally} blocks.
-     */
-    public SafeCleanerRule add(Throwable exception) {
-        Log.w(TAG, "Adding exception directly: " + exception);
-        mThrowables.add(exception);
-        return this;
-    }
-
-    /**
-     * Sets a {@link Dumper} used to log errors.
-     */
-    public SafeCleanerRule setDumper(@NonNull Dumper dumper) {
-        mDumper = dumper;
-        return this;
-    }
-
-    @Override
-    public Statement apply(Statement base, Description description) {
-        return new Statement() {
-            @Override
-            public void evaluate() throws Throwable {
-                // First run the test
-                try {
-                    base.evaluate();
-                } catch (Throwable t) {
-                    Log.w(TAG, "Adding exception from main test at index 0: " + t);
-                    mThrowables.add(0, t);
-                }
-
-                // Then the cleanup runners
-                for (ThrowingRunnable runner : mCleaners) {
-                    try {
-                        runner.run();
-                    } catch (Throwable t) {
-                        Log.w(TAG, "Adding exception from cleaner");
-                        mThrowables.add(t);
-                    }
-                }
-
-                // And finally add the extra exceptions
-                for (Callable<List<Throwable>> extraThrowablesCallable : mExtraThrowables) {
-                    final List<Throwable> extraThrowables = extraThrowablesCallable.call();
-                    if (extraThrowables != null && !extraThrowables.isEmpty()) {
-                        Log.w(TAG, "Adding " + extraThrowables.size() + " extra exceptions");
-                        mThrowables.addAll(extraThrowables);
-                    }
-                }
-
-                // Ignore all instances of AssumptionViolatedExceptions
-                mThrowables.removeIf(t -> t instanceof AssumptionViolatedException);
-
-                // Finally, throw up!
-                if (mThrowables.isEmpty()) return;
-
-                final int numberExceptions = mThrowables.size();
-                if (numberExceptions == 1) {
-                    fail(description, mThrowables.get(0));
-                }
-                fail(description, new MultipleExceptions(mThrowables));
-            }
-
-        };
-    }
-
-    private void fail(Description description, Throwable t) throws Throwable {
-        if (mDumper != null) {
-            mDumper.dump(description.getDisplayName(), t);
-        }
-        throw t;
-    }
-
-    private static String toMesssage(List<Throwable> throwables) {
-        String msg = "D'OH!";
-        try {
-            try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw)) {
-                sw.write("Caught " + throwables.size() + " exceptions\n");
-                for (int i = 0; i < throwables.size(); i++) {
-                    sw.write("\n---- Begin of exception #" + (i + 1) + " ----\n");
-                    final Throwable exception = throwables.get(i);
-                    exception.printStackTrace(pw);
-                    sw.write("---- End of exception #" + (i + 1) + " ----\n\n");
-                }
-                msg = sw.toString();
-            }
-        } catch (IOException e) {
-            // ignore close() errors - should not happen...
-            Log.e(TAG, "Exception closing StringWriter: " + e);
-        }
-        return msg;
-    }
-
-    // VisibleForTesting
-    static class MultipleExceptions extends AssertionError {
-        private final List<Throwable> mThrowables;
-
-        private MultipleExceptions(List<Throwable> throwables) {
-            super(toMesssage(throwables));
-
-            this.mThrowables = throwables;
-        }
-
-        List<Throwable> getThrowables() {
-            return mThrowables;
-        }
-    }
-
-    /**
-     * Optional interface used to dump an error.
-     */
-    public interface Dumper {
-
-        /**
-         * Dumps an error.
-         */
-        void dump(@NonNull String testName, @NonNull Throwable t);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateChangerRule.java b/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateChangerRule.java
deleted file mode 100644
index 3e0662a..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateChangerRule.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-import android.provider.Settings;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * JUnit rule used to set a {@link Settings} preference before the test is run.
- *
- * <p>It stores the current value before the test, changes it (if necessary), then restores it after
- * the test (if necessary).
- */
-public class SettingsStateChangerRule extends StateChangerRule<String> {
-
-    /**
-     * Default constructor for the 'secure' context.
-     *
-     * @param context context used to retrieve the {@link Settings} provider.
-     * @param key prefence key.
-     * @param value value to be set before the test is run.
-     */
-    public SettingsStateChangerRule(@NonNull Context context, @NonNull String key,
-            @Nullable String value) {
-        this(context, SettingsUtils.NAMESPACE_SECURE, key, value);
-    }
-
-    /**
-     * Default constructor.
-     *
-     * @param context context used to retrieve the {@link Settings} provider.
-     * @param namespace settings namespace.
-     * @param key prefence key.
-     * @param value value to be set before the test is run.
-     */
-    public SettingsStateChangerRule(@NonNull Context context, @NonNull String namespace,
-            @NonNull String key, @Nullable String value) {
-        super(new SettingsStateManager(context, namespace, key), value);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateKeeperRule.java b/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateKeeperRule.java
deleted file mode 100644
index 18ca88a..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateKeeperRule.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-import android.provider.Settings;
-
-import androidx.annotation.NonNull;
-
-/**
- * JUnit rule used to restore a {@link Settings} preference after the test is run.
- *
- * <p>It stores the current value before the test, and restores it after the test (if necessary).
- */
-public class SettingsStateKeeperRule extends StateKeeperRule<String> {
-
-    /**
-     * Default constructor.
-     *
-     * @param context context used to retrieve the {@link Settings} provider.
-     * @param key prefence key.
-     */
-    public SettingsStateKeeperRule(@NonNull Context context, @NonNull String key) {
-        super(new SettingsStateManager(context, SettingsUtils.NAMESPACE_SECURE, key));
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateManager.java b/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateManager.java
deleted file mode 100644
index bab06a6..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/SettingsStateManager.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.content.Context;
-import android.provider.Settings;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Manages the state of a preference backed by {@link Settings}.
- */
-public class SettingsStateManager implements StateManager<String> {
-
-    private final Context mContext;
-    private final String mNamespace;
-    private final String mKey;
-
-    /**
-     * Default constructor.
-     *
-     * @param context context used to retrieve the {@link Settings} provider.
-     * @param namespace settings namespace.
-     * @param key prefence key.
-     */
-    public SettingsStateManager(@NonNull Context context, @NonNull String namespace,
-            @NonNull String key) {
-        mContext = Preconditions.checkNotNull(context);
-        mNamespace = Preconditions.checkNotNull(namespace);
-        mKey = Preconditions.checkNotNull(key);
-    }
-
-    @Override
-    public void set(@Nullable String value) {
-        SettingsUtils.syncSet(mContext, mNamespace, mKey, value);
-    }
-
-    @Override
-    @Nullable
-    public String get() {
-        return SettingsUtils.get(mNamespace, mKey);
-    }
-
-    @Override
-    public String toString() {
-        return "SettingsStateManager[namespace=" + mNamespace + ", key=" + mKey + "]";
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/SettingsUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/SettingsUtils.java
deleted file mode 100644
index c13de45..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/SettingsUtils.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.content.Context;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Provides utilities to interact with the device's {@link Settings}.
- */
-public final class SettingsUtils {
-
-    private static final String TAG = SettingsUtils.class.getSimpleName();
-
-    public static final String NAMESPACE_SECURE = "secure";
-    public static final String NAMESPACE_GLOBAL = "global";
-
-    // TODO(b/123885378): we cannot pass an empty value when using 'cmd settings', so we need
-    // to remove the property instead. Once we use the Settings API directly, we can remove this
-    // constant and all if() statements that ues it
-    static final boolean TMP_HACK_REMOVE_EMPTY_PROPERTIES = true;
-
-    /**
-     * Uses a Shell command to set the given preference.
-     */
-    public static void set(@NonNull String namespace, @NonNull String key, @Nullable String value) {
-        if (value == null) {
-            delete(namespace, key);
-            return;
-        }
-        if (TMP_HACK_REMOVE_EMPTY_PROPERTIES && TextUtils.isEmpty(value)) {
-            Log.w(TAG, "Value of " + namespace + ":" + key + " is empty; deleting it instead");
-            delete(namespace, key);
-            return;
-        }
-        runShellCommand("settings put %s %s %s default", namespace, key, value);
-    }
-
-    /**
-     * Sets a preference in the {@link #NAMESPACE_SECURE} namespace.
-     */
-    public static void set(@NonNull String key, @Nullable String value) {
-        set(NAMESPACE_SECURE, key, value);
-    }
-
-    /**
-     * Uses a Shell command to set the given preference, and verifies it was correctly set.
-     */
-    public static void syncSet(@NonNull Context context, @NonNull String namespace,
-            @NonNull String key, @Nullable String value) {
-        if (value == null) {
-            syncDelete(context, namespace, key);
-            return;
-        }
-
-        final String currentValue = get(namespace, key);
-        if (value.equals(currentValue)) {
-            // Already set, ignore
-            return;
-        }
-
-        final OneTimeSettingsListener observer =
-                new OneTimeSettingsListener(context, namespace, key);
-        set(namespace, key, value);
-        observer.assertCalled();
-
-        final String newValue = get(namespace, key);
-        if (TMP_HACK_REMOVE_EMPTY_PROPERTIES && TextUtils.isEmpty(value)) {
-            assertWithMessage("invalid value for '%s' settings", key).that(newValue)
-                .isNull();
-        } else {
-            assertWithMessage("invalid value for '%s' settings", key).that(newValue)
-                    .isEqualTo(value);
-        }
-    }
-
-    /**
-     * Sets a preference in the {@link #NAMESPACE_SECURE} namespace, using a Settings listener to
-     * block until it's set.
-     */
-    public static void syncSet(@NonNull Context context, @NonNull String key,
-            @Nullable String value) {
-        syncSet(context, NAMESPACE_SECURE, key, value);
-    }
-
-    /**
-     * Uses a Shell command to delete the given preference.
-     */
-    public static void delete(@NonNull String namespace, @NonNull String key) {
-        runShellCommand("settings delete %s %s", namespace, key);
-    }
-
-    /**
-     * Deletes a preference in the {@link #NAMESPACE_SECURE} namespace.
-     */
-    public static void delete(@NonNull String key) {
-        delete(NAMESPACE_SECURE, key);
-    }
-
-    /**
-     * Uses a Shell command to delete the given preference, and verifies it was correctly deleted.
-     */
-    public static void syncDelete(@NonNull Context context, @NonNull String namespace,
-            @NonNull String key) {
-
-        final String currentValue = get(namespace, key);
-        if (currentValue == null) {
-            // Already set, ignore
-            return;
-        }
-
-        final OneTimeSettingsListener observer = new OneTimeSettingsListener(context, namespace,
-                key);
-        delete(namespace, key);
-        observer.assertCalled();
-
-        final String newValue = get(namespace, key);
-        assertWithMessage("invalid value for '%s' settings", key).that(newValue).isNull();
-    }
-
-    /**
-     * Deletes a preference in the {@link #NAMESPACE_SECURE} namespace, using a Settings listener to
-     * block until it's deleted.
-     */
-    public static void syncDelete(@NonNull Context context, @NonNull String key) {
-        syncDelete(context, NAMESPACE_SECURE, key);
-    }
-
-    /**
-     * Gets the value of a given preference using Shell command.
-     */
-    @Nullable
-    public static String get(@NonNull String namespace, @NonNull String key) {
-        final String value = runShellCommand("settings get %s %s", namespace, key);
-        if (value == null || value.equals("null")) {
-            return null;
-        } else {
-            return value;
-        }
-    }
-
-    /**
-     * Gets the value of a preference in the {@link #NAMESPACE_SECURE} namespace.
-     */
-    @NonNull
-    public static String get(@NonNull String key) {
-        return get(NAMESPACE_SECURE, key);
-    }
-
-    private SettingsUtils() {
-        throw new UnsupportedOperationException("contain static methods only");
-    }
-
-    /**
-     * @deprecated - use {@link #set(String, String, String)} with {@link #NAMESPACE_GLOBAL}
-     */
-    @Deprecated
-    public static void putGlobalSetting(String key, String value) {
-        set(SettingsUtils.NAMESPACE_GLOBAL, key, value);
-
-    }
-
-    /**
-     * @deprecated - use {@link #set(String, String, String)} with {@link #NAMESPACE_GLOBAL}
-     */
-    @Deprecated
-    public static void putSecureSetting(String key, String value) {
-        set(SettingsUtils.NAMESPACE_SECURE, key, value);
-
-    }
-
-    /**
-     * Get a global setting for the current (foreground) user. Trims ending new line.
-     */
-    public static String getSecureSetting(String key) {
-        return SystemUtil.runShellCommand("settings --user current get secure " + key).trim();
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ShellIdentityUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ShellIdentityUtils.java
deleted file mode 100644
index f3438ee..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ShellIdentityUtils.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import android.app.UiAutomation;
-import android.support.test.InstrumentationRegistry;
-
-/**
- * Provides utility methods to invoke system and privileged APIs as the shell user.
- */
-public class ShellIdentityUtils {
-
-    /**
-     * Utility interface to invoke a method against the target object.
-     *
-     * @param <T> the type returned by the invoked method.
-     * @param <U> the type of the object against which the method is invoked.
-     */
-    public interface ShellPermissionMethodHelper<T, U> {
-        /**
-         * Invokes the method against the target object.
-         *
-         * @param targetObject the object against which the method should be invoked.
-         * @return the result of the invoked method.
-         */
-        T callMethod(U targetObject);
-    }
-
-    /**
-     * Utility interface to invoke a method against the target object.
-     *
-     * @param <U> the type of the object against which the method is invoked.
-     */
-    public interface ShellPermissionMethodHelperNoReturn<U> {
-        /**
-         * Invokes the method against the target object.
-         *
-         * @param targetObject the object against which the method should be invoked.
-         */
-        void callMethod(U targetObject);
-    }
-
-    /**
-     * Invokes the specified method on the targetObject as the shell user. The method can be invoked
-     * as follows:
-     *
-     * {@code ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
-     *        (tm) -> tm.getDeviceId());}
-     */
-    public static <T, U> T invokeMethodWithShellPermissions(U targetObject,
-            ShellPermissionMethodHelper<T, U> methodHelper) {
-        final UiAutomation uiAutomation =
-                InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            return methodHelper.callMethod(targetObject);
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Invokes the specified method on the targetObject as the shell user. The method can be invoked
-     * as follows:
-     *
-     * {@code ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
-     *        (tm) -> tm.getDeviceId());}
-     */
-    public static <U> void invokeMethodWithShellPermissionsNoReturn(
-            U targetObject, ShellPermissionMethodHelperNoReturn<U> methodHelper) {
-        final UiAutomation uiAutomation =
-                InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            methodHelper.callMethod(targetObject);
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Utility interface to invoke a static method.
-     *
-     * @param <T> the type returned by the invoked method.
-     */
-    public interface StaticShellPermissionMethodHelper<T> {
-        /**
-         * Invokes the static method.
-         *
-         * @return the result of the invoked method.
-         */
-        T callMethod();
-    }
-
-    /**
-     * Invokes the specified static method as the shell user. This method can be invoked as follows:
-     *
-     * {@code ShellIdentityUtils.invokeStaticMethodWithShellPermissions(Build::getSerial));}
-     */
-    public static <T> T invokeStaticMethodWithShellPermissions(
-            StaticShellPermissionMethodHelper<T> methodHelper) {
-        final UiAutomation uiAutomation =
-                InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        try {
-            uiAutomation.adoptShellPermissionIdentity();
-            return methodHelper.callMethod();
-        } finally {
-            uiAutomation.dropShellPermissionIdentity();
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ShellUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ShellUtils.java
deleted file mode 100644
index 8cb3290..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ShellUtils.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
-
-import android.support.test.InstrumentationRegistry;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-
-/**
- * Provides Shell-based utilities such as running a command.
- */
-public final class ShellUtils {
-
-    private static final String TAG = "ShellHelper";
-
-    /**
-     * Runs a Shell command, returning a trimmed response.
-     */
-    @NonNull
-    public static String runShellCommand(@NonNull String template, Object...args) {
-        final String command = String.format(template, args);
-        Log.d(TAG, "runShellCommand(): " + command);
-        try {
-            final String result = SystemUtil
-                    .runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
-            return TextUtils.isEmpty(result) ? "" : result.trim();
-        } catch (Exception e) {
-            throw new RuntimeException("Command '" + command + "' failed: ", e);
-        }
-    }
-
-    /**
-     * Tap on the view center, it may change window focus.
-     */
-    public static void tap(View view) {
-        final int[] xy = new int[2];
-        view.getLocationOnScreen(xy);
-        final int viewWidth = view.getWidth();
-        final int viewHeight = view.getHeight();
-        final int x = (int) (xy[0] + (viewWidth / 2.0f));
-        final int y = (int) (xy[1] + (viewHeight / 2.0f));
-
-        runShellCommand("input touchscreen tap %d %d", x, y);
-    }
-
-
-    private ShellUtils() {
-        throw new UnsupportedOperationException("contain static methods only");
-    }
-
-    /**
-     * Simulates input of key event.
-     *
-     * @param keyCode key event to fire.
-     */
-    public static void sendKeyEvent(String keyCode) {
-        runShellCommand("input keyevent " + keyCode);
-    }
-
-    /**
-     * Allows an app to draw overlaid windows.
-     */
-    public static void setOverlayPermissions(@NonNull String packageName, boolean allowed) {
-        final String action = allowed ? "allow" : "ignore";
-        runShellCommand("appops set %s SYSTEM_ALERT_WINDOW %s", packageName, action);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/StateChangerRule.java b/common/device-side/util/src/com/android/compatibility/common/util/StateChangerRule.java
deleted file mode 100644
index 4e59f13..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/StateChangerRule.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.google.common.base.Preconditions;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import java.util.Objects;
-
-/**
- * JUnit rule used to prepare a state before the test is run.
- *
- * <p>It stores the current state before the test, changes it (if necessary), then restores it after
- * the test (if necessary).
- *
- * @param <T> value type
- */
-public class StateChangerRule<T> implements TestRule {
-
-    private final StateManager<T> mStateManager;
-    private final T mValue;
-
-    /**
-     * Default constructor.
-     *
-     * @param stateManager abstraction used to mange the state.
-     * @param value value to be set before the test is run.
-     */
-    public StateChangerRule(@NonNull StateManager<T> stateManager, @Nullable T value) {
-        mStateManager = Preconditions.checkNotNull(stateManager);
-        mValue = value;
-    }
-
-    @Override
-    public Statement apply(Statement base, Description description) {
-        return new Statement() {
-
-            @Override
-            public void evaluate() throws Throwable {
-                final T previousValue = mStateManager.get();
-                if (!Objects.equals(previousValue, mValue)) {
-                    mStateManager.set(mValue);
-                }
-                try {
-                    base.evaluate();
-                } finally {
-                    final T currentValue = mStateManager.get();
-                    if (!Objects.equals(currentValue, previousValue)) {
-                        mStateManager.set(previousValue);
-                        // TODO: if set() thowns a RuntimeException, JUnit will silently catch it
-                        // and re-run the test case; it should fail instead.
-                    }
-                }
-            }
-        };
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/StateKeeperRule.java b/common/device-side/util/src/com/android/compatibility/common/util/StateKeeperRule.java
deleted file mode 100644
index ecc02a2..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/StateKeeperRule.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import androidx.annotation.NonNull;
-
-import com.google.common.base.Preconditions;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import java.util.Objects;
-
-/**
- * JUnit rule used to restore a state after the test is run.
- *
- * <p>It stores the current state before the test, and restores it after the test (if necessary).
- *
- * @param <T> value type
- */
-public class StateKeeperRule<T> implements TestRule {
-
-    private final StateManager<T> mStateManager;
-
-    /**
-     * Default constructor.
-     *
-     * @param stateManager abstraction used to mange the state.
-     */
-    public StateKeeperRule(@NonNull StateManager<T> stateManager) {
-        mStateManager = Preconditions.checkNotNull(stateManager);
-    }
-
-    /**
-     * Hook for subclasses.
-     */
-    protected void preEvaluate(@SuppressWarnings("unused") Description description) {
-    }
-
-    /**
-     * Hook for subclasses.
-     */
-    protected void postEvaluate(@SuppressWarnings("unused") Description description) {
-    }
-
-    @Override
-    public Statement apply(Statement base, Description description) {
-        return new Statement() {
-
-            @Override
-            public void evaluate() throws Throwable {
-                final T previousValue = mStateManager.get();
-                preEvaluate(description);
-                try {
-                    base.evaluate();
-                } finally {
-                    final T currentValue = mStateManager.get();
-                    if (!Objects.equals(previousValue, currentValue)) {
-                        mStateManager.set(previousValue);
-                    }
-                }
-                postEvaluate(description);
-            }
-        };
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/StateManager.java b/common/device-side/util/src/com/android/compatibility/common/util/StateManager.java
deleted file mode 100644
index 2077e08..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/StateManager.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import androidx.annotation.Nullable;
-
-/**
- * Abstraction for a state that is managed somewhere, like Android Settings.
- *
- * @param <T> value type
- */
-public interface StateManager<T> {
-
-    /**
-     * Sets a new state.
-     */
-    void set(@Nullable T value);
-
-    /**
-     * Gets the current state.
-     */
-    @Nullable T get();
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/SystemUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/SystemUtil.java
deleted file mode 100644
index fa7f046..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/SystemUtil.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.compatibility.common.util;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.MemoryInfo;
-import android.app.Instrumentation;
-import android.app.UiAutomation;
-import android.content.Context;
-import android.os.ParcelFileDescriptor;
-import android.os.StatFs;
-import android.support.test.InstrumentationRegistry;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.concurrent.Callable;
-import java.util.function.Predicate;
-
-public class SystemUtil {
-    private static final String TAG = "CtsSystemUtil";
-
-    public static long getFreeDiskSize(Context context) {
-        final StatFs statFs = new StatFs(context.getFilesDir().getAbsolutePath());
-        return (long)statFs.getAvailableBlocks() * statFs.getBlockSize();
-    }
-
-    public static long getFreeMemory(Context context) {
-        final MemoryInfo info = new MemoryInfo();
-        ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryInfo(info);
-        return info.availMem;
-    }
-
-    public static long getTotalMemory(Context context) {
-        final MemoryInfo info = new MemoryInfo();
-        ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryInfo(info);
-        return info.totalMem;
-    }
-
-    /**
-     * Executes a shell command using shell user identity, and return the standard output in string
-     * <p>Note: calling this function requires API level 21 or above
-     * @param instrumentation {@link Instrumentation} instance, obtained from a test running in
-     * instrumentation framework
-     * @param cmd the command to run
-     * @return the standard output of the command
-     * @throws Exception
-     */
-    public static String runShellCommand(Instrumentation instrumentation, String cmd)
-            throws IOException {
-        Log.v(TAG, "Running command: " + cmd);
-        if (cmd.startsWith("pm grant ") || cmd.startsWith("pm revoke ")) {
-            throw new UnsupportedOperationException("Use UiAutomation.grantRuntimePermission() "
-                    + "or revokeRuntimePermission() directly, which are more robust.");
-        }
-        ParcelFileDescriptor pfd = instrumentation.getUiAutomation().executeShellCommand(cmd);
-        byte[] buf = new byte[512];
-        int bytesRead;
-        FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
-        StringBuffer stdout = new StringBuffer();
-        while ((bytesRead = fis.read(buf)) != -1) {
-            stdout.append(new String(buf, 0, bytesRead));
-        }
-        fis.close();
-        return stdout.toString();
-    }
-
-    /**
-     * Simpler version of {@link #runShellCommand(Instrumentation, String)}.
-     */
-    public static String runShellCommand(String cmd) {
-        try {
-            return runShellCommand(InstrumentationRegistry.getInstrumentation(), cmd);
-        } catch (IOException e) {
-            fail("Failed reading command output: " + e);
-            return "";
-        }
-    }
-
-    /**
-     * Same as {@link #runShellCommand(String)}, with optionally
-     * check the result using {@code resultChecker}.
-     */
-    public static String runShellCommand(String cmd, Predicate<String> resultChecker) {
-        final String result = runShellCommand(cmd);
-        if (resultChecker != null) {
-            assertTrue("Assertion failed. Command was: " + cmd + "\n"
-                    + "Output was:\n" + result,
-                    resultChecker.test(result));
-        }
-        return result;
-    }
-
-    /**
-     * Same as {@link #runShellCommand(String)}, but fails if the output is not empty.
-     */
-    public static String runShellCommandForNoOutput(String cmd) {
-        final String result = runShellCommand(cmd);
-        assertTrue("Command failed. Command was: " + cmd + "\n"
-                + "Didn't expect any output, but the output was:\n" + result,
-                result.length() == 0);
-        return result;
-    }
-
-    /**
-     * Runs a command and print the result on logcat.
-     */
-    public static void runCommandAndPrintOnLogcat(String logtag, String cmd) {
-        Log.i(logtag, "Executing: " + cmd);
-        final String output = runShellCommand(cmd);
-        for (String line : output.split("\\n", -1)) {
-            Log.i(logtag, line);
-        }
-    }
-
-    /**
-     * Runs a command and return the section matching the patterns.
-     *
-     * @see TextUtils#extractSection
-     */
-    public static String runCommandAndExtractSection(String cmd,
-            String extractionStartRegex, boolean startInclusive,
-            String extractionEndRegex, boolean endInclusive) {
-        return TextUtils.extractSection(runShellCommand(cmd), extractionStartRegex, startInclusive,
-                extractionEndRegex, endInclusive);
-    }
-
-    /**
-     * Runs a {@link ThrowingRunnable} adopting Shell's permissions.
-     */
-    public static void runWithShellPermissionIdentity(@NonNull ThrowingRunnable runnable) {
-        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        runWithShellPermissionIdentity(automan, runnable);
-    }
-
-    /**
-     * Runs a {@link ThrowingRunnable} adopting a subset of Shell's permissions.
-     */
-    public static void runWithShellPermissionIdentity(@NonNull ThrowingRunnable runnable,
-            String... permissions) {
-        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        runWithShellPermissionIdentity(automan, runnable, permissions);
-    }
-
-    /**
-     * Runs a {@link ThrowingRunnable} adopting Shell's permissions, where you can specify the
-     * uiAutomation used.
-     */
-    public static void runWithShellPermissionIdentity(
-            @NonNull UiAutomation automan, @NonNull ThrowingRunnable runnable) {
-        runWithShellPermissionIdentity(automan, runnable, null /* permissions */);
-    }
-
-    /**
-     * Runs a {@link ThrowingRunnable} adopting Shell's permissions, where you can specify the
-     * uiAutomation used.
-     * @param automan UIAutomation to use.
-     * @param runnable The code to run with Shell's identity.
-     * @param permissions A subset of Shell's permissions. Passing {@code null} will use all
-     *                    available permissions.
-     */
-    public static void runWithShellPermissionIdentity(@NonNull UiAutomation automan,
-            @NonNull ThrowingRunnable runnable, String... permissions) {
-        automan.adoptShellPermissionIdentity(permissions);
-        try {
-            runnable.run();
-        } catch (Exception e) {
-            throw new RuntimeException("Caught exception", e);
-        } finally {
-            automan.dropShellPermissionIdentity();
-        }
-    }
-
-    /**
-     * Calls a {@link Callable} adopting Shell's permissions.
-     */
-    public static <T> T callWithShellPermissionIdentity(@NonNull Callable<T> callable)
-            throws Exception {
-        final UiAutomation automan = InstrumentationRegistry.getInstrumentation().getUiAutomation();
-        automan.adoptShellPermissionIdentity();
-        try {
-            return callable.call();
-        } finally {
-            automan.dropShellPermissionIdentity();
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/TestNameUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/TestNameUtils.java
deleted file mode 100644
index 2dbeaab..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/TestNameUtils.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-/**
- * Generic helper used to set / get the the name of the test being run.
- *
- * <p>Typically used on {@code @Rule} classes.
- */
-public final class TestNameUtils {
-
-    private static String sCurrentTestName;
-    private static String sCurrentTestClass;
-
-    /**
-     * Gets the name of the test current running.
-     */
-    @NonNull
-    public static String getCurrentTestName() {
-        if (sCurrentTestName != null) return sCurrentTestName;
-        if (sCurrentTestClass != null) return sCurrentTestClass;
-        return "(Unknown test)";
-    }
-
-    /**
-     * Sets the name of the test current running
-     */
-    public static void setCurrentTestName(@Nullable String name) {
-        sCurrentTestName = name;
-    }
-
-    /**
-     * Sets the name of the test class current running
-     */
-    public static void setCurrentTestClass(@Nullable String testClass) {
-        sCurrentTestClass = testClass;
-    }
-
-    /**
-     * Checks whether a test is running, based on whether {@link #setCurrentTestName(String)} was
-     * called.
-     */
-    public static boolean isRunningTest() {
-        return sCurrentTestName != null;
-    }
-
-    private TestNameUtils() {
-        throw new UnsupportedOperationException("contain static methods only");
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/TestThread.java b/common/device-side/util/src/com/android/compatibility/common/util/TestThread.java
deleted file mode 100644
index 894b9c8..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/TestThread.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2009 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 com.android.compatibility.common.util;
-
-/**
- * Thread class for executing a Runnable containing assertions in a separate thread.
- * Uncaught exceptions in the Runnable are rethrown in the context of the the thread
- * calling the <code>runTest()</code> method.
- */
-public final class TestThread extends Thread {
-    private Throwable mThrowable;
-    private Runnable mTarget;
-
-    public TestThread(Runnable target) {
-        mTarget = target;
-    }
-
-    @Override
-    public final void run() {
-        try {
-            mTarget.run();
-        } catch (Throwable t) {
-            mThrowable = t;
-        }
-    }
-
-    /**
-     * Run the target Runnable object and wait until the test finish or throw
-     * out Exception if test fail.
-     *
-     * @param runTime
-     * @throws Throwable
-     */
-    public void runTest(long runTime) throws Throwable {
-        start();
-        joinAndCheck(runTime);
-    }
-
-    /**
-     * Get the Throwable object which is thrown when test running
-     * @return  The Throwable object
-     */
-    public Throwable getThrowable() {
-        return mThrowable;
-    }
-
-    /**
-     * Set the Throwable object which is thrown when test running
-     * @param t The Throwable object
-     */
-    public void setThrowable(Throwable t) {
-        mThrowable = t;
-    }
-
-    /**
-     * Wait for the test thread to complete and throw the stored exception if there is one.
-     *
-     * @param runTime The time to wait for the test thread to complete.
-     * @throws Throwable
-     */
-    public void joinAndCheck(long runTime) throws Throwable {
-        this.join(runTime);
-        if (this.isAlive()) {
-            this.interrupt();
-            this.join(runTime);
-            throw new Exception("Thread did not finish within allotted time.");
-        }
-        checkException();
-    }
-
-    /**
-     * Check whether there is an exception when running Runnable object.
-     * @throws Throwable
-     */
-    public void checkException() throws Throwable {
-        if (mThrowable != null) {
-            throw mThrowable;
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/TestUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/TestUtils.java
deleted file mode 100644
index 3b82cb7..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/TestUtils.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import static junit.framework.Assert.fail;
-
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.util.function.BooleanSupplier;
-
-public class TestUtils {
-    private static final String TAG = "CtsTestUtils";
-
-    private TestUtils() {
-    }
-
-    public static final int DEFAULT_TIMEOUT_SECONDS = 30;
-
-    /** Print an error log and fail. */
-    public static void failWithLog(String message) {
-        Log.e(TAG, message);
-        fail(message);
-    }
-
-    @FunctionalInterface
-    public interface BooleanSupplierWithThrow {
-        boolean getAsBoolean() throws Exception;
-    }
-
-    @FunctionalInterface
-    public interface RunnableWithThrow {
-        void run() throws Exception;
-    }
-
-    /**
-     * Wait until {@code predicate} is satisfied, or fail, with {@link #DEFAULT_TIMEOUT_SECONDS}.
-     */
-    public static void waitUntil(String message, BooleanSupplierWithThrow predicate)
-            throws Exception {
-        waitUntil(message, 0, predicate);
-    }
-
-    /**
-     * Wait until {@code predicate} is satisfied, or fail, with a given timeout.
-     */
-    public static void waitUntil(
-            String message, int timeoutSecond, BooleanSupplierWithThrow predicate)
-            throws Exception {
-        if (timeoutSecond <= 0) {
-            timeoutSecond = DEFAULT_TIMEOUT_SECONDS;
-        }
-        int sleep = 125;
-        final long timeout = SystemClock.uptimeMillis() + timeoutSecond * 1000;
-        while (SystemClock.uptimeMillis() < timeout) {
-            if (predicate.getAsBoolean()) {
-                return; // okay
-            }
-            Thread.sleep(sleep);
-            sleep *= 5;
-            sleep = Math.min(2000, sleep);
-        }
-        failWithLog("Timeout: " + message);
-    }
-
-    /**
-     * Run a Runnable {@code r}, and if it throws, also run {@code onFailure}.
-     */
-    public static void runWithFailureHook(RunnableWithThrow r, RunnableWithThrow onFailure)
-            throws Exception {
-        if (r == null) {
-            throw new NullPointerException("r");
-        }
-        if (onFailure == null) {
-            throw new NullPointerException("onFailure");
-        }
-        try {
-            r.run();
-        } catch (Throwable th) {
-            Log.e(TAG, "Caught exception: " + th, th);
-            onFailure.run();
-            throw th;
-        }
-    }
-
-    /**
-     * Synchronized wait for a specified condition.
-     *
-     * @param notifyLock Lock that will be notified when the condition might have changed
-     * @param condition The condition to check
-     * @param timeoutMs The timeout in millis
-     * @param conditionName The name to include in the assertion. If null, will be given a default.
-     */
-    public static void waitOn(Object notifyLock, BooleanSupplier condition,
-            long timeoutMs, String conditionName) {
-        if (conditionName == null) conditionName = "condition";
-        if (condition.getAsBoolean()) return;
-
-        synchronized (notifyLock) {
-            try {
-                long timeSlept = 0;
-                while (!condition.getAsBoolean() && timeSlept < timeoutMs) {
-                    long sleepStart = SystemClock.uptimeMillis();
-                    notifyLock.wait(timeoutMs - timeSlept);
-                    timeSlept += SystemClock.uptimeMillis() - sleepStart;
-                }
-                if (!condition.getAsBoolean()) {
-                    throw new AssertionError("Timed out after " + timeSlept
-                            + "ms waiting for: " + conditionName);
-                }
-            } catch (InterruptedException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-}
-
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/TextUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/TextUtils.java
deleted file mode 100644
index cca2652..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/TextUtils.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import java.util.regex.Pattern;
-
-public class TextUtils {
-    private TextUtils() {
-    }
-
-    /**
-     * Return the first section in {@code source} between the line matches
-     * {@code extractionStartRegex} and the line matches {@code extractionEndRegex}.
-     */
-    public static String extractSection(String source,
-            String extractionStartRegex, boolean startInclusive,
-            String extractionEndRegex, boolean endInclusive) {
-
-        final Pattern start = Pattern.compile(extractionStartRegex);
-        final Pattern end = Pattern.compile(extractionEndRegex);
-
-        final StringBuilder sb = new StringBuilder();
-        final String[] lines = source.split("\\n", -1);
-
-        int i = 0;
-        for (; i < lines.length; i++) {
-            final String line = lines[i];
-            if (start.matcher(line).matches()) {
-                if (startInclusive) {
-                    sb.append(line);
-                    sb.append('\n');
-                }
-                i++;
-                break;
-            }
-        }
-
-        for (; i < lines.length; i++) {
-            final String line = lines[i];
-            if (end.matcher(line).matches()) {
-                if (endInclusive) {
-                    sb.append(line);
-                    sb.append('\n');
-                }
-                break;
-            }
-            sb.append(line);
-            sb.append('\n');
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Creates a string consisted of {@code size} chars {@code c}.
-     */
-    public static String repeat(char c, int size) {
-        StringBuilder builder = new StringBuilder(size);
-        for (int i = 1; i <= size; i++) {
-            builder.append(c);
-        }
-        return builder.toString();
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ThermalUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ThermalUtils.java
deleted file mode 100644
index a61ffc1..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ThermalUtils.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import android.util.Log;
-
-/**
- * Device-side utility class for override/reset thermal status.
- */
-public final class ThermalUtils {
-    private static final String TAG = "CtsThermalUtils";
-
-    private ThermalUtils() {}
-
-    /** Make the target device think it's not throttling. */
-    public static void overrideThermalNotThrottling() throws Exception {
-        overrideThermalStatus(0);
-    }
-
-    /**
-     * Make the target device think it's in given throttling status.
-     * @param status thermal status defined in android.os.Temperature
-     */
-    public static void overrideThermalStatus(int status) throws Exception {
-        SystemUtil.runShellCommandForNoOutput("cmd thermalservice override-status " + status);
-
-        Log.d(TAG, "override-status " + status);
-    }
-
-    /** Cancel the thermal override status on target device. */
-    public static void resetThermalStatus() throws Exception {
-        SystemUtil.runShellCommandForNoOutput("cmd thermalservice reset");
-
-        Log.d(TAG, "reset");
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ThreadUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ThreadUtils.java
deleted file mode 100644
index 3948628..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/ThreadUtils.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import android.os.SystemClock;
-
-public final class ThreadUtils {
-    private ThreadUtils() {
-    }
-
-    public static void sleepUntilRealtime(long realtime) throws Exception {
-        Thread.sleep(Math.max(0, realtime - SystemClock.elapsedRealtime()));
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/Timeout.java b/common/device-side/util/src/com/android/compatibility/common/util/Timeout.java
deleted file mode 100644
index 9ac6323..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/Timeout.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-
-import java.util.concurrent.Callable;
-
-/**
- * A "smart" timeout that supports exponential backoff.
- */
-//TODO: move to common CTS Code
-public final class Timeout {
-
-    private static final String TAG = "Timeout";
-    private static final boolean VERBOSE = true;
-
-    private final String mName;
-    private long mCurrentValue;
-    private final float mMultiplier;
-    private final long mMaxValue;
-
-    private final Sleeper mSleeper;
-
-    private static final Sleeper DEFAULT_SLEEPER = (t) -> SystemClock.sleep(t);
-
-    /**
-     * Default constructor.
-     *
-     * @param name name to be used for logging purposes.
-     * @param initialValue initial timeout value, in ms.
-     * @param multiplier multiplier for {@link #increase()}.
-     * @param maxValue max timeout value (in ms) set by {@link #increase()}.
-     *
-     * @throws IllegalArgumentException if {@code name} is {@code null} or empty,
-     * {@code initialValue}, {@code multiplir} or {@code maxValue} are less than {@code 1},
-     * or if {@code initialValue} is higher than {@code maxValue}
-     */
-    public Timeout(String name, long initialValue, float multiplier, long maxValue) {
-        this(DEFAULT_SLEEPER, name, initialValue, multiplier, maxValue);
-    }
-
-    @VisibleForTesting
-    Timeout(@NonNull Sleeper sleeper, String name, long initialValue, float multiplier,
-            long maxValue) {
-        if (initialValue < 1 || maxValue < 1 || initialValue > maxValue) {
-            throw new IllegalArgumentException(
-                    "invalid initial and/or max values: " + initialValue + " and " + maxValue);
-        }
-        if (multiplier <= 1) {
-            throw new IllegalArgumentException("multiplier must be higher than 1: " + multiplier);
-        }
-        if (TextUtils.isEmpty(name)) {
-            throw new IllegalArgumentException("no name");
-        }
-        mSleeper = sleeper;
-        mName = name;
-        mCurrentValue = initialValue;
-        mMultiplier = multiplier;
-        mMaxValue = maxValue;
-        Log.d(TAG, "Constructor: " + this + " at " + TestNameUtils.getCurrentTestName());
-    }
-
-    /**
-     * Gets the current timeout, in ms.
-     */
-    public long ms() {
-        return mCurrentValue;
-    }
-
-    /**
-     * Gets the max timeout, in ms.
-     */
-    public long getMaxValue() {
-        return mMaxValue;
-    }
-
-    /**
-     * @return the mMultiplier
-     */
-    public float getMultiplier() {
-        return mMultiplier;
-    }
-
-    /**
-     * Gets the user-friendly name of this timeout.
-     */
-    @NonNull
-    public String getName() {
-        return mName;
-    }
-
-    /**
-     * Increases the current value by the {@link #getMultiplier()}, up to {@link #getMaxValue()}.
-     *
-     * @return previous current value.
-     */
-    public long increase() {
-        final long oldValue = mCurrentValue;
-        mCurrentValue = Math.min(mMaxValue, (long) (mCurrentValue * mMultiplier));
-        if (oldValue != mCurrentValue) {
-            Log.w(TAG, mName + " increased from " + oldValue + "ms to " + mCurrentValue + "ms at "
-                    + TestNameUtils.getCurrentTestName());
-        }
-        return oldValue;
-    }
-
-    /**
-     * Runs a {@code job} many times before giving up, sleeping between failed attempts up to
-     * {@link #ms()}.
-     *
-     * @param description description of the job for logging purposes.
-     * @param job job to be run, must return {@code null} if it failed and should be retried.
-     * @throws RetryableException if all attempts failed.
-     * @throws IllegalArgumentException if {@code description} is {@code null} or empty, if
-     * {@code job} is {@code  null}, or if {@code maxAttempts} is less than 1.
-     * @throws Exception any other exception thrown by helper methods.
-     *
-     * @return job's result.
-     */
-    public <T> T run(String description, Callable<T> job) throws Exception {
-        return run(description, 100, job);
-    }
-
-    /**
-     * Runs a {@code job} many times before giving up, sleeping between failed attempts up to
-     * {@link #ms()}.
-     *
-     * @param description description of the job for logging purposes.
-     * @param job job to be run, must return {@code null} if it failed and should be retried.
-     * @param retryMs how long to sleep between failures.
-     * @throws RetryableException if all attempts failed.
-     * @throws IllegalArgumentException if {@code description} is {@code null} or empty, if
-     * {@code job} is {@code  null}, or if {@code maxAttempts} is less than 1.
-     * @throws Exception any other exception thrown by helper methods.
-     *
-     * @return job's result.
-     */
-    public <T> T run(String description, long retryMs, Callable<T> job) throws Exception {
-        if (TextUtils.isEmpty(description)) {
-            throw new IllegalArgumentException("no description");
-        }
-        if (job == null) {
-            throw new IllegalArgumentException("no job");
-        }
-        if (retryMs < 1) {
-            throw new IllegalArgumentException("need to sleep at least 1ms, right?");
-        }
-        long startTime = SystemClock.elapsedRealtime();
-        int attempt = 0;
-        long totalSlept = 0;
-        while (SystemClock.elapsedRealtime() - startTime <= mCurrentValue) {
-            final T result = job.call();
-            if (result != null) {
-                // Good news, everyone: job succeeded on first attempt!
-                return result;
-            }
-            attempt++;
-            final long napTime = Math.min(retryMs, mCurrentValue - totalSlept);
-            if (VERBOSE) {
-                Log.v(TAG, description + " failed at attempt #" + attempt + "; sleeping for "
-                        + napTime + "ms before trying again");
-            }
-            mSleeper.sleep(napTime);
-            totalSlept += napTime;
-
-            retryMs *= mMultiplier;
-        }
-        Log.w(TAG, description + " failed after " + attempt + " attempts and " + totalSlept + "ms: "
-                + this);
-        throw new RetryableException(this, description);
-    }
-
-    @Override
-    public String toString() {
-        return mName + ": [current=" + mCurrentValue + "ms; multiplier=" + mMultiplier + "x; max="
-                + mMaxValue + "ms]";
-    }
-
-    @VisibleForTesting
-    interface Sleeper {
-        void sleep(long napTimeMs);
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/Visitor.java b/common/device-side/util/src/com/android/compatibility/common/util/Visitor.java
deleted file mode 100644
index ab4bbfb..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/Visitor.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.compatibility.common.util;
-
-import androidx.annotation.NonNull;
-
-/**
- * Implements the Visitor design pattern
- *
- * @param <V> visited object
- */
-public interface Visitor<V> {
-
-    /**
-     * Visit that object.
-     */
-    void visit(@NonNull V visited);
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/WatchDog.java b/common/device-side/util/src/com/android/compatibility/common/util/WatchDog.java
deleted file mode 100644
index efcc693..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/WatchDog.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2012 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 com.android.compatibility.common.util;
-
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-import android.util.Log;
-
-import junit.framework.Assert;
-
-/**
- * class for checking if rendering function is alive or not.
- * panic if watch-dog is not reset over certain amount of time
- */
-public class WatchDog implements Runnable {
-    private static final String TAG = "WatchDog";
-    private Thread mThread;
-    private Semaphore mSemaphore;
-    private volatile boolean mStopRequested;
-    private final long mTimeoutInMilliSecs;
-    private TimeoutCallback mCallback = null;
-
-    public WatchDog(long timeoutInMilliSecs) {
-        mTimeoutInMilliSecs = timeoutInMilliSecs;
-    }
-
-    public WatchDog(long timeoutInMilliSecs, TimeoutCallback callback) {
-        this(timeoutInMilliSecs);
-        mCallback = callback;
-    }
-
-    /** start watch-dog */
-    public void start() {
-        Log.i(TAG, "start");
-        mStopRequested = false;
-        mSemaphore = new Semaphore(0);
-        mThread = new Thread(this);
-        mThread.start();
-    }
-
-    /** stop watch-dog */
-    public void stop() {
-        Log.i(TAG, "stop");
-        if (mThread == null) {
-            return; // already finished
-        }
-        mStopRequested = true;
-        mSemaphore.release();
-        try {
-            mThread.join();
-        } catch (InterruptedException e) {
-            // ignore
-        }
-        mThread = null;
-        mSemaphore = null;
-    }
-
-    /** resets watch-dog, thus prevent it from panic */
-    public void reset() {
-        if (!mStopRequested) { // stop requested, but rendering still on-going
-            mSemaphore.release();
-        }
-    }
-
-    @Override
-    public void run() {
-        while (!mStopRequested) {
-            try {
-                boolean success = mSemaphore.tryAcquire(mTimeoutInMilliSecs, TimeUnit.MILLISECONDS);
-                if (mCallback == null) {
-                    Assert.assertTrue("Watchdog timed-out", success);
-                } else if (!success) {
-                    mCallback.onTimeout();
-                }
-            } catch (InterruptedException e) {
-                // this thread will not be interrupted,
-                // but if it happens, just check the exit condition.
-            }
-        }
-    }
-
-    /**
-     * Called by the Watchdog when it has timed out.
-     */
-    public interface TimeoutCallback {
-
-        public void onTimeout();
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/WidgetTestUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/WidgetTestUtils.java
deleted file mode 100644
index 2f2b8f7..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/WidgetTestUtils.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.android.compatibility.common.util;
-
-import static android.view.ViewTreeObserver.OnDrawListener;
-import static android.view.ViewTreeObserver.OnGlobalLayoutListener;
-
-import static org.mockito.hamcrest.MockitoHamcrest.argThat;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.support.test.rule.ActivityTestRule;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.ViewTreeObserver;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import junit.framework.Assert;
-
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * The useful methods for widget test.
- */
-public class WidgetTestUtils {
-    /**
-     * Assert that two bitmaps have identical content (same dimensions, same configuration,
-     * same pixel content).
-     *
-     * @param b1 the first bitmap which needs to compare.
-     * @param b2 the second bitmap which needs to compare.
-     */
-    public static void assertEquals(Bitmap b1, Bitmap b2) {
-        if (b1 == b2) {
-            return;
-        }
-
-        if (b1 == null || b2 == null) {
-            Assert.fail("the bitmaps are not equal");
-        }
-
-        // b1 and b2 are all not null.
-        if (b1.getWidth() != b2.getWidth() || b1.getHeight() != b2.getHeight()
-            || b1.getConfig() != b2.getConfig()) {
-            Assert.fail("the bitmaps are not equal");
-        }
-
-        int w = b1.getWidth();
-        int h = b1.getHeight();
-        int s = w * h;
-        int[] pixels1 = new int[s];
-        int[] pixels2 = new int[s];
-
-        b1.getPixels(pixels1, 0, w, 0, 0, w, h);
-        b2.getPixels(pixels2, 0, w, 0, 0, w, h);
-
-        for (int i = 0; i < s; i++) {
-            if (pixels1[i] != pixels2[i]) {
-                Assert.fail("the bitmaps are not equal");
-            }
-        }
-    }
-
-    /**
-     * Find beginning of the special element.
-     * @param parser XmlPullParser will be parsed.
-     * @param firstElementName the target element name.
-     *
-     * @throws XmlPullParserException if XML Pull Parser related faults occur.
-     * @throws IOException if I/O-related error occur when parsing.
-     */
-    public static final void beginDocument(XmlPullParser parser, String firstElementName)
-            throws XmlPullParserException, IOException {
-        Assert.assertNotNull(parser);
-        Assert.assertNotNull(firstElementName);
-
-        int type;
-        while ((type = parser.next()) != XmlPullParser.START_TAG
-                && type != XmlPullParser.END_DOCUMENT) {
-            ;
-        }
-
-        if (!parser.getName().equals(firstElementName)) {
-            throw new XmlPullParserException("Unexpected start tag: found " + parser.getName()
-                    + ", expected " + firstElementName);
-        }
-    }
-
-    /**
-     * Compare the expected pixels with actual, scaling for the target context density
-     *
-     * @throws AssertionFailedError
-     */
-    public static void assertScaledPixels(int expected, int actual, Context context) {
-        Assert.assertEquals(expected * context.getResources().getDisplayMetrics().density,
-                actual, 3);
-    }
-
-    /** Converts dips into pixels using the {@link Context}'s density. */
-    public static int convertDipToPixels(Context context, int dip) {
-      float density = context.getResources().getDisplayMetrics().density;
-      return Math.round(density * dip);
-    }
-
-    /**
-     * Retrieve a bitmap that can be used for comparison on any density
-     * @param resources
-     * @return the {@link Bitmap} or <code>null</code>
-     */
-    public static Bitmap getUnscaledBitmap(Resources resources, int resId) {
-        BitmapFactory.Options options = new BitmapFactory.Options();
-        options.inScaled = false;
-        return BitmapFactory.decodeResource(resources, resId, options);
-    }
-
-    /**
-     * Retrieve a dithered bitmap that can be used for comparison on any density
-     * @param resources
-     * @param config the preferred config for the returning bitmap
-     * @return the {@link Bitmap} or <code>null</code>
-     */
-    public static Bitmap getUnscaledAndDitheredBitmap(Resources resources,
-            int resId, Bitmap.Config config) {
-        BitmapFactory.Options options = new BitmapFactory.Options();
-        options.inDither = true;
-        options.inScaled = false;
-        options.inPreferredConfig = config;
-        return BitmapFactory.decodeResource(resources, resId, options);
-    }
-
-    /**
-     * Argument matcher for equality check of a CharSequence.
-     *
-     * @param expected expected CharSequence
-     *
-     * @return
-     */
-    public static CharSequence sameCharSequence(final CharSequence expected) {
-        return argThat(new BaseMatcher<CharSequence>() {
-            @Override
-            public boolean matches(Object o) {
-                if (o instanceof CharSequence) {
-                    return TextUtils.equals(expected, (CharSequence) o);
-                }
-                return false;
-            }
-
-            @Override
-            public void describeTo(Description description) {
-                description.appendText("doesn't match " + expected);
-            }
-        });
-    }
-
-    /**
-     * Argument matcher for equality check of an Editable.
-     *
-     * @param expected expected Editable
-     *
-     * @return
-     */
-    public static Editable sameEditable(final Editable expected) {
-        return argThat(new BaseMatcher<Editable>() {
-            @Override
-            public boolean matches(Object o) {
-                if (o instanceof Editable) {
-                    return TextUtils.equals(expected, (Editable) o);
-                }
-                return false;
-            }
-
-            @Override
-            public void describeTo(Description description) {
-                description.appendText("doesn't match " + expected);
-            }
-        });
-    }
-
-    /**
-     * Runs the specified {@link Runnable} on the main thread and ensures that the specified
-     * {@link View}'s tree is drawn before returning.
-     *
-     * @param activityTestRule the activity test rule used to run the test
-     * @param view the view whose tree should be drawn before returning
-     * @param runner the runnable to run on the main thread, or {@code null} to
-     *               simply force invalidation and a draw pass
-     */
-    public static void runOnMainAndDrawSync(@NonNull final ActivityTestRule activityTestRule,
-            @NonNull final View view, @Nullable final Runnable runner) {
-        final CountDownLatch latch = new CountDownLatch(1);
-
-        try {
-            activityTestRule.runOnUiThread(() -> {
-                final OnDrawListener listener = new OnDrawListener() {
-                    @Override
-                    public void onDraw() {
-                        // posting so that the sync happens after the draw that's about to happen
-                        view.post(() -> {
-                            activityTestRule.getActivity().getWindow().getDecorView()
-                                    .getViewTreeObserver().removeOnDrawListener(this);
-                            latch.countDown();
-                        });
-                    }
-                };
-
-                activityTestRule.getActivity().getWindow().getDecorView()
-                        .getViewTreeObserver().addOnDrawListener(listener);
-
-                if (runner != null) {
-                    runner.run();
-                }
-                view.invalidate();
-            });
-
-            Assert.assertTrue("Expected draw pass occurred within 5 seconds",
-                    latch.await(5, TimeUnit.SECONDS));
-        } catch (Throwable t) {
-            throw new RuntimeException(t);
-        }
-    }
-
-    /**
-     * Runs the specified Runnable on the main thread and ensures that the activity's view tree is
-     * laid out before returning.
-     *
-     * @param activityTestRule the activity test rule used to run the test
-     * @param runner the runnable to run on the main thread. {@code null} is
-     * allowed, and simply means that there no runnable is required.
-     * @param forceLayout true if there should be an explicit call to requestLayout(),
-     * false otherwise
-     */
-    public static void runOnMainAndLayoutSync(@NonNull final ActivityTestRule activityTestRule,
-            @Nullable final Runnable runner, boolean forceLayout)
-            throws Throwable {
-        runOnMainAndLayoutSync(activityTestRule,
-                activityTestRule.getActivity().getWindow().getDecorView(), runner, forceLayout);
-    }
-
-    /**
-     * Runs the specified Runnable on the main thread and ensures that the specified view is
-     * laid out before returning.
-     *
-     * @param activityTestRule the activity test rule used to run the test
-     * @param view The view
-     * @param runner the runnable to run on the main thread. {@code null} is
-     * allowed, and simply means that there no runnable is required.
-     * @param forceLayout true if there should be an explicit call to requestLayout(),
-     * false otherwise
-     */
-    public static void runOnMainAndLayoutSync(@NonNull final ActivityTestRule activityTestRule,
-            @NonNull final View view, @Nullable final Runnable runner, boolean forceLayout)
-            throws Throwable {
-        final View rootView = view.getRootView();
-
-        final CountDownLatch latch = new CountDownLatch(1);
-
-        activityTestRule.runOnUiThread(() -> {
-            final OnGlobalLayoutListener listener = new ViewTreeObserver.OnGlobalLayoutListener() {
-                @Override
-                public void onGlobalLayout() {
-                    rootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
-                    // countdown immediately since the layout we were waiting on has happened
-                    latch.countDown();
-                }
-            };
-
-            rootView.getViewTreeObserver().addOnGlobalLayoutListener(listener);
-
-            if (runner != null) {
-                runner.run();
-            }
-
-            if (forceLayout) {
-                rootView.requestLayout();
-            }
-        });
-
-        try {
-            Assert.assertTrue("Expected layout pass within 5 seconds",
-                    latch.await(5, TimeUnit.SECONDS));
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/WifiConfigCreator.java b/common/device-side/util/src/com/android/compatibility/common/util/WifiConfigCreator.java
deleted file mode 100755
index f2d1f65..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/WifiConfigCreator.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2015 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 com.android.compatibility.common.util;
-
-import static android.net.wifi.WifiManager.EXTRA_WIFI_STATE;
-import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.ProxyInfo;
-import android.net.Uri;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * A simple activity to create and manage wifi configurations.
- */
-public class WifiConfigCreator {
-    public static final String ACTION_CREATE_WIFI_CONFIG =
-            "com.android.compatibility.common.util.CREATE_WIFI_CONFIG";
-    public static final String ACTION_UPDATE_WIFI_CONFIG =
-            "com.android.compatibility.common.util.UPDATE_WIFI_CONFIG";
-    public static final String ACTION_REMOVE_WIFI_CONFIG =
-            "com.android.compatibility.common.util.REMOVE_WIFI_CONFIG";
-    public static final String EXTRA_NETID = "extra-netid";
-    public static final String EXTRA_SSID = "extra-ssid";
-    public static final String EXTRA_SECURITY_TYPE = "extra-security-type";
-    public static final String EXTRA_PASSWORD = "extra-password";
-
-    public static final int SECURITY_TYPE_NONE = 1;
-    public static final int SECURITY_TYPE_WPA = 2;
-    public static final int SECURITY_TYPE_WEP = 3;
-
-    private static final String TAG = "WifiConfigCreator";
-
-    private static final long ENABLE_WIFI_WAIT_SEC = 10L;
-
-    private final Context mContext;
-    private final WifiManager mWifiManager;
-
-    public WifiConfigCreator(Context context) {
-        mContext = context;
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-    }
-
-    /**
-     * Adds a new WiFi network.
-     * @return network id or -1 in case of error
-     */
-    public int addNetwork(String ssid, boolean hidden, int securityType,
-            String password) throws InterruptedException, SecurityException {
-        checkAndEnableWifi();
-
-        WifiConfiguration wifiConf = createConfig(ssid, hidden, securityType, password);
-
-        int netId = mWifiManager.addNetwork(wifiConf);
-
-        if (netId != -1) {
-            mWifiManager.enableNetwork(netId, true);
-        } else {
-            Log.w(TAG, "Unable to add SSID '" + ssid + "': netId = " + netId);
-        }
-        return netId;
-    }
-
-    /**
-     * Adds a new wifiConfiguration with OPEN security type, and the given pacProxy
-     * verifies that the proxy is added by getting the configuration back, and checking it.
-     * @return returns the PAC proxy URL after adding the network and getting it from WifiManager
-     * @throws IllegalStateException if any of the WifiManager operations fail
-     */
-    public String addHttpProxyNetworkVerifyAndRemove(String ssid, String pacProxyUrl)
-            throws IllegalStateException {
-        String retrievedPacProxyUrl = null;
-        int netId = -1;
-        try {
-            WifiConfiguration conf = createConfig(ssid, false, SECURITY_TYPE_NONE, null);
-            if (pacProxyUrl != null) {
-                conf.setHttpProxy(ProxyInfo.buildPacProxy(Uri.parse(pacProxyUrl)));
-            }
-            netId = mWifiManager.addNetwork(conf);
-            if (netId == -1) {
-                throw new IllegalStateException("Failed to addNetwork: " + ssid);
-            }
-            for (final WifiConfiguration w : mWifiManager.getConfiguredNetworks()) {
-                if (w.SSID.equals(ssid)) {
-                    conf = w;
-                    break;
-                }
-            }
-            if (conf == null) {
-                throw new IllegalStateException("Failed to get WifiConfiguration for: " + ssid);
-            }
-            Uri pacProxyFileUri = null;
-            ProxyInfo httpProxy = conf.getHttpProxy();
-            if (httpProxy != null) pacProxyFileUri = httpProxy.getPacFileUrl();
-            if (pacProxyFileUri != null) {
-                retrievedPacProxyUrl = conf.getHttpProxy().getPacFileUrl().toString();
-            }
-            if (!mWifiManager.removeNetwork(netId)) {
-                throw new IllegalStateException("Failed to remove WifiConfiguration: " + ssid);
-            }
-        } finally {
-            mWifiManager.removeNetwork(netId);
-        }
-        return retrievedPacProxyUrl;
-    }
-
-    /**
-     * Updates a new WiFi network.
-     * @return network id (may differ from original) or -1 in case of error
-     */
-    public int updateNetwork(WifiConfiguration wifiConf, String ssid, boolean hidden,
-            int securityType, String password) throws InterruptedException, SecurityException {
-        checkAndEnableWifi();
-        if (wifiConf == null) {
-            return -1;
-        }
-
-        WifiConfiguration conf = createConfig(ssid, hidden, securityType, password);
-        conf.networkId = wifiConf.networkId;
-
-        int newNetId = mWifiManager.updateNetwork(conf);
-
-        if (newNetId != -1) {
-            mWifiManager.saveConfiguration();
-            mWifiManager.enableNetwork(newNetId, true);
-        } else {
-            Log.w(TAG, "Unable to update SSID '" + ssid + "': netId = " + newNetId);
-        }
-        return newNetId;
-    }
-
-    /**
-     * Updates a new WiFi network.
-     * @return network id (may differ from original) or -1 in case of error
-     */
-    public int updateNetwork(int netId, String ssid, boolean hidden,
-            int securityType, String password) throws InterruptedException, SecurityException {
-        checkAndEnableWifi();
-
-        WifiConfiguration wifiConf = null;
-        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
-        for (WifiConfiguration config : configs) {
-            if (config.networkId == netId) {
-                wifiConf = config;
-                break;
-            }
-        }
-        return updateNetwork(wifiConf, ssid, hidden, securityType, password);
-    }
-
-    public boolean removeNetwork(int netId) {
-        return mWifiManager.removeNetwork(netId);
-    }
-
-    /**
-     * Creates a WifiConfiguration set up according to given parameters
-     * @param ssid SSID of the network
-     * @param hidden Is SSID not broadcast?
-     * @param securityType One of {@link #SECURITY_TYPE_NONE}, {@link #SECURITY_TYPE_WPA} or
-     *                     {@link #SECURITY_TYPE_WEP}
-     * @param password Password for WPA or WEP
-     * @return Created configuration object
-     */
-    private WifiConfiguration createConfig(String ssid, boolean hidden, int securityType,
-            String password) {
-        WifiConfiguration wifiConf = new WifiConfiguration();
-        if (!TextUtils.isEmpty(ssid)) {
-            wifiConf.SSID = '"' + ssid + '"';
-        }
-        wifiConf.status = WifiConfiguration.Status.ENABLED;
-        wifiConf.hiddenSSID = hidden;
-        switch (securityType) {
-            case SECURITY_TYPE_NONE:
-                wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-                break;
-            case SECURITY_TYPE_WPA:
-                updateForWPAConfiguration(wifiConf, password);
-                break;
-            case SECURITY_TYPE_WEP:
-                updateForWEPConfiguration(wifiConf, password);
-                break;
-        }
-        return wifiConf;
-    }
-
-    private void updateForWPAConfiguration(WifiConfiguration wifiConf, String wifiPassword) {
-        wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
-        if (!TextUtils.isEmpty(wifiPassword)) {
-            wifiConf.preSharedKey = '"' + wifiPassword + '"';
-        }
-    }
-
-    private void updateForWEPConfiguration(WifiConfiguration wifiConf, String password) {
-        wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
-        wifiConf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
-        wifiConf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
-        if (!TextUtils.isEmpty(password)) {
-            int length = password.length();
-            if ((length == 10 || length == 26
-                    || length == 58) && password.matches("[0-9A-Fa-f]*")) {
-                wifiConf.wepKeys[0] = password;
-            } else {
-                wifiConf.wepKeys[0] = '"' + password + '"';
-            }
-            wifiConf.wepTxKeyIndex = 0;
-        }
-    }
-
-    private void checkAndEnableWifi() throws InterruptedException {
-        final CountDownLatch enabledLatch = new CountDownLatch(1);
-
-        // Register a change receiver first to pick up events between isEnabled and setEnabled
-        final BroadcastReceiver watcher = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                if (intent.getIntExtra(EXTRA_WIFI_STATE, -1) == WIFI_STATE_ENABLED) {
-                    enabledLatch.countDown();
-                }
-            }
-        };
-
-        mContext.registerReceiver(watcher, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
-        try {
-            // In case wifi is not already enabled, wait for it to come up
-            if (!mWifiManager.isWifiEnabled()) {
-                SystemUtil.runShellCommand("svc wifi enable");
-                enabledLatch.await(ENABLE_WIFI_WAIT_SEC, TimeUnit.SECONDS);
-            }
-        } finally {
-            mContext.unregisterReceiver(watcher);
-        }
-    }
-}
-
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/Within.java b/common/device-side/util/src/com/android/compatibility/common/util/Within.java
deleted file mode 100644
index 4d9ff80..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/Within.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.compatibility.common.util;
-
-import android.os.SystemClock;
-
-import org.mockito.Mockito;
-import org.mockito.exceptions.base.MockitoAssertionError;
-import org.mockito.internal.verification.api.VerificationData;
-import org.mockito.invocation.Invocation;
-import org.mockito.verification.VerificationMode;
-
-import java.util.List;
-
-/**
- * Custom verification mode that allows waiting for the specific invocation to happen within
- * a certain time interval. Not that unlike {@link Mockito#timeout(int)}, this mode will not
- * return early and throw exception if the expected method was called with a different set of
- * parameters before the call that we're waiting for.
- */
-public class Within implements VerificationMode {
-    private static final long TIME_SLICE = 50;
-    private final long mTimeout;
-
-    public Within(long timeout) {
-        mTimeout = timeout;
-    }
-
-    @Override
-    public void verify(VerificationData data) {
-        long timeout = mTimeout;
-        MockitoAssertionError errorToRethrow = null;
-        // Loop in the same way we do in PollingCheck, sleeping and then testing for the target
-        // invocation
-        while (timeout > 0) {
-            SystemClock.sleep(TIME_SLICE);
-
-            try {
-                final List<Invocation> actualInvocations = data.getAllInvocations();
-                // Iterate over all invocations so far to see if we have a match
-                for (Invocation invocation : actualInvocations) {
-                    if (data.getWanted().matches(invocation)) {
-                        // Found our match within our timeout. Mark all invocations as verified
-                        markAllInvocationsAsVerified(data);
-                        // and return
-                        return;
-                    }
-                }
-            } catch (MockitoAssertionError assertionError) {
-                errorToRethrow = assertionError;
-            }
-
-            timeout -= TIME_SLICE;
-        }
-
-        if (errorToRethrow != null) {
-            throw errorToRethrow;
-        }
-
-        throw new MockitoAssertionError(
-                "Timed out while waiting " + mTimeout + "ms for " + data.getWanted().toString());
-    }
-
-    // TODO: Uncomment once upgraded to 2.7.13
-    // @Override
-    public VerificationMode description(String description) {
-        // Return this for now.
-        // TODO: Return wrapper once upgraded to 2.7.13
-        return this;
-    }
-
-    private void markAllInvocationsAsVerified(VerificationData data) {
-        for (Invocation invocation : data.getAllInvocations()) {
-            invocation.markVerified();
-            data.getWanted().captureArgumentsFrom(invocation);
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/IBooleanCallback.aidl b/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/IBooleanCallback.aidl
deleted file mode 100644
index 2fdb26b..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/IBooleanCallback.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util.devicepolicy.provisioning;
-
-interface IBooleanCallback {
-    oneway void onResult(boolean result);
-}
\ No newline at end of file
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java b/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
deleted file mode 100644
index 05edf1a..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util.devicepolicy.provisioning;
-
-import static android.app.admin.DevicePolicyManager.ACTION_MANAGED_PROFILE_PROVISIONED;
-import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
-import static android.content.Intent.ACTION_MANAGED_PROFILE_ADDED;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.uiautomator.UiDevice;
-import android.util.Log;
-
-import com.android.compatibility.common.util.BlockingBroadcastReceiver;
-
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-public class SilentProvisioningTestManager {
-    private static final long TIMEOUT_SECONDS = 120L;
-    private static final String TAG = "SilentProvisioningTest";
-
-    private final LinkedBlockingQueue<Boolean> mProvisioningResults = new LinkedBlockingQueue(1);
-
-    private final IBooleanCallback mProvisioningResultCallback = new IBooleanCallback.Stub() {
-        @Override
-        public void onResult(boolean result) {
-            try {
-                mProvisioningResults.put(result);
-            } catch (InterruptedException e) {
-                Log.e(TAG, "IBooleanCallback.callback", e);
-            }
-        }
-    };
-
-    private final Context mContext;
-    private Intent mReceivedProfileProvisionedIntent;
-
-    public SilentProvisioningTestManager(Context context) {
-        mContext = context.getApplicationContext();
-    }
-
-    public Intent getReceviedProfileProvisionedIntent() {
-        return mReceivedProfileProvisionedIntent;
-    }
-
-    public boolean startProvisioningAndWait(Intent provisioningIntent) throws InterruptedException {
-        wakeUpAndDismissInsecureKeyguard();
-        mContext.startActivity(getStartIntent(provisioningIntent));
-        Log.i(TAG, "startActivity with intent: " + provisioningIntent);
-
-        if (ACTION_PROVISION_MANAGED_PROFILE.equals(provisioningIntent.getAction())) {
-            return waitManagedProfileProvisioning();
-        } else {
-            return waitDeviceOwnerProvisioning();
-        }
-    }
-
-    private boolean waitDeviceOwnerProvisioning() throws InterruptedException {
-        return pollProvisioningResult();
-    }
-
-    private boolean waitManagedProfileProvisioning() throws InterruptedException {
-        BlockingBroadcastReceiver managedProfileProvisionedReceiver =
-                new BlockingBroadcastReceiver(mContext, ACTION_MANAGED_PROFILE_PROVISIONED);
-        BlockingBroadcastReceiver managedProfileAddedReceiver =
-                new BlockingBroadcastReceiver(mContext, ACTION_MANAGED_PROFILE_ADDED);
-        try {
-            managedProfileProvisionedReceiver.register();
-            managedProfileAddedReceiver.register();
-
-            if (!pollProvisioningResult()) {
-                return false;
-            }
-
-            mReceivedProfileProvisionedIntent =
-                    managedProfileProvisionedReceiver.awaitForBroadcast();
-            if (mReceivedProfileProvisionedIntent == null) {
-                Log.i(TAG, "managedProfileProvisionedReceiver.awaitForBroadcast(): failed");
-                return false;
-            }
-
-            if (managedProfileAddedReceiver.awaitForBroadcast() == null) {
-                Log.i(TAG, "managedProfileAddedReceiver.awaitForBroadcast(): failed");
-                return false;
-            }
-        } finally {
-            managedProfileProvisionedReceiver.unregisterQuietly();
-            managedProfileAddedReceiver.unregisterQuietly();
-        }
-        return true;
-    }
-
-    private boolean pollProvisioningResult() throws InterruptedException {
-        Boolean result = mProvisioningResults.poll(TIMEOUT_SECONDS, TimeUnit.SECONDS);
-        if (result == null) {
-            Log.i(TAG, "ManagedProvisioning doesn't return result within "
-                    + TIMEOUT_SECONDS + " seconds ");
-            return false;
-        }
-
-        if (!result) {
-            Log.i(TAG, "Failed to provision");
-            return false;
-        }
-        return true;
-    }
-
-    private Intent getStartIntent(Intent intent) {
-        final Bundle bundle = new Bundle();
-        bundle.putParcelable(Intent.EXTRA_INTENT, intent);
-        bundle.putBinder(StartProvisioningActivity.EXTRA_BOOLEAN_CALLBACK,
-                mProvisioningResultCallback.asBinder());
-        return new Intent(mContext, StartProvisioningActivity.class)
-                .putExtras(bundle)
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-    }
-
-    private static void wakeUpAndDismissInsecureKeyguard() {
-        try {
-            UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-            uiDevice.wakeUp();
-            uiDevice.pressMenu();
-        } catch (RemoteException e) {
-            Log.e(TAG, "wakeUpScreen", e);
-        }
-    }
-
-    private static class BlockingReceiver extends BroadcastReceiver {
-
-        private final CountDownLatch mLatch = new CountDownLatch(1);
-        private final Context mContext;
-        private final String mAction;
-        private Intent mReceivedIntent;
-
-        private BlockingReceiver(Context context, String action) {
-            mContext = context;
-            mAction = action;
-            mReceivedIntent = null;
-        }
-
-        public void register() {
-            mContext.registerReceiver(this, new IntentFilter(mAction));
-        }
-
-        public boolean await() throws InterruptedException {
-            return mLatch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS);
-        }
-
-        public Intent getReceivedIntent() {
-            return mReceivedIntent;
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            mReceivedIntent = intent;
-            mLatch.countDown();
-        }
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/StartProvisioningActivity.java b/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/StartProvisioningActivity.java
deleted file mode 100644
index 4a98794..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/StartProvisioningActivity.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util.devicepolicy.provisioning;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.WindowManager;
-
-/**
- * Must register it in AndroidManifest.xml
- * <activity android:name="com.android.compatibility.common.util.devicepolicy.provisioning.StartProvisioningActivity"></activity>
- */
-public class StartProvisioningActivity extends Activity {
-    private static final int REQUEST_CODE = 1;
-    private static final String TAG = "StartProvisionActivity";
-
-    public static final String EXTRA_BOOLEAN_CALLBACK = "EXTRA_BOOLEAN_CALLBACK";
-
-    IBooleanCallback mResultCallback;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Reduce flakiness of the test
-        // Show activity on top of keyguard
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
-        // Turn on screen to prevent activity being paused by system
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-
-        mResultCallback = IBooleanCallback.Stub.asInterface(
-                getIntent().getExtras().getBinder(EXTRA_BOOLEAN_CALLBACK));
-        Log.i(TAG, "result callback class name " + mResultCallback);
-
-        // Only provision it if the activity is not re-created
-        if (savedInstanceState == null) {
-            Intent provisioningIntent = getIntent().getParcelableExtra(Intent.EXTRA_INTENT);
-
-            startActivityForResult(provisioningIntent, REQUEST_CODE);
-            Log.i(TAG, "Start provisioning intent");
-        }
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == REQUEST_CODE) {
-            try {
-                boolean result = resultCode == RESULT_OK;
-                mResultCallback.onResult(result);
-                Log.i(TAG, "onActivityResult result: " + result);
-            } catch (RemoteException e) {
-                Log.e(TAG, "onActivityResult", e);
-            }
-        } else {
-            super.onActivityResult(requestCode, resultCode, data);
-        }
-    }
-}
\ No newline at end of file
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/transition/TargetTracking.java b/common/device-side/util/src/com/android/compatibility/common/util/transition/TargetTracking.java
deleted file mode 100644
index 7c53921..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/transition/TargetTracking.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.compatibility.common.util.transition;
-
-import android.graphics.Rect;
-import android.view.View;
-
-import java.util.ArrayList;
-
-public interface TargetTracking {
-    ArrayList<View> getTrackedTargets();
-    void clearTargets();
-    Rect getCapturedEpicenter();
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/transition/TrackingTransition.java b/common/device-side/util/src/com/android/compatibility/common/util/transition/TrackingTransition.java
deleted file mode 100644
index 55b235d..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/transition/TrackingTransition.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.compatibility.common.util.transition;
-
-import android.animation.Animator;
-import android.graphics.Rect;
-import android.transition.Transition;
-import android.transition.TransitionValues;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.util.ArrayList;
-
-/**
- * A transition that tracks which targets are applied to it.
- * It will assume any target that it applies to will have differences
- * between the start and end state, regardless of the differences
- * that actually exist. In other words, it doesn't actually check
- * any size or position differences or any other property of the view.
- * It just records the difference.
- * <p>
- * Both start and end value Views are recorded, but no actual animation
- * is created.
- */
-public class TrackingTransition extends Transition implements TargetTracking {
-    public final ArrayList<View> targets = new ArrayList<>();
-    private final Rect[] mEpicenter = new Rect[1];
-    private static String PROP = "tracking:prop";
-    private static String[] PROPS = { PROP };
-
-    @Override
-    public String[] getTransitionProperties() {
-        return PROPS;
-    }
-
-    @Override
-    public void captureStartValues(TransitionValues transitionValues) {
-        transitionValues.values.put(PROP, 0);
-    }
-
-    @Override
-    public void captureEndValues(TransitionValues transitionValues) {
-        transitionValues.values.put(PROP, 1);
-    }
-
-    @Override
-    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
-            TransitionValues endValues) {
-        if (startValues != null) {
-            targets.add(startValues.view);
-        }
-        if (endValues != null) {
-            targets.add(endValues.view);
-        }
-        Rect epicenter = getEpicenter();
-        if (epicenter != null) {
-            mEpicenter[0] = new Rect(epicenter);
-        } else {
-            mEpicenter[0] = null;
-        }
-        return null;
-    }
-
-    @Override
-    public ArrayList<View> getTrackedTargets() {
-        return targets;
-    }
-
-    @Override
-    public void clearTargets() {
-        targets.clear();
-    }
-
-    @Override
-    public Rect getCapturedEpicenter() {
-        return mEpicenter[0];
-    }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/transition/TrackingVisibility.java b/common/device-side/util/src/com/android/compatibility/common/util/transition/TrackingVisibility.java
deleted file mode 100644
index 8a5a19e..0000000
--- a/common/device-side/util/src/com/android/compatibility/common/util/transition/TrackingVisibility.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.compatibility.common.util.transition;
-
-import android.animation.Animator;
-import android.graphics.Rect;
-import android.transition.TransitionValues;
-import android.transition.Visibility;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.util.ArrayList;
-
-/**
- * Visibility transition that tracks which targets are applied to it.
- * This transition does no animation.
- */
-public class TrackingVisibility extends Visibility implements TargetTracking {
-    public final ArrayList<View> targets = new ArrayList<>();
-    private final Rect[] mEpicenter = new Rect[1];
-
-    @Override
-    public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
-            TransitionValues endValues) {
-        targets.add(endValues.view);
-        Rect epicenter = getEpicenter();
-        if (epicenter != null) {
-            mEpicenter[0] = new Rect(epicenter);
-        } else {
-            mEpicenter[0] = null;
-        }
-        return null;
-    }
-
-    @Override
-    public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
-            TransitionValues endValues) {
-        targets.add(startValues.view);
-        Rect epicenter = getEpicenter();
-        if (epicenter != null) {
-            mEpicenter[0] = new Rect(epicenter);
-        } else {
-            mEpicenter[0] = null;
-        }
-        return null;
-    }
-
-    @Override
-    public ArrayList<View> getTrackedTargets() {
-        return targets;
-    }
-
-    @Override
-    public void clearTargets() {
-        targets.clear();
-    }
-
-    @Override
-    public Rect getCapturedEpicenter() {
-        return mEpicenter[0];
-    }
-}
diff --git a/common/device-side/util/tests/Android.bp b/common/device-side/util/tests/Android.bp
deleted file mode 100644
index 2abba37..0000000
--- a/common/device-side/util/tests/Android.bp
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2015 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.
-
-java_test {
-    name: "compatibility-device-util-tests",
-
-    srcs: ["src/**/*.java"],
-
-    static_libs: [
-        "compatibility-device-util",
-        "junit",
-        "testng", // TODO: remove once Android migrates to JUnit 4.12, which provide assertThrows
-        "truth-prebuilt"
-    ],
-
-    sdk_version: "test_current",
-}
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/ApiLevelUtilTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/ApiLevelUtilTest.java
deleted file mode 100644
index 13305c3..0000000
--- a/common/device-side/util/tests/src/com/android/compatibility/common/util/ApiLevelUtilTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import android.os.Build;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for {@line ApiLevelUtil}.
- */
-@RunWith(AndroidJUnit4.class)
-public class ApiLevelUtilTest {
-
-    @Test
-    public void testComparisonByInt() throws Exception {
-        int version = Build.VERSION.SDK_INT;
-
-        assertFalse(ApiLevelUtil.isBefore(version - 1));
-        assertFalse(ApiLevelUtil.isBefore(version));
-        assertTrue(ApiLevelUtil.isBefore(version + 1));
-
-        assertTrue(ApiLevelUtil.isAfter(version - 1));
-        assertFalse(ApiLevelUtil.isAfter(version));
-        assertFalse(ApiLevelUtil.isAfter(version + 1));
-
-        assertTrue(ApiLevelUtil.isAtLeast(version - 1));
-        assertTrue(ApiLevelUtil.isAtLeast(version));
-        assertFalse(ApiLevelUtil.isAtLeast(version + 1));
-
-        assertFalse(ApiLevelUtil.isAtMost(version - 1));
-        assertTrue(ApiLevelUtil.isAtMost(version));
-        assertTrue(ApiLevelUtil.isAtMost(version + 1));
-    }
-
-    @Test
-    public void testComparisonByString() throws Exception {
-        // test should pass as long as device SDK version is at least 12
-        assertTrue(ApiLevelUtil.isAtLeast("HONEYCOMB_MR1"));
-        assertTrue(ApiLevelUtil.isAtLeast("12"));
-    }
-
-    @Test
-    public void testResolveVersionString() throws Exception {
-        // can only test versions known to the device build
-        assertEquals(ApiLevelUtil.resolveVersionString("GINGERBREAD_MR1"), 10);
-        assertEquals(ApiLevelUtil.resolveVersionString("10"), 10);
-        assertEquals(ApiLevelUtil.resolveVersionString("HONEYCOMB"), 11);
-        assertEquals(ApiLevelUtil.resolveVersionString("11"), 11);
-        assertEquals(ApiLevelUtil.resolveVersionString("honeycomb_mr1"), 12);
-        assertEquals(ApiLevelUtil.resolveVersionString("12"), 12);
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void testResolveMisspelledVersionString() throws Exception {
-        ApiLevelUtil.resolveVersionString("GINGERBEARD");
-    }
-}
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/BusinessLogicDeviceExecutorTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/BusinessLogicDeviceExecutorTest.java
deleted file mode 100644
index 9f3ca47..0000000
--- a/common/device-side/util/tests/src/com/android/compatibility/common/util/BusinessLogicDeviceExecutorTest.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
-import static org.junit.Assume.assumeTrue;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.AssumptionViolatedException;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import junit.framework.AssertionFailedError;
-
-/**
- * Tests for {@line BusinessLogicDeviceExecutor}.
- */
-@RunWith(AndroidJUnit4.class)
-public class BusinessLogicDeviceExecutorTest {
-
-    private static final String THIS_CLASS =
-            "com.android.compatibility.common.util.BusinessLogicDeviceExecutorTest";
-    private static final String METHOD_1 = THIS_CLASS + ".method1";
-    private static final String METHOD_2 = THIS_CLASS + ".method2";
-    private static final String METHOD_3 = THIS_CLASS + ".method3";
-    private static final String METHOD_4 = THIS_CLASS + ".method4";
-    private static final String METHOD_5 = THIS_CLASS + ".method5";
-    private static final String METHOD_6 = THIS_CLASS + ".method6";
-    private static final String METHOD_7 = THIS_CLASS + ".method7";
-    private static final String METHOD_8 = THIS_CLASS + ".method8";
-    private static final String METHOD_9 = THIS_CLASS + ".method9";
-    private static final String METHOD_10 = THIS_CLASS + ".method10";
-    private static final String FAKE_METHOD = THIS_CLASS + ".methodDoesntExist";
-    private static final String ARG_STRING_1 = "arg1";
-    private static final String ARG_STRING_2 = "arg2";
-
-    private static final String OTHER_METHOD_1 = THIS_CLASS + "$OtherClass.method1";
-
-    private String mInvoked = null;
-    private Object[] mArgsUsed = null;
-    private Context mContext;
-    private BusinessLogicExecutor mExecutor;
-
-    @Before
-    public void setUp() {
-        mContext = InstrumentationRegistry.getTargetContext();
-        mExecutor = new BusinessLogicDeviceExecutor(mContext, this);
-        // reset the instance variables tracking the method invoked and the args used
-        mInvoked = null;
-        mArgsUsed = null;
-        // reset the OtherClass class variable tracking the method invoked
-        OtherClass.otherInvoked = null;
-    }
-
-    @Test
-    public void testInvokeMethodInThisClass() throws Exception {
-        mExecutor.invokeMethod(METHOD_1);
-        // assert that mInvoked was set for this BusinessLogicDeviceExecutorTest instance
-        assertEquals("Failed to invoke method in this class", mInvoked, METHOD_1);
-    }
-
-    @Test
-    public void testInvokeMethodInOtherClass() throws Exception {
-        mExecutor.invokeMethod(OTHER_METHOD_1);
-        // assert that OtherClass.method1 was invoked, and static field of OtherClass was changed
-        assertEquals("Failed to invoke method in other class", OtherClass.otherInvoked,
-                OTHER_METHOD_1);
-    }
-
-    @Test
-    public void testInvokeMethodWithStringArgs() throws Exception {
-        mExecutor.invokeMethod(METHOD_2, ARG_STRING_1, ARG_STRING_2);
-        assertEquals("Failed to invoke method in this class", mInvoked, METHOD_2);
-        // assert both String arguments were correctly set for method2
-        assertEquals("Failed to set first argument", mArgsUsed[0], ARG_STRING_1);
-        assertEquals("Failed to set second argument", mArgsUsed[1], ARG_STRING_2);
-    }
-
-    @Test
-    public void testInvokeMethodWithStringAndContextArgs() throws Exception {
-        mExecutor.invokeMethod(METHOD_3, ARG_STRING_1);
-        assertEquals("Failed to invoke method in this class", mInvoked, METHOD_3);
-        // assert that String arg and Context arg were correctly set for method3
-        assertEquals("Failed to set first argument", mArgsUsed[0], ARG_STRING_1);
-        assertEquals("Failed to set second argument", mArgsUsed[1], mContext);
-    }
-
-    @Test
-    public void testInvokeMethodWithContextAndStringArgs() throws Exception {
-        mExecutor.invokeMethod(METHOD_4, ARG_STRING_1);
-        assertEquals("Failed to invoke method in this class", mInvoked, METHOD_4);
-        // Like testInvokeMethodWithStringAndContextArgs, but flip the args for method4
-        assertEquals("Failed to set first argument", mArgsUsed[0], mContext);
-        assertEquals("Failed to set second argument", mArgsUsed[1], ARG_STRING_1);
-    }
-
-    @Test
-    public void testInvokeMethodWithStringArrayArg() throws Exception {
-        mExecutor.invokeMethod(METHOD_5, ARG_STRING_1, ARG_STRING_2);
-        assertEquals("Failed to invoke method in this class", mInvoked, METHOD_5);
-        // assert both String arguments were correctly set for method5
-        assertEquals("Failed to set first argument", mArgsUsed[0], ARG_STRING_1);
-        assertEquals("Failed to set second argument", mArgsUsed[1], ARG_STRING_2);
-    }
-
-    @Test
-    public void testInvokeMethodWithEmptyStringArrayArg() throws Exception {
-        mExecutor.invokeMethod(METHOD_5);
-        assertEquals("Failed to invoke method in this class", mInvoked, METHOD_5);
-        // assert no String arguments were set for method5
-        assertEquals("Incorrectly set args", mArgsUsed.length, 0);
-    }
-
-    @Test
-    public void testInvokeMethodWithStringAndStringArrayArgs() throws Exception {
-        mExecutor.invokeMethod(METHOD_6, ARG_STRING_1, ARG_STRING_2);
-        assertEquals("Failed to invoke method in this class", mInvoked, METHOD_6);
-        // assert both String arguments were correctly set for method6
-        assertEquals("Failed to set first argument", mArgsUsed[0], ARG_STRING_1);
-        assertEquals("Failed to set second argument", mArgsUsed[1], ARG_STRING_2);
-    }
-
-    @Test
-    public void testInvokeMethodWithAllArgTypes() throws Exception {
-        mExecutor.invokeMethod(METHOD_7, ARG_STRING_1, ARG_STRING_2);
-        assertEquals("Failed to invoke method in this class", mInvoked, METHOD_7);
-        // assert all arguments were correctly set for method7
-        assertEquals("Failed to set first argument", mArgsUsed[0], ARG_STRING_1);
-        assertEquals("Failed to set second argument", mArgsUsed[1], mContext);
-        assertEquals("Failed to set third argument", mArgsUsed[2], ARG_STRING_2);
-    }
-
-    @Test
-    public void testInvokeOverloadedMethodOneArg() throws Exception {
-        mExecutor.invokeMethod(METHOD_1, ARG_STRING_1);
-        assertEquals("Failed to invoke method in this class", mInvoked, METHOD_1);
-        assertEquals("Set wrong number of arguments", mArgsUsed.length, 1);
-        assertEquals("Failed to set first argument", mArgsUsed[0], ARG_STRING_1);
-    }
-
-    @Test
-    public void testInvokeOverloadedMethodTwoArgs() throws Exception {
-        mExecutor.invokeMethod(METHOD_1, ARG_STRING_1, ARG_STRING_2);
-        assertEquals("Failed to invoke method in this class", mInvoked, METHOD_1);
-        assertEquals("Set wrong number of arguments", mArgsUsed.length, 2);
-        assertEquals("Failed to set first argument", mArgsUsed[0], ARG_STRING_1);
-        assertEquals("Failed to set second argument", mArgsUsed[1], ARG_STRING_2);
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void testInvokeNonExistentMethod() throws Exception {
-        mExecutor.invokeMethod(FAKE_METHOD, ARG_STRING_1, ARG_STRING_2);
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void testInvokeMethodTooManyArgs() throws Exception {
-        mExecutor.invokeMethod(METHOD_3, ARG_STRING_1, ARG_STRING_2);
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void testInvokeMethodTooFewArgs() throws Exception {
-        mExecutor.invokeMethod(METHOD_2, ARG_STRING_1);
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void testInvokeMethodIncompatibleArgs() throws Exception {
-        mExecutor.invokeMethod(METHOD_8, ARG_STRING_1);
-    }
-
-    @Test
-    public void testExecuteConditionCheckReturnValue() throws Exception {
-        assertTrue("Wrong return value",
-                mExecutor.executeCondition(METHOD_2, ARG_STRING_1, ARG_STRING_1));
-        assertFalse("Wrong return value",
-                mExecutor.executeCondition(METHOD_2, ARG_STRING_1, ARG_STRING_2));
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void testExecuteInvalidCondition() throws Exception {
-        mExecutor.executeCondition(METHOD_1); // method1 does not return type boolean
-    }
-
-    @Test
-    public void testExecuteAction() throws Exception {
-        mExecutor.executeAction(METHOD_2, ARG_STRING_1, ARG_STRING_2);
-        assertEquals("Failed to invoke method in this class", mInvoked, METHOD_2);
-        // assert both String arguments were correctly set for method2
-        assertEquals("Failed to set first argument", mArgsUsed[0], ARG_STRING_1);
-        assertEquals("Failed to set second argument", mArgsUsed[1], ARG_STRING_2);
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void testExecuteActionThrowException() throws Exception {
-        mExecutor.executeAction(METHOD_9);
-    }
-
-    @Test
-    public void testExecuteActionViolateAssumption() throws Exception {
-        try {
-            mExecutor.executeAction(METHOD_10);
-            // JUnit4 doesn't support expecting AssumptionViolatedException with "expected"
-            // attribute on @Test annotation, so test using Assert.fail()
-            fail("Expected assumption failure");
-        } catch (AssumptionViolatedException e) {
-            // expected
-        }
-    }
-
-    public void method1() {
-        mInvoked = METHOD_1;
-    }
-
-    // overloaded method with one arg
-    public void method1(String arg1) {
-        mInvoked = METHOD_1;
-        mArgsUsed = new Object[]{arg1};
-    }
-
-    // overloaded method with two args
-    public void method1(String arg1, String arg2) {
-        mInvoked = METHOD_1;
-        mArgsUsed = new Object[]{arg1, arg2};
-    }
-
-    public boolean method2(String arg1, String arg2) {
-        mInvoked = METHOD_2;
-        mArgsUsed = new Object[]{arg1, arg2};
-        return arg1.equals(arg2);
-    }
-
-    public void method3(String arg1, Context arg2) {
-        mInvoked = METHOD_3;
-        mArgsUsed = new Object[]{arg1, arg2};
-    }
-
-    // Same as method3, but flipped args
-    public void method4(Context arg1, String arg2) {
-        mInvoked = METHOD_4;
-        mArgsUsed = new Object[]{arg1, arg2};
-    }
-
-    public void method5(String... args) {
-        mInvoked = METHOD_5;
-        mArgsUsed = args;
-    }
-
-    public void method6(String arg1, String... moreArgs) {
-        mInvoked = METHOD_6;
-        List<String> allArgs = new ArrayList<>();
-        allArgs.add(arg1);
-        allArgs.addAll(Arrays.asList(moreArgs));
-        mArgsUsed = allArgs.toArray(new String[0]);
-    }
-
-    public void method7(String arg1, Context arg2, String... moreArgs) {
-        mInvoked = METHOD_7;
-        List<Object> allArgs = new ArrayList<>();
-        allArgs.add(arg1);
-        allArgs.add(arg2);
-        allArgs.addAll(Arrays.asList(moreArgs));
-        mArgsUsed = allArgs.toArray(new Object[0]);
-    }
-
-    public void method8(String arg1, Integer arg2) {
-        // This method should never be successfully invoked, since Integer parameter types are
-        // unsupported for the BusinessLogic service
-    }
-
-    // throw AssertionFailedError
-    @Ignore
-    public void method9() throws AssertionFailedError {
-        assertTrue(false);
-    }
-
-    // throw AssumptionViolatedException
-    public void method10() throws AssumptionViolatedException {
-        assumeTrue(false);
-    }
-
-    public static class OtherClass {
-
-        public static String otherInvoked = null;
-
-        public void method1() {
-            otherInvoked = OTHER_METHOD_1;
-        }
-    }
-}
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/BusinessLogicTestCaseTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/BusinessLogicTestCaseTest.java
deleted file mode 100644
index ad4acbb..0000000
--- a/common/device-side/util/tests/src/com/android/compatibility/common/util/BusinessLogicTestCaseTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Tests for {@line BusinessLogicTestCase}.
- */
-@RunWith(AndroidJUnit4.class)
-public class BusinessLogicTestCaseTest {
-
-    private static final String KEY_1 = "key1";
-    private static final String KEY_2 = "key2";
-    private static final String VALUE_1 = "value1";
-    private static final String VALUE_2 = "value2";
-
-    DummyTest mDummyTest;
-    DummyTest mOtherDummyTest;
-
-    @Before
-    public void setUp() {
-        mDummyTest = new DummyTest();
-        mOtherDummyTest = new DummyTest();
-    }
-
-    @Test
-    public void testMapPut() throws Exception {
-        mDummyTest.mapPut("instanceMap", KEY_1, VALUE_1);
-        assertTrue("mapPut failed for instanceMap", mDummyTest.instanceMap.containsKey(KEY_1));
-        assertEquals("mapPut failed for instanceMap", mDummyTest.instanceMap.get(KEY_1), VALUE_1);
-        assertTrue("mapPut affected wrong instance", mOtherDummyTest.instanceMap.isEmpty());
-    }
-
-    @Test
-    public void testStaticMapPut() throws Exception {
-        mDummyTest.mapPut("staticMap", KEY_2, VALUE_2);
-        assertTrue("mapPut failed for staticMap", mDummyTest.staticMap.containsKey(KEY_2));
-        assertEquals("mapPut failed for staticMap", mDummyTest.staticMap.get(KEY_2), VALUE_2);
-        assertTrue("mapPut on static map should affect all instances",
-                mOtherDummyTest.staticMap.containsKey(KEY_2));
-    }
-
-    public static class DummyTest extends BusinessLogicTestCase {
-        public Map<String, String> instanceMap = new HashMap<>();
-        public static Map<String, String> staticMap = new HashMap<>();
-    }
-}
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/DeviceReportTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/DeviceReportTest.java
deleted file mode 100644
index ab42b32..0000000
--- a/common/device-side/util/tests/src/com/android/compatibility/common/util/DeviceReportTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2015 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 com.android.compatibility.common.util;
-
-import android.app.Instrumentation;
-import android.os.Bundle;
-import android.os.Environment;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.lang.StringBuilder;
-
-import junit.framework.TestCase;
-
-import org.json.JSONObject;
-
-/**
- * Tests for {@line DeviceReportLog}.
- */
-public class DeviceReportTest extends TestCase {
-
-    /**
-     * A stub of {@link Instrumentation}
-     */
-    public class TestInstrumentation extends Instrumentation {
-
-        private int mResultCode = -1;
-        private Bundle mResults = null;
-
-        @Override
-        public void sendStatus(int resultCode, Bundle results) {
-            mResultCode = resultCode;
-            mResults = results;
-        }
-    }
-
-    private static final int RESULT_CODE = 2;
-    private static final String RESULT_KEY = "COMPATIBILITY_TEST_RESULT";
-    private static final String TEST_MESSAGE_1 = "Foo";
-    private static final double TEST_VALUE_1 = 3;
-    private static final ResultType TEST_TYPE_1 = ResultType.HIGHER_BETTER;
-    private static final ResultUnit TEST_UNIT_1 = ResultUnit.SCORE;
-    private static final String TEST_MESSAGE_2 = "Bar";
-    private static final double TEST_VALUE_2 = 5;
-    private static final ResultType TEST_TYPE_2 = ResultType.LOWER_BETTER;
-    private static final ResultUnit TEST_UNIT_2 = ResultUnit.COUNT;
-    private static final String TEST_MESSAGE_3 = "Sample";
-    private static final double TEST_VALUE_3 = 7;
-    private static final ResultType TEST_TYPE_3 = ResultType.LOWER_BETTER;
-    private static final ResultUnit TEST_UNIT_3 = ResultUnit.COUNT;
-    private static final String TEST_MESSAGE_4 = "Message";
-    private static final double TEST_VALUE_4 = 9;
-    private static final ResultType TEST_TYPE_4 = ResultType.LOWER_BETTER;
-    private static final ResultUnit TEST_UNIT_4 = ResultUnit.COUNT;
-    private static final String REPORT_NAME_1 = "TestReport1";
-    private static final String REPORT_NAME_2 = "TestReport2";
-    private static final String STREAM_NAME_1 = "SampleStream1";
-    private static final String STREAM_NAME_2 = "SampleStream2";
-    private static final String STREAM_NAME_3 = "SampleStream3";
-    private static final String STREAM_NAME_4 = "SampleStream4";
-
-    public void testSubmit() throws Exception {
-        DeviceReportLog log = new DeviceReportLog(REPORT_NAME_1, STREAM_NAME_1);
-        log.addValue(TEST_MESSAGE_1, TEST_VALUE_1, TEST_TYPE_1, TEST_UNIT_1);
-        log.setSummary(TEST_MESSAGE_2, TEST_VALUE_2, TEST_TYPE_2, TEST_UNIT_2);
-        TestInstrumentation inst = new TestInstrumentation();
-        log.submit(inst);
-        assertEquals("Incorrect result code", RESULT_CODE, inst.mResultCode);
-        assertNotNull("Bundle missing", inst.mResults);
-        String metrics = inst.mResults.getString(RESULT_KEY);
-        assertNotNull("Metrics missing", metrics);
-        ReportLog result = ReportLog.parse(metrics);
-        assertNotNull("Metrics could not be decoded", result);
-    }
-
-    public void testFile() throws Exception {
-        assertTrue("External storage is not mounted",
-                Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED));
-        final File dir = new File(Environment.getExternalStorageDirectory(), "report-log-files");
-        assertTrue("Report Log directory missing", dir.isDirectory() || dir.mkdirs());
-
-        // Remove files from earlier possible runs.
-        File[] files = dir.listFiles();
-        for (File file : files) {
-            file.delete();
-        }
-
-        TestInstrumentation inst = new TestInstrumentation();
-
-        DeviceReportLog log1 = new DeviceReportLog(REPORT_NAME_1, STREAM_NAME_1);
-        log1.addValue(TEST_MESSAGE_1, TEST_VALUE_1, TEST_TYPE_1, TEST_UNIT_1);
-        log1.setSummary(TEST_MESSAGE_1, TEST_VALUE_1, TEST_TYPE_1, TEST_UNIT_1);
-        log1.submit(inst);
-
-        DeviceReportLog log2 = new DeviceReportLog(REPORT_NAME_1, STREAM_NAME_2);
-        log2.addValue(TEST_MESSAGE_2, TEST_VALUE_2, TEST_TYPE_2, TEST_UNIT_2);
-        log2.setSummary(TEST_MESSAGE_2, TEST_VALUE_2, TEST_TYPE_2, TEST_UNIT_2);
-        log2.submit(inst);
-
-        DeviceReportLog log3 = new DeviceReportLog(REPORT_NAME_2, STREAM_NAME_3);
-        log3.addValue(TEST_MESSAGE_3, TEST_VALUE_3, TEST_TYPE_3, TEST_UNIT_3);
-        log3.setSummary(TEST_MESSAGE_3, TEST_VALUE_3, TEST_TYPE_3, TEST_UNIT_3);
-        log3.submit(inst);
-
-        DeviceReportLog log4 = new DeviceReportLog(REPORT_NAME_2, STREAM_NAME_4);
-        log4.addValue(TEST_MESSAGE_4, TEST_VALUE_4, TEST_TYPE_4, TEST_UNIT_4);
-        log4.setSummary(TEST_MESSAGE_4, TEST_VALUE_4, TEST_TYPE_4, TEST_UNIT_4);
-        log4.submit(inst);
-
-        File jsonFile1 = new File(dir, REPORT_NAME_1 + ".reportlog.json");
-        File jsonFile2 = new File(dir, REPORT_NAME_2 + ".reportlog.json");
-        assertTrue("Report Log missing", jsonFile1.exists());
-        assertTrue("Report Log missing", jsonFile2.exists());
-
-        BufferedReader jsonReader = new BufferedReader(new FileReader(jsonFile1));
-        StringBuilder metricsBuilder = new StringBuilder();
-        String line;
-        while ((line = jsonReader.readLine()) != null) {
-            metricsBuilder.append(line);
-        }
-        String metrics = metricsBuilder.toString().trim();
-        JSONObject jsonObject = new JSONObject(metrics);
-        assertTrue("Incorrect metrics",
-                jsonObject.getJSONObject(STREAM_NAME_1).getDouble(TEST_MESSAGE_1) == TEST_VALUE_1);
-        assertTrue("Incorrect metrics",
-                jsonObject.getJSONObject(STREAM_NAME_2).getDouble(TEST_MESSAGE_2) == TEST_VALUE_2);
-
-        jsonReader = new BufferedReader(new FileReader(jsonFile2));
-        metricsBuilder = new StringBuilder();
-        while ((line = jsonReader.readLine()) != null) {
-            metricsBuilder.append(line);
-        }
-        metrics = metricsBuilder.toString().trim();
-        jsonObject = new JSONObject(metrics);
-        assertTrue("Incorrect metrics",
-                jsonObject.getJSONObject(STREAM_NAME_3).getDouble(TEST_MESSAGE_3) == TEST_VALUE_3);
-        assertTrue("Incorrect metrics",
-                jsonObject.getJSONObject(STREAM_NAME_4).getDouble(TEST_MESSAGE_4) == TEST_VALUE_4);
-    }
-}
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/RetryRuleTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/RetryRuleTest.java
deleted file mode 100644
index 644d95f..0000000
--- a/common/device-side/util/tests/src/com/android/compatibility/common/util/RetryRuleTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.testng.Assert.assertThrows;
-import static org.testng.Assert.expectThrows;
-
-import org.junit.Test;
-import org.junit.runner.Description;
-import org.junit.runner.RunWith;
-import org.junit.runners.model.Statement;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class RetryRuleTest {
-
-    private final Description mDescription = Description.createSuiteDescription("Whatever");
-
-    private static final RetryableException sRetryableException =
-            new RetryableException("Y U NO RETRY?");
-
-    private static class RetryableStatement<T extends Exception> extends Statement {
-        private final int mNumberFailures;
-        private int mNumberCalls;
-        private final T mException;
-
-        RetryableStatement(int numberFailures, T exception) {
-            mNumberFailures = numberFailures;
-            mException = exception;
-        }
-
-        @Override
-        public void evaluate() throws Throwable {
-            mNumberCalls++;
-            if (mNumberCalls <= mNumberFailures) {
-                throw mException;
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "RetryableStatement: failures=" + mNumberFailures + ", calls=" + mNumberCalls;
-        }
-    }
-
-    private @Mock Statement mMockStatement;
-
-    @Test
-    public void testInvalidConstructor() throws Throwable {
-        assertThrows(IllegalArgumentException.class, () -> new RetryRule(-1));
-    }
-
-    @Test
-    public void testPassOnRetryableException() throws Throwable {
-        final RetryRule rule = new RetryRule(1);
-        rule.apply(new RetryableStatement<RetryableException>(1, sRetryableException), mDescription)
-                .evaluate();
-    }
-
-    @Test
-    public void testPassOnRetryableExceptionWithTimeout() throws Throwable {
-        final Timeout timeout = new Timeout("YOUR TIME IS GONE", 1, 2, 10);
-        final RetryableException exception = new RetryableException(timeout, "Y U NO?");
-
-        final RetryRule rule = new RetryRule(1);
-        rule.apply(new RetryableStatement<RetryableException>(1, exception), mDescription)
-                .evaluate();
-
-        // Assert timeout was increased
-        assertThat(timeout.ms()).isEqualTo(2);
-    }
-
-    @Test
-    public void testFailOnRetryableException() throws Throwable {
-        final RetryRule rule = new RetryRule(1);
-
-        final RetryableException actualException = expectThrows(RetryableException.class,
-                () -> rule.apply(new RetryableStatement<RetryableException>(2, sRetryableException),
-                        mDescription).evaluate());
-
-        assertThat(actualException).isSameAs(sRetryableException);
-    }
-
-    @Test
-    public void testPassWhenDisabledAndStatementPass() throws Throwable {
-        final RetryRule rule = new RetryRule(0);
-
-        rule.apply(mMockStatement, mDescription).evaluate();
-
-        verify(mMockStatement, times(1)).evaluate();
-    }
-
-    @Test
-    public void testFailWhenDisabledAndStatementThrowsRetryableException() throws Throwable {
-        final RetryableException exception = new RetryableException("Y U NO?");
-        final RetryRule rule = new RetryRule(0);
-        doThrow(exception).when(mMockStatement).evaluate();
-
-        final RetryableException actualException = expectThrows(RetryableException.class,
-                () -> rule.apply(mMockStatement, mDescription).evaluate());
-
-        assertThat(actualException).isSameAs(exception);
-        verify(mMockStatement, times(1)).evaluate();
-    }
-
-    @Test
-    public void testFailWhenDisabledAndStatementThrowsNonRetryableException() throws Throwable {
-        final RuntimeException exception = new RuntimeException("Y U NO?");
-        final RetryRule rule = new RetryRule(0);
-        doThrow(exception).when(mMockStatement).evaluate();
-
-        final RuntimeException actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mMockStatement, mDescription).evaluate());
-
-        assertThat(actualException).isSameAs(exception);
-        verify(mMockStatement, times(1)).evaluate();
-    }
-}
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/SafeCleanerRuleTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/SafeCleanerRuleTest.java
deleted file mode 100644
index a56d7b2..0000000
--- a/common/device-side/util/tests/src/com/android/compatibility/common/util/SafeCleanerRuleTest.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
-import static org.testng.Assert.expectThrows;
-
-import com.android.compatibility.common.util.SafeCleanerRule.Dumper;
-
-import com.google.common.collect.ImmutableList;
-
-import org.junit.AssumptionViolatedException;
-import org.junit.Test;
-import org.junit.runner.Description;
-import org.junit.runner.RunWith;
-import org.junit.runners.model.Statement;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-import java.util.List;
-import java.util.concurrent.Callable;
-
-@RunWith(MockitoJUnitRunner.class)
-public class SafeCleanerRuleTest {
-
-    private static class FailureStatement extends Statement {
-        private final Throwable mThrowable;
-
-        FailureStatement(Throwable t) {
-            mThrowable = t;
-        }
-
-        @Override
-        public void evaluate() throws Throwable {
-            throw mThrowable;
-        }
-    }
-
-    private final Description mDescription = Description.createSuiteDescription("Whatever");
-    private final RuntimeException mRuntimeException = new RuntimeException("D'OH!");
-
-    @Mock private Dumper mDumper;
-
-    // Use mocks for objects that don't throw any exception.
-    @Mock private ThrowingRunnable mGoodGuyRunner1;
-    @Mock private ThrowingRunnable mGoodGuyRunner2;
-    @Mock private Callable<List<Throwable>> mGoodGuyExtraExceptions1;
-    @Mock private Callable<List<Throwable>> mGoodGuyExtraExceptions2;
-    @Mock private Statement mGoodGuyStatement;
-
-    @Test
-    public void testEmptyRule_testPass() throws Throwable {
-        final SafeCleanerRule rule = new SafeCleanerRule();
-        rule.apply(mGoodGuyStatement, mDescription).evaluate();
-    }
-
-    @Test
-    public void testEmptyRule_testFails() throws Throwable {
-        final SafeCleanerRule rule = new SafeCleanerRule();
-        final Throwable actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(new FailureStatement(mRuntimeException), mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-    }
-
-    @Test
-    public void testEmptyRule_testFails_withDumper() throws Throwable {
-        final SafeCleanerRule rule = new SafeCleanerRule().setDumper(mDumper);
-        final Throwable actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(new FailureStatement(mRuntimeException), mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-        verify(mDumper).dump("Whatever", actualException);
-    }
-
-    @Test
-    public void testOnlyTestFails() throws Throwable {
-        final SafeCleanerRule rule = new SafeCleanerRule()
-                .run(mGoodGuyRunner1)
-                .add(mGoodGuyExtraExceptions1);
-        final Throwable actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(new FailureStatement(mRuntimeException), mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-        verify(mGoodGuyRunner1).run();
-        verify(mGoodGuyExtraExceptions1).call();
-    }
-
-    @Test
-    public void testOnlyTestFails_withDumper() throws Throwable {
-        final SafeCleanerRule rule = new SafeCleanerRule()
-                .setDumper(mDumper)
-                .run(mGoodGuyRunner1)
-                .add(mGoodGuyExtraExceptions1);
-        final Throwable actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(new FailureStatement(mRuntimeException), mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-        verify(mGoodGuyRunner1).run();
-        verify(mGoodGuyExtraExceptions1).call();
-        verify(mDumper).dump("Whatever", actualException);
-    }
-
-    @Test
-    public void testTestPass_oneRunnerFails() throws Throwable {
-        final SafeCleanerRule rule = new SafeCleanerRule()
-                .run(mGoodGuyRunner1)
-                .run(() -> { throw mRuntimeException; })
-                .run(mGoodGuyRunner2)
-                .add(mGoodGuyExtraExceptions1);
-        final Throwable actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mGoodGuyStatement, mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-        verify(mGoodGuyRunner1).run();
-        verify(mGoodGuyRunner2).run();
-        verify(mGoodGuyExtraExceptions1).call();
-    }
-
-    @Test
-    public void testTestPass_oneRunnerFails_withDumper() throws Throwable {
-        final SafeCleanerRule rule = new SafeCleanerRule()
-                .setDumper(mDumper)
-                .run(mGoodGuyRunner1)
-                .run(() -> {
-                    throw mRuntimeException;
-                })
-                .run(mGoodGuyRunner2)
-                .add(mGoodGuyExtraExceptions1);
-        final Throwable actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mGoodGuyStatement, mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-        verify(mGoodGuyRunner1).run();
-        verify(mGoodGuyRunner2).run();
-        verify(mGoodGuyExtraExceptions1).call();
-        verify(mDumper).dump("Whatever", actualException);
-    }
-
-    @Test
-    public void testTestPass_oneExtraExceptionThrownAsCallable() throws Throwable {
-        final SafeCleanerRule rule = new SafeCleanerRule()
-                .run(mGoodGuyRunner1)
-                .add(mRuntimeException)
-                .add(mGoodGuyExtraExceptions1)
-                .run(mGoodGuyRunner2);
-        final Throwable actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mGoodGuyStatement, mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-        verify(mGoodGuyRunner1).run();
-        verify(mGoodGuyRunner2).run();
-        verify(mGoodGuyExtraExceptions1).call();
-    }
-
-    @Test
-    public void testTestPass_oneExtraExceptionThrown() throws Throwable {
-        final SafeCleanerRule rule = new SafeCleanerRule()
-                .run(mGoodGuyRunner1)
-                .add(() -> {
-                    return ImmutableList.of(mRuntimeException);
-                })
-                .add(mGoodGuyExtraExceptions1)
-                .run(mGoodGuyRunner2);
-        final Throwable actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mGoodGuyStatement, mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-        verify(mGoodGuyRunner1).run();
-        verify(mGoodGuyRunner2).run();
-        verify(mGoodGuyExtraExceptions1).call();
-    }
-
-    @Test
-    public void testTestPass_oneExtraExceptionThrown_withDumper() throws Throwable {
-        final SafeCleanerRule rule = new SafeCleanerRule()
-                .setDumper(mDumper)
-                .run(mGoodGuyRunner1)
-                .add(() -> { return ImmutableList.of(mRuntimeException); })
-                .add(mGoodGuyExtraExceptions1)
-                .run(mGoodGuyRunner2);
-        final Throwable actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mGoodGuyStatement, mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-        verify(mGoodGuyRunner1).run();
-        verify(mGoodGuyRunner2).run();
-        verify(mGoodGuyExtraExceptions1).call();
-        verify(mDumper).dump("Whatever", actualException);
-    }
-
-    @Test
-    public void testThrowTheKitchenSinkAKAEverybodyThrows() throws Throwable {
-        final Exception extra1 = new Exception("1");
-        final Exception extra2 = new Exception("2");
-        final Exception extra3 = new Exception("3");
-        final Error error1 = new Error("one");
-        final Error error2 = new Error("two");
-        final RuntimeException testException  = new RuntimeException("TEST, Y U NO PASS?");
-        final SafeCleanerRule rule = new SafeCleanerRule()
-                .run(mGoodGuyRunner1)
-                .add(mGoodGuyExtraExceptions1)
-                .add(mRuntimeException)
-                .add(() -> {
-                    return ImmutableList.of(extra1, extra2);
-                })
-                .run(() -> {
-                    throw error1;
-                })
-                .run(mGoodGuyRunner2)
-                .add(() -> {
-                    return ImmutableList.of(extra3);
-                })
-                .add(mGoodGuyExtraExceptions2)
-                .run(() -> {
-                    throw error2;
-                });
-
-        final SafeCleanerRule.MultipleExceptions actualException = expectThrows(
-                SafeCleanerRule.MultipleExceptions.class,
-                () -> rule.apply(new FailureStatement(testException), mDescription).evaluate());
-        assertThat(actualException.getThrowables())
-                .containsExactly(testException, mRuntimeException, error1, error2, extra1, extra2,
-                        extra3)
-                .inOrder();
-        verify(mGoodGuyRunner1).run();
-        verify(mGoodGuyRunner2).run();
-        verify(mGoodGuyExtraExceptions1).call();
-    }
-
-    @Test
-    public void testIgnoreAssumptionViolatedException() throws Throwable {
-        final AssumptionViolatedException ave = new AssumptionViolatedException(
-                "tis an assumption violation");
-        final RuntimeException testException  = new RuntimeException("TEST, Y U NO PASS?");
-        final SafeCleanerRule rule = new SafeCleanerRule()
-                .run(mGoodGuyRunner1)
-                .add(mRuntimeException)
-                .run(() -> {
-                    throw ave;
-                });
-
-        final SafeCleanerRule.MultipleExceptions actualException = expectThrows(
-                SafeCleanerRule.MultipleExceptions.class,
-                () -> rule.apply(new FailureStatement(testException), mDescription).evaluate());
-        assertThat(actualException.getThrowables())
-                .containsExactly(testException, mRuntimeException)
-                .inOrder();
-        verify(mGoodGuyRunner1).run();
-    }
-
-    @Test
-    public void testThrowTheKitchenSinkAKAEverybodyThrows_withDumper() throws Throwable {
-        final Exception extra1 = new Exception("1");
-        final Exception extra2 = new Exception("2");
-        final Exception extra3 = new Exception("3");
-        final Exception extra4 = new Exception("4");
-        final Error error1 = new Error("one");
-        final Error error2 = new Error("two");
-        final RuntimeException testException  = new RuntimeException("TEST, Y U NO PASS?");
-        final SafeCleanerRule rule = new SafeCleanerRule()
-                .setDumper(mDumper)
-                .run(mGoodGuyRunner1)
-                .add(mGoodGuyExtraExceptions1)
-                .add(() -> {
-                    return ImmutableList.of(extra1, extra2);
-                })
-                .run(() -> {
-                    throw error1;
-                })
-                .run(mGoodGuyRunner2)
-                .add(() -> { return ImmutableList.of(extra3); })
-                .add(mGoodGuyExtraExceptions2)
-                .run(() -> {
-                    throw error2;
-                })
-                .run(() -> {
-                    throw extra4;
-                });
-
-        final SafeCleanerRule.MultipleExceptions actualException = expectThrows(
-                SafeCleanerRule.MultipleExceptions.class,
-                () -> rule.apply(new FailureStatement(testException), mDescription).evaluate());
-        assertThat(actualException.getThrowables())
-                .containsExactly(testException, error1, error2, extra4, extra1, extra2, extra3)
-                .inOrder();
-        verify(mGoodGuyRunner1).run();
-        verify(mGoodGuyRunner2).run();
-        verify(mGoodGuyExtraExceptions1).call();
-        verify(mDumper).dump("Whatever", actualException);
-    }
-}
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/StateChangerRuleTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/StateChangerRuleTest.java
deleted file mode 100644
index 9b1851e..0000000
--- a/common/device-side/util/tests/src/com/android/compatibility/common/util/StateChangerRuleTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
-import static org.testng.Assert.expectThrows;
-
-import org.junit.Test;
-import org.junit.runner.Description;
-import org.junit.runner.RunWith;
-import org.junit.runners.model.Statement;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class StateChangerRuleTest {
-
-    private final RuntimeException mRuntimeException = new RuntimeException("D'OH");
-    private final Description mDescription = Description.createSuiteDescription("Whatever");
-
-    @Mock
-    private StateManager<String> mStateManager;
-
-    @Mock
-    private Statement mStatement;
-
-    @Test
-    public void testInvalidConstructor() {
-        assertThrows(NullPointerException.class,
-                () -> new StateChangerRule<Object>(null, "value"));
-    }
-
-    @Test
-    public void testSetAndRestoreOnSuccess() throws Throwable {
-        final StateChangerRule<String> rule = new StateChangerRule<>(mStateManager,
-                "newValue");
-        when(mStateManager.get()).thenReturn("before", "changed");
-
-        rule.apply(mStatement, mDescription).evaluate();
-
-        verify(mStatement, times(1)).evaluate();
-        verify(mStateManager, times(2)).get(); // Needed because of verifyNoMoreInteractions()
-        verify(mStateManager, times(1)).set("newValue");
-        verify(mStateManager, times(1)).set("before");
-        verifyNoMoreInteractions(mStateManager); // Make sure set() was not called again
-    }
-
-    @Test
-    public void testDontSetIfSameValueOnSuccess() throws Throwable {
-        final StateChangerRule<String> rule = new StateChangerRule<>(mStateManager,
-                "sameValue");
-        when(mStateManager.get()).thenReturn("sameValue");
-
-        rule.apply(mStatement, mDescription).evaluate();
-
-        verify(mStatement, times(1)).evaluate();
-        verify(mStateManager, never()).set(anyString());
-    }
-
-    @Test
-    public void testSetButDontRestoreIfSameValueOnSuccess() throws Throwable {
-        final StateChangerRule<String> rule = new StateChangerRule<>(mStateManager,
-                "newValue");
-        when(mStateManager.get()).thenReturn("before", "before");
-
-        rule.apply(mStatement, mDescription).evaluate();
-
-        verify(mStatement, times(1)).evaluate();
-        verify(mStateManager, times(2)).get(); // Needed because of verifyNoMoreInteractions()
-        verify(mStateManager, times(1)).set("newValue");
-        verifyNoMoreInteractions(mStateManager); // Make sure set() was not called again
-    }
-
-    @Test
-    public void testDontSetButRestoreIfValueChangedOnSuccess() throws Throwable {
-        final StateChangerRule<String> rule = new StateChangerRule<>(mStateManager,
-                "sameValue");
-        when(mStateManager.get()).thenReturn("sameValue", "changed");
-
-        rule.apply(mStatement, mDescription).evaluate();
-
-        verify(mStateManager, times(2)).get(); // Needed because of verifyNoMoreInteractions()
-        verify(mStatement, times(1)).evaluate();
-        verify(mStateManager, times(1)).set("sameValue");
-        verifyNoMoreInteractions(mStateManager); // Make sure set() was not called again
-    }
-
-    @Test
-    public void testSetAndRestoreOnFailure() throws Throwable {
-        final StateChangerRule<String> rule = new StateChangerRule<>(mStateManager,
-                "newValue");
-        when(mStateManager.get()).thenReturn("before", "changed");
-        doThrow(mRuntimeException).when(mStatement).evaluate();
-
-        final RuntimeException actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mStatement, mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-
-        verify(mStateManager, times(2)).get(); // Needed because of verifyNoMoreInteractions()
-        verify(mStateManager, times(1)).set("newValue");
-        verify(mStateManager, times(1)).set("before");
-        verifyNoMoreInteractions(mStateManager); // Make sure set() was not called again
-    }
-
-    @Test
-    public void testDontSetIfSameValueOnFailure() throws Throwable {
-        final StateChangerRule<String> rule = new StateChangerRule<>(mStateManager,
-                "sameValue");
-        when(mStateManager.get()).thenReturn("sameValue");
-        doThrow(mRuntimeException).when(mStatement).evaluate();
-
-        final RuntimeException actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mStatement, mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-
-        verify(mStateManager, never()).set(anyString());
-    }
-
-    @Test
-    public void testSetButDontRestoreIfSameValueOnFailure() throws Throwable {
-        final StateChangerRule<String> rule = new StateChangerRule<>(mStateManager,
-                "newValue");
-        when(mStateManager.get()).thenReturn("before", "before");
-        doThrow(mRuntimeException).when(mStatement).evaluate();
-
-        final RuntimeException actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mStatement, mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-
-        verify(mStateManager, times(2)).get(); // Needed because of verifyNoMoreInteractions()
-        verify(mStateManager, times(1)).set("newValue");
-        verifyNoMoreInteractions(mStateManager); // Make sure set() was not called again
-    }
-
-    @Test
-    public void testDontSetButRestoreIfValueChangedOnFailure() throws Throwable {
-        final StateChangerRule<String> rule = new StateChangerRule<>(mStateManager,
-                "sameValue");
-        when(mStateManager.get()).thenReturn("sameValue", "changed");
-        doThrow(mRuntimeException).when(mStatement).evaluate();
-
-        final RuntimeException actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mStatement, mDescription).evaluate());
-        assertThat(actualException).isSameAs(mRuntimeException);
-
-        verify(mStateManager, times(2)).get(); // Needed because of verifyNoMoreInteractions()
-        verify(mStateManager, times(1)).set("sameValue");
-        verifyNoMoreInteractions(mStateManager); // Make sure set() was not called again
-    }
-}
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/StateKeeperRuleTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/StateKeeperRuleTest.java
deleted file mode 100644
index 4599aca..0000000
--- a/common/device-side/util/tests/src/com/android/compatibility/common/util/StateKeeperRuleTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
-import static org.testng.Assert.expectThrows;
-
-import org.junit.Test;
-import org.junit.runner.Description;
-import org.junit.runner.RunWith;
-import org.junit.runners.model.Statement;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class StateKeeperRuleTest {
-
-    private final RuntimeException mRuntimeException = new RuntimeException("D'OH");
-    private final Description mDescription = Description.createSuiteDescription("Whatever");
-
-    @Mock
-    private StateManager<String> mStateManager;
-
-    @Mock
-    private Statement mStatement;
-
-    @Test
-    public void testInvalidConstructor() {
-        assertThrows(NullPointerException.class, () -> new StateKeeperRule<Object>(null));
-    }
-
-    @Test
-    public void testRestoreOnSuccess() throws Throwable {
-        final StateKeeperRule<String> rule = new StateKeeperRule<>(mStateManager);
-        when(mStateManager.get()).thenReturn("before", "changed");
-
-        rule.apply(mStatement, mDescription).evaluate();
-
-        verify(mStatement, times(1)).evaluate();
-        verify(mStateManager, times(2)).get(); // Needed because of verifyNoMoreInteractions()
-        verify(mStateManager, times(1)).set("before");
-        verifyNoMoreInteractions(mStateManager); // Make sure set() was not called again
-    }
-
-    @Test
-    public void testRestoreOnFailure() throws Throwable {
-        final StateKeeperRule<String> rule = new StateKeeperRule<>(mStateManager);
-        when(mStateManager.get()).thenReturn("before", "changed");
-        doThrow(mRuntimeException).when(mStatement).evaluate();
-
-        final RuntimeException actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mStatement, mDescription).evaluate());
-
-        assertThat(actualException).isSameAs(mRuntimeException);
-        verify(mStateManager, times(2)).get(); // Needed because of verifyNoMoreInteractions()
-        verify(mStateManager, times(1)).set("before");
-        verifyNoMoreInteractions(mStateManager); // Make sure set() was not called again
-    }
-
-    @Test
-    public void testDoNotRestoreWhenNotChanged() throws Throwable {
-        final StateKeeperRule<String> rule = new StateKeeperRule<>(mStateManager);
-        when(mStateManager.get()).thenReturn("not_changed");
-
-        rule.apply(mStatement, mDescription).evaluate();
-
-        verify(mStatement, times(1)).evaluate();
-        verify(mStateManager, never()).set(anyString());
-    }
-
-    @Test
-    public void testDoNotRestoreOnFailure() throws Throwable {
-        final StateKeeperRule<String> rule = new StateKeeperRule<>(mStateManager);
-        when(mStateManager.get()).thenReturn("not_changed");
-        doThrow(mRuntimeException).when(mStatement).evaluate();
-
-        final RuntimeException actualException = expectThrows(RuntimeException.class,
-                () -> rule.apply(mStatement, mDescription).evaluate());
-
-        assertThat(actualException).isSameAs(mRuntimeException);
-
-        verify(mStateManager, never()).set(anyString());
-    }
-}
diff --git a/common/device-side/util/tests/src/com/android/compatibility/common/util/TimeoutTest.java b/common/device-side/util/tests/src/com/android/compatibility/common/util/TimeoutTest.java
deleted file mode 100644
index 8992d18..0000000
--- a/common/device-side/util/tests/src/com/android/compatibility/common/util/TimeoutTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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 com.android.compatibility.common.util;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
-import static org.testng.Assert.expectThrows;
-
-import android.os.SystemClock;
-
-import com.android.compatibility.common.util.Timeout.Sleeper;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-import java.util.concurrent.Callable;
-
-@RunWith(MockitoJUnitRunner.class)
-public class TimeoutTest {
-
-    private static final String NAME = "TIME, Y U NO OUT?";
-    private static final String DESC = "something";
-
-    @Mock
-    private Callable<Object> mJob;
-
-    private final MySleeper mSleeper = new MySleeper();
-
-    @Test
-    public void testInvalidConstructor() {
-        // Invalid name
-        assertThrows(IllegalArgumentException.class, ()-> new Timeout(null, 1, 2, 2));
-        assertThrows(IllegalArgumentException.class, ()-> new Timeout("", 1, 2, 2));
-        // Invalid initial value
-        assertThrows(IllegalArgumentException.class, ()-> new Timeout(NAME, -1, 2, 2));
-        assertThrows(IllegalArgumentException.class, ()-> new Timeout(NAME, 0, 2, 2));
-        // Invalid multiplier
-        assertThrows(IllegalArgumentException.class, ()-> new Timeout(NAME, 1, -1, 2));
-        assertThrows(IllegalArgumentException.class, ()-> new Timeout(NAME, 1, 0, 2));
-        assertThrows(IllegalArgumentException.class, ()-> new Timeout(NAME, 1, 1, 2));
-        // Invalid max value
-        assertThrows(IllegalArgumentException.class, ()-> new Timeout(NAME, 1, 2, -1));
-        assertThrows(IllegalArgumentException.class, ()-> new Timeout(NAME, 1, 2, 0));
-        // Max value cannot be less than initial
-        assertThrows(IllegalArgumentException.class, ()-> new Timeout(NAME, 2, 2, 1));
-    }
-
-    @Test
-    public void testGetters() {
-        final Timeout timeout = new Timeout(NAME, 1, 2, 5);
-        assertThat(timeout.ms()).isEqualTo(1);
-        assertFloat(timeout.getMultiplier(), 2);
-        assertThat(timeout.getMaxValue()).isEqualTo(5);
-        assertThat(timeout.getName()).isEqualTo(NAME);
-    }
-
-    @Test
-    public void testIncrease() {
-        final Timeout timeout = new Timeout(NAME, 1, 2, 5);
-        // Pre-maximum
-        assertThat(timeout.increase()).isEqualTo(1);
-        assertThat(timeout.ms()).isEqualTo(2);
-        assertThat(timeout.increase()).isEqualTo(2);
-        assertThat(timeout.ms()).isEqualTo(4);
-        // Post-maximum
-        assertThat(timeout.increase()).isEqualTo(4);
-        assertThat(timeout.ms()).isEqualTo(5);
-        assertThat(timeout.increase()).isEqualTo(5);
-        assertThat(timeout.ms()).isEqualTo(5);
-    }
-
-    @Test
-    public void testRun_invalidArgs() {
-        final Timeout timeout = new Timeout(NAME, 1, 2, 5);
-        // Invalid description
-        assertThrows(IllegalArgumentException.class, ()-> timeout.run(null, mJob));
-        assertThrows(IllegalArgumentException.class, ()-> timeout.run("", mJob));
-        // Invalid max attempts
-        assertThrows(IllegalArgumentException.class, ()-> timeout.run(DESC, -1, mJob));
-        assertThrows(IllegalArgumentException.class, ()-> timeout.run(DESC, 0, mJob));
-        // Invalid job
-        assertThrows(IllegalArgumentException.class, ()-> timeout.run(DESC, null));
-    }
-
-    @Test
-    public void testRun_successOnFirstAttempt() throws Exception {
-        final Timeout timeout = new Timeout(mSleeper, NAME, 100, 2, 500);
-        final Object result = new Object();
-        when(mJob.call()).thenReturn(result);
-        assertThat(timeout.run(DESC, 1, mJob)).isSameAs(result);
-        assertThat(mSleeper.totalSleepingTime).isEqualTo(0);
-    }
-
-    @Test
-    public void testRun_successOnSecondAttempt() throws Exception {
-        final Timeout timeout = new Timeout(mSleeper, NAME, 100, 2, 500);
-        final Object result = new Object();
-        when(mJob.call()).thenReturn((Object) null, result);
-        assertThat(timeout.run(DESC, 10, mJob)).isSameAs(result);
-        assertThat(mSleeper.totalSleepingTime).isEqualTo(10);
-    }
-
-    @Test
-    public void testRun_allAttemptsFailed() throws Exception {
-        final Timeout timeout = new Timeout(mSleeper, NAME, 100, 2, 500);
-        final RetryableException e = expectThrows(RetryableException.class,
-                () -> timeout.run(DESC, 10, mJob));
-        assertThat(e.getMessage()).contains(DESC);
-        assertThat(e.getTimeout()).isSameAs(timeout);
-        assertThat(mSleeper.totalSleepingTime).isEqualTo(100);
-    }
-
-    private static final class MySleeper implements Sleeper {
-        public long totalSleepingTime;
-
-        @Override
-        public void sleep(long napTimeMs) {
-            // We still need to sleep, as the retry is based on ellapsed time. We could use a
-            // Mockito spy, but let's keep it simple
-            SystemClock.sleep(napTimeMs);
-            totalSleepingTime += napTimeMs;
-        }
-    }
-
-    public static void assertFloat(float actualValue, float expectedValue) {
-        assertThat(actualValue).isWithin(1.0e-10f).of(expectedValue);
-    }
-}
diff --git a/hostsidetests/appbinding/hostside/OWNERS b/hostsidetests/appbinding/hostside/OWNERS
new file mode 100644
index 0000000..77d350b
--- /dev/null
+++ b/hostsidetests/appbinding/hostside/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 533114
+omakoto@google.com
+yamasani@google.com
diff --git a/hostsidetests/appsecurity/OWNERS b/hostsidetests/appsecurity/OWNERS
index f86fd96..ea12403 100644
--- a/hostsidetests/appsecurity/OWNERS
+++ b/hostsidetests/appsecurity/OWNERS
@@ -25,8 +25,10 @@
 per-file PermissionsHostTest.java = moltmann@google.com
 per-file PkgInstallSignatureVerificationTest.java = cbrubaker@google.com
 per-file PrivilegedUpdateTests.java = toddke@google.com
+per-file ReviewPermissionHelper = moltmann@google.com
+per-file RequestsOnlyCalendarApp22.java = moltmann@google.com
 per-file ScopedDirectoryAccessTest.java = jsharkey@google.com
 per-file SplitTests.java = toddke@google.com
 per-file StorageHostTest.java = jsharkey@google.com
 per-file UseEmbeddedDexTest.java = victorhsieh@google.com
-per-file UsePermission*.java = moltmann@google.com
+per-file UsePermission*.java = moltmann@google.com
\ No newline at end of file
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppOpsTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppOpsTest.java
deleted file mode 100644
index 5c53f20..0000000
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppOpsTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2019 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 android.platform.test.annotations.AppModeFull;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test for app ops behaviors.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-@AppModeFull(reason = "No instant specific behaviors")
-public final class AppOpsTest extends BaseHostJUnit4Test {
-
-    @Test
-    public void testBadConfigCannotCauseBootLoop() throws Exception {
-        setAppOpHistoryParameters("mode=HISTORICAL_MODE_ENABLED_ACTIVE,baseIntervalMillis=1000"
-                + ",intervalMultiplier=10");
-        try {
-            createBadHistoricalFile();
-            getDevice().reboot();
-        } finally {
-            deleteHistoricalFiles();
-            setAppOpHistoryParameters(null);
-        }
-    }
-
-    private void setAppOpHistoryParameters(String value) throws Exception {
-        getDevice().executeShellCommand("settings put global appop_history_parameters " + value);
-    }
-
-    private void createBadHistoricalFile() throws Exception {
-        getDevice().executeShellCommand("touch data/system/appops/history/1000.xml");
-    }
-
-    private void deleteHistoricalFiles() throws Exception {
-        getDevice().executeShellCommand("rm -rf data/system/appops/history");
-    }
-}
diff --git a/hostsidetests/appsecurity/test-apps/DeclareNotRuntimePermissions/OWNERS b/hostsidetests/appsecurity/test-apps/DeclareNotRuntimePermissions/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/DeclareNotRuntimePermissions/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/DuplicatePermissionDeclareApp/OWNERS b/hostsidetests/appsecurity/test-apps/DuplicatePermissionDeclareApp/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/DuplicatePermissionDeclareApp/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/OWNERS b/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/EscalateToRuntimePermissions/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/OWNERS b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/OWNERS b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/PermissionPolicy25/OWNERS b/hostsidetests/appsecurity/test-apps/PermissionPolicy25/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PermissionPolicy25/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/AndroidManifest.xml
index 7b254dc..30d73f5 100644
--- a/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/AndroidManifest.xml
@@ -19,7 +19,7 @@
         package="com.android.cts.reviewpermissionhelper">
 
     <application>
-        <activity android:name=".ActivityStarter" />
+        <activity android:name="com.android.compatibility.common.util.FutureResultActivity" />
         <uses-library android:name="android.test.runner" />
     </application>
 
diff --git a/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/OWNERS b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/src/com/android/cts/reviewpermissionhelper/ActivityStarter.kt b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/src/com/android/cts/reviewpermissionhelper/ActivityStarter.kt
deleted file mode 100644
index 90dbca9..0000000
--- a/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/src/com/android/cts/reviewpermissionhelper/ActivityStarter.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2018 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 com.android.cts.reviewpermissionhelper
-
-import android.app.Activity
-import android.content.Intent
-import android.os.Bundle
-import java.util.concurrent.LinkedBlockingQueue
-
-val installDialogResults = LinkedBlockingQueue<Int>()
-
-class ActivityStarter : Activity() {
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-
-        savedInstanceState ?: installDialogResults.clear()
-    }
-
-    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
-        installDialogResults.offer(resultCode)
-    }
-}
diff --git a/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/src/com/android/cts/reviewpermissionhelper/ReviewPermissionsTest.kt b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/src/com/android/cts/reviewpermissionhelper/ReviewPermissionsTest.kt
index 15fdff3..b07a4bb 100644
--- a/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/src/com/android/cts/reviewpermissionhelper/ReviewPermissionsTest.kt
+++ b/hostsidetests/appsecurity/test-apps/ReviewPermissionHelper/src/com/android/cts/reviewpermissionhelper/ReviewPermissionsTest.kt
@@ -32,11 +32,13 @@
 import android.support.test.uiautomator.By
 import android.support.test.uiautomator.UiDevice
 import android.support.test.uiautomator.Until
+import com.android.compatibility.common.util.FutureResultActivity
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNull
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
+import java.util.concurrent.CompletableFuture
 import java.util.concurrent.LinkedBlockingQueue
 import java.util.concurrent.TimeUnit
 
@@ -47,16 +49,22 @@
 @RunWith(AndroidJUnit4::class)
 class ReviewPermissionsTest {
     @get:Rule
-    val activityStarter = ActivityTestRule(ActivityStarter::class.java)
+    val activityStarter = ActivityTestRule(FutureResultActivity::class.java)
 
     val instrumentation = InstrumentationRegistry.getInstrumentation()
     val uiDevice = UiDevice.getInstance(instrumentation)
 
-    fun startActivityInReviewedAp() {
+    fun startActivityInReviewedAp(): CompletableFuture<Int> {
         val startAutoClosingActivity = Intent()
         startAutoClosingActivity.component = ComponentName(USE_PERMISSION_PKG,
                 USE_PERMISSION_PKG + ".AutoClosingActivity")
-        activityStarter.activity.startActivityForResult(startAutoClosingActivity, 42)
+        return activityStarter.activity.startActivityForResult(startAutoClosingActivity)
+    }
+
+    private inline fun startActivityInReviewedAp(expectedResult: Int, runAfterStart: () -> Unit) {
+        val activityResult = startActivityInReviewedAp()
+        runAfterStart()
+        assertEquals(expectedResult, activityResult.get(UI_TIMEOUT, TimeUnit.MILLISECONDS))
     }
 
     fun clickContinue() {
@@ -66,24 +74,23 @@
 
     @Test
     fun approveReviewPermissions() {
-        startActivityInReviewedAp()
-        clickContinue()
-        assertEquals(RESULT_OK, installDialogResults.poll(UI_TIMEOUT, TimeUnit.MILLISECONDS))
+        startActivityInReviewedAp(expectedResult = RESULT_OK) {
+            clickContinue()
+        }
     }
 
     @Test
     fun cancelReviewPermissions() {
-        startActivityInReviewedAp()
-
-        uiDevice.wait(Until.findObject(
-                By.res("com.android.permissioncontroller:id/cancel_button")), UI_TIMEOUT).click()
-        assertEquals(RESULT_CANCELED, installDialogResults.poll(UI_TIMEOUT, TimeUnit.MILLISECONDS))
+        startActivityInReviewedAp(expectedResult = RESULT_CANCELED) {
+            uiDevice.wait(Until.findObject(
+                    By.res("com.android.permissioncontroller:id/cancel_button")), UI_TIMEOUT)
+                    .click()
+        }
     }
 
     @Test
     fun assertNoReviewPermissionsNeeded() {
-        startActivityInReviewedAp()
-        assertEquals(RESULT_OK, installDialogResults.poll(UI_TIMEOUT, TimeUnit.MILLISECONDS))
+        startActivityInReviewedAp(expectedResult = RESULT_OK) {}
     }
 
     @Test
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/OWNERS b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java
index 20be2cc..a1bd122 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java
@@ -36,7 +36,6 @@
  * Runtime permission behavior tests for apps targeting API 22
  */
 public class UsePermissionTest22 extends BasePermissionsTest {
-    private static final int REQUEST_CODE_PERMISSIONS = 42;
 
     private final Context mContext = getInstrumentation().getContext();
 
@@ -137,11 +136,9 @@
     public void testNoRuntimePrompt() throws Exception {
         // Request the permission and do nothing
         BasePermissionActivity.Result result = requestPermissions(
-                new String[] {Manifest.permission.SEND_SMS}, REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class, null);
+                new String[]{Manifest.permission.SEND_SMS}, null);
 
         // Expect the permission is not granted
-        assertEquals(REQUEST_CODE_PERMISSIONS, result.requestCode);
         assertTrue(Arrays.equals(result.permissions, new String[0]));
         assertTrue(Arrays.equals(result.grantResults, new int[0]));
     }
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/OWNERS b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionActivity.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionActivity.java
index cacfa80..48dafef 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionActivity.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionActivity.java
@@ -20,23 +20,33 @@
 import android.os.Bundle;
 import android.view.WindowManager;
 
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public class BasePermissionActivity extends Activity {
     private static final long OPERATION_TIMEOUT_MILLIS = 5000;
 
-    private final SynchronousQueue<Result> mResult = new SynchronousQueue<>();
+    /**
+     * Static to ensure correct behavior if {@link Activity} instance was recreated before
+     * result delivery.
+     *
+     * requestCode -> Future<Result>
+     */
+    private static Map<Integer, CompletableFuture<Result>> sPendingResults =
+            new ConcurrentHashMap<>();
+    private static AtomicInteger sNextRequestCode = new AtomicInteger(0);
+
     private final CountDownLatch mOnCreateSync = new CountDownLatch(1);
 
     public static class Result {
-        public final int requestCode;
         public final String[] permissions;
         public final int[] grantResults;
 
-        public Result(int requestCode, String[] permissions, int[] grantResults) {
-            this.requestCode = requestCode;
+        public Result(String[] permissions, int[] grantResults) {
             this.permissions = permissions;
             this.grantResults = grantResults;
         }
@@ -53,14 +63,18 @@
         mOnCreateSync.countDown();
     }
 
+    public CompletableFuture<Result> requestPermissions(String[] permissions) {
+        int requestCode = sNextRequestCode.getAndIncrement();
+        CompletableFuture<Result> future = new CompletableFuture<>();
+        sPendingResults.put(requestCode, future);
+        requestPermissions(permissions, requestCode);
+        return future;
+    }
+
     @Override
     public void onRequestPermissionsResult(int requestCode, String[] permissions,
             int[] grantResults) {
-        try {
-            mResult.offer(new Result(requestCode, permissions, grantResults), 5, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
+        sPendingResults.get(requestCode).complete(new Result(permissions, grantResults));
     }
 
     public void waitForOnCreate() {
@@ -70,12 +84,4 @@
             throw new RuntimeException(e);
         }
     }
-
-    public Result getResult() {
-        try {
-            return mResult.poll(OPERATION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
-    }
 }
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
index 2723a6d..6f2efd1 100755
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
@@ -21,6 +21,9 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
 import android.Manifest;
 import android.app.Activity;
 import android.app.Instrumentation;
@@ -51,6 +54,10 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.compatibility.common.util.ExceptionUtils;
+import com.android.compatibility.common.util.ThrowingRunnable;
+import com.android.compatibility.common.util.UiDumpUtils;
+
 import junit.framework.Assert;
 
 import org.junit.Before;
@@ -59,6 +66,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.regex.Pattern;
 
@@ -83,11 +92,11 @@
     }
 
     protected static void assertPermissionRequestResult(BasePermissionActivity.Result result,
-            int requestCode, String[] permissions, boolean[] granted) {
-        assertEquals(requestCode, result.requestCode);
+            String[] permissions, boolean[] granted) {
         for (int i = 0; i < permissions.length; i++) {
             assertEquals(permissions[i], result.permissions[i]);
-            assertEquals(granted[i] ? PackageManager.PERMISSION_GRANTED
+            assertEquals(granted[i]
+                    ? PackageManager.PERMISSION_GRANTED
                     : PackageManager.PERMISSION_DENIED, result.grantResults[i]);
 
         }
@@ -269,74 +278,71 @@
     }
 
     protected BasePermissionActivity.Result requestPermissions(
-            String[] permissions, int requestCode, Class<?> clazz, Runnable postRequestAction)
+            String[] permissions, ThrowingRunnable postRequestAction)
             throws Exception {
-        // Start an activity
-        BasePermissionActivity activity = (BasePermissionActivity) launchActivity(
-                getInstrumentation().getTargetContext().getPackageName(), clazz, null);
+        return ExceptionUtils.wrappingExceptions(UiDumpUtils::wrapWithUiDump, () -> {
+            // Start an activity
+            BasePermissionActivity activity = (BasePermissionActivity) launchActivity(
+                    getInstrumentation().getTargetContext().getPackageName(),
+                    BasePermissionActivity.class, null);
 
-        activity.waitForOnCreate();
+            activity.waitForOnCreate();
 
-        // Request the permissions
-        activity.requestPermissions(permissions, requestCode);
+            // Request the permissions
+            CompletableFuture<BasePermissionActivity.Result> futureResult =
+                    activity.requestPermissions(permissions);
 
-        // Define a more conservative idle criteria
-        getInstrumentation().getUiAutomation().waitForIdle(
-                IDLE_TIMEOUT_MILLIS, GLOBAL_TIMEOUT_MILLIS);
+            // Define a more conservative idle criteria
+            getInstrumentation().getUiAutomation().waitForIdle(
+                    IDLE_TIMEOUT_MILLIS, GLOBAL_TIMEOUT_MILLIS);
 
-        // Perform the post-request action
-        if (postRequestAction != null) {
-            postRequestAction.run();
-        }
+            // Perform the post-request action
+            if (postRequestAction != null) {
+                postRequestAction.run();
+            }
 
-        BasePermissionActivity.Result result = activity.getResult();
-        activity.finish();
-        return result;
+            BasePermissionActivity.Result result =
+                    futureResult.get(GLOBAL_TIMEOUT_MILLIS, MILLISECONDS);
+            activity.finish();
+            return result;
+        });
     }
 
     protected void clickAllowButton() throws Exception {
-        scrollToBottomIfWatch();
-        waitForIdle();
-        getUiDevice().wait(Until.findObject(By.res(
-                "com.android.permissioncontroller:id/permission_allow_button")),
-                GLOBAL_TIMEOUT_MILLIS).click();
+        scrollToBottom();
+        click("com.android.permissioncontroller:id/permission_allow_button");
     }
 
     protected void clickAllowAlwaysButton() throws Exception {
-        waitForIdle();
-        getUiDevice().wait(Until.findObject(By.res(
-                "com.android.permissioncontroller:id/permission_allow_always_button")),
-                GLOBAL_TIMEOUT_MILLIS).click();
+        click("com.android.permissioncontroller:id/permission_allow_always_button");
     }
 
     protected void clickAllowForegroundButton() throws Exception {
-        waitForIdle();
-        getUiDevice().wait(Until.findObject(By.res(
-                "com.android.permissioncontroller:id/permission_allow_foreground_only_button")),
-                GLOBAL_TIMEOUT_MILLIS).click();
+        click("com.android.permissioncontroller:id/permission_allow_foreground_only_button");
     }
 
     protected void clickDenyButton() throws Exception {
-        scrollToBottomIfWatch();
-        waitForIdle();
-        getUiDevice().wait(Until.findObject(By.res(
-                "com.android.permissioncontroller:id/permission_deny_button")),
-                GLOBAL_TIMEOUT_MILLIS).click();
+        scrollToBottom();
+        click("com.android.permissioncontroller:id/permission_deny_button");
     }
 
     protected void clickDenyAndDontAskAgainButton() throws Exception {
-        waitForIdle();
-        getUiDevice().wait(Until.findObject(By.res(
-                "com.android.permissioncontroller:id/permission_deny_and_dont_ask_again_button")),
-                GLOBAL_TIMEOUT_MILLIS).click();
+        scrollToBottom();
+        click("com.android.permissioncontroller:id/permission_deny_and_dont_ask_again_button");
     }
 
     protected void clickDontAskAgainButton() throws Exception {
-        scrollToBottomIfWatch();
-        waitForIdle();
-        getUiDevice().wait(Until.findObject(By.res(
-                "com.android.permissioncontroller:id/permission_deny_dont_ask_again_button")),
-                GLOBAL_TIMEOUT_MILLIS).click();
+        scrollToBottom();
+        click("com.android.permissioncontroller:id/permission_deny_dont_ask_again_button");
+    }
+
+    private void click(String resourceName) throws TimeoutException {
+        ExceptionUtils.wrappingExceptions(UiDumpUtils::wrapWithUiDump, () -> {
+            waitForIdle();
+            getUiDevice().wait(Until.findObject(By.res(
+                    resourceName)),
+                    GLOBAL_TIMEOUT_MILLIS).click();
+        });
     }
 
     protected void grantPermission(String permission) throws Exception {
@@ -355,114 +361,115 @@
         setPermissionGrantState(permissions, false, legacyApp);
     }
 
-    private void scrollToBottomIfWatch() throws Exception {
-        if (mWatch) {
-            getUiDevice().wait(Until.findObject(By.clazz(ScrollView.class)), GLOBAL_TIMEOUT_MILLIS);
-            UiScrollable scrollable =
-                    new UiScrollable(new UiSelector().className(ScrollView.class));
-            if (scrollable.exists()) {
-                scrollable.flingToEnd(10);
-            }
+    private void scrollToBottom() throws Exception {
+        getUiDevice().wait(Until.findObject(By.clazz(ScrollView.class)), GLOBAL_TIMEOUT_MILLIS);
+        UiScrollable scrollable =
+                new UiScrollable(new UiSelector().className(ScrollView.class));
+        if (scrollable.exists()) {
+            scrollable.flingToEnd(10);
         }
     }
 
     private void setPermissionGrantState(String[] permissions, boolean granted,
             boolean legacyApp) throws Exception {
-        getUiDevice().pressBack();
-        waitForIdle();
-        getUiDevice().pressBack();
-        waitForIdle();
-        getUiDevice().pressBack();
-        waitForIdle();
-
-        if (isTv()) {
-            getUiDevice().pressHome();
+        ExceptionUtils.wrappingExceptions(UiDumpUtils::wrapWithUiDump, () -> {
+            getUiDevice().pressBack();
             waitForIdle();
-        }
+            getUiDevice().pressBack();
+            waitForIdle();
+            getUiDevice().pressBack();
+            waitForIdle();
 
-        // Open the app details settings
-        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
-        intent.addCategory(Intent.CATEGORY_DEFAULT);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.setData(Uri.parse("package:" + mContext.getPackageName()));
-        startActivity(intent);
-
-        waitForIdle();
-
-        // Open the permissions UI
-        String label = mContext.getResources().getString(R.string.Permissions);
-        AccessibilityNodeInfo permLabelView = getNodeTimed(() -> findByText(label), true);
-        Assert.assertNotNull("Permissions label should be present", permLabelView);
-
-        AccessibilityNodeInfo permItemView = findCollectionItem(permLabelView);
-
-        click(permItemView);
-
-        waitForIdle();
-
-        for (String permission : permissions) {
-            // Find the permission screen
-            String permissionLabel = getPermissionLabel(permission);
-
-            UiObject2 permissionView = null;
-            long start = System.currentTimeMillis();
-            while (permissionView == null && start + RETRY_TIMEOUT > System.currentTimeMillis()) {
-                permissionView = getUiDevice().wait(Until.findObject(By.text(permissionLabel)),
-                        GLOBAL_TIMEOUT_MILLIS);
-
-                if (permissionView == null) {
-                    getUiDevice().findObject(By.res("android:id/list_container"))
-                            .scroll(Direction.DOWN, 1);
-                }
+            if (isTv()) {
+                getUiDevice().pressHome();
+                waitForIdle();
             }
 
-            permissionView.click();
+            // Open the app details settings
+            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+            intent.addCategory(Intent.CATEGORY_DEFAULT);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            intent.setData(Uri.parse("package:" + mContext.getPackageName()));
+            startActivity(intent);
+
             waitForIdle();
 
-            String denyLabel = mContext.getResources().getString(R.string.Deny);
+            // Open the permissions UI
+            String label = mContext.getResources().getString(R.string.Permissions);
+            AccessibilityNodeInfo permLabelView = getNodeTimed(() -> findByText(label), true);
+            Assert.assertNotNull("Permissions label should be present", permLabelView);
 
-            final boolean wasGranted = !getUiDevice().wait(Until.findObject(By.text(denyLabel)),
-                    GLOBAL_TIMEOUT_MILLIS).isChecked();
-            if (granted != wasGranted) {
-                // Toggle the permission
+            AccessibilityNodeInfo permItemView = findCollectionItem(permLabelView);
 
-                if (granted) {
-                    String allowLabel = mContext.getResources().getString(R.string.Allow);
-                    getUiDevice().findObject(By.text(allowLabel)).click();
-                } else {
-                    getUiDevice().findObject(By.text(denyLabel)).click();
+            click(permItemView);
+
+            waitForIdle();
+
+            for (String permission : permissions) {
+                // Find the permission screen
+                String permissionLabel = getPermissionLabel(permission);
+
+                UiObject2 permissionView = null;
+                long start = System.currentTimeMillis();
+                while (permissionView == null
+                        && start + RETRY_TIMEOUT > System.currentTimeMillis()) {
+                    permissionView = getUiDevice().wait(Until.findObject(By.text(permissionLabel)),
+                            GLOBAL_TIMEOUT_MILLIS);
+
+                    if (permissionView == null) {
+                        getUiDevice().findObject(By.res("android:id/list_container"))
+                                .scroll(Direction.DOWN, 1);
+                    }
                 }
+
+                permissionView.click();
                 waitForIdle();
 
-                if (wasGranted && legacyApp) {
-                    scrollToBottomIfWatch();
-                    Context context = getInstrumentation().getContext();
-                    String packageName = context.getPackageManager()
-                            .getPermissionControllerPackageName();
-                    String resIdName = "com.android.permissioncontroller"
-                            + ":string/grant_dialog_button_deny_anyway";
-                    Resources resources = context
-                            .createPackageContext(packageName, 0).getResources();
-                    final int confirmResId = resources.getIdentifier(resIdName, null, null);
-                    String confirmTitle = CaseMap.toUpper().apply(
-                            resources.getConfiguration().getLocales().get(0),
-                            resources.getString(confirmResId));
-                    getUiDevice().wait(Until.findObject(
-                            byTextStartsWithCaseInsensitive(confirmTitle)),
-                            GLOBAL_TIMEOUT_MILLIS).click();
+                String denyLabel = mContext.getResources().getString(R.string.Deny);
 
+                final boolean wasGranted = !getUiDevice().wait(Until.findObject(By.text(denyLabel)),
+                        GLOBAL_TIMEOUT_MILLIS).isChecked();
+                if (granted != wasGranted) {
+                    // Toggle the permission
+
+                    if (granted) {
+                        String allowLabel = mContext.getResources().getString(R.string.Allow);
+                        getUiDevice().findObject(By.text(allowLabel)).click();
+                    } else {
+                        getUiDevice().findObject(By.text(denyLabel)).click();
+                    }
                     waitForIdle();
+
+                    if (wasGranted && legacyApp) {
+                        scrollToBottom();
+                        Context context = getInstrumentation().getContext();
+                        String packageName = context.getPackageManager()
+                                .getPermissionControllerPackageName();
+                        String resIdName = "com.android.permissioncontroller"
+                                + ":string/grant_dialog_button_deny_anyway";
+                        Resources resources = context
+                                .createPackageContext(packageName, 0).getResources();
+                        final int confirmResId = resources.getIdentifier(resIdName, null, null);
+                        String confirmTitle = CaseMap.toUpper().apply(
+                                resources.getConfiguration().getLocales().get(0),
+                                resources.getString(confirmResId));
+                        getUiDevice().wait(Until.findObject(
+                                byTextStartsWithCaseInsensitive(confirmTitle)),
+                                GLOBAL_TIMEOUT_MILLIS).click();
+
+                        waitForIdle();
+                    }
                 }
+
+                getUiDevice().pressBack();
+                waitForIdle();
             }
 
             getUiDevice().pressBack();
             waitForIdle();
-        }
-
-        getUiDevice().pressBack();
-        waitForIdle();
-        getUiDevice().pressBack();
-        waitForIdle();
+            getUiDevice().pressBack();
+            waitForIdle();
+        });
     }
 
     private BySelector byTextStartsWithCaseInsensitive(String prefix) {
@@ -587,12 +594,14 @@
     }
 
     private static void click(AccessibilityNodeInfo node) throws Exception {
-        getInstrumentation().getUiAutomation().executeAndWaitForEvent(
-                () -> node.performAction(AccessibilityNodeInfo.ACTION_CLICK),
-                (AccessibilityEvent event) -> event.getEventType()
-                        == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
-                        || event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED,
-                GLOBAL_TIMEOUT_MILLIS);
+        ExceptionUtils.wrappingExceptions(UiDumpUtils::wrapWithUiDump, () -> {
+            getInstrumentation().getUiAutomation().executeAndWaitForEvent(
+                    () -> node.performAction(AccessibilityNodeInfo.ACTION_CLICK),
+                    (AccessibilityEvent event) -> event.getEventType()
+                            == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
+                            || event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED,
+                    GLOBAL_TIMEOUT_MILLIS);
+        });
     }
 
     private static AccessibilityNodeInfo findCollectionItem(AccessibilityNodeInfo current)
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
index 9482df0..dc7ec3b 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
@@ -26,7 +26,6 @@
 import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.net.Uri;
-import android.os.Build;
 import android.provider.CalendarContract;
 
 import androidx.test.InstrumentationRegistry;
@@ -41,7 +40,6 @@
  * Runtime permission behavior tests for apps targeting API 23
  */
 public class UsePermissionTest23 extends BasePermissionsTest {
-    private static final int REQUEST_CODE_PERMISSIONS = 42;
 
     private final Context mContext = getInstrumentation().getContext();
 
@@ -105,21 +103,13 @@
         }
 
         // Go through normal grant flow
-        BasePermissionActivity.Result result = requestPermissions(new String[] {
+        BasePermissionActivity.Result result = requestPermissions(new String[]{
                 Manifest.permission.READ_CALENDAR,
-                Manifest.permission.WRITE_CALENDAR},
-                REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class,
-                () -> {
-                    try {
-                        clickAllowButton();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+                Manifest.permission.WRITE_CALENDAR}, () -> {
+            clickAllowButton();
+            getUiDevice().waitForIdle();
+        });
 
-        assertEquals(REQUEST_CODE_PERMISSIONS, result.requestCode);
         assertEquals(Manifest.permission.READ_CALENDAR, result.permissions[0]);
         assertEquals(Manifest.permission.WRITE_CALENDAR, result.permissions[1]);
         assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
@@ -147,21 +137,13 @@
         String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
 
         // request only one permission from the 'contacts' permission group
-        BasePermissionActivity.Result result = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class,
-                () -> {
-                    try {
-                        clickAllowButton();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result result = requestPermissions(permissions, () -> {
+            clickAllowButton();
+            getUiDevice().waitForIdle();
+        });
 
         // Expect the permission is granted
-        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {true});
+        assertPermissionRequestResult(result, permissions, new boolean[] {true});
 
         // Make sure no undeclared as used permissions are granted
         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
@@ -181,21 +163,13 @@
         // request only one permission from the 'SMS' permission group at runtime,
         // but two from this group are <uses-permission> in the manifest
         // request only one permission from the 'contacts' permission group
-        BasePermissionActivity.Result result = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class,
-                () -> {
-                    try {
-                        clickAllowButton();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result result = requestPermissions(permissions, () -> {
+            clickAllowButton();
+            getUiDevice().waitForIdle();
+        });
 
         // Expect the permission is granted
-        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {true});
+        assertPermissionRequestResult(result, permissions, new boolean[] {true});
 
         // We should now have been granted both of the permissions from this group.
         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
@@ -211,21 +185,13 @@
         String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
 
         // Request the permission and cancel the request
-        BasePermissionActivity.Result result = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class,
-                () -> {
-                    try {
-                        clickDenyButton();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result result = requestPermissions(permissions, () -> {
+            clickDenyButton();
+            getUiDevice().waitForIdle();
+        });
 
         // Expect the permission is not granted
-        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {false});
+        assertPermissionRequestResult(result, permissions, new boolean[] {false});
     }
 
     @Test
@@ -237,29 +203,20 @@
         String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
 
         // Request the permission and allow it
-        BasePermissionActivity.Result firstResult = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class, () -> {
-                    try {
-                        clickAllowButton();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result firstResult = requestPermissions(permissions, () -> {
+            clickAllowButton();
+            getUiDevice().waitForIdle();
+        });
 
         // Expect the permission is granted
-        assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {true});
+        assertPermissionRequestResult(firstResult, permissions, new boolean[] {true});
 
         // Request the permission and do nothing
-        BasePermissionActivity.Result secondResult = requestPermissions(new String[] {
-                Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 1,
-                BasePermissionActivity.class, null);
+        BasePermissionActivity.Result secondResult = requestPermissions(new String[]{
+                Manifest.permission.WRITE_CONTACTS}, null);
 
         // Expect the permission is granted
-        assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1,
-                permissions, new boolean[] {true});
+        assertPermissionRequestResult(secondResult, permissions, new boolean[] {true});
     }
 
     @Test
@@ -271,45 +228,30 @@
         String[] permissions = new String[] {Manifest.permission.WRITE_CONTACTS};
 
         // Request the permission and deny it
-        BasePermissionActivity.Result firstResult = requestPermissions(
-                permissions, REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class, () -> {
-                    try {
-                        clickDenyButton();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result firstResult = requestPermissions(permissions, () -> {
+            clickDenyButton();
+            getUiDevice().waitForIdle();
+        });
 
         // Expect the permission is not granted
-        assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {false});
+        assertPermissionRequestResult(firstResult, permissions, new boolean[] {false});
 
         // Request the permission and choose don't ask again
-        BasePermissionActivity.Result secondResult = requestPermissions(new String[] {
-                        Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 1,
-                BasePermissionActivity.class, () -> {
-                    try {
-                        denyWithPrejudice();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result secondResult = requestPermissions(new String[]{
+                Manifest.permission.WRITE_CONTACTS}, () -> {
+            denyWithPrejudice();
+            getUiDevice().waitForIdle();
+        });
 
         // Expect the permission is not granted
-        assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1,
-                permissions, new boolean[] {false});
+        assertPermissionRequestResult(secondResult, permissions, new boolean[] {false});
 
         // Request the permission and do nothing
-        BasePermissionActivity.Result thirdResult = requestPermissions(new String[] {
-                        Manifest.permission.WRITE_CONTACTS}, REQUEST_CODE_PERMISSIONS + 2,
-                BasePermissionActivity.class, null);
+        BasePermissionActivity.Result thirdResult = requestPermissions(new String[]{
+                Manifest.permission.WRITE_CONTACTS}, null);
 
         // Expect the permission is not granted
-        assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS + 2,
-                permissions, new boolean[] {false});
+        assertPermissionRequestResult(thirdResult, permissions, new boolean[] {false});
     }
 
     @Test
@@ -347,36 +289,23 @@
         String[] permissions = new String[] {Manifest.permission.READ_CALENDAR};
 
         // Request the permission and deny it
-        BasePermissionActivity.Result firstResult = requestPermissions(
-                permissions, REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class, () -> {
-                    try {
-                        clickDenyButton();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result firstResult = requestPermissions(permissions, () -> {
+            clickDenyButton();
+            getUiDevice().waitForIdle();
+        });
 
         // Expect the permission is not granted
-        assertPermissionRequestResult(firstResult, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {false});
+        assertPermissionRequestResult(firstResult, permissions, new boolean[] {false});
 
         // Request the permission and choose don't ask again
-        BasePermissionActivity.Result secondResult = requestPermissions(new String[] {
-                        Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS + 1,
-                BasePermissionActivity.class, () -> {
-                    try {
-                        denyWithPrejudice();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result secondResult = requestPermissions(new String[]{
+                Manifest.permission.READ_CALENDAR}, () -> {
+            denyWithPrejudice();
+            getUiDevice().waitForIdle();
+        });
 
         // Expect the permission is not granted
-        assertPermissionRequestResult(secondResult, REQUEST_CODE_PERMISSIONS + 1,
-                permissions, new boolean[] {false});
+        assertPermissionRequestResult(secondResult, permissions, new boolean[] {false});
 
         // Clear the denial with prejudice
         grantPermission(Manifest.permission.READ_CALENDAR);
@@ -392,20 +321,15 @@
                 .checkSelfPermission(Manifest.permission.READ_CALENDAR));
 
         // Request the permission and allow it
-        BasePermissionActivity.Result thirdResult = requestPermissions(new String[] {
-                        Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS + 2,
-                BasePermissionActivity.class, () -> {
-                    try {
-                        clickAllowButton();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result thirdResult = requestPermissions(new String[]{
+                Manifest.permission.READ_CALENDAR}, () -> {
+            clickAllowButton();
+            getUiDevice().waitForIdle();
+        });
 
         // Make sure the permission is granted
-        assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS + 2,
-                new String[] {Manifest.permission.READ_CALENDAR}, new boolean[] {true});
+        assertPermissionRequestResult(thirdResult, new String[] {Manifest.permission.READ_CALENDAR},
+                new boolean[] {true});
     }
 
     @Test
@@ -417,12 +341,10 @@
         String[] permissions = new String[] {Manifest.permission.BIND_PRINT_SERVICE};
 
         // Request the permission and do nothing
-        BasePermissionActivity.Result result = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, null);
+        BasePermissionActivity.Result result = requestPermissions(permissions, null);
 
         // Expect the permission is not granted
-        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {false});
+        assertPermissionRequestResult(result, permissions, new boolean[] {false});
     }
 
     @Test
@@ -434,12 +356,10 @@
         String[] permissions = new String[] {"permission.does.not.exist"};
 
         // Request the permission and do nothing
-        BasePermissionActivity.Result result = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, null);
+        BasePermissionActivity.Result result = requestPermissions(permissions, null);
 
         // Expect the permission is not granted
-        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {false});
+        assertPermissionRequestResult(result, permissions, new boolean[] {false});
     }
 
     @Test
@@ -456,8 +376,7 @@
         };
 
         // Request the permission and allow it
-        BasePermissionActivity.Result result = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, () -> {
+        BasePermissionActivity.Result result = requestPermissions(permissions, () -> {
             try {
                 clickAllowButton();
                 getUiDevice().waitForIdle();
@@ -469,8 +388,7 @@
         });
 
         // Expect the permission are reported as granted
-        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {true, true});
+        assertPermissionRequestResult(result, permissions, new boolean[] {true, true});
 
         // The permissions are granted
         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
@@ -534,20 +452,19 @@
                 .checkSelfPermission(Manifest.permission.READ_CALENDAR));
 
         // Request the permission and allow it
-        BasePermissionActivity.Result thirdResult = requestPermissions(new String[] {
-                        Manifest.permission.READ_CALENDAR}, REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class, () -> {
-                    try {
-                        clickAllowButton();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result thirdResult = requestPermissions(new String[]{
+                Manifest.permission.READ_CALENDAR}, () -> {
+            try {
+                clickAllowButton();
+                getUiDevice().waitForIdle();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
 
         // Make sure the permission is granted
-        assertPermissionRequestResult(thirdResult, REQUEST_CODE_PERMISSIONS,
-                new String[] {Manifest.permission.READ_CALENDAR}, new boolean[] {true});
+        assertPermissionRequestResult(thirdResult, new String[] {Manifest.permission.READ_CALENDAR},
+                new boolean[] {true});
     }
 
     @Test
@@ -571,12 +488,9 @@
 
         // Go through normal grant flow
         BasePermissionActivity.Result result = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class,
                 () -> { /* empty */ });
 
-        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {false});
+        assertPermissionRequestResult(result, permissions, new boolean[] {false});
     }
 
     @Test
@@ -595,21 +509,19 @@
         };
 
         // Request the permission and allow it
-        BasePermissionActivity.Result result = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS, BasePermissionActivity.class, () -> {
-                    try {
-                        clickAllowButton();
-                        getUiDevice().waitForIdle();
-                        clickAllowButton();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result result = requestPermissions(permissions, () -> {
+            try {
+                clickAllowButton();
+                getUiDevice().waitForIdle();
+                clickAllowButton();
+                getUiDevice().waitForIdle();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
 
         // Expect the permission are reported as granted
-        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {false, true, false, true});
+        assertPermissionRequestResult(result, permissions, new boolean[] {false, true, false, true});
 
         // The permissions are granted
         assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
@@ -626,13 +538,10 @@
 
         // Request the permission and allow it
         BasePermissionActivity.Result result = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class,
                 () -> { /* empty */ });
 
         // Expect the permissions is not granted
-        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[] {false});
+        assertPermissionRequestResult(result, permissions, new boolean[] {false});
     }
 
     private void assertAllPermissionsRevoked() {
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp25/OWNERS b/hostsidetests/appsecurity/test-apps/UsePermissionApp25/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp25/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp26/OWNERS b/hostsidetests/appsecurity/test-apps/UsePermissionApp26/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp26/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp26/src/com/android/cts/usepermission/UsePermissionTest26.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp26/src/com/android/cts/usepermission/UsePermissionTest26.java
index e64838b..85b3529 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp26/src/com/android/cts/usepermission/UsePermissionTest26.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp26/src/com/android/cts/usepermission/UsePermissionTest26.java
@@ -42,21 +42,17 @@
         // request only one permission from the 'SMS' permission group at runtime,
         // but two from this group are <uses-permission> in the manifest
         // request only one permission from the 'contacts' permission group
-        BasePermissionActivity.Result result = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class,
-                () -> {
-                    try {
-                        clickAllowButton();
-                        getUiDevice().waitForIdle();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result result = requestPermissions(permissions, () -> {
+            try {
+                clickAllowButton();
+                getUiDevice().waitForIdle();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
 
         // Expect the permission is granted
-        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
-                permissions, new boolean[]{true});
+        assertPermissionRequestResult(result, permissions, new boolean[]{true});
 
         assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getTargetContext()
                 .checkSelfPermission(Manifest.permission.SEND_SMS));
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp28/OWNERS b/hostsidetests/appsecurity/test-apps/UsePermissionApp28/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp28/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp28/src/com/android/cts/usepermission/UsePermissionTest28.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp28/src/com/android/cts/usepermission/UsePermissionTest28.java
index 1c32d39..4dd5349 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp28/src/com/android/cts/usepermission/UsePermissionTest28.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp28/src/com/android/cts/usepermission/UsePermissionTest28.java
@@ -23,9 +23,7 @@
 
 import static junit.framework.Assert.assertEquals;
 
-import android.Manifest;
 import android.content.Context;
-import android.content.pm.PackageManager;
 
 import org.junit.Test;
 
@@ -46,19 +44,15 @@
 
         // request only foreground permission. This should automatically also add the background
         // permission
-        BasePermissionActivity.Result result = requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class,
-                () -> {
-                    try {
-                        clickAllowAlwaysButton();
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        BasePermissionActivity.Result result = requestPermissions(permissions, () -> {
+            try {
+                clickAllowAlwaysButton();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
 
-        assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS, permissions,
-                new boolean[]{true});
+        assertPermissionRequestResult(result, permissions, new boolean[]{true});
 
         assertEquals(PERMISSION_GRANTED, context.checkSelfPermission(ACCESS_FINE_LOCATION));
         assertEquals(PERMISSION_GRANTED, context.checkSelfPermission(ACCESS_BACKGROUND_LOCATION));
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp29/OWNERS b/hostsidetests/appsecurity/test-apps/UsePermissionApp29/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp29/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp29/src/com/android/cts/usepermission/UsePermissionTest29.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp29/src/com/android/cts/usepermission/UsePermissionTest29.java
index e0e21eb..4fdc6c8 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp29/src/com/android/cts/usepermission/UsePermissionTest29.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp29/src/com/android/cts/usepermission/UsePermissionTest29.java
@@ -48,25 +48,21 @@
 
     private BasePermissionActivity.Result requestPermissions(String[] permissions,
             UiInteraction... uiInteractions) throws Exception {
-        return super.requestPermissions(permissions,
-                REQUEST_CODE_PERMISSIONS,
-                BasePermissionActivity.class,
-                () -> {
-                    try {
-                        for (UiInteraction uiInteraction : uiInteractions) {
-                            uiInteraction.run();
-                            getUiDevice().waitForIdle();
-                        }
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                });
+        return requestPermissions(permissions, () -> {
+            try {
+                for (UiInteraction uiInteraction : uiInteractions) {
+                    uiInteraction.run();
+                    getUiDevice().waitForIdle();
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
     }
 
-    private static void assertPermissionRequestResult(BasePermissionActivity.Result result,
+    protected static void assertPermissionRequestResult(BasePermissionActivity.Result result,
             String[] permissions, boolean... granted) {
-        BasePermissionsTest.assertPermissionRequestResult(result, REQUEST_CODE_PERMISSIONS,
-                permissions, granted);
+        BasePermissionsTest.assertPermissionRequestResult(result, permissions, granted);
     }
 
     @Before
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppLatest/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionAppLatest/Android.mk
index 6becbc8..cddfe17 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionAppLatest/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppLatest/Android.mk
@@ -23,7 +23,8 @@
     androidx.test.rules \
     compatibility-device-util-axt \
     ctstestrunner-axt \
-    ub-uiautomator
+    ub-uiautomator \
+    compatibility-device-util-axt \
 
 LOCAL_SRC_FILES := $(call all-java-files-under, ../UsePermissionApp26/src)  \
     $(call all-java-files-under, ../UsePermissionApp29/src)  \
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppLatest/OWNERS b/hostsidetests/appsecurity/test-apps/UsePermissionAppLatest/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppLatest/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/OWNERS b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/OWNERS
new file mode 100644
index 0000000..8075c9c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/OWNERS
@@ -0,0 +1,2 @@
+moltmann@google.com
+eugenesusla@google.com
diff --git a/hostsidetests/backup/KeyValueApp/src/android/cts/backup/keyvaluerestoreapp/KeyValueBackupAgent.java b/hostsidetests/backup/KeyValueApp/src/android/cts/backup/keyvaluerestoreapp/KeyValueBackupAgent.java
index f79baa9..85a96b1 100644
--- a/hostsidetests/backup/KeyValueApp/src/android/cts/backup/keyvaluerestoreapp/KeyValueBackupAgent.java
+++ b/hostsidetests/backup/KeyValueApp/src/android/cts/backup/keyvaluerestoreapp/KeyValueBackupAgent.java
@@ -17,6 +17,10 @@
 package android.cts.backup.keyvaluerestoreapp;
 
 import android.app.backup.BackupAgentHelper;
+import android.app.backup.BackupDataInput;
+import android.app.backup.BackupDataOutput;
+import android.os.ParcelFileDescriptor;
+import java.io.IOException;
 
 public class KeyValueBackupAgent extends BackupAgentHelper {
 
@@ -31,4 +35,20 @@
         addHelper(KEY_BACKUP_TEST_FILES_PREFIX,
                 KeyValueBackupRestoreTest.getFileBackupHelper(this));
     }
+
+    @Override
+    public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+        ParcelFileDescriptor newState) throws IOException {
+        // Explicitly override and call super() to help go/android-api-coverage-dashboard pick up
+        // the test coverage (b/113067697).
+        super.onBackup(oldState, data, newState);
+    }
+
+    @Override
+    public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
+        throws IOException {
+        // Explicitly override and call super() to help go/android-api-coverage-dashboard pick up
+        // the test coverage (b/113067697).
+        super.onRestore(data, appVersionCode, newState);
+    }
 }
diff --git a/hostsidetests/backup/OWNERS b/hostsidetests/backup/OWNERS
index 3637e32..c28c4d8 100644
--- a/hostsidetests/backup/OWNERS
+++ b/hostsidetests/backup/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 41666
 # Use this reviewer by default.
 br-framework-team+reviews@google.com
 
diff --git a/hostsidetests/backup/src/android/cts/backup/BackupPreparer.java b/hostsidetests/backup/src/android/cts/backup/BackupPreparer.java
index 11a1dbc..2bbd8ff 100644
--- a/hostsidetests/backup/src/android/cts/backup/BackupPreparer.java
+++ b/hostsidetests/backup/src/android/cts/backup/BackupPreparer.java
@@ -16,6 +16,7 @@
 
 package android.cts.backup;
 
+import com.android.compatibility.common.util.BackupHostSideUtils;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.config.Option;
 import com.android.tradefed.config.OptionClass;
@@ -27,6 +28,7 @@
 import com.android.tradefed.targetprep.ITargetCleaner;
 import com.android.tradefed.targetprep.TargetSetupError;
 
+import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -53,9 +55,6 @@
     private static final String LOCAL_TRANSPORT =
             "com.android.localtransport/.LocalTransport";
 
-    private static final int BACKUP_PROVISIONING_TIMEOUT_SECONDS = 30;
-    private static final int BACKUP_PROVISIONING_POLL_INTERVAL_SECONDS = 1;
-
     private boolean mIsBackupSupported;
     private boolean mWasBackupEnabled;
     private String mOldTransport;
@@ -87,7 +86,11 @@
                     mOldTransport = setBackupTransport(LOCAL_TRANSPORT);
                     CLog.d("Old transport : %s", mOldTransport);
                 }
-                waitForBackupInitialization();
+                try {
+                    BackupHostSideUtils.createBackupUtils(mDevice).waitForBackupInitialization();
+                } catch (IOException e) {
+                    throw new TargetSetupError("Backup not initialized", e);
+                }
             }
         }
     }
@@ -149,27 +152,6 @@
         }
     }
 
-    private void waitForBackupInitialization()
-        throws TargetSetupError, DeviceNotAvailableException {
-        long tryUntilNanos = System.nanoTime()
-            + TimeUnit.SECONDS.toNanos(BACKUP_PROVISIONING_TIMEOUT_SECONDS);
-        while (System.nanoTime() < tryUntilNanos) {
-            String output = mDevice.executeShellCommand("dumpsys backup");
-            if (output.matches("(?s)"  // DOTALL
-                + "^Backup Manager is .* not pending init.*")) {
-                return;
-            }
-            try {
-                Thread.sleep(TimeUnit.SECONDS.toMillis(BACKUP_PROVISIONING_POLL_INTERVAL_SECONDS));
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                break;
-            }
-        }
-        throw new TargetSetupError("Timed out waiting for backup initialization",
-            mDevice.getDeviceDescriptor());
-    }
-
     // Copied over from BaseDevicePolicyTest
     private void waitForBroadcastIdle() throws DeviceNotAvailableException, TargetSetupError {
         CollectingOutputReceiver receiver = new CollectingOutputReceiver();
diff --git a/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java b/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java
index 81737e9..1956562 100644
--- a/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java
+++ b/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java
@@ -58,7 +58,7 @@
             FULL_BACKUP_TEST_PACKAGE + ".ProfileFullBackupRestoreTest";
 
     protected final BackupUtils mBackupUtils = getBackupUtils();
-    protected ITestDevice mDevice;
+    private ITestDevice mDevice;
 
     // Store initial device state as Optional as tearDown() will execute even if we have assumption
     // failures in setUp().
diff --git a/hostsidetests/backup/src/android/cts/backup/MultiUserBackupStateTest.java b/hostsidetests/backup/src/android/cts/backup/MultiUserBackupStateTest.java
index 4fa4469..673416c 100644
--- a/hostsidetests/backup/src/android/cts/backup/MultiUserBackupStateTest.java
+++ b/hostsidetests/backup/src/android/cts/backup/MultiUserBackupStateTest.java
@@ -44,7 +44,7 @@
     public void setUp() throws Exception {
         super.setUp();
 
-        int profileUserId = createProfileUser(mDevice.getCurrentUser(), "MU-State");
+        int profileUserId = createProfileUser(getDevice().getCurrentUser(), "MU-State");
         mProfileUserId = Optional.of(profileUserId);
         startUser(profileUserId);
     }
@@ -54,7 +54,7 @@
     @Override
     public void tearDown() throws Exception {
         if (mProfileUserId.isPresent()) {
-            assertTrue(mDevice.removeUser(mProfileUserId.get()));
+            assertTrue(getDevice().removeUser(mProfileUserId.get()));
             mProfileUserId = Optional.empty();
         }
         super.tearDown();
@@ -77,7 +77,7 @@
 
         assertTrue(mBackupUtils.isBackupActivatedForUser(profileUserId));
 
-        assertTrue(mDevice.removeUser(profileUserId));
+        assertTrue(getDevice().removeUser(profileUserId));
         mProfileUserId = Optional.empty();
 
         HostSideTestUtils.waitUntil("wait for backup to be deactivated for removed user",
diff --git a/hostsidetests/bootstats/OWNERS b/hostsidetests/bootstats/OWNERS
new file mode 100644
index 0000000..1f99e96
--- /dev/null
+++ b/hostsidetests/bootstats/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 183496
+keunyoung@google.com
diff --git a/hostsidetests/classloaders/OWNERS b/hostsidetests/classloaders/OWNERS
new file mode 100644
index 0000000..137abb9
--- /dev/null
+++ b/hostsidetests/classloaders/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 86431
+calin@google.com
+ngeoffray@google.com
+sehr@google.com
diff --git a/hostsidetests/compilation/OWNERS b/hostsidetests/compilation/OWNERS
new file mode 100644
index 0000000..f386ff2
--- /dev/null
+++ b/hostsidetests/compilation/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 86431
+include ../classloaders/OWNERS
diff --git a/hostsidetests/compilation/app/Android.bp b/hostsidetests/compilation/app/Android.bp
index f4954c7..770baea 100644
--- a/hostsidetests/compilation/app/Android.bp
+++ b/hostsidetests/compilation/app/Android.bp
@@ -16,7 +16,7 @@
     name: "CtsCompilationApp",
     defaults: ["cts_support_defaults"],
     srcs: ["src/**/*.java"],
-    sdk_version: "current",
+    sdk_version: "29",
     // tag this module as a cts test artifact
     test_suites: [
         "cts",
diff --git a/hostsidetests/compilation/assets/CtsCompilationApp.apk b/hostsidetests/compilation/assets/CtsCompilationApp.apk
index 18c76d3..ba89b24 100644
--- a/hostsidetests/compilation/assets/CtsCompilationApp.apk
+++ b/hostsidetests/compilation/assets/CtsCompilationApp.apk
Binary files differ
diff --git a/hostsidetests/devicepolicy/OWNERS b/hostsidetests/devicepolicy/OWNERS
new file mode 100644
index 0000000..12341eb
--- /dev/null
+++ b/hostsidetests/devicepolicy/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 100560
+include /tests/admin/OWNERS
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/Android.bp b/hostsidetests/devicepolicy/app/CertInstaller/Android.bp
index 9b99054..a3ae108 100644
--- a/hostsidetests/devicepolicy/app/CertInstaller/Android.bp
+++ b/hostsidetests/devicepolicy/app/CertInstaller/Android.bp
@@ -31,6 +31,7 @@
     ],
     // tag this module as a cts test artifact
     test_suites: [
+        "arcts",
         "cts",
         "vts",
         "general-tests",
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.bp b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.bp
index 1062d2e..513eda2 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.bp
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.bp
@@ -61,6 +61,7 @@
     min_sdk_version: "23",
     // tag this module as a cts test artifact
     test_suites: [
+        "arcts",
         "cts",
         "vts",
         "general-tests",
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceIdentifiersTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceIdentifiersTest.java
index ea60582..3c53de9 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceIdentifiersTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceIdentifiersTest.java
@@ -16,6 +16,7 @@
 package com.android.cts.deviceowner;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.Build;
 import android.telephony.TelephonyManager;
 
@@ -72,39 +73,66 @@
         // SecurityException when querying for device identifiers.
         TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
                 Context.TELEPHONY_SERVICE);
+        // Allow the APIs to also return null if the telephony feature is not supported.
+        boolean hasTelephonyFeature =
+                mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
         try {
-            telephonyManager.getDeviceId();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getDeviceId"));
+            String deviceId = telephonyManager.getDeviceId();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getDeviceId"));
+            } else {
+                assertEquals(null, deviceId);
+            }
         } catch (SecurityException expected) {
         }
 
         try {
-            telephonyManager.getImei();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getImei"));
+            String imei = telephonyManager.getImei();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getImei"));
+            } else {
+                assertEquals(null, imei);
+            }
         } catch (SecurityException expected) {
         }
 
         try {
-            telephonyManager.getMeid();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getMeid"));
+            String meid = telephonyManager.getMeid();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getMeid"));
+            } else {
+                assertEquals(null, meid);
+            }
         } catch (SecurityException expected) {
         }
 
         try {
-            telephonyManager.getSubscriberId();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getSubscriberId"));
+            String subscriberId = telephonyManager.getSubscriberId();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getSubscriberId"));
+            } else {
+                assertEquals(null, subscriberId);
+            }
         } catch (SecurityException expected) {
         }
 
         try {
-            telephonyManager.getSimSerialNumber();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getSimSerialNumber"));
+            String simSerialNumber = telephonyManager.getSimSerialNumber();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getSimSerialNumber"));
+            } else {
+                assertEquals(null, simSerialNumber);
+            }
         } catch (SecurityException expected) {
         }
 
         try {
-            Build.getSerial();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "Build#getSerial"));
+            String serial = Build.getSerial();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "Build#getSerial"));
+            } else {
+              assertEquals(null, serial);
+            }
         } catch (SecurityException expected) {
         }
     }
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/Android.mk b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
index 3cfc542..fc424be 100644
--- a/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
+++ b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
@@ -38,6 +38,6 @@
 LOCAL_MIN_SDK_VERSION := 21
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := arcts cts vts general-tests
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/LauncherTestsSupport/Android.bp b/hostsidetests/devicepolicy/app/LauncherTestsSupport/Android.bp
index f134b69..c690f9c 100644
--- a/hostsidetests/devicepolicy/app/LauncherTestsSupport/Android.bp
+++ b/hostsidetests/devicepolicy/app/LauncherTestsSupport/Android.bp
@@ -21,6 +21,7 @@
     min_sdk_version: "21",
     // tag this module as a cts test artifact
     test_suites: [
+        "arcts",
         "cts",
         "vts",
         "general-tests",
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DeviceIdentifiersTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DeviceIdentifiersTest.java
index 7c26fad..14e7b0c 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DeviceIdentifiersTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DeviceIdentifiersTest.java
@@ -16,6 +16,7 @@
 package com.android.cts.managedprofile;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.Build;
 import android.telephony.TelephonyManager;
 
@@ -72,39 +73,66 @@
         // SecurityException when querying for device identifiers.
         TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
                 Context.TELEPHONY_SERVICE);
+        // Allow the APIs to also return null if the telephony feature is not supported.
+        boolean hasTelephonyFeature =
+                mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
         try {
-            telephonyManager.getDeviceId();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getDeviceId"));
+            String deviceId = telephonyManager.getDeviceId();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getDeviceId"));
+            } else {
+                assertEquals(null, deviceId);
+            }
         } catch (SecurityException expected) {
         }
 
         try {
-            telephonyManager.getImei();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getImei"));
+            String imei = telephonyManager.getImei();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getImei"));
+            } else {
+                assertEquals(null, imei);
+            }
         } catch (SecurityException expected) {
         }
 
         try {
-            telephonyManager.getMeid();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getMeid"));
+            String meid = telephonyManager.getMeid();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getMeid"));
+            } else {
+                assertEquals(null, meid);
+            }
         } catch (SecurityException expected) {
         }
 
         try {
-            telephonyManager.getSubscriberId();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getSubscriberId"));
+            String subscriberId = telephonyManager.getSubscriberId();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getSubscriberId"));
+            } else {
+                assertEquals(null, subscriberId);
+            }
         } catch (SecurityException expected) {
         }
 
         try {
-            telephonyManager.getSimSerialNumber();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getSimSerialNumber"));
+            String simSerialNumber = telephonyManager.getSimSerialNumber();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "getSimSerialNumber"));
+            } else {
+                assertEquals(null, simSerialNumber);
+            }
         } catch (SecurityException expected) {
         }
 
         try {
-            Build.getSerial();
-            fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "Build#getSerial"));
+            String serial = Build.getSerial();
+            if (hasTelephonyFeature) {
+                fail(String.format(NO_SECURITY_EXCEPTION_ERROR_MESSAGE, "Build#getSerial"));
+            } else {
+              assertEquals(null, serial);
+            }
         } catch (SecurityException expected) {
         }
     }
diff --git a/hostsidetests/devicepolicy/app/NoLaunchableActivityApp/Android.bp b/hostsidetests/devicepolicy/app/NoLaunchableActivityApp/Android.bp
index 2e8d9f4..f0f4716 100644
--- a/hostsidetests/devicepolicy/app/NoLaunchableActivityApp/Android.bp
+++ b/hostsidetests/devicepolicy/app/NoLaunchableActivityApp/Android.bp
@@ -25,6 +25,7 @@
     srcs: ["src/**/*.java"],
     // tag this module as a cts test artifact
     test_suites: [
+        "arcts",
         "cts",
         "vts",
         "general-tests",
@@ -45,6 +46,7 @@
     srcs: ["src/**/*.java"],
     // tag this module as a cts test artifact
     test_suites: [
+        "arcts",
         "cts",
         "vts",
         "general-tests",
@@ -66,6 +68,7 @@
     srcs: ["src/**/*.java"],
     // tag this module as a cts test artifact
     test_suites: [
+        "arcts",
         "cts",
         "vts",
         "general-tests",
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 01d64ed..538a2a5 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -94,7 +94,8 @@
     //The maximum time to wait for user to be unlocked.
     private static final long USER_UNLOCK_TIMEOUT_NANO = 30_000_000_000L;
 
-    private static final String USER_UNLOCKED_SHELL_OUTPUT = "RUNNING_UNLOCKED";
+    private static final String USER_STATE_UNLOCKED = "RUNNING_UNLOCKED";
+    private static final String USER_STATE_LOCKED = "RUNNING_LOCKED";
 
     private int mParentUserId;
 
@@ -130,7 +131,7 @@
         final String command = String.format("am get-started-user-state %d", mProfileUserId);
         final long deadline = System.nanoTime() + USER_UNLOCK_TIMEOUT_NANO;
         while (System.nanoTime() <= deadline) {
-            if (getDevice().executeShellCommand(command).startsWith(USER_UNLOCKED_SHELL_OUTPUT)) {
+            if (getDevice().executeShellCommand(command).startsWith(USER_STATE_UNLOCKED)) {
                 return;
             }
             Thread.sleep(100);
@@ -265,15 +266,9 @@
     }
 
     private void waitUntilProfileLocked() throws Exception {
-        final String cmd = "dumpsys activity | grep 'User #" + mProfileUserId + ": state='";
-        final Pattern p = Pattern.compile("state=([\\p{Upper}_]+)$");
-        SuccessCondition userLocked = () -> {
-            final String activityDump = getDevice().executeShellCommand(cmd);
-            final Matcher m = p.matcher(activityDump);
-            return m.find() && m.group(1).equals("RUNNING_LOCKED");
-        };
+        final String cmd = String.format("am get-started-user-state %d", mProfileUserId);
         tryWaitForSuccess(
-                userLocked,
+                () -> getDevice().executeShellCommand(cmd).startsWith(USER_STATE_LOCKED),
                 "The managed profile has not been locked after calling "
                         + "lockNow(FLAG_SECURE_USER_DATA)",
                 TIMEOUT_USER_LOCKED_MILLIS);
diff --git a/hostsidetests/media/OWNERS b/hostsidetests/media/OWNERS
index 9884b18..8d6b291e 100644
--- a/hostsidetests/media/OWNERS
+++ b/hostsidetests/media/OWNERS
@@ -1,4 +1,4 @@
-rachad@google.com
+# Bug component: 1344
 elaurent@google.com
 lajos@google.com
 marcone@google.com
diff --git a/hostsidetests/rollback/OWNERS b/hostsidetests/rollback/OWNERS
new file mode 100644
index 0000000..e84df8e
--- /dev/null
+++ b/hostsidetests/rollback/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 557916
+ruhler@google.com
+*
\ No newline at end of file
diff --git a/hostsidetests/sample/OWNERS b/hostsidetests/sample/OWNERS
new file mode 100644
index 0000000..84828b2
--- /dev/null
+++ b/hostsidetests/sample/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 346961
+include /tests/sample/OWNERS
diff --git a/hostsidetests/security/OWNERS b/hostsidetests/security/OWNERS
new file mode 100644
index 0000000..94522e3
--- /dev/null
+++ b/hostsidetests/security/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 36824
+include /tests/tests/security/OWNERS
diff --git a/hostsidetests/signedconfig/hostside/OWNERS b/hostsidetests/signedconfig/hostside/OWNERS
new file mode 100644
index 0000000..f968305
--- /dev/null
+++ b/hostsidetests/signedconfig/hostside/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 533114
+mathewi@google.com
+*
diff --git a/hostsidetests/stagedinstall/OWNERS b/hostsidetests/stagedinstall/OWNERS
new file mode 100644
index 0000000..2dd1076
--- /dev/null
+++ b/hostsidetests/stagedinstall/OWNERS
@@ -0,0 +1,6 @@
+# Bug component: 36137
+dariofreni@google.com
+toddke@google.com
+narayan@google.com
+patb@google.com
+ioffe@google.com
diff --git a/hostsidetests/theme/OWNERS b/hostsidetests/theme/OWNERS
index ae2c27b..b43358c 100644
--- a/hostsidetests/theme/OWNERS
+++ b/hostsidetests/theme/OWNERS
@@ -1,2 +1,3 @@
 # Bug component: 25700
-alanv@google.com
\ No newline at end of file
+alanv@google.com
+aurimas@google.com
\ No newline at end of file
diff --git a/hostsidetests/theme/assets/29/140dpi.zip b/hostsidetests/theme/assets/29/140dpi.zip
index cb385f1..48de32b 100644
--- a/hostsidetests/theme/assets/29/140dpi.zip
+++ b/hostsidetests/theme/assets/29/140dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/180dpi.zip b/hostsidetests/theme/assets/29/180dpi.zip
index b034a7f..4def986 100644
--- a/hostsidetests/theme/assets/29/180dpi.zip
+++ b/hostsidetests/theme/assets/29/180dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/200dpi.zip b/hostsidetests/theme/assets/29/200dpi.zip
index 9a0ca5e..fe2495e 100644
--- a/hostsidetests/theme/assets/29/200dpi.zip
+++ b/hostsidetests/theme/assets/29/200dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/220dpi.zip b/hostsidetests/theme/assets/29/220dpi.zip
index b65a035..a2c2ea2 100644
--- a/hostsidetests/theme/assets/29/220dpi.zip
+++ b/hostsidetests/theme/assets/29/220dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/260dpi.zip b/hostsidetests/theme/assets/29/260dpi.zip
index 9cdefe7..74890a2 100644
--- a/hostsidetests/theme/assets/29/260dpi.zip
+++ b/hostsidetests/theme/assets/29/260dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/280dpi.zip b/hostsidetests/theme/assets/29/280dpi.zip
index 2e39de5..83fd290 100644
--- a/hostsidetests/theme/assets/29/280dpi.zip
+++ b/hostsidetests/theme/assets/29/280dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/300dpi.zip b/hostsidetests/theme/assets/29/300dpi.zip
index fba9c6c..25334d8 100644
--- a/hostsidetests/theme/assets/29/300dpi.zip
+++ b/hostsidetests/theme/assets/29/300dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/340dpi.zip b/hostsidetests/theme/assets/29/340dpi.zip
index 72e6f8f..2092326 100644
--- a/hostsidetests/theme/assets/29/340dpi.zip
+++ b/hostsidetests/theme/assets/29/340dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/360dpi.zip b/hostsidetests/theme/assets/29/360dpi.zip
index 3970139..c13ad5c 100644
--- a/hostsidetests/theme/assets/29/360dpi.zip
+++ b/hostsidetests/theme/assets/29/360dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/400dpi.zip b/hostsidetests/theme/assets/29/400dpi.zip
index 510eb94d..1df1a95 100644
--- a/hostsidetests/theme/assets/29/400dpi.zip
+++ b/hostsidetests/theme/assets/29/400dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/420dpi.zip b/hostsidetests/theme/assets/29/420dpi.zip
index a457bda..d58d418 100644
--- a/hostsidetests/theme/assets/29/420dpi.zip
+++ b/hostsidetests/theme/assets/29/420dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/440dpi.zip b/hostsidetests/theme/assets/29/440dpi.zip
index 07355d1..535102f 100644
--- a/hostsidetests/theme/assets/29/440dpi.zip
+++ b/hostsidetests/theme/assets/29/440dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/560dpi.zip b/hostsidetests/theme/assets/29/560dpi.zip
index 6a85ad8..20f1c7b 100644
--- a/hostsidetests/theme/assets/29/560dpi.zip
+++ b/hostsidetests/theme/assets/29/560dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/hdpi.zip b/hostsidetests/theme/assets/29/hdpi.zip
index e1a534a..582989d 100644
--- a/hostsidetests/theme/assets/29/hdpi.zip
+++ b/hostsidetests/theme/assets/29/hdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/ldpi.zip b/hostsidetests/theme/assets/29/ldpi.zip
index 5475608..3035146 100644
--- a/hostsidetests/theme/assets/29/ldpi.zip
+++ b/hostsidetests/theme/assets/29/ldpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/mdpi.zip b/hostsidetests/theme/assets/29/mdpi.zip
index 67c5c03..a831e7b 100644
--- a/hostsidetests/theme/assets/29/mdpi.zip
+++ b/hostsidetests/theme/assets/29/mdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/tvdpi.zip b/hostsidetests/theme/assets/29/tvdpi.zip
index 60f5afe..bd4bf75 100644
--- a/hostsidetests/theme/assets/29/tvdpi.zip
+++ b/hostsidetests/theme/assets/29/tvdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/xhdpi.zip b/hostsidetests/theme/assets/29/xhdpi.zip
index d2895a1..0dd72e2 100644
--- a/hostsidetests/theme/assets/29/xhdpi.zip
+++ b/hostsidetests/theme/assets/29/xhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/xxhdpi.zip b/hostsidetests/theme/assets/29/xxhdpi.zip
index 637649a..64fc846 100644
--- a/hostsidetests/theme/assets/29/xxhdpi.zip
+++ b/hostsidetests/theme/assets/29/xxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/29/xxxhdpi.zip b/hostsidetests/theme/assets/29/xxxhdpi.zip
index 9ab19b1..87beb9a 100644
--- a/hostsidetests/theme/assets/29/xxxhdpi.zip
+++ b/hostsidetests/theme/assets/29/xxxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/140dpi.zip b/hostsidetests/theme/assets/R/140dpi.zip
new file mode 100644
index 0000000..48de32b
--- /dev/null
+++ b/hostsidetests/theme/assets/R/140dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/180dpi.zip b/hostsidetests/theme/assets/R/180dpi.zip
new file mode 100644
index 0000000..4def986
--- /dev/null
+++ b/hostsidetests/theme/assets/R/180dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/200dpi.zip b/hostsidetests/theme/assets/R/200dpi.zip
new file mode 100644
index 0000000..fe2495e
--- /dev/null
+++ b/hostsidetests/theme/assets/R/200dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/220dpi.zip b/hostsidetests/theme/assets/R/220dpi.zip
new file mode 100644
index 0000000..a2c2ea2
--- /dev/null
+++ b/hostsidetests/theme/assets/R/220dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/260dpi.zip b/hostsidetests/theme/assets/R/260dpi.zip
index ba5d363..74890a2 100644
--- a/hostsidetests/theme/assets/R/260dpi.zip
+++ b/hostsidetests/theme/assets/R/260dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/280dpi.zip b/hostsidetests/theme/assets/R/280dpi.zip
index 34ea14c..83fd290 100644
--- a/hostsidetests/theme/assets/R/280dpi.zip
+++ b/hostsidetests/theme/assets/R/280dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/300dpi.zip b/hostsidetests/theme/assets/R/300dpi.zip
index 7595d24..25334d8 100644
--- a/hostsidetests/theme/assets/R/300dpi.zip
+++ b/hostsidetests/theme/assets/R/300dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/340dpi.zip b/hostsidetests/theme/assets/R/340dpi.zip
index 8ce960c..2092326 100644
--- a/hostsidetests/theme/assets/R/340dpi.zip
+++ b/hostsidetests/theme/assets/R/340dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/360dpi.zip b/hostsidetests/theme/assets/R/360dpi.zip
index aae3adc..c13ad5c 100644
--- a/hostsidetests/theme/assets/R/360dpi.zip
+++ b/hostsidetests/theme/assets/R/360dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/400dpi.zip b/hostsidetests/theme/assets/R/400dpi.zip
index 363d602..1df1a95 100644
--- a/hostsidetests/theme/assets/R/400dpi.zip
+++ b/hostsidetests/theme/assets/R/400dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/420dpi.zip b/hostsidetests/theme/assets/R/420dpi.zip
index 0f2ce47..d58d418 100644
--- a/hostsidetests/theme/assets/R/420dpi.zip
+++ b/hostsidetests/theme/assets/R/420dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/440dpi.zip b/hostsidetests/theme/assets/R/440dpi.zip
index 2328c61..535102f 100644
--- a/hostsidetests/theme/assets/R/440dpi.zip
+++ b/hostsidetests/theme/assets/R/440dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/560dpi.zip b/hostsidetests/theme/assets/R/560dpi.zip
index 5f1bb0b..20f1c7b 100644
--- a/hostsidetests/theme/assets/R/560dpi.zip
+++ b/hostsidetests/theme/assets/R/560dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/hdpi.zip b/hostsidetests/theme/assets/R/hdpi.zip
index 6d82318..582989d 100644
--- a/hostsidetests/theme/assets/R/hdpi.zip
+++ b/hostsidetests/theme/assets/R/hdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/ldpi.zip b/hostsidetests/theme/assets/R/ldpi.zip
index cc60027..3035146 100644
--- a/hostsidetests/theme/assets/R/ldpi.zip
+++ b/hostsidetests/theme/assets/R/ldpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/mdpi.zip b/hostsidetests/theme/assets/R/mdpi.zip
index 66d41d4..a831e7b 100644
--- a/hostsidetests/theme/assets/R/mdpi.zip
+++ b/hostsidetests/theme/assets/R/mdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/tvdpi.zip b/hostsidetests/theme/assets/R/tvdpi.zip
index b43032f..bd4bf75 100644
--- a/hostsidetests/theme/assets/R/tvdpi.zip
+++ b/hostsidetests/theme/assets/R/tvdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/xhdpi.zip b/hostsidetests/theme/assets/R/xhdpi.zip
index 64905f3..0dd72e2 100644
--- a/hostsidetests/theme/assets/R/xhdpi.zip
+++ b/hostsidetests/theme/assets/R/xhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/xxhdpi.zip b/hostsidetests/theme/assets/R/xxhdpi.zip
index b2cb422..64fc846 100644
--- a/hostsidetests/theme/assets/R/xxhdpi.zip
+++ b/hostsidetests/theme/assets/R/xxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/R/xxxhdpi.zip b/hostsidetests/theme/assets/R/xxxhdpi.zip
index d00dbbd..87beb9a 100644
--- a/hostsidetests/theme/assets/R/xxxhdpi.zip
+++ b/hostsidetests/theme/assets/R/xxxhdpi.zip
Binary files differ
diff --git a/libs/deviceutillegacy/Android.bp b/libs/deviceutillegacy/Android.bp
index bbdd399..220b2ab 100644
--- a/libs/deviceutillegacy/Android.bp
+++ b/libs/deviceutillegacy/Android.bp
@@ -13,23 +13,6 @@
 // limitations under the License.
 
 java_library_static {
-    name: "ctsdeviceutillegacy",
-
-    static_libs: [
-        "compatibility-device-util",
-        "junit",
-    ],
-
-    libs: ["android.test.base.stubs"],
-
-    srcs: ["src/**/*.java"],
-
-    sdk_version: "test_current",
-
-}
-
-// A variant of ctsdeviceutillegacy that depends on androidx.test instead of android.support.test
-java_library_static {
     name: "ctsdeviceutillegacy-axt",
 
     static_libs: [
diff --git a/libs/runner/Android.bp b/libs/runner/Android.bp
index 425c593..40977ff 100644
--- a/libs/runner/Android.bp
+++ b/libs/runner/Android.bp
@@ -12,16 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// The legacy library that brings in android-support-test transitively
-java_library {
-    name: "ctstestrunner",
-
-    static_libs: ["cts-test-runner"],
-
-    sdk_version: "current",
-
-}
-
 // The library variant that brings in androidx-test transitively
 java_library {
     name: "ctstestrunner-axt",
diff --git a/tests/DropBoxManager/OWNERS b/tests/DropBoxManager/OWNERS
new file mode 100644
index 0000000..1a5b740
--- /dev/null
+++ b/tests/DropBoxManager/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 1344
+mwachens@google.com
diff --git a/tests/JobScheduler/OWNERS b/tests/JobScheduler/OWNERS
new file mode 100644
index 0000000..ef7929f
--- /dev/null
+++ b/tests/JobScheduler/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 330738
+ctate@google.com
\ No newline at end of file
diff --git a/tests/JobSchedulerSharedUid/OWNERS b/tests/JobSchedulerSharedUid/OWNERS
new file mode 100644
index 0000000..ef7929f
--- /dev/null
+++ b/tests/JobSchedulerSharedUid/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 330738
+ctate@google.com
\ No newline at end of file
diff --git a/tests/acceleration/OWNERS b/tests/acceleration/OWNERS
new file mode 100644
index 0000000..3d2576a
--- /dev/null
+++ b/tests/acceleration/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 32850
+include platform/frameworks/base:/libs/hwui/OWNERS
diff --git a/tests/accessibility/AndroidManifest.xml b/tests/accessibility/AndroidManifest.xml
index f07494f..d4cea0f 100644
--- a/tests/accessibility/AndroidManifest.xml
+++ b/tests/accessibility/AndroidManifest.xml
@@ -21,9 +21,11 @@
           android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
-    <application android:theme="@android:style/Theme.Holo.NoActionBar" >
+    <application android:theme="@android:style/Theme.Holo.NoActionBar"
+            android:requestLegacyExternalStorage="true">
         <uses-library android:name="android.test.runner"/>
         <service android:name=".SpeakingAccessibilityService"
                  android:label="@string/title_speaking_accessibility_service"
diff --git a/tests/accessibility/AndroidTest.xml b/tests/accessibility/AndroidTest.xml
index 7783a25..3057ae8 100644
--- a/tests/accessibility/AndroidTest.xml
+++ b/tests/accessibility/AndroidTest.xml
@@ -30,4 +30,8 @@
         <option name="package" value="android.view.accessibility.cts" />
         <option name="runtime-hint" value="8m"/>
     </test>
+    <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+        <option name="directory-keys" value="/sdcard/android.view.accessibility.cts" />
+        <option name="collect-on-run-ended-only" value="true" />
+    </metrics_collector>
 </configuration>
diff --git a/tests/accessibility/common/src/android/accessibility/cts/common/AccessibilityDumpOnFailureRule.java b/tests/accessibility/common/src/android/accessibility/cts/common/AccessibilityDumpOnFailureRule.java
new file mode 100644
index 0000000..a7a4282
--- /dev/null
+++ b/tests/accessibility/common/src/android/accessibility/cts/common/AccessibilityDumpOnFailureRule.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 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.accessibility.cts.common;
+
+import android.util.Log;
+
+import org.junit.AssumptionViolatedException;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Custom {@code TestRule} that dump UI data upon test failures.
+ *
+ * <p>Note: when using other {@code TestRule}s, make sure to use a {@code RuleChain} to ensure it
+ * is applied outside of other rules that can fail a test (otherwise this rule may not know that the
+ * test failed).
+ *
+ * <p>To capture the output of this rule, add the following to AndroidTest.xml:
+ * <pre>
+ *  <!-- Collect output of AccessibilityDumpOnFailureRule. -->
+ *  <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+ *    <option name="directory-keys" value="/sdcard/<test.package.name>" />
+ *    <option name="collect-on-run-ended-only" value="true" />
+ *  </metrics_collector>
+ * </pre>
+ * <p>And disable external storage isolation:
+ * <pre>
+ *  <application ... android:requestLegacyExternalStorage="true" ... >
+ * </pre>
+ */
+public class AccessibilityDumpOnFailureRule implements TestRule {
+
+    private static final String LOG_TAG = AccessibilityDumpOnFailureRule.class.getSimpleName();
+
+    private AccessibilityDumper mDumper = new AccessibilityDumper();
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                try {
+                    base.evaluate();
+                } catch (Throwable t) {
+                    // Ignore AssumptionViolatedException. It's not a test fail.
+                    if (!(t instanceof AssumptionViolatedException)) {
+                        onTestFailure(description, t);
+                        throw t;
+                    }
+                }
+            }
+        };
+    }
+
+    public void dump(int flag) {
+        mDumper.dump(flag);
+    }
+
+    protected void onTestFailure(Description description, Throwable t) {
+        try {
+            mDumper.setName(getTestNameFrom(description));
+            mDumper.dump();
+        } catch (Throwable throwable) {
+            Log.e(LOG_TAG, "Dump fail", throwable);
+        }
+    }
+
+    private String getTestNameFrom(Description description) {
+        return description.getTestClass().getSimpleName()
+                + "_" + description.getMethodName();
+    }
+}
diff --git a/tests/accessibility/common/src/android/accessibility/cts/common/AccessibilityDumper.java b/tests/accessibility/common/src/android/accessibility/cts/common/AccessibilityDumper.java
new file mode 100644
index 0000000..3d37d3c
--- /dev/null
+++ b/tests/accessibility/common/src/android/accessibility/cts/common/AccessibilityDumper.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2019 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.accessibility.cts.common;
+
+import static androidx.test.InstrumentationRegistry.getContext;
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertFalse;
+
+import android.app.UiAutomation;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.os.Environment;
+import android.support.test.uiautomator.UiDevice;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
+
+import com.android.compatibility.common.util.BitmapUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.time.LocalTime;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Helper class to dump data for accessibility test cases.
+ *
+ * It can dump {@code dumpsys accessibility}, accessibility node tree to logcat and/or
+ * screenshot for inspect later.
+ */
+public class AccessibilityDumper {
+    private static final String TAG = "AccessibilityDumper";
+
+    /** Dump flag to write the output of {@code dumpsys accessibility} to logcat. */
+    public static final int FLAG_DUMPSYS = 0x1;
+
+    /** Dump flag to write the output of {@code uiautomator dump} to logcat. */
+    public static final int FLAG_HIERARCHY = 0x2;
+
+    /** Dump flag to save the screenshot to external storage. */
+    public static final int FLAG_SCREENSHOT = 0x4;
+
+    /** Dump flag to write the tree of accessility node info to logcat. */
+    public static final int FLAG_NODETREE = 0x8;
+
+    /** Default dump flag */
+    public static final int FLAG_DUMP_ALL = FLAG_DUMPSYS | FLAG_HIERARCHY | FLAG_SCREENSHOT;
+
+    private int mFlag;
+
+    /** Screenshot filename */
+    private String mName;
+
+    /** Root directory matching the directory-key of collector in AndroidTest.xml */
+    private File mRoot;
+
+    /**
+     * Define the directory to dump/clean and initial dump options
+     *
+     * @param flag control what to dump
+     */
+    public AccessibilityDumper(int flag) {
+        mRoot = getDumpRoot(getContext().getPackageName());
+        mFlag = flag;
+    }
+
+    public AccessibilityDumper() {
+        this(FLAG_DUMP_ALL);
+    }
+
+    public void dump(int flag) {
+        if ((flag & FLAG_DUMPSYS) != 0) {
+            dumpsysOnLogcat();
+        }
+        if ((flag & FLAG_HIERARCHY) != 0) {
+            dumpHierarchyOnLogcat();
+        }
+        if ((flag & FLAG_SCREENSHOT) != 0) {
+            dumpScreen();
+        }
+        if ((flag & FLAG_NODETREE) != 0) {
+            dumpAccessibilityNodeTreeOnLogcat();
+        }
+    }
+
+    void dump() {
+        dump(mFlag);
+    }
+
+    void setName(String name) {
+        assertNotEmpty(name);
+        mName = name;
+    }
+
+    private File getDumpRoot(String directory) {
+        return new File(Environment.getExternalStorageDirectory(), directory);
+    }
+
+    private void dumpsysOnLogcat() {
+        ShellCommandBuilder.create(getInstrumentation())
+            .addCommandPrintOnLogCat("dumpsys accessibility")
+            .run();
+    }
+
+    private void dumpHierarchyOnLogcat() {
+        try(ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            UiDevice.getInstance(getInstrumentation()).dumpWindowHierarchy(os);
+            Log.w(TAG, "Window hierarchy:");
+            for (String line : os.toString("UTF-8").split("\\n")) {
+                Log.w(TAG, line);
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "ERROR: unable to dumping hierarchy on logcat", e);
+        }
+    }
+
+    private void dumpScreen() {
+        assertNotEmpty(mName);
+        final Bitmap screenshot = getInstrumentation().getUiAutomation().takeScreenshot();
+        final String filename = String.format("%s_%s__screenshot.png", mName, LocalTime.now());
+        BitmapUtils.saveBitmap(screenshot, mRoot.toString(), filename);
+    }
+
+    /** Dump hierarchy compactly and include nodes not visible to user */
+    private void dumpAccessibilityNodeTreeOnLogcat() {
+        final Set<AccessibilityNodeInfo> roots = new HashSet<>();
+        final UiAutomation automation = getInstrumentation().getUiAutomation();
+        for (AccessibilityWindowInfo window : automation.getWindows()) {
+            AccessibilityNodeInfo root = window.getRoot();
+            if (root == null) {
+                Log.w(TAG, String.format("Skipping null root node for window: %s",
+                        window.toString()));
+            } else {
+                roots.add(root);
+            }
+        }
+        if (roots.isEmpty()) {
+            Log.w(TAG, "No node of windows to dump");
+        } else {
+            Log.w(TAG, "Accessibility nodes hierarchy:");
+            for (AccessibilityNodeInfo root : roots) {
+                dumpTreeWithPrefix(root, "");
+            }
+        }
+    }
+
+    private static void dumpTreeWithPrefix(AccessibilityNodeInfo node, String prefix) {
+        final StringBuilder nodeText = new StringBuilder(prefix);
+        appendNodeText(nodeText, node);
+        Log.v(TAG, nodeText.toString());
+        final int count = node.getChildCount();
+        for (int i = 0; i < count; i++) {
+            AccessibilityNodeInfo child = node.getChild(i);
+            if (child != null) {
+                dumpTreeWithPrefix(child, "-" + prefix);
+            } else {
+                Log.i(TAG, String.format("%sNull child %d/%d", prefix, i, count));
+            }
+        }
+    }
+
+    private static void appendNodeText(StringBuilder out, AccessibilityNodeInfo node) {
+        final CharSequence txt = node.getText();
+        final CharSequence description = node.getContentDescription();
+        final String viewId = node.getViewIdResourceName();
+
+        if (!TextUtils.isEmpty(description)) {
+            out.append(escape(description));
+        } else if (!TextUtils.isEmpty(txt)) {
+            out.append('"').append(escape(txt)).append('"');
+        }
+        if (!TextUtils.isEmpty(viewId)) {
+            out.append("(").append(viewId).append(")");
+        }
+        out.append("+").append(node.getClassName());
+        out.append("+ \t<");
+        out.append(node.isCheckable()       ? "C" : ".");
+        out.append(node.isChecked()         ? "c" : ".");
+        out.append(node.isClickable()       ? "K" : ".");
+        out.append(node.isEnabled()         ? "E" : ".");
+        out.append(node.isFocusable()       ? "F" : ".");
+        out.append(node.isFocused()         ? "f" : ".");
+        out.append(node.isScrollable()      ? "S" : ".");
+        out.append(node.isLongClickable()   ? "L" : ".");
+        out.append(node.isPassword()        ? "P" : ".");
+        out.append(node.isSelected()        ? "s" : ".");
+        out.append(node.isVisibleToUser()   ? "V" : ".");
+        out.append("> ");
+        final Rect bounds = new Rect();
+        node.getBoundsInScreen(bounds);
+        out.append(bounds.toShortString());
+    }
+
+    /**
+     * Produce a displayable string from a CharSequence
+     */
+    private static String escape(CharSequence s) {
+        final StringBuilder out = new StringBuilder();
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            if ((c < 127) || (c == 0xa0) || ((c >= 0x2000) && (c < 0x2070))) {
+                out.append(c);
+            } else {
+                out.append("\\u").append(Integer.toHexString(c));
+            }
+        }
+        return out.toString();
+    }
+
+    private void assertNotEmpty(String name) {
+        assertFalse("Expected non empty name.", TextUtils.isEmpty(name));
+    }
+}
diff --git a/tests/accessibility/common/src/android/accessibility/cts/common/InstrumentedAccessibilityService.java b/tests/accessibility/common/src/android/accessibility/cts/common/InstrumentedAccessibilityService.java
index 3f9a344..cbfb570 100644
--- a/tests/accessibility/common/src/android/accessibility/cts/common/InstrumentedAccessibilityService.java
+++ b/tests/accessibility/common/src/android/accessibility/cts/common/InstrumentedAccessibilityService.java
@@ -52,7 +52,7 @@
 
     // Match com.android.server.accessibility.AccessibilityManagerService#COMPONENT_NAME_SEPARATOR
     private static final String COMPONENT_NAME_SEPARATOR = ":";
-    private static final int TIMEOUT_SERVICE_PERFORM_SYNC = DEBUG ? Integer.MAX_VALUE : 5000;
+    private static final int TIMEOUT_SERVICE_PERFORM_SYNC = DEBUG ? Integer.MAX_VALUE : 10000;
 
     private static final HashMap<Class, WeakReference<InstrumentedAccessibilityService>>
             sInstances = new HashMap<>();
@@ -119,13 +119,14 @@
     public <T extends Object> T getOnService(Callable<T> callable) {
         AtomicReference<T> returnValue = new AtomicReference<>(null);
         AtomicReference<Throwable> throwable = new AtomicReference<>(null);
-        runOnServiceSync(() -> {
-            try {
-                returnValue.set(callable.call());
-            } catch (Throwable e) {
-                throwable.set(e);
-            }
-        });
+        runOnServiceSync(
+                () -> {
+                    try {
+                        returnValue.set(callable.call());
+                    } catch (Throwable e) {
+                        throwable.set(e);
+                    }
+                });
         if (throwable.get() != null) {
             throw new RuntimeException(throwable.get());
         }
@@ -170,21 +171,23 @@
             Instrumentation instrumentation, Class<T> clazz) {
         final String serviceName = clazz.getSimpleName();
         final Context context = instrumentation.getContext();
-        final String enabledServices = Settings.Secure.getString(
-                context.getContentResolver(),
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+        final String enabledServices =
+                Settings.Secure.getString(
+                        context.getContentResolver(),
+                        Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
         if (enabledServices != null) {
             assertFalse("Service is already enabled", enabledServices.contains(serviceName));
         }
-        final AccessibilityManager manager = (AccessibilityManager) context.getSystemService(
-                Context.ACCESSIBILITY_SERVICE);
+        final AccessibilityManager manager =
+                (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
         final List<AccessibilityServiceInfo> serviceInfos =
                 manager.getInstalledAccessibilityServiceList();
         for (AccessibilityServiceInfo serviceInfo : serviceInfos) {
             final String serviceId = serviceInfo.getId();
             if (serviceId.endsWith(serviceName)) {
                 ShellCommandBuilder.create(instrumentation)
-                        .putSecureSetting(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                        .putSecureSetting(
+                                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
                                 enabledServices + COMPONENT_NAME_SEPARATOR + serviceId)
                         .putSecureSetting(Settings.Secure.ACCESSIBILITY_ENABLED, "1")
                         .run();
@@ -192,11 +195,15 @@
                 final T instance = getInstanceForClass(clazz, TIMEOUT_SERVICE_ENABLE);
                 if (instance == null) {
                     ShellCommandBuilder.create(instrumentation)
-                            .putSecureSetting(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
-                                    enabledServices)
+                            .putSecureSetting(
+                                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServices)
                             .run();
-                    throw new RuntimeException("Starting accessibility service " + serviceName
-                            + " took longer than " + TIMEOUT_SERVICE_ENABLE + "ms");
+                    throw new RuntimeException(
+                            "Starting accessibility service "
+                                    + serviceName
+                                    + " took longer than "
+                                    + TIMEOUT_SERVICE_ENABLE
+                                    + "ms");
                 }
                 return instance;
             }
@@ -204,8 +211,8 @@
         throw new RuntimeException("Accessibility service " + serviceName + " not found");
     }
 
-    public static <T extends InstrumentedAccessibilityService> T getInstanceForClass(Class clazz,
-            long timeoutMillis) {
+    public static <T extends InstrumentedAccessibilityService> T getInstanceForClass(
+            Class clazz, long timeoutMillis) {
         final long timeoutTimeMillis = SystemClock.uptimeMillis() + timeoutMillis;
         while (SystemClock.uptimeMillis() < timeoutTimeMillis) {
             synchronized (sInstances) {
@@ -235,12 +242,13 @@
                 (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
         // Updates to manager.isEnabled() aren't synchronized
         final AtomicBoolean accessibilityEnabled = new AtomicBoolean(manager.isEnabled());
-        manager.addAccessibilityStateChangeListener(b -> {
-            synchronized (waitLockForA11yOff) {
-                waitLockForA11yOff.notifyAll();
-                accessibilityEnabled.set(b);
-            }
-        });
+        manager.addAccessibilityStateChangeListener(
+                b -> {
+                    synchronized (waitLockForA11yOff) {
+                        waitLockForA11yOff.notifyAll();
+                        accessibilityEnabled.set(b);
+                    }
+                });
         final UiAutomation uiAutomation = instrumentation.getUiAutomation(
                 UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
         ShellCommandBuilder.create(uiAutomation)
diff --git a/tests/accessibility/common/src/android/accessibility/cts/common/ShellCommandBuilder.java b/tests/accessibility/common/src/android/accessibility/cts/common/ShellCommandBuilder.java
index c305ceb..cfeb1fd 100644
--- a/tests/accessibility/common/src/android/accessibility/cts/common/ShellCommandBuilder.java
+++ b/tests/accessibility/common/src/android/accessibility/cts/common/ShellCommandBuilder.java
@@ -21,6 +21,8 @@
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
+import com.android.compatibility.common.util.SystemUtil;
+
 import java.io.BufferedReader;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -88,6 +90,25 @@
         return this;
     }
 
+    public ShellCommandBuilder addCommandPrintOnLogCat(String command) {
+        mCommands.add(() -> {
+            execShellCommandAndPrintOnLogcat(mUiAutomation, command);
+        });
+        return this;
+    }
+
+    public static void execShellCommandAndPrintOnLogcat(UiAutomation automation, String command) {
+        Log.i(LOG_TAG, "command [" + command + "]");
+        try {
+            final String output = SystemUtil.runShellCommand(automation, command);
+            for (String line : output.split("\\n", -1)) {
+                Log.i(LOG_TAG, line);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException("Failed to exec shell command [" + command + "]", e);
+        }
+    }
+
     public static void execShellCommand(UiAutomation automation, String command) {
         Log.i(LOG_TAG, "command [" + command + "]");
         try (ParcelFileDescriptor fd = automation.executeShellCommand(command)) {
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityDelegateTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityDelegateTest.java
index fcc4f6e..d3b6162 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityDelegateTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityDelegateTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.app.Activity;
 import android.os.Bundle;
 import android.view.View;
@@ -36,6 +37,7 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 /**
@@ -47,10 +49,17 @@
     private LinearLayout mParentView;
     private View mChildView;
 
-    @Rule
-    public ActivityTestRule<DummyActivity> mActivityRule =
+    private ActivityTestRule<DummyActivity> mActivityRule =
             new ActivityTestRule<>(DummyActivity.class, false, false);
 
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
+
     @Before
     public void setUp() throws Exception {
         Activity activity = mActivityRule.launchActivity(null);
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
index 509092f..b140f37 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
@@ -16,27 +16,45 @@
 
 package android.view.accessibility.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.os.Message;
 import android.os.Parcel;
 import android.platform.test.annotations.Presubmit;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.text.TextUtils;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityRecord;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import junit.framework.TestCase;
 
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Class for testing {@link AccessibilityEvent}.
  */
 @Presubmit
-public class AccessibilityEventTest extends TestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityEventTest {
+
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     /**
      * Tests whether accessibility events are correctly written and
      * read from a parcel (version 1).
      */
     @SmallTest
+    @Test
     public void testMarshaling() throws Exception {
         // fully populate the event to marshal
         AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
@@ -58,6 +76,7 @@
      * Tests if {@link AccessibilityEvent} are properly reused.
      */
     @SmallTest
+    @Test
     public void testReuse() {
         AccessibilityEvent firstEvent = AccessibilityEvent.obtain();
         firstEvent.recycle();
@@ -69,6 +88,7 @@
      * Tests if {@link AccessibilityEvent} are properly recycled.
      */
     @SmallTest
+    @Test
     public void testRecycle() {
         // obtain and populate an event
         AccessibilityEvent populatedEvent = AccessibilityEvent.obtain();
@@ -86,6 +106,7 @@
      * Tests whether the event types are correctly converted to strings.
      */
     @SmallTest
+    @Test
     public void testEventTypeToString() {
         assertEquals("TYPE_NOTIFICATION_STATE_CHANGED", AccessibilityEvent.eventTypeToString(
                 AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED));
@@ -123,6 +144,7 @@
      * Tests whether the event describes its contents consistently.
      */
     @SmallTest
+    @Test
     public void testDescribeContents() {
         AccessibilityEvent event = AccessibilityEvent.obtain();
         assertSame("Accessibility events always return 0 for this method.", 0,
@@ -137,6 +159,7 @@
      * read from a parcel (version 2).
      */
     @SmallTest
+    @Test
     public void testMarshaling2() {
         AccessibilityEvent marshaledEvent = AccessibilityEvent.obtain();
         fullyPopulateAccessibilityEvent(marshaledEvent);
@@ -155,6 +178,7 @@
      * can't change the object by changing the objects backing CharSequence
      */
     @SmallTest
+    @Test
     public void testChangeTextAfterSetting_shouldNotAffectEvent() {
         final String originalText = "Cassowary";
         final String newText = "Hornbill";
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
index a681baf..ee0d4de 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
@@ -28,6 +28,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibility.cts.common.InstrumentedAccessibilityService;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.Instrumentation;
@@ -52,6 +53,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -65,6 +67,10 @@
 @RunWith(AndroidJUnit4.class)
 public class AccessibilityManagerTest {
 
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     private static final Instrumentation sInstrumentation =
             InstrumentationRegistry.getInstrumentation();
 
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
index 0923a92..c7c9b0d 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
@@ -16,13 +16,20 @@
 
 package android.view.accessibility.cts;
 
+import static androidx.test.InstrumentationRegistry.getContext;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.platform.test.annotations.Presubmit;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.text.InputType;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -35,6 +42,13 @@
 import android.view.accessibility.AccessibilityNodeInfo.RangeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.TouchDelegateInfo;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -43,9 +57,15 @@
  * Class for testing {@link AccessibilityNodeInfo}.
  */
 @Presubmit
-public class AccessibilityNodeInfoTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityNodeInfoTest {
+
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
 
     @SmallTest
+    @Test
     public void testMarshaling() throws Exception {
         // fully populate the node info to marshal
         AccessibilityNodeInfo sentInfo = AccessibilityNodeInfo.obtain(new View(getContext()));
@@ -67,6 +87,7 @@
      * Tests if {@link AccessibilityNodeInfo}s are properly reused.
      */
     @SmallTest
+    @Test
     public void testReuse() {
         AccessibilityEvent firstInfo = AccessibilityEvent.obtain();
         firstInfo.recycle();
@@ -78,6 +99,7 @@
      * Tests if {@link AccessibilityNodeInfo} are properly recycled.
      */
     @SmallTest
+    @Test
     public void testRecycle() {
         // obtain and populate an node info
         AccessibilityNodeInfo populatedInfo = AccessibilityNodeInfo.obtain();
@@ -95,6 +117,7 @@
      * Tests whether the event describes its contents consistently.
      */
     @SmallTest
+    @Test
     public void testDescribeContents() {
         AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
         assertSame("Accessibility node infos always return 0 for this method.", 0,
@@ -108,6 +131,7 @@
      * Tests whether accessibility actions are properly added.
      */
     @SmallTest
+    @Test
     public void testAddActions() {
         List<AccessibilityAction> customActions = new ArrayList<AccessibilityAction>();
         customActions.add(new AccessibilityAction(AccessibilityNodeInfo.ACTION_FOCUS, "Foo"));
@@ -133,6 +157,7 @@
      * Tests whether we catch addition of an action with invalid id.
      */
     @SmallTest
+    @Test
     public void testCreateInvalidActionId() {
         try {
             new AccessibilityAction(3, null);
@@ -145,6 +170,7 @@
      * Tests whether accessibility actions are properly removed.
      */
     @SmallTest
+    @Test
     public void testRemoveActions() {
         AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
 
@@ -173,6 +199,7 @@
      * can't change the object by changing the objects backing CharSequence
      */
     @SmallTest
+    @Test
     public void testChangeTextAfterSetting_shouldNotAffectInfo() {
         final String originalText = "Cassowaries";
         final String newText = "Hornbill";
@@ -191,6 +218,7 @@
     }
 
     @SmallTest
+    @Test
     public void testIsHeadingTakesOldApiIntoAccount() {
         final AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
         assertFalse(info.isHeading());
@@ -399,11 +427,11 @@
                 (receivedRange != null));
         if (expectedRange != null) {
             assertEquals("RangeInfo#getCurrent has incorrect value", expectedRange.getCurrent(),
-                    receivedRange.getCurrent());
+                    receivedRange.getCurrent(), 0.0);
             assertEquals("RangeInfo#getMin has incorrect value", expectedRange.getMin(),
-                    receivedRange.getMin());
+                    receivedRange.getMin(), 0.0);
             assertEquals("RangeInfo#getMax has incorrect value", expectedRange.getMax(),
-                    receivedRange.getMax());
+                    receivedRange.getMax(), 0.0);
             assertEquals("RangeInfo#getType has incorrect value", expectedRange.getType(),
                     receivedRange.getType());
         }
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_CollectionInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_CollectionInfoTest.java
index 98b87fc..cabfd98 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_CollectionInfoTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_CollectionInfoTest.java
@@ -16,18 +16,34 @@
 
 package android.view.accessibility.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.platform.test.annotations.Presubmit;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Class for testing {@link CollectionInfo}.
  */
 @Presubmit
-public class AccessibilityNodeInfo_CollectionInfoTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityNodeInfo_CollectionInfoTest  {
+
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
 
     @SmallTest
+    @Test
     public void testObtain() {
         CollectionInfo c;
 
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_RangeInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_RangeInfoTest.java
index 4b01129..e7761f4 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_RangeInfoTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfo_RangeInfoTest.java
@@ -16,22 +16,36 @@
 
 package android.view.accessibility.cts;
 
+import static org.junit.Assert.assertEquals;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.platform.test.annotations.Presubmit;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.RangeInfo;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Class for testing {@link AccessibilityNodeInfo.RangeInfo}.
  */
 @Presubmit
-public class AccessibilityNodeInfo_RangeInfoTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityNodeInfo_RangeInfoTest {
 
     /** Allowed tolerance for floating point equality comparisons. */
     public static final float FLOAT_TOLERANCE = 0.001f;
 
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     @SmallTest
+    @Test
     public void testObtain() {
         RangeInfo r;
 
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeProviderTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeProviderTest.java
index 0c2a2dd..60bc1a3 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeProviderTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeProviderTest.java
@@ -16,17 +16,33 @@
 
 package android.view.accessibility.cts;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.platform.test.annotations.Presubmit;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.view.accessibility.AccessibilityNodeProvider;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Class for testing {@link AccessibilityNodeProvider}.
  */
 @Presubmit
-public class AccessibilityNodeProviderTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityNodeProviderTest {
+
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     @SmallTest
+    @Test
     public void testDefaultBehavior() {
         AccessibilityNodeProvider p = new AccessibilityNodeProvider() {
             // Class is abstract, but has no abstract methods.
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityRecordTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityRecordTest.java
index 72bb4e0..7ae8070 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityRecordTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityRecordTest.java
@@ -16,17 +16,23 @@
 
 package android.view.accessibility.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.os.Message;
 import android.platform.test.annotations.Presubmit;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityRecord;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
 import junit.framework.TestCase;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.Iterator;
 import java.util.List;
 
@@ -34,11 +40,18 @@
  * Class for testing {@link AccessibilityRecord}.
  */
 @Presubmit
-public class AccessibilityRecordTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityRecordTest {
+
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     /**
      * Tests the cloning obtain method.
      */
     @SmallTest
+    @Test
     public void testObtain() {
         AccessibilityRecord originalRecord = AccessibilityRecord.obtain();
         fullyPopulateAccessibilityRecord(originalRecord);
@@ -50,6 +63,7 @@
     * Tests if {@link AccessibilityRecord}s are properly recycled.
     */
    @SmallTest
+   @Test
    public void testRecycle() {
        // obtain and populate an event
        AccessibilityRecord populatedRecord = AccessibilityRecord.obtain();
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
index 0029b53..d80ba5c 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityServiceInfoTest.java
@@ -16,14 +16,29 @@
 
 package android.view.accessibility.cts;
 
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibility.cts.common.InstrumentedAccessibilityService;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.Service;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.List;
 
 /**
@@ -33,15 +48,20 @@
  * accessibility service and the fake service used for implementing the UI
  * automation is not reported through the APIs.
  */
-public class AccessibilityServiceInfoTest  extends InstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityServiceInfoTest {
 
-    @Override
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Before
     public void setUp() throws Exception {
         SpeakingAccessibilityService.enableSelf(getInstrumentation());
         VibratingAccessibilityService.enableSelf(getInstrumentation());
     }
 
-    @Override
+    @After
     public void tearDown() {
         InstrumentedAccessibilityService.disableAllServices(getInstrumentation());
     }
@@ -52,6 +72,7 @@
      */
     @MediumTest
     @SuppressWarnings("deprecation")
+    @Test
     public void testAccessibilityServiceInfoForEnabledService() {
         AccessibilityManager accessibilityManager = (AccessibilityManager)
                 getInstrumentation().getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityWindowInfoTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityWindowInfoTest.java
index e959544..f391263 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityWindowInfoTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityWindowInfoTest.java
@@ -16,21 +16,41 @@
 
 package android.view.accessibility.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.graphics.Rect;
 import android.os.Parcel;
 import android.platform.test.annotations.Presubmit;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.text.TextUtils;
 import android.view.accessibility.AccessibilityWindowInfo;
 
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Class for testing {@link AccessibilityWindowInfo}.
  */
 @Presubmit
-public class AccessibilityWindowInfoTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityWindowInfoTest {
+
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
 
     @SmallTest
+    @Test
     public void testObtain() {
         AccessibilityWindowInfo w1 = AccessibilityWindowInfo.obtain();
         assertNotNull(w1);
@@ -41,6 +61,7 @@
     }
 
     @SmallTest
+    @Test
     public void testParceling() {
         Parcel parcel = Parcel.obtain();
         AccessibilityWindowInfo w1 = AccessibilityWindowInfo.obtain();
@@ -53,6 +74,7 @@
     }
 
     @SmallTest
+    @Test
     public void testDefaultValues() {
         AccessibilityWindowInfo w = AccessibilityWindowInfo.obtain();
         assertEquals(0, w.getChildCount());
@@ -80,6 +102,7 @@
     }
 
     @SmallTest
+    @Test
     public void testRecycle() {
         AccessibilityWindowInfo w = AccessibilityWindowInfo.obtain();
         w.recycle();
diff --git a/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java b/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java
index d0db868..c3054ef 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java
@@ -16,6 +16,12 @@
 
 package android.view.accessibility.cts;
 
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.mockito.Matchers.anyFloat;
 import static org.mockito.Matchers.anyObject;
 import static org.mockito.Mockito.mock;
@@ -23,13 +29,19 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.app.UiAutomation;
 import android.os.ParcelFileDescriptor;
-import android.test.InstrumentationTestCase;
 import android.view.accessibility.CaptioningManager;
 import android.view.accessibility.CaptioningManager.CaptionStyle;
 import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
 
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.Mockito;
 
 import java.io.FileInputStream;
@@ -40,15 +52,19 @@
 /**
  * Tests whether the CaptioningManager APIs are functional.
  */
-public class CaptioningManagerTest extends InstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class CaptioningManagerTest {
+
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     private static final int LISTENER_TIMEOUT = 3000;
     private CaptioningManager mManager;
     private UiAutomation mUiAutomation;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
+    @Before
+    public void setUp() throws Exception {
         mManager = getInstrumentation().getTargetContext().getSystemService(
                 CaptioningManager.class);
 
@@ -60,6 +76,7 @@
     /**
      * Tests whether a client can observe changes in caption properties.
      */
+    @Test
     public void testChangeListener() {
         putSecureSetting("accessibility_captioning_enabled","0");
         putSecureSetting("accessibility_captioning_preset", "1");
@@ -97,16 +114,18 @@
         }
     }
 
+    @Test
     public void testProperties() {
         putSecureSetting("accessibility_captioning_font_scale", "2.0");
         putSecureSetting("accessibility_captioning_locale", "ja_JP");
         putSecureSetting("accessibility_captioning_enabled", "1");
 
-        assertEquals("Test runner set font scale to 2.0", 2.0f, mManager.getFontScale());
+        assertEquals("Test runner set font scale to 2.0", 2.0f, mManager.getFontScale(), 0f);
         assertEquals("Test runner set locale to Japanese", Locale.JAPAN, mManager.getLocale());
         assertEquals("Test runner set enabled to true", true, mManager.isEnabled());
     }
 
+    @Test
     public void testUserStyle() {
         putSecureSetting("accessibility_captioning_preset", "-1");
         putSecureSetting("accessibility_captioning_foreground_color", "511");
diff --git a/tests/accessibilityservice/Android.bp b/tests/accessibilityservice/Android.bp
index 527ce29..40b928c 100644
--- a/tests/accessibilityservice/Android.bp
+++ b/tests/accessibilityservice/Android.bp
@@ -19,6 +19,7 @@
         "ctstestrunner-axt",
         "hamcrest-library",
         "mockito-target-minus-junit4",
+        "compatibility-device-util-axt",
         "platform-test-annotations",
         "CtsAccessibilityCommon",
     ],
diff --git a/tests/accessibilityservice/AndroidManifest.xml b/tests/accessibilityservice/AndroidManifest.xml
index fc0b2e6..f4227c1 100644
--- a/tests/accessibilityservice/AndroidManifest.xml
+++ b/tests/accessibilityservice/AndroidManifest.xml
@@ -20,10 +20,12 @@
           android:targetSandboxVersion="2">
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <uses-permission android:name="android.permission.USE_FINGERPRINT" />
 
-    <application android:theme="@android:style/Theme.Holo.NoActionBar">
+    <application android:theme="@android:style/Theme.Holo.NoActionBar"
+                 android:requestLegacyExternalStorage="true">
 
         <uses-library android:name="android.test.runner" />
 
@@ -67,6 +69,15 @@
             android:label="@string/accessibility_soft_keyboard_modes_activity"
             android:name=".AccessibilitySoftKeyboardModesTest$SoftKeyboardModesActivity" />
 
+        <activity
+            android:label="@string/accessibility_embedded_display_test_parent_activity"
+            android:name=".AccessibilityEmbeddedDisplayTest$EmbeddedDisplayParentActivity"
+            android:theme="@android:style/Theme.Dialog" />
+
+        <activity
+            android:label="@string/accessibility_embedded_display_test_activity"
+            android:name=".AccessibilityEmbeddedDisplayTest$EmbeddedDisplayActivity" />
+
         <service
                 android:name=".StubGestureAccessibilityService"
                 android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
@@ -93,6 +104,17 @@
         </service>
 
         <service
+                android:name=".TouchExplorationStubAccessibilityService"
+                android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
+            <intent-filter>
+                <action android:name="android.accessibilityservice.AccessibilityService" />
+                <category android:name="android.accessibilityservice.category.FEEDBACK_GENERIC" />
+            </intent-filter>
+            <meta-data
+                    android:name="android.accessibilityservice"
+                    android:resource="@xml/stub_touch_exploration_a11y_service" />
+        </service>
+        <service
             android:name="android.accessibility.cts.common.InstrumentedAccessibilityService"
             android:label="@string/title_soft_keyboard_modes_accessibility_service"
             android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
diff --git a/tests/accessibilityservice/AndroidTest.xml b/tests/accessibilityservice/AndroidTest.xml
index eb75538..b0e873c 100644
--- a/tests/accessibilityservice/AndroidTest.xml
+++ b/tests/accessibilityservice/AndroidTest.xml
@@ -34,4 +34,8 @@
         <option name="package" value="android.accessibilityservice.cts" />
         <option name="runtime-hint" value="2m12s" />
     </test>
+    <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+        <option name="directory-keys" value="/sdcard/android.accessibilityservice.cts" />
+        <option name="collect-on-run-ended-only" value="true" />
+    </metrics_collector>
 </configuration>
diff --git a/tests/accessibilityservice/res/layout/accessibility_embedded_display_test.xml b/tests/accessibilityservice/res/layout/accessibility_embedded_display_test.xml
new file mode 100644
index 0000000..666bfbe
--- /dev/null
+++ b/tests/accessibilityservice/res/layout/accessibility_embedded_display_test.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:gravity="center"
+              android:orientation="vertical">
+
+    <Button
+        android:id="@+id/button"
+        android:text="@string/button_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+</LinearLayout>
diff --git a/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml b/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
index 0dbd62a..e05c259 100644
--- a/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
+++ b/tests/accessibilityservice/res/layout/accessibility_view_tree_reporting_test.xml
@@ -88,6 +88,14 @@
               android:text="@string/secondButton"
               android:textSize="10dip" />
 
+          <Button
+              android:id="@+id/hiddenButton"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:text="@string/secondButton"
+              android:textSize="10dip"
+              android:visibility="gone" />
+
       </LinearLayout>
 
     </FrameLayout>
diff --git a/tests/accessibilityservice/res/values/strings.xml b/tests/accessibilityservice/res/values/strings.xml
index ad5d3fd..3fd45bd 100644
--- a/tests/accessibilityservice/res/values/strings.xml
+++ b/tests/accessibilityservice/res/values/strings.xml
@@ -147,7 +147,9 @@
 
     <string name="stub_gesture_dispatch_a11y_service_description">com.android.accessibilityservice.cts.StubGestureAccessibilityService</string>
 
-    <string name="stub_gesture_detector_a11y_service_description">com.android.accessibilityservice.cts.StubService</string>
+    <string name="stub_gesture_detector_a11y_service_description">com.android.accessibilityservice.cts.GestureDetectionStubAccessibilityService</string>
+
+    <string name="stub_touch_exploration_a11y_service_description">com.android.accessibilityservice.cts.TouchExplorationStubAccessibilityService</string>
 
     <string name="stub_fprint_a11y_service_description">com.android.accessibilityservice.cts.StubFingerprintGestureAccessibilityService</string>
 
@@ -170,4 +172,12 @@
     <!-- Description of the accessibility service -->
     <string name="soft_keyboard_modes_accessibility_service_description">This Accessibility Service was installed for testing purposes. It can be uninstalled by going to Settings > Apps > android.view.accessibilityservice.services and selecting \"Uninstall\".</string>
 
+    <!-- AccessibilityEmbeddedDisplayTest -->
+
+    <!-- String title of accessibility embedded display test parent window activity -->
+    <string name="accessibility_embedded_display_test_parent_activity">Embedded display test parent</string>
+
+    <!-- String title of accessibility embedded display test activity -->
+    <string name="accessibility_embedded_display_test_activity">Embedded display test</string>
+
 </resources>
diff --git a/tests/accessibilityservice/res/xml/stub_touch_exploration_a11y_service.xml b/tests/accessibilityservice/res/xml/stub_touch_exploration_a11y_service.xml
new file mode 100644
index 0000000..33c5ec8
--- /dev/null
+++ b/tests/accessibilityservice/res/xml/stub_touch_exploration_a11y_service.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2019 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.
+-->
+
+<accessibility-service
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:description="@string/stub_touch_exploration_a11y_service_description"
+        android:accessibilityEventTypes="typeAllMask"
+        android:accessibilityFeedbackType="feedbackGeneric"
+        android:accessibilityFlags="flagDefault|flagRequestTouchExplorationMode|flagReportViewIds"
+        android:canRequestTouchExplorationMode="true"
+        android:canRetrieveWindowContent="true"
+        android:canPerformGestures="true" />
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityButtonTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityButtonTest.java
index 84fb0ef..6b758c0 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityButtonTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityButtonTest.java
@@ -16,6 +16,7 @@
 
 import static android.accessibilityservice.cts.utils.CtsTestUtils.runIfNotNull;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityButtonController;
 import android.app.Instrumentation;
 import android.platform.test.annotations.AppModeFull;
@@ -25,6 +26,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -37,6 +39,10 @@
 @RunWith(AndroidJUnit4.class)
 public class AccessibilityButtonTest {
 
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     private StubAccessibilityButtonService mService;
     private AccessibilityButtonController mButtonController;
     private AccessibilityButtonController.AccessibilityButtonCallback mStubCallback =
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedDisplayTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedDisplayTest.java
new file mode 100644
index 0000000..c3c1efc
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEmbeddedDisplayTest.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2019 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.accessibilityservice.cts;
+
+import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.findWindowByTitle;
+import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityAndWaitForItToBeOnscreen;
+import static android.accessibilityservice.cts.utils.AsyncUtils.DEFAULT_TIMEOUT_MS;
+import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
+import android.accessibilityservice.cts.activities.AccessibilityTestActivity;
+import android.app.Activity;
+import android.app.ActivityView;
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.platform.test.annotations.Presubmit;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests that AccessibilityWindowInfos and AccessibilityNodeInfos from a window on an embedded
+ * display that is re-parented to another window are properly populated.
+ */
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityEmbeddedDisplayTest {
+    private static Instrumentation sInstrumentation;
+    private static UiAutomation sUiAutomation;
+
+    private EmbeddedDisplayParentActivity mActivity;
+    private ActivityView mActivityView;
+    private Context mContext;
+
+    private String mParentActivityTitle;
+    private String mActivityTitle;
+
+    private final ActivityTestRule<EmbeddedDisplayParentActivity> mActivityRule =
+            new ActivityTestRule<>(EmbeddedDisplayParentActivity.class, false, false);
+
+    private final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
+
+    @BeforeClass
+    public static void oneTimeSetup() throws Exception {
+        sInstrumentation = InstrumentationRegistry.getInstrumentation();
+        sUiAutomation = sInstrumentation.getUiAutomation();
+    }
+
+    @AfterClass
+    public static void postTestTearDown() {
+        sUiAutomation.destroy();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = sInstrumentation.getContext();
+        assumeTrue(supportsMultiDisplay());
+
+        mParentActivityTitle = mContext.getString(
+                R.string.accessibility_embedded_display_test_parent_activity);
+        mActivityTitle = mContext.getString(R.string.accessibility_embedded_display_test_activity);
+
+        SystemUtil.runWithShellPermissionIdentity(() -> {
+            mActivity = launchActivityAndWaitForItToBeOnscreen(
+                    sInstrumentation, sUiAutomation, mActivityRule);
+            mActivityView = mActivity.getActivityView();
+        });
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (mActivityView != null) {
+            SystemUtil.runWithShellPermissionIdentity(() -> mActivityView.release());
+        }
+    }
+
+    @Presubmit
+    @Test
+    public void testA11yWindowInfoHasCorrectLayer() throws Exception {
+        launchActivityInActivityView();
+
+        assertTrue(findWindowByTitle(sUiAutomation, mActivityTitle).getLayer()
+                > findWindowByTitle(sUiAutomation, mParentActivityTitle).getLayer());
+    }
+
+    @Presubmit
+    @Test
+    public void testA11yWindowInfoAndA11yNodeInfoHasCorrectBoundsInScreen() throws Exception {
+        launchActivityInActivityView();
+
+        final AccessibilityNodeInfo button = findWindowByTitle(sUiAutomation,
+                mActivityTitle).getRoot().findAccessibilityNodeInfosByViewId(
+                "android.accessibilityservice.cts:id/button").get(0);
+        final Rect parentActivityBound = getWindowBoundByTitle(mParentActivityTitle);
+        final Rect activityBound = getWindowBoundByTitle(mActivityTitle);
+        final Rect buttonBound = new Rect();
+        button.getBoundsInScreen(buttonBound);
+
+        assertTrue(parentActivityBound.contains(activityBound));
+        assertTrue(parentActivityBound.contains(buttonBound));
+    }
+
+    private void launchActivityInActivityView() throws Exception {
+        final Rect bounds = new Rect();
+        sUiAutomation.executeAndWaitForEvent(
+                () -> sInstrumentation.runOnMainSync(() -> {
+                    Intent intent = new Intent(mContext, EmbeddedDisplayActivity.class);
+                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                    SystemUtil.runWithShellPermissionIdentity(
+                            () -> mActivityView.startActivity(intent));
+                }),
+                (event) -> {
+                    // Ensure the target activity is shown
+                    final AccessibilityWindowInfo window =
+                            findWindowByTitle(sUiAutomation, mContext.getString(
+                                    R.string.accessibility_embedded_display_test_activity));
+                    if (window == null) {
+                        return false;
+                    }
+                    window.getBoundsInScreen(bounds);
+                    return !bounds.isEmpty();
+                }, DEFAULT_TIMEOUT_MS);
+    }
+
+    private Rect getWindowBoundByTitle(String title) {
+        final AccessibilityWindowInfo window = findWindowByTitle(sUiAutomation, title);
+        final Rect bound = new Rect();
+        window.getBoundsInScreen(bound);
+        return bound;
+    }
+
+    private boolean supportsMultiDisplay() {
+        return mContext.getPackageManager().hasSystemFeature(
+                FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
+    }
+
+    public static class EmbeddedDisplayParentActivity extends Activity {
+        private ActivityView mActivityView;
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mActivityView = new ActivityView(this);
+            setContentView(mActivityView);
+        }
+
+        ActivityView getActivityView() {
+            return mActivityView;
+        }
+    }
+
+    public static class EmbeddedDisplayActivity extends AccessibilityTestActivity {
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setContentView(R.layout.accessibility_embedded_display_test);
+        }
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
index 60ef850..142b1cf 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -45,6 +45,7 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibility.cts.common.InstrumentedAccessibilityService;
 import android.accessibility.cts.common.ShellCommandBuilder;
 import android.accessibilityservice.AccessibilityServiceInfo;
@@ -101,6 +102,7 @@
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 import java.util.Iterator;
@@ -131,10 +133,17 @@
 
     private AccessibilityEndToEndActivity mActivity;
 
-    @Rule
-    public ActivityTestRule<AccessibilityEndToEndActivity> mActivityRule =
+    private ActivityTestRule<AccessibilityEndToEndActivity> mActivityRule =
             new ActivityTestRule<>(AccessibilityEndToEndActivity.class, false, false);
 
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
+
     @BeforeClass
     public static void oneTimeSetup() throws Exception {
         sInstrumentation = InstrumentationRegistry.getInstrumentation();
@@ -504,6 +513,7 @@
                 .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
         InstrumentedAccessibilityService service = InstrumentedAccessibilityService.enableService(
                 sInstrumentation, InstrumentedAccessibilityService.class);
+
         try {
             assertFalse(service.wasOnInterruptCalled());
 
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFingerprintGestureTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFingerprintGestureTest.java
index 1db66a2..0dc118c 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFingerprintGestureTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFingerprintGestureTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.FingerprintGestureController;
 import android.accessibilityservice.FingerprintGestureController.FingerprintGestureCallback;
 import android.accessibilityservice.cts.activities.AccessibilityEndToEndActivity;
@@ -39,6 +40,7 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -57,10 +59,16 @@
     FingerprintGestureController mFingerprintGestureController;
     CancellationSignal mCancellationSignal = new CancellationSignal();
 
-    @Rule
-    public ActivityTestRule<AccessibilityEndToEndActivity> mActivityRule =
+    private ActivityTestRule<AccessibilityEndToEndActivity> mActivityRule =
             new ActivityTestRule<>(AccessibilityEndToEndActivity.class, false, false);
 
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
 
     @Mock FingerprintManager.AuthenticationCallback mMockAuthenticationCallback;
     @Mock FingerprintGestureCallback mMockFingerprintGestureCallback;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java
index 43c12e9..7d5146a 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityFocusAndInputFocusSyncTest.java
@@ -26,8 +26,8 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityServiceInfo;
-import android.accessibilityservice.cts.R;
 import android.accessibilityservice.cts.activities.AccessibilityFocusAndInputFocusSyncActivity;
 import android.app.Instrumentation;
 import android.app.UiAutomation;
@@ -46,6 +46,7 @@
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 import java.util.LinkedList;
@@ -65,10 +66,17 @@
 
     private AccessibilityFocusAndInputFocusSyncActivity mActivity;
 
-    @Rule
-    public ActivityTestRule<AccessibilityFocusAndInputFocusSyncActivity> mActivityRule =
+    private ActivityTestRule<AccessibilityFocusAndInputFocusSyncActivity> mActivityRule =
             new ActivityTestRule<>(AccessibilityFocusAndInputFocusSyncActivity.class, false, false);
 
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
+
     @BeforeClass
     public static void oneTimeSetup() throws Exception {
         sInstrumentation = InstrumentationRegistry.getInstrumentation();
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
index 24c00ff..a1307ba 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDetectorTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.GestureDescription;
 import android.accessibilityservice.GestureDescription.StrokeDescription;
@@ -44,6 +45,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -59,6 +61,10 @@
     private static final long GESTURE_DISPATCH_TIMEOUT_MS = 3000;
     private static final long EVENT_DISPATCH_TIMEOUT_MS = 3000;
 
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     // Test AccessibilityService that collects gestures.
     GestureDetectionStubAccessibilityService mService; 
     boolean mHasTouchScreen;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
index 757be1b..096878d 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
@@ -14,6 +14,7 @@
 
 package android.accessibilityservice.cts;
 
+import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityAndWaitForItToBeOnscreen;
 import static android.accessibilityservice.cts.utils.AsyncUtils.await;
 import static android.accessibilityservice.cts.utils.AsyncUtils.awaitCancellation;
 import static android.accessibilityservice.cts.utils.CtsTestUtils.runIfNotNull;
@@ -26,19 +27,25 @@
 import static android.accessibilityservice.cts.utils.GestureUtils.path;
 import static android.accessibilityservice.cts.utils.GestureUtils.times;
 
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
 import static org.hamcrest.CoreMatchers.allOf;
 import static org.hamcrest.CoreMatchers.any;
 import static org.hamcrest.CoreMatchers.both;
 import static org.hamcrest.CoreMatchers.everyItem;
 import static org.hamcrest.CoreMatchers.hasItem;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.GestureDescription;
 import android.accessibilityservice.GestureDescription.StrokeDescription;
 import android.accessibilityservice.cts.activities.AccessibilityTestActivity;
+import android.app.Instrumentation;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.graphics.Matrix;
@@ -47,7 +54,6 @@
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.platform.test.annotations.AppModeFull;
-import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
 import android.view.Display;
 import android.view.MotionEvent;
@@ -56,9 +62,18 @@
 import android.view.WindowManager;
 import android.widget.TextView;
 
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -68,8 +83,8 @@
  * Verify that gestures dispatched from an accessibility service show up in the current UI
  */
 @AppModeFull
-public class AccessibilityGestureDispatchTest extends
-        ActivityInstrumentationTestCase2<AccessibilityGestureDispatchTest.GestureDispatchActivity> {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityGestureDispatchTest {
     private static final String TAG = AccessibilityGestureDispatchTest.class.getSimpleName();
 
     private static final int GESTURE_COMPLETION_TIMEOUT = 5000; // millis
@@ -88,6 +103,16 @@
     private static final Matcher<MotionEvent> IS_ACTION_MOVE =
             new MotionEventActionMatcher(MotionEvent.ACTION_MOVE);
 
+    private ActivityTestRule<GestureDispatchActivity> mActivityRule =
+            new ActivityTestRule<>(GestureDispatchActivity.class, false, false);
+
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
 
     final List<MotionEvent> mMotionEvents = new ArrayList<>();
     StubGestureAccessibilityService mService;
@@ -99,48 +124,46 @@
     boolean mHasTouchScreen;
     boolean mHasMultiTouch;
 
-    public AccessibilityGestureDispatchTest() {
-        super(GestureDispatchActivity.class);
-    }
+    private GestureDispatchActivity mActivity;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-        PackageManager pm = getInstrumentation().getContext().getPackageManager();
+        Instrumentation instrumentation = getInstrumentation();
+        PackageManager pm = instrumentation.getContext().getPackageManager();
         mHasTouchScreen = pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
                 || pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);
         if (!mHasTouchScreen) {
             return;
         }
 
-        getActivity().waitForEnterAnimationComplete();
+        mActivity = launchActivityAndWaitForItToBeOnscreen(instrumentation,
+                instrumentation.getUiAutomation(), mActivityRule);
 
         mHasMultiTouch = pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)
                 || pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT);
 
-        mFullScreenTextView =
-                (TextView) getActivity().findViewById(R.id.full_screen_text_view);
+        mFullScreenTextView = mActivity.findViewById(R.id.full_screen_text_view);
         getInstrumentation().runOnMainSync(() -> {
             mFullScreenTextView.getLocationOnScreen(mViewLocation);
             mFullScreenTextView.setOnTouchListener(mMyTouchListener);
         });
 
-        mService = StubGestureAccessibilityService.enableSelf(getInstrumentation());
+        mService = StubGestureAccessibilityService.enableSelf(instrumentation);
 
         mMotionEvents.clear();
         mGotUpEvent = false;
     }
 
-    @Override
+    @After
     public void tearDown() throws Exception {
         if (!mHasTouchScreen) {
             return;
         }
 
         runIfNotNull(mService, service -> service.runOnServiceSync(service::disableSelf));
-        super.tearDown();
     }
 
+    @Test
     public void testClickAt_producesDownThenUp() throws InterruptedException {
         if (!mHasTouchScreen) {
             return;
@@ -160,10 +183,10 @@
         assertEquals(0, clickDown.getActionIndex());
         assertEquals(0, clickDown.getDeviceId());
         assertEquals(0, clickDown.getEdgeFlags());
-        assertEquals(1F, clickDown.getXPrecision());
-        assertEquals(1F, clickDown.getYPrecision());
+        assertEquals(1F, clickDown.getXPrecision(), 0F);
+        assertEquals(1F, clickDown.getYPrecision(), 0F);
         assertEquals(1, clickDown.getPointerCount());
-        assertEquals(1F, clickDown.getPressure());
+        assertEquals(1F, clickDown.getPressure(), 0F);
 
         // Verify timing matches click
         assertEquals(clickDown.getDownTime(), clickDown.getEventTime());
@@ -174,6 +197,7 @@
                 > clickUp.getEventTime());
     }
 
+    @Test
     public void testLongClickAt_producesEventsWithLongClickTiming() throws InterruptedException {
         if (!mHasTouchScreen) {
             return;
@@ -194,6 +218,7 @@
         assertEquals(clickDown.getDownTime(), clickUp.getDownTime());
     }
 
+    @Test
     public void testSwipe_shouldContainPointsInALine() throws InterruptedException {
         if (!mHasTouchScreen) {
             return;
@@ -232,6 +257,7 @@
         await(dispatchGesture(mService, gesture), timeoutMs, MILLISECONDS);
     }
 
+    @Test
     public void testSlowSwipe_shouldNotContainMovesForTinyMovement() throws InterruptedException {
         if (!mHasTouchScreen) {
             return;
@@ -256,6 +282,7 @@
         assertThat(mMotionEvents.get(4), both(IS_ACTION_UP).and(isAtPoint(endPoint)));
     }
 
+    @Test
     public void testAngledPinch_looksReasonable() throws InterruptedException {
         if (!(mHasTouchScreen && mHasMultiTouch)) {
             return;
@@ -305,6 +332,7 @@
 
     // This test assumes device's screen contains its center (W/2, H/2) with some surroundings
     // and should work for rectangular, round and round with chin screens.
+    @Test
     public void testClickWhenMagnified_matchesActualTouch() throws InterruptedException {
         final float POINT_TOL = 2.0f;
         final float CLICK_OFFSET_X = 10;
@@ -314,7 +342,7 @@
             return;
         }
 
-        int displayId = getActivity().getWindow().getDecorView().getDisplay().getDisplayId();
+        int displayId = mActivity.getWindow().getDecorView().getDisplay().getDisplayId();
         if (displayId != Display.DEFAULT_DISPLAY) {
             Log.i(TAG, "Magnification is not supported on virtual displays.");
             return;
@@ -388,6 +416,7 @@
                 both(IS_ACTION_UP).and(isAtPoint(magRegionOffsetPoint, POINT_TOL)));
     }
 
+    @Test
     public void testContinuedGestures_motionEventsContinue() throws Exception {
         if (!mHasTouchScreen) {
             return;
@@ -422,6 +451,7 @@
                 allOf(IS_ACTION_UP, isAtPoint(end)));
     }
 
+    @Test
     public void testContinuedGesture_withLineDisconnect_isCancelled() throws Exception {
         if (!mHasTouchScreen) {
             return;
@@ -450,6 +480,7 @@
         assertEquals(1, mMotionEvents.size());
     }
 
+    @Test
     public void testContinuedGesture_nextGestureDoesntContinue_isCancelled() throws Exception {
         if (!mHasTouchScreen) {
             return;
@@ -482,6 +513,7 @@
                 both(IS_ACTION_UP).and(isAtPoint(endPoint)));
     }
 
+    @Test
     public void testContinuingGesture_withNothingToContinue_isCancelled() {
         if (!mHasTouchScreen) {
             return;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
index 5c45080..9379fc5 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGlobalActionsTest.java
@@ -16,12 +16,22 @@
 
 package android.accessibilityservice.cts;
 
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertTrue;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityService;
 import android.os.SystemClock;
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
+
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.concurrent.TimeoutException;
 
@@ -30,7 +40,8 @@
  */
 @Presubmit
 @AppModeFull
-public class AccessibilityGlobalActionsTest extends InstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityGlobalActionsTest {
     /**
      * Timeout required for pending Binder calls or event processing to
      * complete.
@@ -42,7 +53,12 @@
      */
     private static final long TIMEOUT_ACCESSIBILITY_STATE_IDLE = 500;
 
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     @MediumTest
+    @Test
     public void testPerformGlobalActionBack() throws Exception {
         assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
                 AccessibilityService.GLOBAL_ACTION_BACK));
@@ -52,6 +68,7 @@
     }
 
     @MediumTest
+    @Test
     public void testPerformGlobalActionHome() throws Exception {
         assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
                 AccessibilityService.GLOBAL_ACTION_HOME));
@@ -61,6 +78,7 @@
     }
 
     @MediumTest
+    @Test
     public void testPerformGlobalActionRecents() throws Exception {
         // Perform the action.
         boolean actionWasPerformed =
@@ -85,6 +103,7 @@
     }
 
     @MediumTest
+    @Test
     public void testPerformGlobalActionNotifications() throws Exception {
         // Perform the action under test
         assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
@@ -102,6 +121,7 @@
     }
 
     @MediumTest
+    @Test
     public void testPerformGlobalActionQuickSettings() throws Exception {
         // Check whether the action succeeded.
         assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
@@ -122,6 +142,7 @@
     }
 
     @MediumTest
+    @Test
     public void testPerformGlobalActionPowerDialog() throws Exception {
         // Check whether the action succeeded.
         assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
@@ -139,6 +160,7 @@
     }
 
     @MediumTest
+    @Test
     public void testPerformActionScreenshot() throws Exception {
         // Action should succeed
         assertTrue(getInstrumentation().getUiAutomation().performGlobalAction(
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityLoggingTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityLoggingTest.java
index 9654352..66baa04 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityLoggingTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityLoggingTest.java
@@ -17,6 +17,7 @@
 
 import static junit.framework.Assert.assertTrue;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.content.Context;
 import android.platform.test.annotations.Presubmit;
 
@@ -25,6 +26,7 @@
 
 import com.android.compatibility.common.util.AppOpsUtils;
 
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -32,6 +34,10 @@
 @Presubmit
 public class AccessibilityLoggingTest {
 
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     /**
      * Tests that new accessibility services are logged by the system.
      */
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
index 2774457..f0a4209 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
@@ -18,6 +18,11 @@
 
 import static android.accessibilityservice.cts.utils.CtsTestUtils.runIfNotNull;
 
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyFloat;
 import static org.mockito.Mockito.eq;
@@ -25,6 +30,7 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibility.cts.common.InstrumentedAccessibilityService;
 import android.accessibility.cts.common.ShellCommandBuilder;
 import android.accessibilityservice.AccessibilityService.MagnificationController;
@@ -34,7 +40,14 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.platform.test.annotations.AppModeFull;
-import android.test.InstrumentationTestCase;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -42,7 +55,8 @@
  * Class for testing {@link AccessibilityServiceInfo}.
  */
 @AppModeFull
-public class AccessibilityMagnificationTest extends InstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityMagnificationTest {
 
     /** Maximum timeout when waiting for a magnification callback. */
     public static final int LISTENER_TIMEOUT_MILLIS = 500;
@@ -51,10 +65,13 @@
     private StubMagnificationAccessibilityService mService;
     private Instrumentation mInstrumentation;
 
-    @Override
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-        ShellCommandBuilder.create(this.getInstrumentation())
+        ShellCommandBuilder.create(getInstrumentation())
                 .deleteSecureSetting(ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED)
                 .run();
         mInstrumentation = getInstrumentation();
@@ -63,13 +80,12 @@
         mService = StubMagnificationAccessibilityService.enableSelf(mInstrumentation);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         runIfNotNull(mService, service -> service.runOnServiceSync(service::disableSelfAndRemove));
-
-        super.tearDown();
     }
 
+    @Test
     public void testSetScale() {
         final MagnificationController controller = mService.getMagnificationController();
         final float scale = 2.0f;
@@ -78,14 +94,15 @@
         mService.runOnServiceSync(() -> result.set(controller.setScale(scale, false)));
 
         assertTrue("Failed to set scale", result.get());
-        assertEquals("Failed to apply scale", scale, controller.getScale());
+        assertEquals("Failed to apply scale", scale, controller.getScale(), 0f);
 
         mService.runOnServiceSync(() -> result.set(controller.reset(false)));
 
         assertTrue("Failed to reset", result.get());
-        assertEquals("Failed to apply reset", 1.0f, controller.getScale());
+        assertEquals("Failed to apply reset", 1.0f, controller.getScale(), 0f);
     }
 
+    @Test
     public void testSetScaleAndCenter() {
         final MagnificationController controller = mService.getMagnificationController();
         final Region region = controller.getMagnificationRegion();
@@ -103,7 +120,7 @@
         });
 
         assertTrue("Failed to set scale", setScale.get());
-        assertEquals("Failed to apply scale", scale, controller.getScale());
+        assertEquals("Failed to apply scale", scale, controller.getScale(), 0f);
 
         assertTrue("Failed to set center", setCenter.get());
         assertEquals("Failed to apply center X", x, controller.getCenterX(), 5.0f);
@@ -112,9 +129,10 @@
         mService.runOnServiceSync(() -> result.set(controller.reset(false)));
 
         assertTrue("Failed to reset", result.get());
-        assertEquals("Failed to apply reset", 1.0f, controller.getScale());
+        assertEquals("Failed to apply reset", 1.0f, controller.getScale(), 0f);
     }
 
+    @Test
     public void testListener() {
         final MagnificationController controller = mService.getMagnificationController();
         final OnMagnificationChangedListener listener = mock(OnMagnificationChangedListener.class);
@@ -140,6 +158,7 @@
         }
     }
 
+    @Test
     public void testMagnificationServiceShutsDownWhileMagnifying_shouldReturnTo1x() {
         final MagnificationController controller = mService.getMagnificationController();
         mService.runOnServiceSync(() -> controller.setScale(2.0f, false));
@@ -151,12 +170,13 @@
         final MagnificationController controller2 = service.getMagnificationController();
         try {
             assertEquals("Magnification must reset when a service dies",
-                    1.0f, controller2.getScale());
+                    1.0f, controller2.getScale(), 0f);
         } finally {
             service.runOnServiceSync(() -> service.disableSelf());
         }
     }
 
+    @Test
     public void testGetMagnificationRegion_whenCanControlMagnification_shouldNotBeEmpty() {
         final MagnificationController controller = mService.getMagnificationController();
         Region magnificationRegion = controller.getMagnificationRegion();
@@ -164,6 +184,7 @@
                  + "magnification is being actively controlled", magnificationRegion.isEmpty());
     }
 
+    @Test
     public void testGetMagnificationRegion_whenCantControlMagnification_shouldBeEmpty() {
         mService.runOnServiceSync(() -> mService.disableSelf());
         mService = null;
@@ -179,6 +200,7 @@
         }
     }
 
+    @Test
     public void testGetMagnificationRegion_whenMagnificationGesturesEnabled_shouldNotBeEmpty() {
         ShellCommandBuilder.create(mInstrumentation)
                 .putSecureSetting(ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, "1")
@@ -200,6 +222,7 @@
         }
     }
 
+    @Test
     public void testAnimatingMagnification() throws InterruptedException {
         final MagnificationController controller = mService.getMagnificationController();
         final int timeBetweenAnimationChanges = 100;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityOverlayTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityOverlayTest.java
index e461bdf..37128fd 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityOverlayTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityOverlayTest.java
@@ -20,6 +20,7 @@
 
 import static org.junit.Assert.assertTrue;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibility.cts.common.InstrumentedAccessibilityService;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accessibilityservice.cts.utils.AsyncUtils;
@@ -36,6 +37,7 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -49,6 +51,10 @@
     private static UiAutomation sUiAutomation;
     InstrumentedAccessibilityService mService;
 
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     @BeforeClass
     public static void oneTimeSetUp() {
         sInstrumentation = InstrumentationRegistry.getInstrumentation();
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityPaneTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityPaneTest.java
index 959f315..b4a8b09 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityPaneTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityPaneTest.java
@@ -28,6 +28,7 @@
 import static org.hamcrest.Matchers.both;
 import static org.junit.Assert.assertEquals;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.cts.activities.AccessibilityEndToEndActivity;
 import android.app.Activity;
 import android.app.Instrumentation;
@@ -45,6 +46,7 @@
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 /**
@@ -58,10 +60,17 @@
     private Activity mActivity;
     private View mPaneView;
 
-    @Rule
-    public ActivityTestRule<AccessibilityEndToEndActivity> mActivityRule =
+    private ActivityTestRule<AccessibilityEndToEndActivity> mActivityRule =
             new ActivityTestRule<>(AccessibilityEndToEndActivity.class, false, false);
 
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
+
     @BeforeClass
     public static void oneTimeSetup() throws Exception {
         sInstrumentation = InstrumentationRegistry.getInstrumentation();
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
index 67626fe..01d1659 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
@@ -16,20 +16,35 @@
 
 package android.accessibilityservice.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.os.Parcel;
 import android.platform.test.annotations.Presubmit;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
 import android.view.accessibility.AccessibilityEvent;
 
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 /**
  * Class for testing {@link AccessibilityServiceInfo}.
  */
 @Presubmit
-public class AccessibilityServiceInfoTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityServiceInfoTest {
+
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
 
     @MediumTest
+    @Test
     public void testMarshalling() throws Exception {
 
         // fully populate the service info to marshal
@@ -51,6 +66,7 @@
      * Tests whether the service info describes its contents consistently.
      */
     @MediumTest
+    @Test
     public void testDescribeContents() {
         AccessibilityServiceInfo info = new AccessibilityServiceInfo();
         assertSame("Accessibility service info always return 0 for this method.", 0,
@@ -64,6 +80,7 @@
      * Tests whether a feedback type is correctly transformed to a string.
      */
     @MediumTest
+    @Test
     public void testFeedbackTypeToString() {
         assertEquals("[FEEDBACK_AUDIBLE]", AccessibilityServiceInfo.feedbackTypeToString(
                 AccessibilityServiceInfo.FEEDBACK_AUDIBLE));
@@ -87,6 +104,7 @@
      * Tests whether a flag is correctly transformed to a string.
      */
     @MediumTest
+    @Test
     public void testFlagToString() {
         assertEquals("DEFAULT", AccessibilityServiceInfo.flagToString(
                 AccessibilityServiceInfo.DEFAULT));
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java
index f01251a..3199dc6 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySettingsTest.java
@@ -16,15 +16,25 @@
 
 package android.accessibilityservice.cts;
 
+import static androidx.test.InstrumentationRegistry.getContext;
+
+import static org.junit.Assert.assertTrue;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
-import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.List;
 
 /**
@@ -32,12 +42,18 @@
  * accessibility settings has an activity that handles it.
  */
 @Presubmit
-public class AccessibilitySettingsTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AccessibilitySettingsTest {
+
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
 
     @MediumTest
     @AppModeFull
+    @Test
     public void testAccessibilitySettingsIntentHandled() throws Throwable {
-        PackageManager packageManager = mContext.getPackageManager();
+        PackageManager packageManager = getContext().getPackageManager();
         Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
         List<ResolveInfo> resolvedActivities = packageManager.queryIntentActivities(intent,
                 PackageManager.MATCH_DEFAULT_ONLY);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
index 8bb1bfb..7575167 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilitySoftKeyboardModesTest.java
@@ -13,6 +13,7 @@
  */
 
 package android.accessibilityservice.cts;
+
 import static android.accessibilityservice.AccessibilityService.SHOW_MODE_AUTO;
 import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HIDDEN;
 import static android.accessibilityservice.AccessibilityService.SHOW_MODE_IGNORE_HARD_KEYBOARD;
@@ -21,6 +22,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibility.cts.common.InstrumentedAccessibilityService;
 import android.accessibilityservice.AccessibilityService.SoftKeyboardController;
 import android.accessibilityservice.AccessibilityService.SoftKeyboardController.OnShowModeChangedListener;
@@ -36,6 +38,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -57,7 +60,9 @@
         }
     };
 
-
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
 
     @Before
     public void setUp() throws Exception {
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java
index e89b4dd..58fbfd8 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextActionTest.java
@@ -30,7 +30,7 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.accessibilityservice.cts.R;
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.cts.activities.AccessibilityTextTraversalActivity;
 import android.app.Instrumentation;
 import android.app.UiAutomation;
@@ -60,6 +60,7 @@
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 import java.util.Arrays;
@@ -80,10 +81,17 @@
 
     private AccessibilityTextTraversalActivity mActivity;
 
-    @Rule
-    public ActivityTestRule<AccessibilityTextTraversalActivity> mActivityRule =
+    private ActivityTestRule<AccessibilityTextTraversalActivity> mActivityRule =
             new ActivityTestRule<>(AccessibilityTextTraversalActivity.class, false, false);
 
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
+
     @BeforeClass
     public static void oneTimeSetup() throws Exception {
         sInstrumentation = InstrumentationRegistry.getInstrumentation();
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
index 75eda1d..1729269 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityTextTraversalTest.java
@@ -23,7 +23,7 @@
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
-import android.accessibilityservice.cts.R;
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.cts.activities.AccessibilityTextTraversalActivity;
 import android.app.Instrumentation;
 import android.app.UiAutomation;
@@ -47,6 +47,7 @@
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 /**
@@ -64,10 +65,17 @@
 
     private AccessibilityTextTraversalActivity mActivity;
 
-    @Rule
-    public ActivityTestRule<AccessibilityTextTraversalActivity> mActivityRule =
+    private ActivityTestRule<AccessibilityTextTraversalActivity> mActivityRule =
             new ActivityTestRule<>(AccessibilityTextTraversalActivity.class, false, false);
 
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
+
     @BeforeClass
     public static void oneTimeSetup() throws Exception {
         sInstrumentation = InstrumentationRegistry.getInstrumentation();
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
index 28a3acd..a1b993b 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityViewTreeReportingTest.java
@@ -14,8 +14,7 @@
 
 package android.accessibilityservice.cts;
 
-import static android.accessibilityservice.cts.utils.ActivityLaunchUtils
-        .launchActivityAndWaitForItToBeOnscreen;
+import static android.accessibilityservice.cts.utils.ActivityLaunchUtils.launchActivityAndWaitForItToBeOnscreen;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -23,15 +22,12 @@
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityServiceInfo;
-import android.accessibilityservice.cts.R;
 import android.accessibilityservice.cts.activities.AccessibilityViewTreeReportingActivity;
 import android.app.Instrumentation;
 import android.app.UiAutomation;
 import android.content.Context;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.rule.ActivityTestRule;
-import androidx.test.runner.AndroidJUnit4;
 import android.text.TextUtils;
 import android.view.View;
 import android.view.ViewGroup;
@@ -40,11 +36,16 @@
 import android.widget.Button;
 import android.widget.LinearLayout;
 
+import androidx.test.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 /**
@@ -61,10 +62,17 @@
 
     private AccessibilityViewTreeReportingActivity mActivity;
 
-    @Rule
-    public ActivityTestRule<AccessibilityViewTreeReportingActivity> mActivityRule =
+    private ActivityTestRule<AccessibilityViewTreeReportingActivity> mActivityRule =
             new ActivityTestRule<>(AccessibilityViewTreeReportingActivity.class, false, false);
 
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
+
     @BeforeClass
     public static void oneTimeSetup() throws Exception {
         sInstrumentation = InstrumentationRegistry.getInstrumentation();
@@ -309,6 +317,44 @@
         assertTrue(awaitedEvent.getSource().isImportantForAccessibility());
     }
 
+
+    @Test
+    public void testHideView_receiveSubtreeEvent() throws Throwable {
+        final View view = mActivity.findViewById(R.id.secondButton);
+        AccessibilityEvent awaitedEvent =
+                sUiAutomation.executeAndWaitForEvent(
+                        () -> mActivity.runOnUiThread(() -> view.setVisibility(View.GONE)),
+                        (event) -> {
+                            boolean isContentChanged = event.getEventType()
+                                    == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
+                            int isSubTree = (event.getContentChangeTypes()
+                                    & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
+                            boolean isFromThisPackage = TextUtils.equals(event.getPackageName(),
+                                    mActivity.getPackageName());
+                            return isContentChanged && (isSubTree != 0) && isFromThisPackage;
+                        }, TIMEOUT_ASYNC_PROCESSING);
+        awaitedEvent.recycle();
+    }
+
+    @Test
+    public void testUnhideView_receiveSubtreeEvent() throws Throwable {
+        final View view = mActivity.findViewById(R.id.hiddenButton);
+        AccessibilityEvent awaitedEvent =
+                sUiAutomation.executeAndWaitForEvent(
+                        () -> mActivity.runOnUiThread(() -> view.setVisibility(View.VISIBLE)),
+                        (event) -> {
+                            boolean isContentChanged = event.getEventType()
+                                    == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
+                            int isSubTree = (event.getContentChangeTypes()
+                                    & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE);
+                            boolean isFromThisPackage = TextUtils.equals(event.getPackageName(),
+                                    mActivity.getPackageName());
+                            return isContentChanged && (isSubTree != 0) && isFromThisPackage;
+                        }, TIMEOUT_ASYNC_PROCESSING);
+        awaitedEvent.recycle();
+    }
+
+
     private void setGetNonImportantViews(boolean getNonImportantViews) {
         AccessibilityServiceInfo serviceInfo = sUiAutomation.getServiceInfo();
         serviceInfo.flags &= ~AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java
index 16e0b68..4eb140d 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityVolumeTest.java
@@ -17,6 +17,7 @@
 
 import static org.junit.Assert.assertEquals;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibility.cts.common.InstrumentedAccessibilityService;
 import android.app.Instrumentation;
 import android.content.pm.PackageManager;
@@ -28,6 +29,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -43,6 +45,10 @@
     // If a11y volume is stuck at a single value, don't run the tests
     boolean mFixedA11yVolume;
 
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     @Before
     public void setUp() {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
index e757a66..fe8b70d 100755
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
@@ -48,9 +48,9 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.AccessibilityServiceInfo;
-import android.accessibilityservice.cts.activities.AccessibilityEndToEndActivity;
 import android.accessibilityservice.cts.activities.AccessibilityWindowQueryActivity;
 import android.app.Instrumentation;
 import android.app.UiAutomation;
@@ -80,6 +80,7 @@
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
@@ -108,13 +109,16 @@
 
     private AccessibilityWindowQueryActivity mActivity;
 
-    @Rule
-    public ActivityTestRule<AccessibilityWindowQueryActivity> mActivityRule =
+    private ActivityTestRule<AccessibilityWindowQueryActivity> mActivityRule =
             new ActivityTestRule<>(AccessibilityWindowQueryActivity.class, false, false);
 
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
     @Rule
-    public ActivityTestRule<AccessibilityEndToEndActivity> mEndToEndActivityRule =
-            new ActivityTestRule<>(AccessibilityEndToEndActivity.class, false, false);
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
 
     @BeforeClass
     public static void oneTimeSetup() throws Exception {
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
index 71c34c2..83c8154 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowReportingTest.java
@@ -39,6 +39,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accessibilityservice.cts.activities.AccessibilityWindowReportingActivity;
 import android.app.Activity;
@@ -62,6 +63,7 @@
 import org.junit.BeforeClass;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 import java.util.List;
@@ -82,10 +84,17 @@
     private Activity mActivity;
     private CharSequence mActivityTitle;
 
-    @Rule
-    public ActivityTestRule<AccessibilityWindowReportingActivity> mActivityRule =
+    private ActivityTestRule<AccessibilityWindowReportingActivity> mActivityRule =
             new ActivityTestRule<>(AccessibilityWindowReportingActivity.class, false, false);
 
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
+
     @BeforeClass
     public static void oneTimeSetup() throws Exception {
         sInstrumentation = InstrumentationRegistry.getInstrumentation();
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
index 92821b8..4f19ef7 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
@@ -14,30 +14,48 @@
 
 package android.accessibilityservice.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.GestureDescription;
 import android.accessibilityservice.GestureDescription.StrokeDescription;
 import android.graphics.Path;
 import android.graphics.PathMeasure;
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
-import android.test.InstrumentationTestCase;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 /**
  * Tests for creating gesture descriptions.
  */
 @Presubmit
 @AppModeFull
-public class GestureDescriptionTest extends InstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class GestureDescriptionTest {
     static final int NOMINAL_PATH_DURATION = 100;
     private Path mNominalPath;
 
-    @Override
+    @Rule
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Before
     public void setUp() {
         mNominalPath = new Path();
         mNominalPath.moveTo(0, 0);
         mNominalPath.lineTo(10, 10);
     }
 
+    @Test
     public void testCreateStroke_noDuration_shouldThrow() {
         try {
             new StrokeDescription(mNominalPath, 0, 0);
@@ -46,6 +64,7 @@
         }
     }
 
+    @Test
     public void testCreateStroke_negativeStartTime_shouldThrow() {
         try {
             new StrokeDescription(mNominalPath, -1, NOMINAL_PATH_DURATION);
@@ -54,6 +73,7 @@
         }
     }
 
+    @Test
     public void testCreateStroke_negativeStartX_shouldThrow() {
         Path negativeStartXPath = new Path();
         negativeStartXPath.moveTo(-1, 0);
@@ -65,6 +85,7 @@
         }
     }
 
+    @Test
     public void testCreateStroke_negativeStartY_shouldThrow() {
         Path negativeStartYPath = new Path();
         negativeStartYPath.moveTo(0, -1);
@@ -76,6 +97,7 @@
         }
     }
 
+    @Test
     public void testCreateStroke_negativeEndX_shouldThrow() {
         Path negativeEndXPath = new Path();
         negativeEndXPath.moveTo(0, 0);
@@ -87,6 +109,7 @@
         }
     }
 
+    @Test
     public void testCreateStroke_negativeEndY_shouldThrow() {
         Path negativeEndYPath = new Path();
         negativeEndYPath.moveTo(0, 0);
@@ -98,6 +121,7 @@
         }
     }
 
+    @Test
     public void testCreateStroke_withEmptyPath_shouldThrow() {
         Path emptyPath = new Path();
         try {
@@ -107,6 +131,7 @@
         }
     }
 
+    @Test
     public void testCreateStroke_pathWithMultipleContours_shouldThrow() {
         Path multiContourPath = new Path();
         multiContourPath.moveTo(0, 0);
@@ -120,6 +145,7 @@
         }
     }
 
+    @Test
     public void testStrokeDescriptionWillContinue() {
         StrokeDescription strokeDescription = new StrokeDescription(mNominalPath, 0, 100);
         assertFalse(strokeDescription.willContinue());
@@ -138,6 +164,7 @@
         assertTrue(continuation.willContinue());
     }
 
+    @Test
     public void testAddStroke_allowUpToMaxPaths() {
         GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
         for (int i = 0; i < GestureDescription.getMaxStrokeCount(); i++) {
@@ -156,6 +183,7 @@
         }
     }
 
+    @Test
     public void testAddStroke_withDurationTooLong_shouldThrow() {
         Path path = new Path();
         path.moveTo(10, 10);
@@ -169,6 +197,7 @@
         }
     }
 
+    @Test
     public void testEmptyDescription_shouldThrow() {
         GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
         try {
@@ -178,6 +207,7 @@
         }
     }
 
+    @Test
     public void testStrokeDescriptionGetters_workAsExpected() {
         int x = 100;
         int startY = 100;
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDetectionStubAccessibilityService.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDetectionStubAccessibilityService.java
index 042904b..a2a3472 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDetectionStubAccessibilityService.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDetectionStubAccessibilityService.java
@@ -14,20 +14,24 @@
 
 package android.accessibilityservice.cts;
 
+import static org.junit.Assert.fail;
+
 import android.accessibility.cts.common.InstrumentedAccessibilityService;
 
 import android.app.Instrumentation;
 import android.view.accessibility.AccessibilityEvent;
+
 import java.util.ArrayList;
+import java.util.List;
 
 /** Accessibility service stub, which will collect recognized gestures. */
 public class GestureDetectionStubAccessibilityService extends InstrumentedAccessibilityService {
     private static final long GESTURE_RECOGNIZE_TIMEOUT_MS = 3000;
-    private static final long EVENT_RECOGNIZE_TIMEOUT_MS = 3000;
+    private static final long EVENT_RECOGNIZE_TIMEOUT_MS = 5000;
     // Member variables
-    private final Object mLock = new Object();
+    protected final Object mLock = new Object();
     private ArrayList<Integer> mCollectedGestures = new ArrayList();
-    private ArrayList<Integer> mCollectedEvents = new ArrayList();
+    protected ArrayList<Integer> mCollectedEvents = new ArrayList();
 
     public static GestureDetectionStubAccessibilityService enableSelf(
             Instrumentation instrumentation) {
@@ -124,4 +128,37 @@
             }
         }
     }
+
+    /** Insure that the specified accessibility events have been received. */
+    public void assertPropagated(int... events) {
+        waitUntilEvent(events.length);
+        // Set up readable error reporting.
+        List<String> received = new ArrayList<>();
+        List<String> expected = new ArrayList<>();
+        for (int event : events) {
+            expected.add(AccessibilityEvent.eventTypeToString(event));
+        }
+        for (int i = 0; i < getEventsSize(); ++i) {
+            received.add(AccessibilityEvent.eventTypeToString(getEvent(i)));
+        }
+
+        if (events.length != getEventsSize()) {
+            String message =
+                    String.format(
+                            "Received %d events when expecting %d. Received %s, expected %s",
+                            received.size(),
+                            expected.size(),
+                            received.toString(),
+                            expected.toString());
+            fail(message);
+        }
+        else if (!expected.equals(received)) {
+            String message =
+                    String.format(
+                            "Received %s, expected %s",
+                            received.toString(),
+                            expected.toString());
+            fail(message);
+        }
+    }
 }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
index 72bbd97..95740cd 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
@@ -24,6 +24,7 @@
 import static android.accessibilityservice.cts.utils.GestureUtils.dispatchGesture;
 import static android.accessibilityservice.cts.utils.GestureUtils.distance;
 import static android.accessibilityservice.cts.utils.GestureUtils.drag;
+import static android.accessibilityservice.cts.utils.GestureUtils.doubleTap;
 import static android.accessibilityservice.cts.utils.GestureUtils.endTimeOf;
 import static android.accessibilityservice.cts.utils.GestureUtils.lastPointOf;
 import static android.accessibilityservice.cts.utils.GestureUtils.longClick;
@@ -31,6 +32,7 @@
 import static android.accessibilityservice.cts.utils.GestureUtils.pointerUp;
 import static android.accessibilityservice.cts.utils.GestureUtils.startingAt;
 import static android.accessibilityservice.cts.utils.GestureUtils.swipe;
+import static android.accessibilityservice.cts.utils.GestureUtils.tripleTap;
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_MOVE;
 import static android.view.MotionEvent.ACTION_UP;
@@ -45,6 +47,7 @@
 
 import static java.util.concurrent.TimeUnit.SECONDS;
 
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibility.cts.common.InstrumentedAccessibilityService;
 import android.accessibilityservice.GestureDescription;
 import android.accessibilityservice.GestureDescription.StrokeDescription;
@@ -67,6 +70,7 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
@@ -95,10 +99,17 @@
 
     private final Object mZoomLock = new Object();
 
-    @Rule
-    public ActivityTestRule<GestureDispatchActivity> mActivityRule =
+    private ActivityTestRule<GestureDispatchActivity> mActivityRule =
             new ActivityTestRule<>(GestureDispatchActivity.class);
 
+    private AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
+
+    @Rule
+    public final RuleChain mRuleChain = RuleChain
+            .outerRule(mDumpOnFailureRule)
+            .around(mActivityRule);
+
     @Before
     public void setUp() throws Exception {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
@@ -196,9 +207,9 @@
 
     private void setZoomByTripleTapping(boolean desiredZoomState) {
         if (isZoomed() == desiredZoomState) return;
-        dispatch(tripleTap());
+        dispatch(tripleTap(mTapLocation));
         waitOn(mZoomLock, () -> isZoomed() == desiredZoomState);
-        assertNoTouchInputPropagated();
+        mTouchListener.assertNonePropagated();
     }
 
     private void tripleTapAndDragViewport() {
@@ -210,10 +221,10 @@
         dispatch(drag);
         waitOn(mZoomLock, () -> distance(mCurrentZoomCenter, oldCenter) >= mPan / 5);
         assertTrue(isZoomed());
-        assertNoTouchInputPropagated();
+        mTouchListener.assertNonePropagated();
 
         dispatch(pointerUp(drag));
-        assertNoTouchInputPropagated();
+        mTouchListener.assertNonePropagated();
     }
 
     private StrokeDescription tripleTapAndHold() {
@@ -227,22 +238,18 @@
 
     private void assertGesturesPropagateToView() {
         dispatch(click(mTapLocation));
-        assertPropagated(ACTION_DOWN, ACTION_UP);
+        mTouchListener.assertPropagated(ACTION_DOWN, ACTION_UP);
 
         dispatch(longClick(mTapLocation));
-        assertPropagated(ACTION_DOWN, ACTION_UP);
+        mTouchListener.assertPropagated(ACTION_DOWN, ACTION_UP);
 
-        dispatch(doubleTap());
-        assertPropagated(ACTION_DOWN, ACTION_UP, ACTION_DOWN, ACTION_UP);
+        dispatch(doubleTap(mTapLocation));
+        mTouchListener.assertPropagated(ACTION_DOWN, ACTION_UP, ACTION_DOWN, ACTION_UP);
 
         dispatch(swipe(
                 mTapLocation,
                 add(mTapLocation, 0, 29)));
-        assertPropagated(ACTION_DOWN, ACTION_MOVE, ACTION_UP);
-    }
-
-    private void assertNoTouchInputPropagated() {
-        assertThat(prettyPrintable(mTouchListener.events), is(empty()));
+        mTouchListener.assertPropagated(ACTION_DOWN, ACTION_MOVE, ACTION_UP);
     }
 
     private void setMagnificationEnabled(boolean enabled) {
@@ -254,50 +261,6 @@
         return mCurrentScale >= MIN_SCALE;
     }
 
-    private void assertPropagated(int... eventTypes) {
-        MotionEvent ev;
-        try {
-            while (true) {
-                if (eventTypes.length == 0) return;
-                int expectedEventType = eventTypes[0];
-                long startedPollingAt = SystemClock.uptimeMillis();
-                ev = mTouchListener.events.poll(5, SECONDS);
-                assertNotNull("Expected "
-                        + MotionEvent.actionToString(expectedEventType)
-                        + " but none present after "
-                        + (SystemClock.uptimeMillis() - startedPollingAt) + "ms",
-                        ev);
-                int action = ev.getActionMasked();
-                if (action == expectedEventType) {
-                    eventTypes = Arrays.copyOfRange(eventTypes, 1, eventTypes.length);
-                } else {
-                    if (action != ACTION_MOVE) fail("Unexpected event: " + ev);
-                }
-            }
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private GestureDescription doubleTap() {
-        return multiTap(2);
-    }
-
-    private GestureDescription tripleTap() {
-        return multiTap(3);
-    }
-
-    private GestureDescription multiTap(int taps) {
-        GestureDescription.Builder builder = new GestureDescription.Builder();
-        long time = 0;
-        for (int i = 0; i < taps; i++) {
-            StrokeDescription stroke = click(mTapLocation);
-            builder.addStroke(startingAt(time, stroke));
-            time += stroke.getDuration() + 20;
-        }
-        return builder.build();
-    }
-
     public void dispatch(StrokeDescription firstStroke, StrokeDescription... rest) {
         GestureDescription.Builder builder =
                 new GestureDescription.Builder().addStroke(firstStroke);
@@ -310,17 +273,4 @@
     public void dispatch(GestureDescription gesture) {
         await(dispatchGesture(mService, gesture));
     }
-
-    private static <T> Collection<T> prettyPrintable(Collection<T> c) {
-        return new ArrayList<T>(c) {
-
-            @Override
-            public String toString() {
-                return stream()
-                        .map(t -> "\n" + t)
-                        .reduce(String::concat)
-                        .orElse("");
-            }
-        };
-    }
 }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorationStubAccessibilityService.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorationStubAccessibilityService.java
new file mode 100644
index 0000000..07f8ea8
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorationStubAccessibilityService.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>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.accessibilityservice.cts;
+
+import static android.view.accessibility.AccessibilityEvent.TYPE_GESTURE_DETECTION_END;
+import static android.view.accessibility.AccessibilityEvent.TYPE_GESTURE_DETECTION_START;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_CLICKED;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_HOVER_ENTER;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_HOVER_EXIT;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_LONG_CLICKED;
+
+import android.accessibility.cts.common.InstrumentedAccessibilityService;
+import android.app.Instrumentation;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * This accessibility service stub collects all events relating to touch exploration rather than
+ * just the few collected by GestureDetectionStubAccessibilityService
+ */
+public class TouchExplorationStubAccessibilityService
+        extends GestureDetectionStubAccessibilityService {
+    @Override
+    public void onAccessibilityEvent(AccessibilityEvent event) {
+        synchronized (mLock) {
+            switch (event.getEventType()) {
+                case TYPE_GESTURE_DETECTION_START:
+                case TYPE_GESTURE_DETECTION_END:
+                case TYPE_VIEW_HOVER_ENTER:
+                case TYPE_VIEW_HOVER_EXIT:
+                case TYPE_VIEW_FOCUSED:
+                case TYPE_VIEW_ACCESSIBILITY_FOCUSED:
+                case TYPE_VIEW_CLICKED:
+                case TYPE_VIEW_LONG_CLICKED:
+                    mCollectedEvents.add(event.getEventType());
+            }
+        }
+        super.onAccessibilityEvent(event);
+    }
+
+    public static TouchExplorationStubAccessibilityService enableSelf(
+            Instrumentation instrumentation) {
+        return InstrumentedAccessibilityService.enableService(
+                instrumentation, TouchExplorationStubAccessibilityService.class);
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
new file mode 100644
index 0000000..87d7166
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2019 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.accessibilityservice.cts;
+
+import static android.accessibilityservice.cts.utils.AsyncUtils.await;
+import static android.accessibilityservice.cts.utils.GestureUtils.add;
+import static android.accessibilityservice.cts.utils.GestureUtils.click;
+import static android.accessibilityservice.cts.utils.GestureUtils.dispatchGesture;
+import static android.accessibilityservice.cts.utils.GestureUtils.doubleTap;
+import static android.accessibilityservice.cts.utils.GestureUtils.doubleTapAndHold;
+import static android.accessibilityservice.cts.utils.GestureUtils.swipe;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_HOVER_ENTER;
+import static android.view.MotionEvent.ACTION_HOVER_EXIT;
+import static android.view.MotionEvent.ACTION_HOVER_MOVE;
+import static android.view.MotionEvent.ACTION_UP;
+import static android.view.accessibility.AccessibilityEvent.TYPE_GESTURE_DETECTION_END;
+import static android.view.accessibility.AccessibilityEvent.TYPE_GESTURE_DETECTION_START;
+import static android.view.accessibility.AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END;
+import static android.view.accessibility.AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_START;
+import static android.view.accessibility.AccessibilityEvent.TYPE_TOUCH_INTERACTION_END;
+import static android.view.accessibility.AccessibilityEvent.TYPE_TOUCH_INTERACTION_START;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_CLICKED;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_HOVER_ENTER;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_HOVER_EXIT;
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_LONG_CLICKED;
+
+import android.accessibilityservice.GestureDescription;
+import android.accessibilityservice.GestureDescription.StrokeDescription;
+import android.accessibilityservice.cts.AccessibilityGestureDispatchTest.GestureDispatchActivity;
+import android.accessibilityservice.cts.utils.EventCapturingClickListener;
+import android.accessibilityservice.cts.utils.EventCapturingHoverListener;
+import android.accessibilityservice.cts.utils.EventCapturingLongClickListener;
+import android.accessibilityservice.cts.utils.EventCapturingTouchListener;
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.platform.test.annotations.AppModeFull;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * A set of tests for testing touch exploration. Each test dispatches a gesture and checks for the
+ * appropriate hover and/or touch events followed by the appropriate accessibility events. Some
+ * tests will then check for events from the view.
+ */
+@RunWith(AndroidJUnit4.class)
+@AppModeFull
+public class TouchExplorerTest {
+    // Constants
+    private static final float GESTURE_LENGTH_INCHES = 1.0f;
+    private TouchExplorationStubAccessibilityService mService;
+    private Instrumentation mInstrumentation;
+    private UiAutomation mUiAutomation;
+    private boolean mHasTouchscreen;
+    private boolean mScreenBigEnough;
+    private EventCapturingHoverListener mHoverListener = new EventCapturingHoverListener(false);
+    private EventCapturingTouchListener mTouchListener = new EventCapturingTouchListener(false);
+    private EventCapturingClickListener mClickListener = new EventCapturingClickListener();
+    private EventCapturingLongClickListener mLongClickListener =
+            new EventCapturingLongClickListener();
+
+    @Rule
+    public ActivityTestRule<GestureDispatchActivity> mActivityRule =
+            new ActivityTestRule<>(GestureDispatchActivity.class, false);
+
+    Point mCenter; // Center of screen. Gestures all start from this point.
+    PointF mTapLocation;
+    float mSwipeDistance;
+    View mView;
+
+    @Before
+    public void setUp() throws Exception {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mUiAutomation = mInstrumentation.getUiAutomation();
+        PackageManager pm = mInstrumentation.getContext().getPackageManager();
+        mHasTouchscreen = pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
+                || pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);
+        // Find screen size, check that it is big enough for gestures.
+        // Gestures will start in the center of the screen, so we need enough horiz/vert space.
+        WindowManager windowManager =
+                (WindowManager)
+                        mInstrumentation.getContext().getSystemService(Context.WINDOW_SERVICE);
+        final DisplayMetrics metrics = new DisplayMetrics();
+        windowManager.getDefaultDisplay().getRealMetrics(metrics);
+        mCenter = new Point((int) metrics.widthPixels / 2, (int) metrics.heightPixels / 2);
+        mTapLocation = new PointF(mCenter);
+        mScreenBigEnough = (metrics.widthPixels / (2 * metrics.xdpi) > GESTURE_LENGTH_INCHES);
+        if (!mHasTouchscreen || !mScreenBigEnough) return;
+        mService = TouchExplorationStubAccessibilityService.enableSelf(mInstrumentation);
+        mView = mActivityRule.getActivity().findViewById(R.id.full_screen_text_view);
+        mView.setOnHoverListener(mHoverListener);
+        mView.setOnTouchListener(mTouchListener);
+        mInstrumentation.runOnMainSync(
+                () -> {
+                    mSwipeDistance = mView.getWidth() / 4;
+                    mView.setOnClickListener(mClickListener);
+                    mView.setOnLongClickListener(mLongClickListener);
+                });
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (!mHasTouchscreen || !mScreenBigEnough) return;
+        if (mService != null) {
+            mService.runOnServiceSync(() -> mService.disableSelfAndRemove());
+            mService = null;
+        }
+    }
+
+    /** Test a slow swipe which should initiate touch exploration. */
+    @Test
+    @AppModeFull
+    public void testSlowSwipe() {
+        if (!mHasTouchscreen || !mScreenBigEnough) return;
+        dispatch(swipe(mTapLocation, add(mTapLocation, mSwipeDistance, 0), 400));
+        mHoverListener.assertPropagated(ACTION_HOVER_ENTER,         ACTION_HOVER_MOVE, ACTION_HOVER_EXIT);
+        mTouchListener.assertNonePropagated();
+        mService.assertPropagated(
+                TYPE_VIEW_FOCUSED,
+                TYPE_TOUCH_INTERACTION_START,
+                TYPE_TOUCH_EXPLORATION_GESTURE_START,
+                TYPE_VIEW_HOVER_ENTER,
+                TYPE_VIEW_HOVER_EXIT,
+                TYPE_TOUCH_EXPLORATION_GESTURE_END,
+                TYPE_TOUCH_INTERACTION_END);
+    }
+
+    /** Test a fast swipe which should not initiate touch exploration. */
+    @Test
+    @AppModeFull
+    public void testFastSwipe() {
+        if (!mHasTouchscreen || !mScreenBigEnough) return;
+        dispatch(swipe(mTapLocation, add(mTapLocation, mSwipeDistance, 0)));
+        mHoverListener.assertNonePropagated();
+        mTouchListener.assertNonePropagated();
+        mService.assertPropagated(
+                TYPE_VIEW_FOCUSED,
+                TYPE_TOUCH_INTERACTION_START,
+                TYPE_GESTURE_DETECTION_START,
+                TYPE_GESTURE_DETECTION_END,
+                TYPE_TOUCH_INTERACTION_END);
+    }
+
+    /** Test a basic single tap which should initiate touch exploration. */
+    @Test
+    @AppModeFull
+    public void testSingleTap() {
+        if (!mHasTouchscreen || !mScreenBigEnough) return;
+        dispatch(click(mTapLocation));
+        mHoverListener.assertPropagated(ACTION_HOVER_ENTER, ACTION_HOVER_EXIT);
+        mTouchListener.assertNonePropagated();
+        mService.assertPropagated(
+                TYPE_VIEW_FOCUSED,
+                TYPE_TOUCH_INTERACTION_START,
+                TYPE_TOUCH_EXPLORATION_GESTURE_START,
+                TYPE_VIEW_HOVER_ENTER,
+                TYPE_VIEW_HOVER_EXIT,
+                TYPE_TOUCH_EXPLORATION_GESTURE_END,
+                TYPE_TOUCH_INTERACTION_END);
+    }
+
+    /**
+     * Test the case where we want to click on the item that has accessibility focus by using
+     * AccessibilityNodeInfo.performAction.
+     */
+    @Test
+    @AppModeFull
+    public void testDoubleTapAccessibilityFocus() {
+        if (!mHasTouchscreen || !mScreenBigEnough) return;
+        syncAccessibilityFocusToInputFocus();
+        dispatch(doubleTap(mTapLocation));
+        mHoverListener.assertNonePropagated();
+        // The click should not be delivered via touch events in this case.
+        mTouchListener.assertNonePropagated();
+        mService.assertPropagated(
+                TYPE_VIEW_FOCUSED,
+                TYPE_VIEW_ACCESSIBILITY_FOCUSED,
+                TYPE_TOUCH_INTERACTION_START,
+                TYPE_TOUCH_INTERACTION_END,
+                TYPE_VIEW_CLICKED);
+        mClickListener.assertClicked(mView);
+    }
+
+    /**
+     * Test the case where we double tap but there is no  accessibility focus. Nothing should happen.
+     */
+    @Test
+    @AppModeFull
+    public void testDoubleTapNoAccessibilityFocus() {
+        if (!mHasTouchscreen || !mScreenBigEnough) return;
+        dispatch(doubleTap(mTapLocation));
+        mHoverListener.assertNonePropagated();
+        mTouchListener.assertNonePropagated();
+        mService.assertPropagated(
+                TYPE_VIEW_FOCUSED, TYPE_TOUCH_INTERACTION_START, TYPE_TOUCH_INTERACTION_END);
+        mService.clearEvents();
+        mClickListener.assertNoneClicked();
+    }
+
+    /** Test the case where we want to long click on the item that has accessibility focus. */
+    @Test
+    @AppModeFull
+    public void testDoubleTapAndHoldAccessibilityFocus() {
+        if (!mHasTouchscreen || !mScreenBigEnough) return;
+        syncAccessibilityFocusToInputFocus();
+        dispatch(doubleTapAndHold(mTapLocation));
+        mHoverListener.assertNonePropagated();
+        // The click should not be delivered via touch events in this case.
+        mTouchListener.assertNonePropagated();
+        mService.assertPropagated(
+                TYPE_VIEW_FOCUSED,
+                TYPE_VIEW_ACCESSIBILITY_FOCUSED,
+                TYPE_TOUCH_INTERACTION_START,
+                TYPE_VIEW_LONG_CLICKED,
+                TYPE_TOUCH_INTERACTION_END);
+        mLongClickListener.assertLongClicked(mView);
+    }
+
+    /**
+     * Test the case where we double tap and hold but there is no accessibility focus.
+     * Nothing should happen.
+     */
+    @Test
+    @AppModeFull
+    public void testDoubleTapAndHoldNoAccessibilityFocus() {
+        if (!mHasTouchscreen || !mScreenBigEnough) return;
+        dispatch(doubleTap(mTapLocation));
+        mHoverListener.assertNonePropagated();
+        mTouchListener.assertNonePropagated();
+        mService.assertPropagated(
+                TYPE_VIEW_FOCUSED, TYPE_TOUCH_INTERACTION_START, TYPE_TOUCH_INTERACTION_END);
+        mService.clearEvents();
+        mLongClickListener.assertNoneLongClicked();
+    }
+
+    public void dispatch(StrokeDescription firstStroke, StrokeDescription... rest) {
+        GestureDescription.Builder builder =
+                new GestureDescription.Builder().addStroke(firstStroke);
+        for (StrokeDescription stroke : rest) {
+            builder.addStroke(stroke);
+        }
+        dispatch(builder.build());
+    }
+
+    public void dispatch(GestureDescription gesture) {
+        await(dispatchGesture(mService, gesture));
+    }
+
+    /** Set the accessibility focus to the element that has input focus. */
+    private void syncAccessibilityFocusToInputFocus() {
+        mService.runOnServiceSync(
+                () -> {
+                    mUiAutomation
+                            .getRootInActiveWindow()
+                            .findFocus(AccessibilityNodeInfo.FOCUS_INPUT)
+                            .performAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
+                });
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingClickListener.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingClickListener.java
new file mode 100644
index 0000000..116bccf
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingClickListener.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2019 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.accessibilityservice.cts.utils;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.view.View;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/** A click event listener that keeps an ordered record of events. */
+public class EventCapturingClickListener implements View.OnClickListener {
+
+    private final BlockingQueue<View> mViews = new LinkedBlockingQueue<>();
+
+    @Override
+    public void onClick(View view) {
+        mViews.offer(view);
+    }
+
+    /** Insure that the specified views have received click events. */
+    public void assertClicked(View... views) {
+        View view;
+        try {
+            for (View v : views) {
+                long waitTime = 5; // seconds
+                view = mViews.poll(waitTime, SECONDS);
+                assertNotNull(
+                        "Expected click event for "
+                                + v.toString()
+                                + " but none present after "
+                                + waitTime
+                                + " seconds",
+                        view);
+                if (v != view) {
+                    fail("Unexpected click event for view" + view.toString());
+                }
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Insure that no click events have been received. */
+    public void assertNoneClicked() {
+        try {
+            long waitTime = 1; // seconds
+            View view = mViews.poll(waitTime, SECONDS);
+            if (view != null) {
+                fail("Unexpected click event for view" + view.toString());
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingHoverListener.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingHoverListener.java
new file mode 100644
index 0000000..87d46ba
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingHoverListener.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 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.accessibilityservice.cts.utils;
+
+import static android.view.MotionEvent.ACTION_HOVER_MOVE;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.view.MotionEvent;
+import android.view.View;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/** This Listener listens for and logs hover events so they can be checked later by tests. */
+public class EventCapturingHoverListener implements View.OnHoverListener {
+
+    private boolean shouldConsumeEvents; // whether or not to keep events from propagating to other
+    // listeners
+    private final BlockingQueue<MotionEvent> mEvents = new LinkedBlockingQueue<>();
+
+    public EventCapturingHoverListener(boolean shouldConsumeEvents) {
+        this.shouldConsumeEvents = shouldConsumeEvents;
+    }
+
+    public EventCapturingHoverListener() {
+        this.shouldConsumeEvents = true;
+    }
+
+    @Override
+    public boolean onHover(View view, MotionEvent MotionEvent) {
+        assertTrue(mEvents.offer(MotionEvent.obtain(MotionEvent)));
+        return shouldConsumeEvents;
+    }
+
+    /** Insure that no hover events have been detected. */
+    public void assertNonePropagated() {
+        try {
+            long waitTime = 1; // seconds
+            MotionEvent event = mEvents.poll(waitTime, SECONDS);
+            if (event != null) {
+                fail("Unexpected touch event " + event.toString());
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Check for the specified hover events. Note that specifying ACTION_HOVER_MOVE will match one
+     * or more consecutive ACTION_HOVER_MOVE events.
+     */
+    public void assertPropagated(int... eventTypes) {
+        MotionEvent ev;
+        long waitTime = 5; // seconds
+        try {
+            List<String> expected = new ArrayList<>();
+            List<String> received = new ArrayList<>();
+            for (int e : eventTypes) {
+                expected.add(MotionEvent.actionToString(e));
+            }
+            ev = mEvents.poll(waitTime, SECONDS);
+            assertNotNull(
+                    "Expected " + expected + " but none present after " + waitTime + " seconds",
+                    ev);
+            // By this point there is at least one received event.
+            received.add(MotionEvent.actionToString(ev.getActionMasked()));
+            ev = mEvents.poll(waitTime, SECONDS);
+            while (ev != null) {
+                int action = ev.getActionMasked();
+                if (action != ACTION_HOVER_MOVE) {
+                    received.add(MotionEvent.actionToString(action));
+                } else {
+                    // Add the current event if the previous received event was not ACTION_MOVE
+                    String prev = received.get(received.size() - 1);
+                    if (!prev.equals(MotionEvent.actionToString(ACTION_HOVER_MOVE))) {
+                        received.add(MotionEvent.actionToString(action));
+                    }
+                }
+                ev = mEvents.poll(waitTime, SECONDS);
+            }
+            assertEquals(expected, received);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingLongClickListener.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingLongClickListener.java
new file mode 100644
index 0000000..5daf89e
--- /dev/null
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingLongClickListener.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 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.accessibilityservice.cts.utils;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.view.View;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/** A click event listener that keeps an ordered record of events. */
+public class EventCapturingLongClickListener implements View.OnLongClickListener {
+
+    // whether or not to keep events from propagating to other listeners.
+    // Note that setting this to false means that the accessibility service will see both a long
+    // click and a click event when you perform a double tap and hold gesture
+    private boolean shouldConsumeEvents;
+    private final BlockingQueue<View> mViews = new LinkedBlockingQueue<>();
+
+    public EventCapturingLongClickListener(boolean shouldConsumeEvents) {
+        this.shouldConsumeEvents = shouldConsumeEvents;
+    }
+
+    public EventCapturingLongClickListener() {
+        this.shouldConsumeEvents = true;
+    }
+
+    @Override
+    public boolean onLongClick(View view) {
+        mViews.offer(view);
+        return true;
+    }
+
+    /** Insure that the specified views have received long click events. */
+    public void assertLongClicked(View... views) {
+        View view;
+        try {
+            for (View v : views) {
+                long waitTime = 5; // seconds
+                view = mViews.poll(waitTime, SECONDS);
+                assertNotNull(
+                        "Expected long click event for "
+                                + v.toString()
+                                + " but none present after "
+                                + waitTime
+                                + " seconds",
+                        view);
+                if (v != view) {
+                    fail("Unexpected long click event for view" + view.toString());
+                }
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Insure that no click events have been received. */
+    public void assertNoneLongClicked() {
+        try {
+            long waitTime = 1; // seconds
+            View view = mViews.poll(waitTime, SECONDS);
+            if (view != null) {
+                fail("Unexpected long click event for view" + view.toString());
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingTouchListener.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingTouchListener.java
index d7ae4592..e0adce2 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingTouchListener.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/EventCapturingTouchListener.java
@@ -16,22 +16,91 @@
 
 package android.accessibilityservice.cts.utils;
 
+import static android.view.MotionEvent.ACTION_MOVE;
 
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.view.MotionEvent;
 import android.view.View;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 
 public class EventCapturingTouchListener implements View.OnTouchListener {
+    // whether or not to keep events from propagating to other listeners
+    private boolean shouldConsumeEvents;
+    private final BlockingQueue<MotionEvent> events = new LinkedBlockingQueue<>();
 
-    public final BlockingQueue<MotionEvent> events = new LinkedBlockingQueue<>();
+    public EventCapturingTouchListener(boolean shouldConsumeEvents) {
+        this.shouldConsumeEvents = shouldConsumeEvents;
+    }
+
+    public EventCapturingTouchListener() {
+        this.shouldConsumeEvents = true;
+    }
 
     @Override
     public boolean onTouch(View view, MotionEvent motionEvent) {
         assertTrue(events.offer(MotionEvent.obtain(motionEvent)));
-        return true;
+        return shouldConsumeEvents;
+    }
+
+    /** Insure that no touch events have been detected. */
+    public void assertNonePropagated() {
+        try {
+            long waitTime = 1; // seconds
+            MotionEvent event = events.poll(waitTime, SECONDS);
+            if (event != null) {
+                fail("Unexpected touch event " + event.toString());
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Check for the specified touch events. Note that specifying ACTION_MOVE will match one or more
+     * consecutive ACTION_MOVE events.
+     */
+    public void assertPropagated(int... eventTypes) {
+        MotionEvent ev;
+        long waitTime = 5; // seconds
+        try {
+            List<String> expected = new ArrayList<>();
+            List<String> received = new ArrayList<>();
+            for (int e : eventTypes) {
+                expected.add(MotionEvent.actionToString(e));
+            }
+            ev = events.poll(waitTime, SECONDS);
+            assertNotNull(
+                    "Expected " + expected + " but none present after " + waitTime + " seconds",
+                    ev);
+            // By this point there is at least one received event.
+            received.add(MotionEvent.actionToString(ev.getActionMasked()));
+            ev = events.poll(waitTime, SECONDS);
+            while (ev != null) {
+                int action = ev.getActionMasked();
+                if (action != ACTION_MOVE) {
+                    received.add(MotionEvent.actionToString(action));
+                } else {
+                    // Add the current event if the previous received event was not ACTION_MOVE
+                    String prev = received.get(received.size() - 1);
+                    if (!prev.equals(MotionEvent.actionToString(ACTION_MOVE))) {
+                        received.add(MotionEvent.actionToString(action));
+                    }
+                }
+                ev = events.poll(waitTime, SECONDS);
+            }
+            assertEquals(expected, received);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
     }
 }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/GestureUtils.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/GestureUtils.java
index 99fa727..6a29f60 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/GestureUtils.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/GestureUtils.java
@@ -73,7 +73,7 @@
 
     public static StrokeDescription longClick(PointF point) {
         return new StrokeDescription(path(point), 0,
-                ViewConfiguration.getLongPressTimeout() * 3 / 2);
+                ViewConfiguration.getLongPressTimeout() * 3);
     }
 
     public static StrokeDescription swipe(PointF from, PointF to) {
@@ -141,4 +141,33 @@
     public static PointF ceil(PointF p) {
         return new PointF((float) Math.ceil(p.x), (float) Math.ceil(p.y));
     }
-}
+
+    public static GestureDescription doubleTap(PointF point) {
+        return multiTap(point, 2);
+    }
+
+    public static GestureDescription tripleTap(PointF point) {
+      return multiTap(point, 3);
+    }
+
+    public static GestureDescription multiTap(PointF point, int taps) {
+        GestureDescription.Builder builder = new GestureDescription.Builder();
+        long time = 0;
+        for (int i = 0; i < taps; i++) {
+            StrokeDescription stroke = click(point);
+            builder.addStroke(startingAt(time, stroke));
+            time += stroke.getDuration() + 40;
+        }
+        return builder.build();
+    }
+
+    public static GestureDescription doubleTapAndHold(PointF point) {
+        GestureDescription.Builder builder = new GestureDescription.Builder();
+        StrokeDescription tap1 = click(point);
+        StrokeDescription tap2 = startingAt(endTimeOf(tap1) + 40, longClick(point));
+        builder.addStroke(tap1);
+        builder.addStroke(tap2);
+        return builder.build();
+    }
+
+}
\ No newline at end of file
diff --git a/tests/admin/OWNERS b/tests/admin/OWNERS
new file mode 100644
index 0000000..46669be
--- /dev/null
+++ b/tests/admin/OWNERS
@@ -0,0 +1,9 @@
+# Bug component: 100560
+sandness@google.com
+rubinxu@google.com
+eranm@google.com
+irinaid@google.com
+pgrafov@google.com
+alexkershaw@google.com
+arangelov@google.com
+scottjonathan@google.com
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index 3513f21..84b8adc 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -1571,6 +1571,7 @@
         }
     }
 
+    @FlakyTest(bugId = 133501804)
     public void testAutogrouping() throws Exception {
         sendNotification(1, R.drawable.black);
         sendNotification(2, R.drawable.blue);
@@ -1581,6 +1582,7 @@
         assertAllPostedNotificationsAutogrouped();
     }
 
+    @FlakyTest(bugId = 133501804)
     public void testAutogrouping_autogroupStaysUntilAllNotificationsCanceled() throws Exception {
         sendNotification(1, R.drawable.black);
         sendNotification(2, R.drawable.blue);
@@ -1600,6 +1602,7 @@
         assertNotificationCount(0);
     }
 
+    @FlakyTest(bugId = 133501804)
     public void testAutogrouping_autogroupStaysUntilAllNotificationsAddedToGroup()
             throws Exception {
         String newGroup = "new!";
@@ -1630,7 +1633,8 @@
         assertOnlySomeNotificationsAutogrouped(postedIds);
     }
 
-    public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled()
+    // b/133502627.
+    public void disabledTestNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled()
         throws Exception {
         String newGroup = "new!";
         sendNotification(10, R.drawable.black);
@@ -2176,7 +2180,8 @@
         listener.onListenerDisconnected();
     }
 
-    public void testNotificationListener_setNotificationsShown() throws Exception {
+    // b/133502627
+    public void disabledTestNotificationListener_setNotificationsShown() throws Exception {
         if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
             return;
         }
@@ -2272,7 +2277,8 @@
         }
     }
 
-    public void testNotificationListener_getActiveNotifications() throws Exception {
+    // b/133502627
+    public void disabledTestNotificationListener_getActiveNotifications() throws Exception {
         if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
             return;
         }
@@ -2322,7 +2328,8 @@
         assertEquals(mListener.mRankingMap, mListener.getCurrentRanking());
     }
 
-    public void testNotificationListener_cancelNotifications() throws Exception {
+    // b/133502627
+    public void disabledTestNotificationListener_cancelNotifications() throws Exception {
         if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
             return;
         }
@@ -2586,7 +2593,8 @@
         }
     }
 
-    public void testNotificationManagerBubblePolicy_flagForAppForeground() throws Exception {
+    // b/133502627
+    public void disabledTestNotificationManagerBubblePolicy_flagForAppForeground() throws Exception {
         try {
             // turn on bubbles globally
             toggleBubbleSetting(true);
diff --git a/tests/aslr/OWNERS b/tests/aslr/OWNERS
new file mode 100644
index 0000000..94522e3
--- /dev/null
+++ b/tests/aslr/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 36824
+include /tests/tests/security/OWNERS
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 2e56a02..9f87565 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -813,7 +813,12 @@
     private String getString(String id) {
         final Resources resources = mContext.getResources();
         final int stringId = resources.getIdentifier(id, "string", "android");
-        return resources.getString(stringId);
+        try {
+            return resources.getString(stringId);
+        } catch (Resources.NotFoundException e) {
+            throw new IllegalStateException("no internal string for '" + id + "' / res=" + stringId
+                    + ": ", e);
+        }
     }
 
     /**
@@ -822,7 +827,12 @@
     private String getString(String id, Object... formatArgs) {
         final Resources resources = mContext.getResources();
         final int stringId = resources.getIdentifier(id, "string", "android");
-        return resources.getString(stringId, formatArgs);
+        try {
+            return resources.getString(stringId, formatArgs);
+        } catch (Resources.NotFoundException e) {
+            throw new IllegalStateException("no internal string for '" + id + "' / res=" + stringId
+                    + ": ", e);
+        }
     }
 
     /**
diff --git a/tests/backup/OWNERS b/tests/backup/OWNERS
index 3637e32..c28c4d8 100644
--- a/tests/backup/OWNERS
+++ b/tests/backup/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 41666
 # Use this reviewer by default.
 br-framework-team+reviews@google.com
 
diff --git a/tests/backup/app/src/android/backup/app/FullBackupBackupAgent.java b/tests/backup/app/src/android/backup/app/FullBackupBackupAgent.java
index 8535344..0f4a123 100644
--- a/tests/backup/app/src/android/backup/app/FullBackupBackupAgent.java
+++ b/tests/backup/app/src/android/backup/app/FullBackupBackupAgent.java
@@ -53,23 +53,25 @@
     @Override
     public void onRestoreFile(ParcelFileDescriptor data, long size,
             File destination, int type, long mode, long mtime) throws IOException {
-        Log.d(MainActivity.TAG, "onRestoreFile " + destination);
         super.onRestoreFile(data, size, destination, type, mode, mtime);
+        Log.d(MainActivity.TAG, "onRestoreFile " + destination);
     }
 
     @Override
     public void onFullBackup(FullBackupDataOutput data) throws IOException {
-        Log.d(MainActivity.TAG, "Full backup requested, quota is " + data.getQuota());
         super.onFullBackup(data);
+        Log.d(MainActivity.TAG, "Full backup requested, quota is " + data.getQuota());
     }
 
     @Override
     public void onQuotaExceeded(long backupDataBytes, long quotaBytes) {
+        super.onQuotaExceeded(backupDataBytes, quotaBytes);
         Log.d(MainActivity.TAG, "Quota exceeded!");
     }
 
     @Override
     public void onRestoreFinished() {
+        super.onRestoreFinished();
         Log.d(MainActivity.TAG, "onRestoreFinished");
     }
 
diff --git a/tests/backup/app/src/android/backup/app/KeyValueBackupAgent.java b/tests/backup/app/src/android/backup/app/KeyValueBackupAgent.java
index 155d8f9..c73731e 100644
--- a/tests/backup/app/src/android/backup/app/KeyValueBackupAgent.java
+++ b/tests/backup/app/src/android/backup/app/KeyValueBackupAgent.java
@@ -77,11 +77,13 @@
 
     @Override
     public void onQuotaExceeded(long backupDataBytes, long quotaBytes) {
+        super.onQuotaExceeded(backupDataBytes, quotaBytes);
         Log.d(MainActivity.TAG, "Quota exceeded!");
     }
 
     @Override
     public void onRestoreFinished() {
+        super.onRestoreFinished();
         Log.d(MainActivity.TAG, "onRestoreFinished");
     }
 
diff --git a/tests/core/runner/Android.bp b/tests/core/runner/Android.bp
deleted file mode 100644
index de3d724..0000000
--- a/tests/core/runner/Android.bp
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (C) 2009 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.
-
-//==========================================================
-// Build the core runner.
-//==========================================================
-
-// Build library
-java_library {
-    name: "cts-core-test-runner",
-
-    srcs: ["src/**/*.java"],
-    static_libs: [
-        "compatibility-device-util",
-        "android-support-test",
-        "vogarexpect",
-        "testng",
-    ],
-
-    libs: ["android.test.runner.stubs"],
-    sdk_version: "test_current",
-
-}
-
-//==========================================================
-// Build the run listener
-//==========================================================
-
-// Build library
-java_library {
-    name: "cts-test-runner",
-
-    srcs: ["src/com/android/cts/runner/**/*.java"],
-    static_libs: ["android-support-test"],
-    sdk_version: "current",
-
-}
diff --git a/tests/core/runner/AndroidManifest.xml b/tests/core/runner/AndroidManifest.xml
deleted file mode 100644
index 001e6f2..0000000
--- a/tests/core/runner/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="android.core.tests.runner">
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="android.core.tests.runner"
-                     android:label="cts framework tests"/>
-
-</manifest>
diff --git a/tests/core/runner/src/com/android/cts/core/runner/ExpectationBasedFilter.java b/tests/core/runner/src/com/android/cts/core/runner/ExpectationBasedFilter.java
deleted file mode 100644
index f409dbd..0000000
--- a/tests/core/runner/src/com/android/cts/core/runner/ExpectationBasedFilter.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.cts.core.runner;
-
-import android.os.Bundle;
-import android.util.Log;
-import com.google.common.base.Splitter;
-import java.io.IOException;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import javax.annotation.Nullable;
-import org.junit.runner.Description;
-import org.junit.runner.manipulation.Filter;
-import org.junit.runners.ParentRunner;
-import org.junit.runners.Suite;
-import vogar.Expectation;
-import vogar.ExpectationStore;
-import vogar.ModeId;
-import vogar.Result;
-
-/**
- * Filter out tests/classes that are not requested or which are expected to fail.
- *
- * <p>This filter has to handle both a hierarchy of {@code Description descriptions} that looks
- * something like this:
- * <pre>
- * Suite
- *     Suite
- *         Suite
- *             ParentRunner
- *                 Test
- *                 ...
- *             ...
- *         ParentRunner
- *             Test
- *             ...
- *         ...
- *     Suite
- *         ParentRunner
- *             Test
- *             ...
- *         ...
- *     ...
- * </pre>
- *
- * <p>It cannot filter out the non-leaf nodes in the hierarchy, i.e. {@link Suite} and
- * {@link ParentRunner}, as that would prevent it from traversing the hierarchy and finding
- * the leaf nodes.
- */
-class ExpectationBasedFilter extends Filter {
-
-    static final String TAG = "ExpectationBasedFilter";
-
-    private static final String ARGUMENT_EXPECTATIONS = "core-expectations";
-
-    private static final Splitter CLASS_LIST_SPLITTER = Splitter.on(',').trimResults();
-
-    private final ExpectationStore expectationStore;
-
-    private static List<String> getExpectationResourcePaths(Bundle args) {
-        return CLASS_LIST_SPLITTER.splitToList(args.getString(ARGUMENT_EXPECTATIONS));
-    }
-
-    public ExpectationBasedFilter(Bundle args) {
-        ExpectationStore expectationStore = null;
-        try {
-            // Get the set of resource names containing the expectations.
-            Set<String> expectationResources = new LinkedHashSet<>(
-                getExpectationResourcePaths(args));
-            Log.i(TAG, "Loading expectations from: " + expectationResources);
-            expectationStore = ExpectationStore.parseResources(
-                getClass(), expectationResources, ModeId.DEVICE);
-        } catch (IOException e) {
-            Log.e(TAG, "Could not initialize ExpectationStore: ", e);
-        }
-
-        this.expectationStore = expectationStore;
-    }
-
-    @Override
-    public boolean shouldRun(Description description) {
-        // Only filter leaf nodes. The description is for a test if and only if it is a leaf node.
-        // Non-leaf nodes must not be filtered out as that would prevent leaf nodes from being
-        // visited in the case when we are traversing the hierarchy of classes.
-        Description testDescription = getTestDescription(description);
-        if (testDescription != null) {
-            String className = testDescription.getClassName();
-            String methodName = testDescription.getMethodName();
-            String testName = className + "#" + methodName;
-
-            if (expectationStore != null) {
-                Expectation expectation = expectationStore.get(testName);
-                if (expectation.getResult() != Result.SUCCESS) {
-                    Log.d(TAG, "Excluding test " + testDescription
-                            + " as it matches expectation: " + expectation);
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    private Description getTestDescription(Description description) {
-        List<Description> children = description.getChildren();
-        // An empty description is by definition a test.
-        if (children.isEmpty()) {
-            return description;
-        }
-
-        // Handle initialization errors that were wrapped in an ErrorReportingRunner as a special
-        // case. This is needed because ErrorReportingRunner is treated as a suite of Throwables,
-        // (where each Throwable corresponds to a test called initializationError) and so its
-        // description contains children, one for each Throwable, and so is not treated as a test
-        // to filter. Unfortunately, it does not support Filterable so this filter is never applied
-        // to its children.
-        // See https://github.com/junit-team/junit/issues/1253
-        Description child = children.get(0);
-        String methodName = child.getMethodName();
-        if ("initializationError".equals(methodName)) {
-            return child;
-        }
-
-        return null;
-    }
-
-    @Override
-    public String describe() {
-        return "TestFilter";
-    }
-}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/SingleTestNGTestRunListener.java b/tests/core/runner/src/com/android/cts/core/runner/support/SingleTestNGTestRunListener.java
deleted file mode 100644
index 7a68a8b..0000000
--- a/tests/core/runner/src/com/android/cts/core/runner/support/SingleTestNGTestRunListener.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.cts.core.runner.support;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * Listener for TestNG runs that provides gtest-like console output.
- *
- * Prints a message like [RUN], [OK], [ERROR], [SKIP] to stdout
- * as tests are being executed with their status.
- *
- * This output is also saved as the device logs (logcat) when the test is run through
- * cts-tradefed.
- */
-public class SingleTestNGTestRunListener implements org.testng.ITestListener {
-    private int mTestStarted = 0;
-
-    private Map<String, Throwable> failures = new LinkedHashMap<>();
-
-    private static class Prefixes {
-        @SuppressWarnings("unused")
-        private static final String INFORMATIONAL_MARKER =  "[----------]";
-        private static final String START_TEST_MARKER =     "[ RUN      ]";
-        private static final String OK_TEST_MARKER =        "[       OK ]";
-        private static final String ERROR_TEST_RUN_MARKER = "[    ERROR ]";
-        private static final String SKIPPED_TEST_MARKER =   "[     SKIP ]";
-        private static final String TEST_RUN_MARKER =       "[==========]";
-    }
-
-    // How many tests did TestNG *actually* try to run?
-    public int getNumTestStarted() {
-      return mTestStarted;
-    }
-
-    public Map<String, Throwable> getFailures() {
-        return Collections.unmodifiableMap(failures);
-    }
-
-    @Override
-    public void onFinish(org.testng.ITestContext context) {
-        System.out.println(String.format("%s", Prefixes.TEST_RUN_MARKER));
-    }
-
-    @Override
-    public void onStart(org.testng.ITestContext context) {
-        System.out.println(String.format("%s", Prefixes.INFORMATIONAL_MARKER));
-    }
-
-    @Override
-    public void onTestFailedButWithinSuccessPercentage(org.testng.ITestResult result) {
-        onTestFailure(result);
-    }
-
-    @Override
-    public void onTestFailure(org.testng.ITestResult result) {
-        // All failures are coalesced into one '[ FAILED ]' message at the end
-        // This is because a single test method can run multiple times with different parameters.
-        // Since we only test a single method, it's safe to combine all failures into one
-        // failure at the end.
-        //
-        // The big pass/fail is printed from SingleTestNGTestRunner, not from the listener.
-        String id = getId(result);
-        Throwable throwable = result.getThrowable();
-        System.out.println(String.format("%s %s ::: %s", Prefixes.ERROR_TEST_RUN_MARKER,
-                id, stringify(throwable)));
-        failures.put(id, throwable);
-    }
-
-    @Override
-    public void onTestSkipped(org.testng.ITestResult result) {
-        System.out.println(String.format("%s %s", Prefixes.SKIPPED_TEST_MARKER,
-              getId(result)));
-    }
-
-    @Override
-    public void onTestStart(org.testng.ITestResult result) {
-        mTestStarted++;
-        System.out.println(String.format("%s %s", Prefixes.START_TEST_MARKER,
-              getId(result)));
-    }
-
-    @Override
-    public void onTestSuccess(org.testng.ITestResult result) {
-        System.out.println(String.format("%s", Prefixes.OK_TEST_MARKER));
-    }
-
-    private String getId(org.testng.ITestResult test) {
-        // TestNG is quite complicated since tests can have arbitrary parameters.
-        // Use its code to stringify a result name instead of doing it ourselves.
-
-        org.testng.remote.strprotocol.TestResultMessage msg =
-                new org.testng.remote.strprotocol.TestResultMessage(
-                    null, /*suite name*/
-                    null, /*test name -- display the test method name instead */
-                    test);
-
-        String className = test.getTestClass().getName();
-        //String name = test.getMethod().getMethodName();
-        return String.format("%s#%s", className, msg.toDisplayString());
-
-    }
-
-    private String stringify(Throwable error) {
-        return Arrays.toString(error.getStackTrace()).replaceAll("\n", " ");
-    }
-}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/SingleTestNgTestExecutor.java b/tests/core/runner/src/com/android/cts/core/runner/support/SingleTestNgTestExecutor.java
deleted file mode 100644
index deb18df..0000000
--- a/tests/core/runner/src/com/android/cts/core/runner/support/SingleTestNgTestExecutor.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.cts.core.runner.support;
-
-import android.util.Log;
-
-import org.testng.TestNG;
-import org.testng.xml.XmlClass;
-import org.testng.xml.XmlInclude;
-import org.testng.xml.XmlSuite;
-import org.testng.xml.XmlTest;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Test executor to run a single TestNG test method.
- */
-public class SingleTestNgTestExecutor {
-    // Execute any method which is in the class klass.
-    // The klass is passed in separately to handle inherited methods only.
-    // Returns true if all tests pass, false otherwise.
-    public static Result execute(Class<?> klass, String methodName) {
-        if (klass == null) {
-          throw new NullPointerException("klass must not be null");
-        }
-
-        if (methodName == null) {
-          throw new NullPointerException("methodName must not be null");
-        }
-
-        //if (!method.getDeclaringClass().isAssignableFrom(klass)) {
-        //  throw new IllegalArgumentException("klass must match method's declaring class");
-        //}
-
-        SingleTestNGTestRunListener listener = new SingleTestNGTestRunListener();
-
-        // Although creating a new testng "core" every time might seem heavyweight, in practice
-        // it seems to take a mere few milliseconds at most.
-        // Since we're running all the parameteric combinations of a test,
-        // this ends up being neglible relative to that.
-        TestNG testng = createTestNG(klass.getName(), methodName, listener);
-        testng.run();
-
-        if (listener.getNumTestStarted() <= 0) {
-          // It's possible to be invoked here with an arbitrary method name
-          // so print out a warning incase TestNG actually had a no-op.
-          Log.w("TestNgExec", "execute class " + klass.getName() + ", method " + methodName +
-              " had 0 tests executed. Not a test method?");
-        }
-
-        return new Result(testng.hasFailure(), listener.getFailures());
-    }
-
-    private static org.testng.TestNG createTestNG(String klass, String method,
-            SingleTestNGTestRunListener listener) {
-        org.testng.TestNG testng = new org.testng.TestNG();
-        testng.setUseDefaultListeners(false);  // Don't create the testng-specific HTML/XML reports.
-        // It still prints the X/Y tests succeeded/failed summary to stdout.
-
-        // We don't strictly need this listener for CTS, but having it print SUCCESS/FAIL
-        // makes it easier to diagnose which particular combination of a test method had failed
-        // from looking at device logcat.
-        testng.addListener(listener);
-
-        /* Construct the following equivalent XML configuration:
-         *
-         * <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
-         * <suite>
-         *   <test>
-         *     <classes>
-         *       <class name="$klass">
-         *         <include name="$method" />
-         *       </class>
-         *     </classes>
-         *   </test>
-         * </suite>
-         *
-         * This will ensure that only a single klass/method is being run by testng.
-         * (It can still be run multiple times due to @DataProvider, with different parameters
-         * each time)
-         */
-        List<XmlSuite> suites = new ArrayList<>();
-        XmlSuite the_suite = new XmlSuite();
-        XmlTest the_test = new XmlTest(the_suite);
-        XmlClass the_class = new XmlClass(klass);
-        XmlInclude the_include = new XmlInclude(method);
-
-        the_class.getIncludedMethods().add(the_include);
-        the_test.getXmlClasses().add(the_class);
-        suites.add(the_suite);
-        testng.setXmlSuites(suites);
-
-        return testng;
-    }
-
-    public static class Result {
-        private final boolean hasFailure;
-        private final Map<String,Throwable> failures;
-
-
-        Result(boolean hasFailure, Map<String, Throwable> failures) {
-            this.hasFailure = hasFailure;
-            this.failures = Collections.unmodifiableMap(new LinkedHashMap<>(failures));
-        }
-
-        public boolean hasFailure() {
-            return hasFailure;
-        }
-
-        public Map<String, Throwable> getFailures() {
-            return failures;
-        }
-    }
-}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/TestNgRunner.java b/tests/core/runner/src/com/android/cts/core/runner/support/TestNgRunner.java
deleted file mode 100644
index d9bf037..0000000
--- a/tests/core/runner/src/com/android/cts/core/runner/support/TestNgRunner.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.cts.core.runner.support;
-
-import android.util.Log;
-
-import org.junit.runner.Description;
-import org.junit.runner.Runner;
-import org.junit.runner.manipulation.Filter;
-import org.junit.runner.manipulation.Filterable;
-import org.junit.runner.manipulation.NoTestsRemainException;
-import org.junit.runner.notification.Failure;
-import org.junit.runner.notification.RunNotifier;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashSet;
-import java.util.Map;
-
-/**
- * A {@link Runner} that can TestNG tests.
- *
- * <p>Implementation note: Avoid extending ParentRunner since that also has
- * logic to handle BeforeClass/AfterClass and other junit-specific functionality
- * that would be invalid for TestNG.</p>
- */
-class TestNgRunner extends Runner implements Filterable {
-
-  private static final boolean DEBUG = false;
-
-  private Description mDescription;
-  /** Class name for debugging. */
-  private String mClassName;
-  /** Don't include the same method names twice. */
-  private HashSet<String> mMethodSet = new HashSet<>();
-
-  /**
-   * @param testClass the test class to run
-   */
-  TestNgRunner(Class<?> testClass) {
-    mDescription = generateTestNgDescription(testClass);
-    mClassName = testClass.getName();
-  }
-
-  // Runner implementation
-  @Override
-  public Description getDescription() {
-    return mDescription;
-  }
-
-  // Runner implementation
-  @Override
-  public int testCount() {
-    if (!descriptionHasChildren(getDescription())) {  // Avoid NPE when description is null.
-      return 0;
-    }
-
-    // We always follow a flat Parent->Leaf hierarchy, so no recursion necessary.
-    return getDescription().testCount();
-  }
-
-  // Filterable implementation
-  @Override
-  public void filter(Filter filter) throws NoTestsRemainException {
-    mDescription = filterDescription(mDescription, filter);
-
-    if (!descriptionHasChildren(getDescription())) {  // Avoid NPE when description is null.
-      if (DEBUG) {
-        Log.d("TestNgRunner",
-            "Filtering has removed all tests :( for class " + mClassName);
-      }
-      throw new NoTestsRemainException();
-    }
-
-    if (DEBUG) {
-      Log.d("TestNgRunner",
-          "Filtering has retained " + testCount() + " tests for class " + mClassName);
-    }
-  }
-
-  // Filterable implementation
-  @Override
-  public void run(RunNotifier notifier) {
-    if (!descriptionHasChildren(getDescription())) {  // Avoid NPE when description is null.
-      // Nothing to do.
-      return;
-    }
-
-    for (Description child : getDescription().getChildren()) {
-      String className = child.getClassName();
-      String methodName = child.getMethodName();
-
-      Class<?> klass;
-      try {
-        klass = Class.forName(className, false, Thread.currentThread().getContextClassLoader());
-      } catch (ClassNotFoundException e) {
-        throw new AssertionError(e);
-      }
-
-      notifier.fireTestStarted(child);
-
-      // Avoid looking at all the methods by just using the string method name.
-      SingleTestNgTestExecutor.Result result = SingleTestNgTestExecutor.execute(klass, methodName);
-      if (result.hasFailure()) {
-        // TODO: get the error messages from testng somehow.
-        notifier.fireTestFailure(new Failure(child, extractException(result.getFailures())));
-      }
-
-      notifier.fireTestFinished(child);
-      // TODO: Check @Test(enabled=false) and invoke #fireTestIgnored instead.
-    }
-  }
-
-  private Throwable extractException(Map<String, Throwable> failures) {
-    if (failures.isEmpty()) {
-      return new AssertionError();
-    }
-    if (failures.size() == 1) {
-      return failures.values().iterator().next();
-    }
-
-    StringBuilder errorMessage = new StringBuilder("========== Multiple Failures ==========");
-    for (Map.Entry<String, Throwable> failureEntry : failures.entrySet()) {
-      errorMessage.append("\n\n=== "). append(failureEntry.getKey()).append(" ===\n");
-      Throwable throwable = failureEntry.getValue();
-      errorMessage
-              .append(throwable.getClass()).append(": ")
-              .append(throwable.getMessage());
-      for (StackTraceElement e : throwable.getStackTrace()) {
-        if (e.getClassName().equals(getClass().getName())) {
-          break;
-        }
-        errorMessage.append("\n  at ").append(e);
-      }
-    }
-    errorMessage.append("\n=======================================\n\n");
-    return new AssertionError(errorMessage.toString());
-  }
-
-
-  /**
-   * Recursively (preorder traversal) apply the filter to all the descriptions.
-   *
-   * @return null if the filter rejects the whole tree.
-   */
-  private static Description filterDescription(Description desc, Filter filter) {
-    if (!filter.shouldRun(desc)) {  // XX: Does the filter itself do the recursion?
-      return null;
-    }
-
-    Description newDesc = desc.childlessCopy();
-
-    // Return leafs.
-    if (!descriptionHasChildren(desc)) {
-      return newDesc;
-    }
-
-    // Filter all subtrees, only copying them if the filter accepts them.
-    for (Description child : desc.getChildren()) {
-      Description filteredChild = filterDescription(child, filter);
-
-      if (filteredChild != null) {
-        newDesc.addChild(filteredChild);
-      }
-    }
-
-    return newDesc;
-  }
-
-  private Description generateTestNgDescription(Class<?> cls) {
-    // Add the overall class description as the parent.
-    Description parent = Description.createSuiteDescription(cls);
-
-    if (DEBUG) {
-      Log.d("TestNgRunner", "Generating TestNg Description for class " + cls.getName());
-    }
-
-    // Add each test method as a child.
-    for (Method m : cls.getDeclaredMethods()) {
-
-      // Filter to only 'public void' signatures.
-      if ((m.getModifiers() & Modifier.PUBLIC) == 0) {
-        continue;
-      }
-
-      if (!m.getReturnType().equals(Void.TYPE)) {
-        continue;
-      }
-
-      // Note that TestNG methods may actually have parameters
-      // (e.g. with @DataProvider) which TestNG will populate itself.
-
-      // Add [Class, MethodName] as a Description leaf node.
-      String name = m.getName();
-
-      if (!mMethodSet.add(name)) {
-        // Overloaded methods have the same name, don't add them twice.
-        if (DEBUG) {
-          Log.d("TestNgRunner", "Already added child " + cls.getName() + "#" + name);
-        }
-        continue;
-      }
-
-      Description child = Description.createTestDescription(cls, name);
-
-      parent.addChild(child);
-
-      if (DEBUG) {
-        Log.d("TestNgRunner", "Add child " + cls.getName() + "#" + name);
-      }
-    }
-
-    return parent;
-  }
-
-  private static boolean descriptionHasChildren(Description desc) {
-    // Note: Although "desc.isTest()" is equivalent to "!desc.getChildren().isEmpty()"
-    // we add the pre-requisite 2 extra null checks to avoid throwing NPEs.
-    return desc != null && desc.getChildren() != null && !desc.getChildren().isEmpty();
-  }
-}
diff --git a/tests/core/runner/src/com/android/cts/core/runner/support/TestNgRunnerBuilder.java b/tests/core/runner/src/com/android/cts/core/runner/support/TestNgRunnerBuilder.java
deleted file mode 100644
index 2f084b3..0000000
--- a/tests/core/runner/src/com/android/cts/core/runner/support/TestNgRunnerBuilder.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.cts.core.runner.support;
-
-import java.lang.reflect.Method;
-
-import org.junit.runner.Runner;
-import org.junit.runners.model.RunnerBuilder;
-
-import org.testng.annotations.Test;
-
-/**
- * A {@link RunnerBuilder} that can handle TestNG tests.
- */
-public class TestNgRunnerBuilder extends RunnerBuilder {
-  // Returns a TestNG runner for this class, only if it is a class
-  // annotated with testng's @Test or has any methods with @Test in it.
-  @Override
-  public Runner runnerForClass(Class<?> testClass) {
-    if (isTestNgTestClass(testClass)) {
-      return new TestNgRunner(testClass);
-    }
-
-    return null;
-  }
-
-  private static boolean isTestNgTestClass(Class<?> cls) {
-    // TestNG test is either marked @Test at the class
-    if (cls.getAnnotation(Test.class) != null) {
-      return true;
-    }
-
-    // Or It's marked @Test at the method level
-    for (Method m : cls.getDeclaredMethods()) {
-      if (m.getAnnotation(Test.class) != null) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-}
diff --git a/tests/core/runner/src/com/android/cts/runner/CrashParserRunListener.java b/tests/core/runner/src/com/android/cts/runner/CrashParserRunListener.java
deleted file mode 100644
index fbbb684..0000000
--- a/tests/core/runner/src/com/android/cts/runner/CrashParserRunListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 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 com.android.cts.runner;
-
-import android.support.test.internal.runner.listener.InstrumentationRunListener;
-import android.util.Log;
-import org.junit.runner.Description;
-
-/**
- * A {@link RunListener} for CrashParser. Dumps the test name to logs when
- * tests start.
- */
-public class CrashParserRunListener extends InstrumentationRunListener {
-
-    private static final String TAG = "CrashParserRunListener";
-
-    // Constant must be kept in sync with CrashUtils.java
-    public static final String NEW_TEST_ALERT = "New test starting with name: ";
-
-    @Override
-    public void testStarted(Description description) throws Exception {
-        Log.i(TAG, NEW_TEST_ALERT + description.toString());
-    }
-
-}
diff --git a/tests/core/runner/src/com/android/cts/runner/CtsTestRunListener.java b/tests/core/runner/src/com/android/cts/runner/CtsTestRunListener.java
deleted file mode 100644
index 1f9a939..0000000
--- a/tests/core/runner/src/com/android/cts/runner/CtsTestRunListener.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2014 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 com.android.cts.runner;
-
-import android.app.ActivityManager;
-import android.app.Instrumentation;
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.support.test.internal.runner.listener.InstrumentationRunListener;
-import android.text.TextUtils;
-import android.util.Log;
-
-import junit.framework.TestCase;
-
-import org.junit.runner.Description;
-import org.junit.runner.notification.RunListener;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.Class;
-import java.lang.ReflectiveOperationException;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.net.Authenticator;
-import java.net.CookieHandler;
-import java.net.ResponseCache;
-import java.text.DateFormat;
-import java.util.Locale;
-import java.util.Properties;
-import java.util.TimeZone;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLSocketFactory;
-
-/**
- * A {@link RunListener} for CTS. Sets the system properties necessary for many
- * core tests to run. This is needed because there are some core tests that need
- * writing access to the file system.
- * Finally, we add a means to free memory allocated by a TestCase after its
- * execution.
- */
-public class CtsTestRunListener extends InstrumentationRunListener {
-
-    private static final String TAG = "CtsTestRunListener";
-
-    private TestEnvironment mEnvironment;
-    private Class<?> lastClass;
-
-    @Override
-    public void testRunStarted(Description description) throws Exception {
-        mEnvironment = new TestEnvironment(getInstrumentation().getTargetContext());
-
-        // We might want to move this to /sdcard, if is is mounted/writable.
-        File cacheDir = getInstrumentation().getTargetContext().getCacheDir();
-        System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
-
-        // attempt to disable keyguard, if current test has permission to do so
-        // TODO: move this to a better place, such as InstrumentationTestRunner
-        // ?
-        if (getInstrumentation().getContext().checkCallingOrSelfPermission(
-                android.Manifest.permission.DISABLE_KEYGUARD)
-                == PackageManager.PERMISSION_GRANTED) {
-            Log.i(TAG, "Disabling keyguard");
-            KeyguardManager keyguardManager =
-                    (KeyguardManager) getInstrumentation().getContext().getSystemService(
-                            Context.KEYGUARD_SERVICE);
-            keyguardManager.newKeyguardLock("cts").disableKeyguard();
-        } else {
-            Log.i(TAG, "Test lacks permission to disable keyguard. " +
-                    "UI based tests may fail if keyguard is up");
-        }
-    }
-
-    @Override
-    public void testStarted(Description description) throws Exception {
-        if (description.getTestClass() != lastClass) {
-            lastClass = description.getTestClass();
-            printMemory(description.getTestClass());
-        }
-
-        mEnvironment.reset();
-    }
-
-    @Override
-    public void testFinished(Description description) {
-        // no way to implement this in JUnit4...
-        // offending test cases that need this logic should probably be cleaned
-        // up individually
-        // if (test instanceof TestCase) {
-        // cleanup((TestCase) test);
-        // }
-    }
-
-    /**
-     * Dumps some memory info.
-     */
-    private void printMemory(Class<?> testClass) {
-        Runtime runtime = Runtime.getRuntime();
-
-        long total = runtime.totalMemory();
-        long free = runtime.freeMemory();
-        long used = total - free;
-
-        Log.d(TAG, "Total memory  : " + total);
-        Log.d(TAG, "Used memory   : " + used);
-        Log.d(TAG, "Free memory   : " + free);
-
-        String tempdir = System.getProperty("java.io.tmpdir", "");
-        // TODO: Remove these extra Logs added to debug a specific timeout problem.
-        Log.d(TAG, "java.io.tmpdir is:" + tempdir);
-
-        if (!TextUtils.isEmpty(tempdir)) {
-            String[] commands = {"df", tempdir};
-            BufferedReader in = null;
-            try {
-                Log.d(TAG, "About to .exec df");
-                Process proc = runtime.exec(commands);
-                Log.d(TAG, ".exec returned");
-                in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
-                Log.d(TAG, "Stream reader created");
-                String line;
-                while ((line = in.readLine()) != null) {
-                    Log.d(TAG, line);
-                }
-            } catch (IOException e) {
-                Log.d(TAG, "Exception: " + e.toString());
-                // Well, we tried
-            } finally {
-                Log.d(TAG, "In finally");
-                if (in != null) {
-                    try {
-                        in.close();
-                    } catch (IOException e) {
-                        // Meh
-                    }
-                }
-            }
-        }
-
-        Log.d(TAG, "Now executing : " + testClass.getName());
-    }
-
-    /**
-     * Nulls all non-static reference fields in the given test class. This
-     * method helps us with those test classes that don't have an explicit
-     * tearDown() method. Normally the garbage collector should take care of
-     * everything, but since JUnit keeps references to all test cases, a little
-     * help might be a good idea.
-     */
-    private void cleanup(TestCase test) {
-        Class<?> clazz = test.getClass();
-
-        while (clazz != TestCase.class) {
-            Field[] fields = clazz.getDeclaredFields();
-            for (int i = 0; i < fields.length; i++) {
-                Field f = fields[i];
-                if (!f.getType().isPrimitive() &&
-                        !Modifier.isStatic(f.getModifiers())) {
-                    try {
-                        f.setAccessible(true);
-                        f.set(test, null);
-                    } catch (Exception ignored) {
-                        // Nothing we can do about it.
-                    }
-                }
-            }
-
-            clazz = clazz.getSuperclass();
-        }
-    }
-
-    // http://code.google.com/p/vogar/source/browse/trunk/src/vogar/target/TestEnvironment.java
-    static class TestEnvironment {
-        private static final Field sDateFormatIs24HourField;
-        static {
-            try {
-                Class<?> dateFormatClass = Class.forName("java.text.DateFormat");
-                sDateFormatIs24HourField = dateFormatClass.getDeclaredField("is24Hour");
-            } catch (ReflectiveOperationException e) {
-                throw new AssertionError("Missing DateFormat.is24Hour", e);
-            }
-        }
-
-        private final Locale mDefaultLocale;
-        private final TimeZone mDefaultTimeZone;
-        private final HostnameVerifier mHostnameVerifier;
-        private final SSLSocketFactory mSslSocketFactory;
-        private final Properties mProperties = new Properties();
-        private final Boolean mDefaultIs24Hour;
-
-        TestEnvironment(Context context) {
-            mDefaultLocale = Locale.getDefault();
-            mDefaultTimeZone = TimeZone.getDefault();
-            mHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
-            mSslSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
-
-            mProperties.setProperty("user.home", "");
-            mProperties.setProperty("java.io.tmpdir", context.getCacheDir().getAbsolutePath());
-            // The CDD mandates that devices that support WiFi are the only ones that will have
-            // multicast.
-            PackageManager pm = context.getPackageManager();
-            mProperties.setProperty("android.cts.device.multicast",
-                    Boolean.toString(pm.hasSystemFeature(PackageManager.FEATURE_WIFI)));
-            mDefaultIs24Hour = getDateFormatIs24Hour();
-
-            // There are tests in libcore that should be disabled for low ram devices. They can't
-            // access ActivityManager to call isLowRamDevice, but can read system properties.
-            ActivityManager activityManager =
-                    (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-            mProperties.setProperty("android.cts.device.lowram",
-                    Boolean.toString(activityManager.isLowRamDevice()));
-        }
-
-        void reset() {
-            System.setProperties(null);
-            System.setProperties(mProperties);
-            Locale.setDefault(mDefaultLocale);
-            TimeZone.setDefault(mDefaultTimeZone);
-            Authenticator.setDefault(null);
-            CookieHandler.setDefault(null);
-            ResponseCache.setDefault(null);
-            HttpsURLConnection.setDefaultHostnameVerifier(mHostnameVerifier);
-            HttpsURLConnection.setDefaultSSLSocketFactory(mSslSocketFactory);
-            setDateFormatIs24Hour(mDefaultIs24Hour);
-        }
-
-        private static Boolean getDateFormatIs24Hour() {
-            try {
-                return (Boolean) sDateFormatIs24HourField.get(null);
-            } catch (ReflectiveOperationException e) {
-                throw new AssertionError("Unable to get java.text.DateFormat.is24Hour", e);
-            }
-        }
-
-        private static void setDateFormatIs24Hour(Boolean value) {
-            try {
-                sDateFormatIs24HourField.set(null, value);
-            } catch (ReflectiveOperationException e) {
-                throw new AssertionError("Unable to set java.text.DateFormat.is24Hour", e);
-            }
-        }
-    }
-
-}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AmStartOptionsTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AmStartOptionsTests.java
index c83cb2e..87039b3 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AmStartOptionsTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AmStartOptionsTests.java
@@ -29,9 +29,7 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.fail;
 
 import android.content.ComponentName;
 import android.platform.test.annotations.Presubmit;
@@ -40,9 +38,6 @@
 
 import org.junit.Test;
 
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
 /**
  * Build/Install/Run:
  *     atest CtsWindowManagerDeviceTestCases:AmStartOptionsTests
@@ -92,9 +87,10 @@
         // Start LaunchingActivity again and finish TestActivity
         final int flags =
                 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP;
-        final String result = executeShellCommand(
-                "am start -W -f " + flags + " -n " + getActivityName(LAUNCHING_ACTIVITY));
-        verifyShellOutput(result, LAUNCHING_ACTIVITY, false);
+        executeShellCommand("am start -W -f " + flags + " -n " + getActivityName(LAUNCHING_ACTIVITY)
+                + " --display " + DEFAULT_DISPLAY);
+        waitAndAssertTopResumedActivity(LAUNCHING_ACTIVITY, DEFAULT_DISPLAY,
+                "Activity must be launched.");
     }
 
     private void testDashW(final ComponentName entryActivity, final ComponentName actualActivity)
@@ -112,73 +108,14 @@
 
     private void startActivityAndVerifyResult(final ComponentName entryActivity,
             final ComponentName actualActivity, boolean shouldStart) {
-        // See TODO below
-        // final LogSeparator logSeparator = separateLogs();
-
         // Pass in different data only when cold starting. This is to make the intent
         // different in subsequent warm/hot launches, so that the entrypoint alias
         // activity is always started, but the actual activity is not started again
         // because of the NEW_TASK and singleTask flags.
-        final String result = executeShellCommand(
-                "am start -n " + getActivityName(entryActivity) + " -W"
-                + (shouldStart ? " -d about:blank" : ""));
+        executeShellCommand("am start -n " + getActivityName(entryActivity) + " -W --display "
+                + DEFAULT_DISPLAY + (shouldStart ? " -d about:blank" : ""));
 
-        // Verify shell command return value
-        verifyShellOutput(result, actualActivity, shouldStart);
-
-        // TODO: Disable logcat check for now.
-        // Logcat of WM or AM tag could be lost (eg. chatty if earlier events generated
-        // too many lines), and make the test look flaky. We need to either use event
-        // log or swith to other mechanisms. Only verify shell output for now, it should
-        // still catch most failures.
-
-        // Verify adb logcat log
-        //verifyLogcat(actualActivity, shouldStart, logSeparator);
-    }
-
-    private static final Pattern sNotStartedWarningPattern = Pattern.compile(
-            "Warning: Activity not started(.*)");
-    private static final Pattern sStatusPattern = Pattern.compile(
-            "Status: (.*)");
-    private static final Pattern sActivityPattern = Pattern.compile(
-            "Activity: (.*)");
-    private static final String sStatusOk = "ok";
-
-    private void verifyShellOutput(
-            final String result, final ComponentName activity, boolean shouldStart) {
-        boolean warningFound = false;
-        String status = null;
-        String reportedActivity = null;
-
-        final String[] lines = result.split("\\n");
-        // Going from the end of logs to beginning in case if some other activity is started first.
-        for (int i = lines.length - 1; i >= 0; i--) {
-            final String line = lines[i].trim();
-            Matcher matcher = sNotStartedWarningPattern.matcher(line);
-            if (matcher.matches()) {
-                warningFound = true;
-                continue;
-            }
-            matcher = sStatusPattern.matcher(line);
-            if (matcher.matches()) {
-                status = matcher.group(1);
-                continue;
-            }
-            matcher = sActivityPattern.matcher(line);
-            if (matcher.matches()) {
-                reportedActivity = matcher.group(1);
-                continue;
-            }
-        }
-
-        assertEquals("Status is ok", sStatusOk, status);
-        assertEquals("Reported activity is " +  getActivityName(activity),
-                getActivityName(activity), reportedActivity);
-
-        if (shouldStart && warningFound) {
-            fail("Should start new activity but brought something to front.");
-        } else if (!shouldStart && !warningFound){
-            fail("Should bring existing activity to front but started new activity.");
-        }
+        waitAndAssertTopResumedActivity(actualActivity, DEFAULT_DISPLAY,
+                "Activity must be launched");
     }
 }
diff --git a/tests/leanbackjank/OWNERS b/tests/leanbackjank/OWNERS
new file mode 100644
index 0000000..729b9b6
--- /dev/null
+++ b/tests/leanbackjank/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 188489
+dake@google.com
\ No newline at end of file
diff --git a/tests/perfetto/OWNERS b/tests/perfetto/OWNERS
new file mode 100644
index 0000000..05798d7
--- /dev/null
+++ b/tests/perfetto/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 323270
+primiano@google.com
+lalitm@google.com
diff --git a/tests/rollback/OWNERS b/tests/rollback/OWNERS
new file mode 100644
index 0000000..5a631b6
--- /dev/null
+++ b/tests/rollback/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 557916
+include /hostsidetests/rollback/OWNERS
diff --git a/tests/sample/OWNERS b/tests/sample/OWNERS
new file mode 100644
index 0000000..7782fbe
--- /dev/null
+++ b/tests/sample/OWNERS
@@ -0,0 +1,10 @@
+# Bug component: 346961
+diqian@google.com
+fdeng@google.com
+moonk@google.com
+normancheung@google.com
+williamgoh@google.com
+peykov@google.com
+yichunli@google.com
+yimingpan@google.com
+
diff --git a/tests/tests/animation/OWNERS b/tests/tests/animation/OWNERS
new file mode 100644
index 0000000..475f1b8
--- /dev/null
+++ b/tests/tests/animation/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 47085
+tianliu@google.com
+mount@google.com
+andreykulikov@google.com
diff --git a/tests/tests/batterysaving/OWNERS b/tests/tests/batterysaving/OWNERS
new file mode 100644
index 0000000..1fe2293
--- /dev/null
+++ b/tests/tests/batterysaving/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 330055
+omakoto@google.com
+yamasani@google.com
diff --git a/tests/tests/externalservice/OWNERS b/tests/tests/externalservice/OWNERS
new file mode 100644
index 0000000..210a568
--- /dev/null
+++ b/tests/tests/externalservice/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 76427
+maco@google.com
+narayan@google.com
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png
index e3be1d1..e67fce8 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_clamp_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png
index ce18075..8a48104 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png
index f991189..2145eec 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png
index f2798b4..5428052 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_2_repeat_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png
index aee71ec..70ee76a 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png
index a879e3c..0a195a8 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_gradient_3_mirror_golden.png
Binary files differ
diff --git a/tests/tests/graphics/src/android/graphics/cts/CameraTest.java b/tests/tests/graphics/src/android/graphics/cts/CameraTest.java
index ff8f77c..92f6322 100644
--- a/tests/tests/graphics/src/android/graphics/cts/CameraTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/CameraTest.java
@@ -91,8 +91,8 @@
         float[] f = new float[9];
         m2.getValues(f);
         assertArrayEquals(new float[] {
-                1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.0017361111f, 1.0f
-        }, f, 0.0f);
+                1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
+        }, f, 0.0017361111f);
     }
 
     @Test
@@ -107,8 +107,8 @@
         float[] f = new float[9];
         m2.getValues(f);
         assertArrayEquals(new float[] {
-                0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0017361111f, 0.0f, 1.0f
-        }, f, 0.0f);
+                0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f
+        }, f, 0.0017361111f);
     }
 
     @Test
@@ -124,7 +124,7 @@
         m2.getValues(f);
         assertArrayEquals(new float[] {
                 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
-        }, f, 0.0f);
+        }, f, 0.0017361111f);
     }
 
     @Test
diff --git a/tests/tests/jni/OWNERS b/tests/tests/jni/OWNERS
new file mode 100644
index 0000000..29fea99
--- /dev/null
+++ b/tests/tests/jni/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 86431
+include /hostsidetests/classloaders/OWNERS
diff --git a/tests/tests/media/Android.bp b/tests/tests/media/Android.bp
index e8be516..b066af1 100644
--- a/tests/tests/media/Android.bp
+++ b/tests/tests/media/Android.bp
@@ -40,7 +40,6 @@
         "truth-prebuilt",
         "mockito-target-minus-junit4",
         "androidx.heifwriter_heifwriter",
-        "androidx.media2_media2",
     ],
     jni_libs: [
         "libaudio_jni",
diff --git a/tests/tests/media/src/android/media/cts/AudioPlaybackConfigurationTest.java b/tests/tests/media/src/android/media/cts/AudioPlaybackConfigurationTest.java
index 6256175..21f7a1b 100644
--- a/tests/tests/media/src/android/media/cts/AudioPlaybackConfigurationTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioPlaybackConfigurationTest.java
@@ -33,6 +33,7 @@
 import android.media.AudioPlaybackConfiguration;
 
 import com.android.compatibility.common.util.CtsAndroidTestCase;
+import com.android.internal.annotations.GuardedBy;
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -361,16 +362,16 @@
     }
 
     private static class MyAudioPlaybackCallback extends AudioManager.AudioPlaybackCallback {
-        private int mCalled = 0;
-        private int mNbConfigs = 0;
-        private List<AudioPlaybackConfiguration> mConfigs;
         private final Object mCbLock = new Object();
+        @GuardedBy("mCbLock")
+        private int mCalled;
+        @GuardedBy("mCbLock")
+        private List<AudioPlaybackConfiguration> mConfigs;
 
         void reset() {
             synchronized (mCbLock) {
                 mCalled = 0;
-                mNbConfigs = 0;
-                mConfigs.clear();
+                mConfigs = new ArrayList<AudioPlaybackConfiguration>();
             }
         }
 
@@ -381,9 +382,7 @@
         }
 
         int getNbConfigs() {
-            synchronized (mCbLock) {
-                return mNbConfigs;
-            }
+            return getConfigs().size();
         }
 
         List<AudioPlaybackConfiguration> getConfigs() {
@@ -393,13 +392,13 @@
         }
 
         MyAudioPlaybackCallback() {
+            reset();
         }
 
         @Override
         public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {
             synchronized (mCbLock) {
                 mCalled++;
-                mNbConfigs = configs.size();
                 mConfigs = configs;
             }
         }
diff --git a/tests/tests/midi/OWNERS b/tests/tests/midi/OWNERS
new file mode 100644
index 0000000..e78e1d0
--- /dev/null
+++ b/tests/tests/midi/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 1344
+philburk@google.com
diff --git a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
index 91949db..42d3057 100644
--- a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
+++ b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
@@ -1556,10 +1556,7 @@
             }
         }
     } else {
-        // TODO(b/123042748): The fact that glEGLImageTargetTexStorageEXT does not work for YUV
-        //                    textures is a bug. The condition for the target should be removed
-        //                    once the bug is fixed.
-        if (HasGLExtension("GL_EXT_EGL_image_storage") && mTexTarget != GL_TEXTURE_EXTERNAL_OES) {
+        if (HasGLExtension("GL_EXT_EGL_image_storage")) {
             glEGLImageTargetTexStorageEXT(mTexTarget, static_cast<GLeglImageOES>(mEGLImage),
                                           nullptr);
         } else {
diff --git a/tests/tests/nativemedia/sl/OWNERS b/tests/tests/nativemedia/sl/OWNERS
new file mode 100644
index 0000000..38b4a35
--- /dev/null
+++ b/tests/tests/nativemedia/sl/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 1344
+jmtrivi@google.com
diff --git a/tests/tests/nativemedia/xa/OWNERS b/tests/tests/nativemedia/xa/OWNERS
new file mode 100644
index 0000000..90b75e4
--- /dev/null
+++ b/tests/tests/nativemedia/xa/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 1344
+include ../sl/OWNERS
diff --git a/tests/tests/nativemidi/OWNERS b/tests/tests/nativemidi/OWNERS
new file mode 100644
index 0000000..ce5adf1
--- /dev/null
+++ b/tests/tests/nativemidi/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 48436
+pmclean@google.com
\ No newline at end of file
diff --git a/tests/tests/netsecpolicy/OWNERS b/tests/tests/netsecpolicy/OWNERS
new file mode 100644
index 0000000..fdd42d8
--- /dev/null
+++ b/tests/tests/netsecpolicy/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 36824
+include ../networksecurityconfig/OWNERS
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/OWNERS b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/OWNERS
deleted file mode 100644
index 7705bfe..0000000
--- a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-# Inherits OWNERS from parent directory.
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/OWNERS b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/OWNERS
deleted file mode 100644
index 7705bfe..0000000
--- a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-# Inherits OWNERS from parent directory.
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext-pre-P/OWNERS b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext-pre-P/OWNERS
deleted file mode 100644
index 7705bfe..0000000
--- a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext-pre-P/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-# Inherits OWNERS from parent directory.
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/OWNERS b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/OWNERS
deleted file mode 100644
index 7705bfe..0000000
--- a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-# Inherits OWNERS from parent directory.
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/OWNERS b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/OWNERS
deleted file mode 100644
index 7705bfe..0000000
--- a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-# Inherits OWNERS from parent directory.
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/OWNERS b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/OWNERS
deleted file mode 100644
index 7705bfe..0000000
--- a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-# Inherits OWNERS from parent directory.
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-downloadmanager/OWNERS b/tests/tests/networksecurityconfig/networksecurityconfig-downloadmanager/OWNERS
deleted file mode 100644
index 7705bfe..0000000
--- a/tests/tests/networksecurityconfig/networksecurityconfig-downloadmanager/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-# Inherits OWNERS from parent directory.
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/OWNERS b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/OWNERS
deleted file mode 100644
index 7705bfe..0000000
--- a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-# Inherits OWNERS from parent directory.
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/OWNERS b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/OWNERS
deleted file mode 100644
index 7705bfe..0000000
--- a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-# Inherits OWNERS from parent directory.
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/OWNERS b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/OWNERS
deleted file mode 100644
index 7705bfe..0000000
--- a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-# Inherits OWNERS from parent directory.
diff --git a/tests/tests/notificationlegacy/notificationlegacy20/OWNERS b/tests/tests/notificationlegacy/notificationlegacy20/OWNERS
deleted file mode 100644
index d6078e0..0000000
--- a/tests/tests/notificationlegacy/notificationlegacy20/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# DO NOT DELETE: OWNERS is intended to be empty as module owner and bug component are defined
-# in parent directory. This file is needed as a placeholder for verification purpose as we
-# need to tell the difference between "no owner is specified for this module" vs "explicitly
-# defer to parent OWNERS file"
diff --git a/tests/tests/notificationlegacy/notificationlegacy27/OWNERS b/tests/tests/notificationlegacy/notificationlegacy27/OWNERS
deleted file mode 100644
index d6078e0..0000000
--- a/tests/tests/notificationlegacy/notificationlegacy27/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# DO NOT DELETE: OWNERS is intended to be empty as module owner and bug component are defined
-# in parent directory. This file is needed as a placeholder for verification purpose as we
-# need to tell the difference between "no owner is specified for this module" vs "explicitly
-# defer to parent OWNERS file"
diff --git a/tests/tests/notificationlegacy/notificationlegacy28/OWNERS b/tests/tests/notificationlegacy/notificationlegacy28/OWNERS
deleted file mode 100644
index d6078e0..0000000
--- a/tests/tests/notificationlegacy/notificationlegacy28/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# DO NOT DELETE: OWNERS is intended to be empty as module owner and bug component are defined
-# in parent directory. This file is needed as a placeholder for verification purpose as we
-# need to tell the difference between "no owner is specified for this module" vs "explicitly
-# defer to parent OWNERS file"
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/OWNERS b/tests/tests/notificationlegacy/notificationlegacy29/OWNERS
deleted file mode 100644
index d6078e0..0000000
--- a/tests/tests/notificationlegacy/notificationlegacy29/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-# DO NOT DELETE: OWNERS is intended to be empty as module owner and bug component are defined
-# in parent directory. This file is needed as a placeholder for verification purpose as we
-# need to tell the difference between "no owner is specified for this module" vs "explicitly
-# defer to parent OWNERS file"
diff --git a/tests/tests/os/Android.bp b/tests/tests/os/Android.bp
index 6c48c87..1f9ca09 100644
--- a/tests/tests/os/Android.bp
+++ b/tests/tests/os/Android.bp
@@ -47,7 +47,7 @@
         "vts",
         "general-tests",
     ],
-    platform_apis: true,
+    sdk_version: "test_current",
     libs: [
         "android.test.runner.stubs",
         "android.test.base.stubs",
diff --git a/tests/tests/packageinstaller/atomicinstall/OWNERS b/tests/tests/packageinstaller/atomicinstall/OWNERS
new file mode 100644
index 0000000..25775b8
--- /dev/null
+++ b/tests/tests/packageinstaller/atomicinstall/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 36137
+include /hostsidetests/stagedinstall/OWNERS
diff --git a/tests/tests/packageinstaller/install/AndroidManifest.xml b/tests/tests/packageinstaller/install/AndroidManifest.xml
index 7d2e984..eeef252 100644
--- a/tests/tests/packageinstaller/install/AndroidManifest.xml
+++ b/tests/tests/packageinstaller/install/AndroidManifest.xml
@@ -22,7 +22,7 @@
     <application android:label="Cts Package Installer Tests">
         <uses-library android:name="android.test.runner" />
 
-        <activity android:name=".InstallConfirmDialogStarter" />
+        <activity android:name="com.android.compatibility.common.util.FutureResultActivity" />
 
         <provider android:authorities="android.packageinstaller.install.cts.fileprovider"
                   android:name="androidx.core.content.FileProvider"
diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/InstallConfirmDialogStarter.kt b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/InstallConfirmDialogStarter.kt
deleted file mode 100644
index b026943..0000000
--- a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/InstallConfirmDialogStarter.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2018 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.packageinstaller.install.cts
-
-import android.app.Activity
-import android.content.Intent
-import android.os.Bundle
-import java.util.concurrent.LinkedBlockingQueue
-
-val installDialogResults = LinkedBlockingQueue<Int>()
-
-class InstallConfirmDialogStarter : Activity() {
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-
-        savedInstanceState ?: installDialogResults.clear()
-    }
-
-    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
-        installDialogResults.offer(resultCode)
-    }
-}
diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/IntentTest.kt b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/IntentTest.kt
index e163a32..a8a8917 100644
--- a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/IntentTest.kt
+++ b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/IntentTest.kt
@@ -28,6 +28,7 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import java.util.concurrent.TimeUnit
 
 private const val INSTALL_BUTTON_ID = "button1"
 private const val CANCEL_BUTTON_ID = "button2"
@@ -47,11 +48,11 @@
      */
     @Test
     fun confirmInstallation() {
-        startInstallationViaIntent()
+        val installation = startInstallationViaIntent()
         clickInstallerUIButton(INSTALL_BUTTON_ID)
 
         // Install should have succeeded
-        assertEquals(RESULT_OK, getInstallDialogResult())
+        assertEquals(RESULT_OK, installation.get(TIMEOUT, TimeUnit.MILLISECONDS))
         assertInstalled()
     }
 
@@ -61,14 +62,12 @@
      */
     @Test
     fun cancelInstallation() {
-        startInstallationViaIntent()
+        val installation = startInstallationViaIntent()
         clickInstallerUIButton(CANCEL_BUTTON_ID)
 
         // Install should have been aborted
-        assertEquals(RESULT_CANCELED, getInstallDialogResult())
+        assertEquals(RESULT_CANCELED, installation.get(TIMEOUT, TimeUnit.MILLISECONDS))
         assertNotInstalled()
-
-        assertNoMoreInstallResults()
     }
 
     /**
@@ -85,12 +84,12 @@
         intent.putExtra(Intent.EXTRA_RETURN_RESULT, true)
         intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
 
-        installDialogStarter.activity.startActivityForResult(intent, 0)
+        val reinstall = installDialogStarter.activity.startActivityForResult(intent)
 
         clickInstallerUIButton(INSTALL_BUTTON_ID)
 
         // Install should have succeeded
-        assertEquals(RESULT_OK, getInstallDialogResult())
+        assertEquals(RESULT_OK, reinstall.get(TIMEOUT, TimeUnit.MILLISECONDS))
         assertInstalled()
     }
 }
diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt
index f6bbe06..d84ab1b 100644
--- a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt
+++ b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt
@@ -38,12 +38,14 @@
 import android.support.test.uiautomator.Until
 import androidx.core.content.FileProvider
 import com.android.compatibility.common.util.AppOpsUtils
+import com.android.compatibility.common.util.FutureResultActivity
 import org.junit.After
 import org.junit.Assert
 import org.junit.Before
 import org.junit.Rule
 import java.io.File
 import java.lang.IllegalArgumentException
+import java.util.concurrent.CompletableFuture
 import java.util.concurrent.LinkedBlockingQueue
 import java.util.concurrent.TimeUnit
 
@@ -62,7 +64,7 @@
 
 open class PackageInstallerTestBase {
     @get:Rule
-    val installDialogStarter = ActivityTestRule(InstallConfirmDialogStarter::class.java)
+    val installDialogStarter = ActivityTestRule(FutureResultActivity::class.java)
 
     private val context = InstrumentationRegistry.getTargetContext()
     private val pm = context.packageManager
@@ -79,7 +81,7 @@
             if (status == STATUS_PENDING_USER_ACTION) {
                 val activityIntent = intent.getParcelableExtra<Intent>(EXTRA_INTENT)
                 activityIntent!!.addFlags(FLAG_ACTIVITY_CLEAR_TASK or FLAG_ACTIVITY_NEW_TASK)
-                installDialogStarter.activity.startActivityForResult(activityIntent, 0)
+                installDialogStarter.activity.startActivityForResult(activityIntent)
             }
 
             installSessionResult.offer(status)
@@ -128,7 +130,7 @@
     /**
      * Start an installation via a session
      */
-    protected fun startInstallationViaSession(): PackageInstaller.Session {
+    protected fun startInstallationViaSession(): CompletableFuture<Int> {
         val pi = pm.packageInstaller
 
         // Create session
@@ -143,33 +145,28 @@
         }
 
         // Commit session
-        val pendingIntent = PendingIntent.getBroadcast(context, 0, Intent(INSTALL_ACTION_CB),
-                FLAG_UPDATE_CURRENT)
-        session.commit(pendingIntent.intentSender)
+        val dialog = FutureResultActivity.doAndAwaitStart {
+            val pendingIntent = PendingIntent.getBroadcast(context, 0, Intent(INSTALL_ACTION_CB),
+                    FLAG_UPDATE_CURRENT)
+            session.commit(pendingIntent.intentSender)
+        }
 
         // The system should have asked us to launch the installer
         Assert.assertEquals(STATUS_PENDING_USER_ACTION, getInstallSessionResult())
 
-        return session
+        return dialog
     }
 
     /**
      * Start an installation via a session
      */
-    protected fun startInstallationViaIntent() {
+    protected fun startInstallationViaIntent(): CompletableFuture<Int> {
         val intent = Intent(Intent.ACTION_INSTALL_PACKAGE)
         intent.data = FileProvider.getUriForFile(context, CONTENT_AUTHORITY, apkFile)
         intent.putExtra(Intent.EXTRA_RETURN_RESULT, true)
         intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
 
-        installDialogStarter.activity.startActivityForResult(intent, 0)
-    }
-
-    /**
-     * Wait for result of install dialog and return it
-     */
-    fun getInstallDialogResult(timeout: Long = TIMEOUT): Int? {
-        return installDialogResults.poll(timeout, TimeUnit.MILLISECONDS)
+        return installDialogStarter.activity.startActivityForResult(intent)
     }
 
     fun assertInstalled() {
@@ -195,14 +192,6 @@
                 .click()
     }
 
-    /**
-     * Assert that there are no more callbacks from the install session or install dialog
-     */
-    fun assertNoMoreInstallResults() {
-        Assert.assertNull(getInstallSessionResult(0))
-        Assert.assertEquals(0, installDialogResults.size)
-    }
-
     @After
     fun unregisterInstallResultReceiver() {
         try {
diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt
index 34b78c3..111e6a8 100644
--- a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt
+++ b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt
@@ -30,6 +30,7 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import java.util.concurrent.TimeUnit
 
 private const val INSTALL_BUTTON_ID = "button1"
 private const val CANCEL_BUTTON_ID = "button2"
@@ -50,7 +51,7 @@
      */
     @Test
     fun confirmInstallation() {
-        startInstallationViaSession()
+        val installation = startInstallationViaSession()
         clickInstallerUIButton(INSTALL_BUTTON_ID)
 
         // Install should have succeeded
@@ -58,9 +59,7 @@
         assertInstalled()
 
         // Even when the install succeeds the install confirm dialog returns 'canceled'
-        assertEquals(RESULT_CANCELED, getInstallDialogResult())
-
-        assertNoMoreInstallResults()
+        assertEquals(RESULT_CANCELED, installation.get(TIMEOUT, TimeUnit.MILLISECONDS))
 
         assertTrue(AppOpsUtils.allowedOperationLogged(context.packageName, APP_OP_STR))
     }
@@ -70,7 +69,7 @@
      */
     @Test
     fun setAppCategory() {
-        startInstallationViaSession()
+        val installation = startInstallationViaSession()
         clickInstallerUIButton(INSTALL_BUTTON_ID)
 
         // Wait for installation to finish
@@ -90,14 +89,12 @@
      */
     @Test
     fun cancelInstallation() {
-        startInstallationViaSession()
+        val installation = startInstallationViaSession()
         clickInstallerUIButton(CANCEL_BUTTON_ID)
 
         // Install should have been aborted
         assertEquals(STATUS_FAILURE_ABORTED, getInstallSessionResult())
-        assertEquals(RESULT_CANCELED, getInstallDialogResult())
+        assertEquals(RESULT_CANCELED, installation.get(TIMEOUT, TimeUnit.MILLISECONDS))
         assertNotInstalled()
-
-        assertNoMoreInstallResults()
     }
 }
diff --git a/tests/tests/packageinstaller/tapjacking/OWNERS b/tests/tests/packageinstaller/tapjacking/OWNERS
new file mode 100644
index 0000000..0088192
--- /dev/null
+++ b/tests/tests/packageinstaller/tapjacking/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 36137
+moltmann@google.com
\ No newline at end of file
diff --git a/tests/tests/packageinstaller/uninstall/OWNERS b/tests/tests/packageinstaller/uninstall/OWNERS
new file mode 100644
index 0000000..0088192
--- /dev/null
+++ b/tests/tests/packageinstaller/uninstall/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 36137
+moltmann@google.com
\ No newline at end of file
diff --git a/tests/tests/permission/sdk28/OWNERS b/tests/tests/permission/sdk28/OWNERS
new file mode 100644
index 0000000..c126a70
--- /dev/null
+++ b/tests/tests/permission/sdk28/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 137825
+moltmann@google.com
\ No newline at end of file
diff --git a/tests/tests/permission2/Android.bp b/tests/tests/permission2/Android.bp
index f4f25b0..916e986 100644
--- a/tests/tests/permission2/Android.bp
+++ b/tests/tests/permission2/Android.bp
@@ -26,6 +26,7 @@
     ],
     libs: ["android.test.base.stubs"],
     static_libs: [
+        "androidx.test.core",
         "compatibility-device-util-axt",
         "ctstestrunner-axt",
         "guava",
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 49c28b4..402a286 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1522,18 +1522,6 @@
     <permission android:name="android.permission.OVERRIDE_WIFI_CONFIG"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @hide -->
-    <permission android:name="android.permission.ACCESS_WIMAX_STATE"
-        android:description="@string/permdesc_accessWimaxState"
-        android:label="@string/permlab_accessWimaxState"
-        android:protectionLevel="normal" />
-
-    <!-- @hide -->
-    <permission android:name="android.permission.CHANGE_WIMAX_STATE"
-        android:description="@string/permdesc_changeWimaxState"
-        android:label="@string/permlab_changeWimaxState"
-        android:protectionLevel="normal" />
-
     <!-- Allows applications to act as network scorers. @hide @SystemApi-->
     <permission android:name="android.permission.SCORE_NETWORKS"
         android:protectionLevel="signature|privileged" />
@@ -1603,12 +1591,6 @@
     <permission android:name="android.permission.MANAGE_LOWPAN_INTERFACES"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @hide Allows internal management of Wi-Fi connectivity state when on
-         wireless consent mode.
-         <p>Not for use by third-party applications. -->
-    <permission android:name="android.permission.MANAGE_WIFI_WHEN_WIRELESS_CONSENT_REQUIRED"
-        android:protectionLevel="signature" />
-
     <!-- #SystemApi @hide Allows an app to bypass Private DNS.
          <p>Not for use by third-party applications.
          TODO: publish as system API in next API release. -->
@@ -2829,6 +2811,11 @@
     <permission android:name="android.permission.STATUS_BAR_SERVICE"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to trigger bugreports via the shell app (which uses bugreport API)
+    @hide -->
+    <permission android:name="android.permission.TRIGGER_SHELL_BUGREPORT"
+        android:protectionLevel="signature" />
+
     <!-- Allows an application to bind to third party quick settings tiles.
          <p>Should only be requested by the System, should be required by
          TileService declarations.-->
@@ -3457,6 +3444,11 @@
     <permission android:name="android.permission.OBSERVE_ROLE_HOLDERS"
         android:protectionLevel="signature|installer" />
 
+    <!-- Allows an application to manage the companion devices.
+         @hide -->
+    <permission android:name="android.permission.MANAGE_COMPANION_DEVICES"
+                android:protectionLevel="signature" />
+
     <!-- @SystemApi Allows an application to use SurfaceFlinger's low level features.
          <p>Not for use by third-party applications.
          @hide
diff --git a/tests/tests/preference/OWNERS b/tests/tests/preference/OWNERS
index 827134e..0ea8182 100644
--- a/tests/tests/preference/OWNERS
+++ b/tests/tests/preference/OWNERS
@@ -1,3 +1,4 @@
+# Bug component: 25700
 lpf@google.com
 pavlis@google.com
 clarabayarri@google.com
diff --git a/tests/tests/provider/OWNERS b/tests/tests/provider/OWNERS
new file mode 100644
index 0000000..fea932d
--- /dev/null
+++ b/tests/tests/provider/OWNERS
@@ -0,0 +1,7 @@
+# Bug component: 1344
+jsharkey@android.com
+omakoto@google.com
+yamasani@google.com
+tgunn@google.com
+nicksauer@google.com
+nona@google.com
diff --git a/tests/tests/renderscript/OWNERS b/tests/tests/renderscript/OWNERS
new file mode 100644
index 0000000..d61905a
--- /dev/null
+++ b/tests/tests/renderscript/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 43047
+include platform/frameworks/rs:/OWNERS
diff --git a/tests/tests/role/Android.bp b/tests/tests/role/Android.bp
index ac8d967..47e84fc 100644
--- a/tests/tests/role/Android.bp
+++ b/tests/tests/role/Android.bp
@@ -24,7 +24,7 @@
         "androidx.test.rules",
         "compatibility-device-util-axt",
         "ctstestrunner-axt",
-        "truth-prebuilt"
+        "truth-prebuilt",
     ],
 
     test_suites: [
diff --git a/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java b/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
index 736e501..42cce23 100644
--- a/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
+++ b/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
@@ -50,7 +50,9 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.compatibility.common.util.AppOpsUtils;
+import com.android.compatibility.common.util.ExceptionUtils;
 import com.android.compatibility.common.util.ThrowingRunnable;
+import com.android.compatibility.common.util.UiDumpUtils;
 
 import org.junit.After;
 import org.junit.Before;
@@ -326,14 +328,15 @@
     @NonNull
     private Pair<Integer, Intent> clickButtonAndWaitForResult(boolean positive) throws IOException,
             InterruptedException {
-        String buttonId = positive ? "android:id/button1" : "android:id/button2";
-        UiObject2 button = sUiDevice.wait(Until.findObject(By.res(buttonId)), TIMEOUT_MILLIS);
-        if (button == null) {
-            dumpWindowHierarchy();
-            fail("Cannot find button to click");
-        }
-        button.click();
-        return waitForResult();
+        return ExceptionUtils.wrappingExceptions(UiDumpUtils::wrapWithUiDump, () -> {
+            String buttonId = positive ? "android:id/button1" : "android:id/button2";
+            UiObject2 button = sUiDevice.wait(Until.findObject(By.res(buttonId)), TIMEOUT_MILLIS);
+            if (button == null) {
+                fail("Cannot find button to click");
+            }
+            button.click();
+            return waitForResult();
+        });
     }
 
     private void dumpWindowHierarchy() throws InterruptedException, IOException {
diff --git a/tests/tests/security/OWNERS b/tests/tests/security/OWNERS
new file mode 100644
index 0000000..c5cfd1e
--- /dev/null
+++ b/tests/tests/security/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 36824
+cbrubaker@google.com
+jeffv@google.com
+nnk@google.com
diff --git a/tests/tests/syncmanager/OWNERS b/tests/tests/syncmanager/OWNERS
new file mode 100644
index 0000000..c475c6e
--- /dev/null
+++ b/tests/tests/syncmanager/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 197138
+omakoto@google.com
+yamasani@google.com
diff --git a/tests/tests/systemintents/OWNERS b/tests/tests/systemintents/OWNERS
new file mode 100644
index 0000000..b465964
--- /dev/null
+++ b/tests/tests/systemintents/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 25692
+ctate@google.com
\ No newline at end of file
diff --git a/tests/tests/telecom/OWNERS b/tests/tests/telecom/OWNERS
new file mode 100644
index 0000000..f4921e0
--- /dev/null
+++ b/tests/tests/telecom/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 20868
+include ../telephony/OWNERS
diff --git a/tests/tests/telecom2/OWNERS b/tests/tests/telecom2/OWNERS
new file mode 100644
index 0000000..f4921e0
--- /dev/null
+++ b/tests/tests/telecom2/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 20868
+include ../telephony/OWNERS
diff --git a/tests/tests/telecom3/OWNERS b/tests/tests/telecom3/OWNERS
new file mode 100644
index 0000000..f4921e0
--- /dev/null
+++ b/tests/tests/telecom3/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 20868
+include ../telephony/OWNERS
diff --git a/tests/tests/telephony/OWNERS b/tests/tests/telephony/OWNERS
new file mode 100644
index 0000000..73fa25e
--- /dev/null
+++ b/tests/tests/telephony/OWNERS
@@ -0,0 +1,14 @@
+# Bug component: 20868
+amitmahajan@google.com
+fionaxu@google.com
+jackyu@google.com
+rgreenwalt@google.com
+refuhoo@google.com
+mpq@google.com
+jminjie@google.com
+shuoq@google.com
+hallliu@google.com
+tgunn@google.com
+breadley@google.com
+paulye@google.com
+nazaninb@google.com
diff --git a/tests/tests/telephony/current/OWNERS b/tests/tests/telephony/current/OWNERS
deleted file mode 100644
index 7c8e7d8..0000000
--- a/tests/tests/telephony/current/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-# Bug component: 20868
-rgreenwalt@google.com
-jackyu@google.com
-tgunn@google.com
-amitmahajan@google.com
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index 5e4abf4..714eca6 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -134,21 +134,25 @@
     }
 
     /**
-     * Sanity check that the device has a cellular network and a valid default data subId
-     * when {@link PackageManager#FEATURE_TELEPHONY} support.
+     * Sanity check that both {@link PackageManager#FEATURE_TELEPHONY} and
+     * {@link NetworkCapabilities#TRANSPORT_CELLULAR} network must both be
+     * either defined or undefined; you can't cross the streams.
      */
     @Test
     public void testSanity() throws Exception {
-        if (!isSupported()) return;
-
         final boolean hasCellular = findCellularNetwork() != null;
-        if (!hasCellular) {
+        if (isSupported() && !hasCellular) {
             fail("Device claims to support " + PackageManager.FEATURE_TELEPHONY
                     + " but has no active cellular network, which is required for validation");
+        } else if (!isSupported() && hasCellular) {
+            fail("Device has active cellular network, but claims to not support "
+                    + PackageManager.FEATURE_TELEPHONY);
         }
 
-        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            fail("Device must have a valid default data subId for validation");
+        if (isSupported()) {
+            if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                fail("Device must have a valid default data subId for validation");
+            }
         }
     }
 
diff --git a/tests/tests/telephony2/OWNERS b/tests/tests/telephony2/OWNERS
index 7c8e7d8..f4921e0 100644
--- a/tests/tests/telephony2/OWNERS
+++ b/tests/tests/telephony2/OWNERS
@@ -1,5 +1,2 @@
 # Bug component: 20868
-rgreenwalt@google.com
-jackyu@google.com
-tgunn@google.com
-amitmahajan@google.com
+include ../telephony/OWNERS
diff --git a/tests/tests/telephony3/OWNERS b/tests/tests/telephony3/OWNERS
new file mode 100644
index 0000000..f4921e0
--- /dev/null
+++ b/tests/tests/telephony3/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 20868
+include ../telephony/OWNERS
diff --git a/tests/tests/telephony4/OWNERS b/tests/tests/telephony4/OWNERS
index 5617896..3a905dd 100644
--- a/tests/tests/telephony4/OWNERS
+++ b/tests/tests/telephony4/OWNERS
@@ -1,2 +1,4 @@
 # Bug component: 20868
-yinxu@google.com
\ No newline at end of file
+include ../telephony/OWNERS
+
+yinxu@google.com
diff --git a/tests/tests/telephonyprovider/OWNERS b/tests/tests/telephonyprovider/OWNERS
index 92458db..7f7694d 100644
--- a/tests/tests/telephonyprovider/OWNERS
+++ b/tests/tests/telephonyprovider/OWNERS
@@ -1,12 +1,3 @@
-amitmahajan@google.com
-fionaxu@google.com
-jackyu@google.com
-rgreenwalt@google.com
-refuhoo@google.com
-mpq@google.com
-jminjie@google.com
-shuoq@google.com
-hallliu@google.com
-tgunn@google.com
-breadley@google.com
-nazaninb@google.com
+# Bug component: 450841
+include ../telephony/OWNERS
+lelandmiller@google.com
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java
index 05acf32..7933791 100644
--- a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/TelephonyProviderTest.java
@@ -41,25 +41,18 @@
     // In JB MR1 access to the TelephonyProvider's Carriers table was clamped down and would
     // throw a SecurityException when queried. That was fixed in JB MR2. Verify that 3rd parties
     // can access the APN info the carriers table, after JB MR1.
+
+    // However, in R, a security bug was discovered that let apps read the password by querying
+    // multiple times and matching passwords against a regex in the query. Due to this hole, we're
+    // locking down the API and no longer allowing the exception. Accordingly, the behavior of this
+    // test is now reversed and we expect a SecurityException to be thrown.
     public void testAccessToApns() {
         try {
             String selection = Carriers.CURRENT + " IS NOT NULL";
             String[] selectionArgs = null;
             Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI,
                     APN_PROJECTION, selection, selectionArgs, null);
-        } catch (SecurityException e) {
-            fail("No access to current APN");
-        }
-    }
-
-    public void testNoAccessToPassword() {
-        try {
-            String selection = Carriers.CURRENT + " IS NOT NULL AND "
-                    + Carriers.PASSWORD + " IS NOT NULL";
-            String[] selectionArgs = null;
-            Cursor cursor = mContentResolver.query(Carriers.CONTENT_URI,
-                    APN_PROJECTION, selection, selectionArgs, null);
-            fail("Expected SecurityExceptio");
+            fail("No SecurityException thrown");
         } catch (SecurityException e) {
             // expected
         }
diff --git a/tests/tests/tools/processors/view_inspector/OWNERS b/tests/tests/tools/processors/view_inspector/OWNERS
new file mode 100644
index 0000000..1572c57
--- /dev/null
+++ b/tests/tests/tools/processors/view_inspector/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 25700
+ashleyrose@google.com
+aurimas@google.com
diff --git a/tests/tests/uiautomation/Android.bp b/tests/tests/uiautomation/Android.bp
index 22dd8f6..67f3ed7 100644
--- a/tests/tests/uiautomation/Android.bp
+++ b/tests/tests/uiautomation/Android.bp
@@ -23,7 +23,7 @@
         "cts_instant",
     ],
     static_libs: [
-        "compatibility-device-util-axt",
+        "CtsAccessibilityCommon",
         "ctstestrunner-axt",
         "ub-uiautomator",
     ],
diff --git a/tests/tests/uiautomation/AndroidManifest.xml b/tests/tests/uiautomation/AndroidManifest.xml
index af4f4cd..4da45fc 100644
--- a/tests/tests/uiautomation/AndroidManifest.xml
+++ b/tests/tests/uiautomation/AndroidManifest.xml
@@ -21,10 +21,12 @@
         android:targetSandboxVersion="2">
 
   <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
   <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
   <uses-permission android:name="android.permission.CAMERA" />
 
-  <application android:theme="@android:style/Theme.Holo.NoActionBar" >
+  <application android:theme="@android:style/Theme.Holo.NoActionBar"
+          android:requestLegacyExternalStorage="true">
 
       <uses-library android:name="android.test.runner"/>
 
diff --git a/tests/tests/uiautomation/AndroidTest.xml b/tests/tests/uiautomation/AndroidTest.xml
index f5cf748..9fe5a4f 100644
--- a/tests/tests/uiautomation/AndroidTest.xml
+++ b/tests/tests/uiautomation/AndroidTest.xml
@@ -29,4 +29,8 @@
         <option name="package" value="android.app.uiautomation.cts" />
         <option name="runtime-hint" value="6m42s" />
     </test>
+    <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+        <option name="directory-keys" value="/sdcard/android.app.uiautomation.cts" />
+        <option name="collect-on-run-ended-only" value="true" />
+    </metrics_collector>
 </configuration>
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationLogRule.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationLogRule.java
deleted file mode 100644
index 3f81d3a..0000000
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationLogRule.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2019 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.app.uiautomation.cts;
-
-import android.app.UiAutomation;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.test.InstrumentationRegistry;
-
-import com.android.compatibility.common.util.SystemUtil;
-
-import org.junit.AssumptionViolatedException;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import java.io.IOException;
-
-/**
- * Improves UiAutomationTest logging, dumps log when a test case gets failed.
- *
- *  <ol>
- *    <li>Call {@code dumpsys accessibility}.
- *  </ol>
- */
-public final class UiAutomationLogRule implements TestRule {
-
-    private final String mTestName;
-
-    public UiAutomationLogRule(@NonNull String testName) {
-        mTestName = testName;
-    }
-
-    @Override
-    public Statement apply(Statement base, Description description) {
-        return new Statement() {
-            @Override
-            public void evaluate() throws Throwable {
-                Throwable throwable = null;
-                // First run the test
-                try {
-                    base.evaluate();
-                } catch (Throwable t) {
-                    throwable = t;
-                }
-
-                // Ignore AssumptionViolatedException. It's not a test fail.
-                if (throwable != null && throwable instanceof AssumptionViolatedException) {
-                    throwable = null;
-                }
-
-                if (throwable != null) {
-                    try {
-                        Log.e(mTestName, "TEST FAIL");
-                        dump();
-                    } catch (Throwable t) {
-                        Log.e(mTestName, "Dump fail", t);
-                    }
-                }
-
-                // Finally, throw exception!
-                if (throwable == null) return;
-                throw throwable;
-            }
-        };
-    }
-
-    private void dump() throws IOException {
-        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation(
-                UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
-        try {
-            final String a11yDump = SystemUtil.runShellCommand(
-                    uiAutomation, "dumpsys accessibility");
-            Log.e(mTestName, "==== dumpsys accessibility ====\n" + a11yDump);
-        } finally {
-            uiAutomation.destroy();
-        }
-    }
-}
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
index 828d9b5..dd354d7 100755
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
@@ -17,13 +17,13 @@
 package android.app.uiautomation.cts;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.Manifest;
+import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -71,8 +71,8 @@
     private static final int TIMEOUT_FOR_SERVICE_ENABLE = 10000; // millis; 10s
 
     @Rule
-    public final UiAutomationLogRule mLogRule = new UiAutomationLogRule(
-            UiAutomationTest.class.getSimpleName());
+    public final AccessibilityDumpOnFailureRule mDumpOnFailureRule =
+            new AccessibilityDumpOnFailureRule();
 
     @Before
     public void setUp() throws Exception {
diff --git a/tests/tests/uidisolation/OWNERS b/tests/tests/uidisolation/OWNERS
new file mode 100644
index 0000000..94522e3
--- /dev/null
+++ b/tests/tests/uidisolation/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 36824
+include /tests/tests/security/OWNERS
diff --git a/tests/tests/view/OWNERS b/tests/tests/view/OWNERS
new file mode 100644
index 0000000..8200a30
--- /dev/null
+++ b/tests/tests/view/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 25700
+adamp@google.com
+shepshapard@google.com
+clarabayarri@google.com
diff --git a/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp b/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp
index 2bfab1e..3bc8890 100644
--- a/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp
+++ b/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp
@@ -31,7 +31,9 @@
 #include <android/surface_control.h>
 #include <android/sync.h>
 
+#include <errno.h>
 #include <jni.h>
+#include <time.h>
 
 namespace {
 
@@ -57,6 +59,16 @@
         return;                            \
     }
 
+#define NANOS_PER_SECOND 1000000000LL
+int64_t systemTime() {
+    struct timespec time;
+    int result = clock_gettime(CLOCK_MONOTONIC, &time);
+    if (result < 0) {
+        return -errno;
+    }
+    return (time.tv_sec * NANOS_PER_SECOND) + time.tv_nsec;
+}
+
 static AHardwareBuffer* allocateBuffer(int32_t width, int32_t height) {
     AHardwareBuffer* buffer = nullptr;
     AHardwareBuffer_Desc desc = {};
@@ -337,12 +349,16 @@
     int* contextIntPtr = reinterpret_cast<int*>(context);
     contextIntPtr[0]++;
     contextIntPtr[1] = presentFence;
+    int64_t* systemTimeLongPtr = reinterpret_cast<int64_t*>(contextIntPtr + 2);
+    *systemTimeLongPtr = systemTime();
 }
 
 jlong SurfaceTransaction_setOnComplete(JNIEnv* /*env*/, jclass, jlong surfaceTransaction) {
-    int* context = new int[2];
+    int* context = new int[4];
     context[0] = 0;
     context[1] = -1;
+    context[2] = -1;
+    context[3] = -1;
 
     ASurfaceTransaction_setOnComplete(
             reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
@@ -358,6 +374,9 @@
     int data = contextPtr[0];
     int presentFence = contextPtr[1];
 
+    int64_t* callbackTimePtr = reinterpret_cast<int64_t*>(contextPtr + 2);
+    int64_t callbackTime = *callbackTimePtr;
+
     delete[] contextPtr;
 
     if (desiredPresentTime < 0) {
@@ -367,31 +386,41 @@
         return;
     }
 
-    struct sync_file_info* syncFileInfo = sync_file_info(presentFence);
-    ASSERT(syncFileInfo, "invalid fence")
+    if (presentFence >= 0) {
+        struct sync_file_info* syncFileInfo = sync_file_info(presentFence);
+        ASSERT(syncFileInfo, "invalid fence");
 
-    if (syncFileInfo->status != 1) {
-        sync_file_info_free(syncFileInfo);
-        ASSERT(syncFileInfo->status == 1, "fence did not signal")
-    }
-
-    uint64_t presentTime = 0;
-    struct sync_fence_info* syncFenceInfo = sync_get_fence_info(syncFileInfo);
-    for (size_t i = 0; i < syncFileInfo->num_fences; i++) {
-        if (syncFenceInfo[i].timestamp_ns > presentTime) {
-            presentTime = syncFenceInfo[i].timestamp_ns;
+        if (syncFileInfo->status != 1) {
+            sync_file_info_free(syncFileInfo);
+            ASSERT(syncFileInfo->status == 1, "fence did not signal")
         }
+
+        uint64_t presentTime = 0;
+        struct sync_fence_info* syncFenceInfo = sync_get_fence_info(syncFileInfo);
+        for (size_t i = 0; i < syncFileInfo->num_fences; i++) {
+            if (syncFenceInfo[i].timestamp_ns > presentTime) {
+                presentTime = syncFenceInfo[i].timestamp_ns;
+            }
+        }
+
+        sync_file_info_free(syncFileInfo);
+        close(presentFence);
+
+        // In the worst case the worst present time should be no more than three frames off from the
+        // desired present time. Since the test case is using a virtual display and there are no
+        // requirements for virtual display refresh rate timing, lets assume a refresh rate of 16fps.
+        ASSERT(presentTime < desiredPresentTime + 0.188 * 1e9, "transaction was presented too late");
+        ASSERT(presentTime >= desiredPresentTime, "transaction was presented too early");
+    } else {
+        ASSERT(presentFence == -1, "invalid fences should be -1");
+        // The device doesn't support present fences. We will use the callback time to roughly
+        // verify the result. Since the callback could take up to half a frame, do the normal bound
+        // check plus an additional half frame.
+        ASSERT(callbackTime < desiredPresentTime + (0.188 + 0.031) * 1e9,
+                                                  "transaction was presented too late");
+        ASSERT(callbackTime >= desiredPresentTime, "transaction was presented too early");
     }
 
-    sync_file_info_free(syncFileInfo);
-    close(presentFence);
-
-    // In the worst case the worst present time should be no more than three frames off from the
-    // desired present time. Since the test case is using a virtual display and there are no
-    // requirements for virtual display refresh rate timing, lets assume a refresh rate of 16fps.
-    ASSERT(presentTime < desiredPresentTime + 0.188 * 1e9, "transaction was presented too late");
-    ASSERT(presentTime >= desiredPresentTime, "transaction was presented too early");
-
     ASSERT(data >= 1, "did not receive a callback")
     ASSERT(data <= 1, "received too many callbacks")
 }
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/DirectActionsTest.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/DirectActionsTest.java
index 338c361..6c4a3a7 100644
--- a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/DirectActionsTest.java
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/DirectActionsTest.java
@@ -134,7 +134,6 @@
             mActivityControl.finishActivity();
         }
     }
-
     private final class SessionControl {
         private @Nullable RemoteCallback mControl;
 
diff --git a/tests/tests/widget/OWNERS b/tests/tests/widget/OWNERS
new file mode 100644
index 0000000..12f176d
--- /dev/null
+++ b/tests/tests/widget/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 25700
+adamp@google.com
+mount@google.com
+shepshapard@google.com
+clarabayarri@google.com
diff --git a/tests/tests/widget/src/android/widget/cts/MagnifierTest.java b/tests/tests/widget/src/android/widget/cts/MagnifierTest.java
index a31963c..0264665 100644
--- a/tests/tests/widget/src/android/widget/cts/MagnifierTest.java
+++ b/tests/tests/widget/src/android/widget/cts/MagnifierTest.java
@@ -728,14 +728,15 @@
         WidgetTestUtils.runOnMainAndLayoutSync(mActivityRule, () -> {
             mActivity.setContentView(R.layout.magnifier_activity_centered_surfaceview_layout);
         }, false /* forceLayout */);
-        final View view = mActivity.findViewById(R.id.magnifier_centered_view);
-        WidgetTestUtils.runOnMainAndDrawSync(mActivityRule, view, () -> {
+        WidgetTestUtils.runOnMainAndLayoutSync(mActivityRule, () -> {
             // Draw something in the SurfaceView for the Magnifier to copy.
+            final View view = mActivity.findViewById(R.id.magnifier_centered_view);
             final SurfaceHolder surfaceHolder = ((SurfaceView) view).getHolder();
             final Canvas canvas = surfaceHolder.lockHardwareCanvas();
             canvas.drawColor(Color.BLUE);
             surfaceHolder.unlockCanvasAndPost(canvas);
-        });
+        }, false /* forceLayout */);
+        final View view = mActivity.findViewById(R.id.magnifier_centered_view);
         final Magnifier.Builder builder = new Magnifier.Builder(view)
                 .setSize(100, 100)
                 .setInitialZoom(5f) /* 20x20 source size */
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 01d5cd8..86e674e 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -169,6 +169,7 @@
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Locale;
 
 /**
@@ -7149,6 +7150,106 @@
                 TextUtils.equals(hintText, info.getHintText()));
     }
 
+    @UiThreadTest
+    @Test
+    public void testOnInitializeA11yNodeInfo_removesClickabilityWithLinkMovementMethod() {
+        mTextView = findTextView(R.id.textview_text);
+        mTextView.setMovementMethod(new LinkMovementMethod());
+
+        assertTrue("clickable should be true", mTextView.isClickable());
+        assertFalse("View should not have onClickListeners", mTextView.hasOnClickListeners());
+        assertTrue("longClickable should be true", mTextView.isLongClickable());
+        assertFalse("View should not have onLongClickListeners",
+                mTextView.hasOnLongClickListeners());
+
+        final AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+        mTextView.onInitializeAccessibilityNodeInfo(info);
+        List<AccessibilityNodeInfo.AccessibilityAction> actionList = info.getActionList();
+        assertFalse("info's isClickable should be false", info.isClickable());
+        assertFalse("info should not have ACTION_CLICK",
+                actionList.contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK));
+        assertFalse("info's isLongClickable should be false",
+                info.isLongClickable());
+        assertFalse("info should not have ACTION_LONG_CLICK",
+                actionList.contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK));
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnInitializeA11yNodeInfo_keepsClickabilityWithMovementMethod() {
+        mTextView = findTextView(R.id.textview_text);
+        mTextView.setMovementMethod(new ArrowKeyMovementMethod());
+
+        assertTrue("clickable should be true", mTextView.isClickable());
+        assertFalse("View should not have onClickListeners", mTextView.hasOnClickListeners());
+        assertTrue("longClickable should be false", mTextView.isLongClickable());
+        assertFalse("View should not have onLongClickListeners",
+                mTextView.hasOnLongClickListeners());
+
+        final AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+        mTextView.onInitializeAccessibilityNodeInfo(info);
+        List<AccessibilityNodeInfo.AccessibilityAction> actionList = info.getActionList();
+        assertTrue("info's isClickable should be true", info.isClickable());
+        assertTrue("info should have ACTION_CLICK",
+                actionList.contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK));
+        assertTrue("info's isLongClickable should be true",
+                info.isLongClickable());
+        assertTrue("info should have ACTION_LONG_CLICK",
+                actionList.contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK));
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnInitializeA11yNodeInfo_keepsClickabilityWithOnClickListener() {
+        mTextView = findTextView(R.id.textview_text);
+        mTextView.setMovementMethod(new LinkMovementMethod());
+
+        assertTrue("clickable should be true", mTextView.isClickable());
+        assertFalse("View should not have onClickListeners", mTextView.hasOnClickListeners());
+        assertTrue("longClickable should be true", mTextView.isLongClickable());
+        assertFalse("View should not have onLongClickListeners",
+                mTextView.hasOnLongClickListeners());
+
+        mTextView.setOnClickListener(mock(View.OnClickListener.class));
+
+        final AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+        mTextView.onInitializeAccessibilityNodeInfo(info);
+        List<AccessibilityNodeInfo.AccessibilityAction> actionList = info.getActionList();
+        assertTrue("info's isClickable should be true", info.isClickable());
+        assertTrue("info should have ACTION_CLICK",
+                actionList.contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK));
+        assertFalse("info's isLongClickable should not be true",
+                info.isLongClickable());
+        assertFalse("info should have ACTION_LONG_CLICK",
+                actionList.contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK));
+    }
+
+    @UiThreadTest
+    @Test
+    public void testOnInitializeA11yNodeInfo_keepsLongClickabilityWithOnLongClickListener() {
+        mTextView = findTextView(R.id.textview_text);
+        mTextView.setMovementMethod(new LinkMovementMethod());
+
+        assertTrue("clickable should be true", mTextView.isClickable());
+        assertFalse("View should not have onClickListeners", mTextView.hasOnClickListeners());
+        assertTrue("longClickable should be true", mTextView.isLongClickable());
+        assertFalse("View should not have onLongClickListeners",
+                mTextView.hasOnLongClickListeners());
+
+        mTextView.setOnLongClickListener(mock(View.OnLongClickListener.class));
+
+        final AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+        mTextView.onInitializeAccessibilityNodeInfo(info);
+        List<AccessibilityNodeInfo.AccessibilityAction> actionList = info.getActionList();
+        assertFalse("info's isClickable should be false", info.isClickable());
+        assertFalse("info should not have ACTION_CLICK",
+                actionList.contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK));
+        assertTrue("info's isLongClickable should be true",
+                info.isLongClickable());
+        assertTrue("info should have ACTION_LONG_CLICK",
+                actionList.contains(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK));
+    }
+
     @Test
     public void testAutosizeWithMaxLines_shouldNotThrowException() throws Throwable {
         // the layout contains an instance of CustomTextViewWithTransformationMethod
diff --git a/tests/vr/OWNERS b/tests/vr/OWNERS
new file mode 100644
index 0000000..b0936ba
--- /dev/null
+++ b/tests/vr/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 189591
+krzysio@google.com
diff --git a/tools/vm-tests-tf/OWNERS b/tools/vm-tests-tf/OWNERS
new file mode 100644
index 0000000..29fea99
--- /dev/null
+++ b/tools/vm-tests-tf/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 86431
+include /hostsidetests/classloaders/OWNERS