Merge "cts: Add Khaje target to whitelist in the CTS test case"
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
deleted file mode 100644
index 1795c46..0000000
--- a/apps/CtsVerifier/Android.mk
+++ /dev/null
@@ -1,44 +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.
-#
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-#
-# Creates a "cts-verifier" directory that will contain:
-#
-# 1. Out directory with a "android-cts-verifier" containing the CTS Verifier
-#    and other binaries it needs.
-#
-# 2. Zipped version of the android-cts-verifier directory to be included with
-#    the build distribution.
-#
-cts-dir := $(HOST_OUT)/cts-verifier
-verifier-dir-name := android-cts-verifier
-verifier-dir := $(cts-dir)/$(verifier-dir-name)
-verifier-zip-name := $(verifier-dir-name).zip
-verifier-zip := $(cts-dir)/$(verifier-zip-name)
-
-cts : $(verifier-zip)
-$(verifier-zip): PRIVATE_DIR := $(cts-dir)
-$(verifier-zip): $(SOONG_ANDROID_CTS_VERIFIER_ZIP)
-	rm -rf $(PRIVATE_DIR)
-	mkdir -p $(PRIVATE_DIR)
-	unzip -q -d $(PRIVATE_DIR) $<
-	$(copy-file-to-target)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/build/Android.mk b/build/Android.mk
deleted file mode 100644
index 3c065c8..0000000
--- a/build/Android.mk
+++ /dev/null
@@ -1,160 +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.
-#
-
-# Makefile for producing CTS coverage reports.
-# Run "make cts-test-coverage" in the $ANDROID_BUILD_TOP directory.
-
-cts_api_coverage_exe := $(HOST_OUT_EXECUTABLES)/cts-api-coverage
-dexdeps_exe := $(HOST_OUT_EXECUTABLES)/dexdeps
-
-coverage_out := $(HOST_OUT)/cts-api-coverage
-
-api_xml_description := $(TARGET_OUT_COMMON_INTERMEDIATES)/api.xml
-
-napi_text_description := cts/tools/cts-api-coverage/etc/ndk-api.xml
-napi_xml_description := $(coverage_out)/ndk-api.xml
-$(napi_xml_description) : $(napi_text_description) $(ACP)
-		$(hide) echo "Preparing NDK API XML: $@"
-		$(hide) mkdir -p $(dir $@)
-		$(hide) $(ACP)  $< $@
-
-system_api_xml_description := $(TARGET_OUT_COMMON_INTERMEDIATES)/system-api.xml
-
-cts-test-coverage-report := $(coverage_out)/test-coverage.html
-cts-system-api-coverage-report := $(coverage_out)/system-api-coverage.html
-cts-system-api-xml-coverage-report := $(coverage_out)/system-api-coverage.xml
-cts-verifier-coverage-report := $(coverage_out)/verifier-coverage.html
-cts-combined-coverage-report := $(coverage_out)/combined-coverage.html
-cts-combined-xml-coverage-report := $(coverage_out)/combined-coverage.xml
-
-cts_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(api_xml_description) $(napi_xml_description)
-cts_system_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(system_api_xml_description)
-
-android_cts_zip := $(HOST_OUT)/cts/android-cts.zip
-cts_verifier_apk := $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk
-
-$(cts-test-coverage-report): PRIVATE_TEST_CASES := $(COMPATIBILITY_TESTCASES_OUT_cts)
-$(cts-test-coverage-report): PRIVATE_CTS_API_COVERAGE_EXE := $(cts_api_coverage_exe)
-$(cts-test-coverage-report): PRIVATE_DEXDEPS_EXE := $(dexdeps_exe)
-$(cts-test-coverage-report): PRIVATE_API_XML_DESC := $(api_xml_description)
-$(cts-test-coverage-report): PRIVATE_NAPI_XML_DESC := $(napi_xml_description)
-$(cts-test-coverage-report) : $(android_cts_zip) $(cts_api_coverage_dependencies) | $(ACP)
-	$(call generate-coverage-report-cts,"CTS Tests API-NDK Coverage Report",\
-			$(PRIVATE_TEST_CASES),html)
-
-$(cts-system-api-coverage-report): PRIVATE_TEST_CASES := $(COMPATIBILITY_TESTCASES_OUT_cts)
-$(cts-system-api-coverage-report): PRIVATE_CTS_API_COVERAGE_EXE := $(cts_api_coverage_exe)
-$(cts-system-api-coverage-report): PRIVATE_DEXDEPS_EXE := $(dexdeps_exe)
-$(cts-system-api-coverage-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-system-api-coverage-report): PRIVATE_NAPI_XML_DESC := ""
-$(cts-system-api-coverage-report) : $(android_cts_zip) $(cts_system_api_coverage_dependencies) | $(ACP)
-	$(call generate-coverage-report-cts,"CTS System API Coverage Report",\
-			$(PRIVATE_TEST_CASES),html)
-
-$(cts-system-api-xml-coverage-report): PRIVATE_TEST_CASES := $(COMPATIBILITY_TESTCASES_OUT_cts)
-$(cts-system-api-xml-coverage-report): PRIVATE_CTS_API_COVERAGE_EXE := $(cts_api_coverage_exe)
-$(cts-system-api-xml-coverage-report): PRIVATE_DEXDEPS_EXE := $(dexdeps_exe)
-$(cts-system-api-xml-coverage-report): PRIVATE_API_XML_DESC := $(system_api_xml_description)
-$(cts-system-api-xml-coverage-report): PRIVATE_NAPI_XML_DESC := ""
-$(cts-system-api-xml-coverage-report) : $(android_cts_zip) $(cts_system_api_coverage_dependencies) | $(ACP)
-	$(call generate-coverage-report-cts,"CTS System API Coverage Report - XML",\
-			$(PRIVATE_TEST_CASES),xml)
-
-$(cts-verifier-coverage-report): PRIVATE_TEST_CASES := $(cts_verifier_apk)
-$(cts-verifier-coverage-report): PRIVATE_CTS_API_COVERAGE_EXE := $(cts_api_coverage_exe)
-$(cts-verifier-coverage-report): PRIVATE_DEXDEPS_EXE := $(dexdeps_exe)
-$(cts-verifier-coverage-report): PRIVATE_API_XML_DESC := $(api_xml_description)
-$(cts-verifier-coverage-report): PRIVATE_NAPI_XML_DESC := $(napi_xml_description)
-$(cts-verifier-coverage-report) : $(cts_verifier_apk) $(cts_api_coverage_dependencies) | $(ACP)
-	$(call generate-coverage-report-cts,"CTS Verifier API Coverage Report",\
-			$(PRIVATE_TEST_CASES),html)
-
-$(cts-combined-coverage-report): PRIVATE_TEST_CASES := $(foreach c, $(cts_verifier_apk) $(COMPATIBILITY_TESTCASES_OUT_cts), $(c))
-$(cts-combined-coverage-report): PRIVATE_CTS_API_COVERAGE_EXE := $(cts_api_coverage_exe)
-$(cts-combined-coverage-report): PRIVATE_DEXDEPS_EXE := $(dexdeps_exe)
-$(cts-combined-coverage-report): PRIVATE_API_XML_DESC := $(api_xml_description)
-$(cts-combined-coverage-report): PRIVATE_NAPI_XML_DESC := $(napi_xml_description)
-$(cts-combined-coverage-report) : $(android_cts_zip) $(cts_verifier_apk) $(cts_api_coverage_dependencies) | $(ACP)
-	$(call generate-coverage-report-cts,"CTS Combined API Coverage Report",\
-			$(PRIVATE_TEST_CASES),html)
-
-$(cts-combined-xml-coverage-report): PRIVATE_TEST_CASES := $(foreach c, $(cts_verifier_apk) $(COMPATIBILITY_TESTCASES_OUT_cts), $(c))
-$(cts-combined-xml-coverage-report): PRIVATE_CTS_API_COVERAGE_EXE := $(cts_api_coverage_exe)
-$(cts-combined-xml-coverage-report): PRIVATE_DEXDEPS_EXE := $(dexdeps_exe)
-$(cts-combined-xml-coverage-report): PRIVATE_API_XML_DESC := $(api_xml_description)
-$(cts-combined-xml-coverage-report): PRIVATE_NAPI_XML_DESC := $(napi_xml_description)
-$(cts-combined-xml-coverage-report) : $(android_cts_zip) $(cts_verifier_apk) $(cts_api_coverage_dependencies) | $(ACP)
-	$(call generate-coverage-report-cts,"CTS Combined API Coverage Report - XML",\
-			$(PRIVATE_TEST_CASES),xml)
-
-.PHONY: cts-test-coverage
-cts-test-coverage : $(cts-test-coverage-report)
-
-.PHONY: cts-system-api-coverage
-cts-system-api-coverage : $(cts-system-api-coverage-report)
-
-.PHONY: cts-system-api-xml-coverage
-cts-system-api-xml-coverage : $(cts-system-api-xml-coverage-report)
-
-.PHONY: cts-verifier-coverage
-cts-verifier-coverage : $(cts-verifier-coverage-report)
-
-.PHONY: cts-combined-coverage
-cts-combined-coverage : $(cts-combined-coverage-report)
-
-.PHONY: cts-combined-xml-coverage
-cts-combined-xml-coverage : $(cts-combined-xml-coverage-report)
-
-.PHONY: cts-coverage-report-all cts-api-coverage
-cts-coverage-report-all: cts-test-coverage cts-verifier-coverage cts-combined-coverage cts-combined-xml-coverage
-
-# Put the test coverage report in the dist dir if "cts-api-coverage" is among the build goals.
-$(call dist-for-goals, cts-api-coverage, $(cts-test-coverage-report):cts-test-coverage-report.html)
-$(call dist-for-goals, cts-api-coverage, $(cts-system-api-coverage-report):cts-system-api-coverage-report.html)
-$(call dist-for-goals, cts-api-coverage, $(cts-system-api-xml-coverage-report):cts-system-api-coverage-report.xml)
-$(call dist-for-goals, cts-api-coverage, $(cts-verifier-coverage-report):cts-verifier-coverage-report.html)
-$(call dist-for-goals, cts-api-coverage, $(cts-combined-coverage-report):cts-combined-coverage-report.html)
-$(call dist-for-goals, cts-api-coverage, $(cts-combined-xml-coverage-report):cts-combined-coverage-report.xml)
-
-# Arguments;
-#  1 - Name of the report printed out on the screen
-#  2 - List of apk files that will be scanned to generate the report
-#  3 - Format of the report
-define generate-coverage-report-cts
-	$(hide) mkdir -p $(dir $@)
-	$(hide) $(PRIVATE_CTS_API_COVERAGE_EXE) -d $(PRIVATE_DEXDEPS_EXE) -a $(PRIVATE_API_XML_DESC) -n $(PRIVATE_NAPI_XML_DESC) -f $(3) -o $@ $(2)
-	@ echo $(1): file://$$(cd $(dir $@); pwd)/$(notdir $@)
-endef
-
-# Reset temp vars
-cts_api_coverage_dependencies :=
-cts_system_api_coverage_dependencies :=
-cts-combined-coverage-report :=
-cts-combined-xml-coverage-report :=
-cts-verifier-coverage-report :=
-cts-test-coverage-report :=
-cts-system-api-coverage-report :=
-cts-system-api-xml-coverage-report :=
-api_xml_description :=
-api_text_description :=
-system_api_xml_description :=
-napi_xml_description :=
-napi_text_description :=
-coverage_out :=
-dexdeps_exe :=
-cts_api_coverage_exe :=
-cts_verifier_apk :=
-android_cts_zip :=
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/LocaleDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/LocaleDeviceInfo.java
index 7a5dfb8..bf2b551 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/LocaleDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/LocaleDeviceInfo.java
@@ -16,6 +16,7 @@
 package com.android.compatibility.common.deviceinfo;
 
 import android.icu.util.ULocale;
+import android.icu.util.VersionInfo;
 import android.util.Log;
 import androidx.annotation.Nullable;
 import com.android.compatibility.common.util.DeviceInfoStore;
@@ -31,6 +32,7 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Locale device info collector.
@@ -66,35 +68,49 @@
      * /apex/com.android.i18n/etc/icu/icudt65l.dat
      */
     private void collectLocaleDataFilesInfo(DeviceInfoStore store) throws IOException {
+        int icuVersion = VersionInfo.ICU_VERSION.getMajor();
+        File[] fixedDatPaths = new File[] {
+                new File("/apex/com.android.tzdata/etc/icu/icu_tzdata.dat"),
+                new File("/apex/com.android.i18n/etc/icu/icudt" + icuVersion + "l.dat"),
+        };
+
+        // This property has been deprecated since Android 12. The property will not work if this
+        // app targets SDK level 31 or higher. Thus, we add the above fixedDatPaths in case that
+        // the property is not working. When this comment was written, this CTS app still targets
+        // SDK level 23.
         String prop = System.getProperty("android.icu.impl.ICUBinary.dataPath");
         store.startArray("icu_data_file_info");
+
+        List<File> datFiles = new ArrayList<>();
         if (prop != null) {
             String[] dataDirs = prop.split(":");
-            // List all readable ".dat" files in the directories.
-            List<File> datFiles = Arrays.stream(dataDirs)
+            // List all ".dat" files in the directories.
+            datFiles = Arrays.stream(dataDirs)
                 .filter((dir) -> dir != null && !dir.isEmpty())
                 .map((dir) -> new File(dir))
                 .filter((f) -> f.canRead() && f.isDirectory())
                 .map((f) -> f.listFiles())
                 .filter((files) -> files != null)
-                .map((files) -> Arrays.asList(files))
-                .reduce(new ArrayList<>(), (l1, l2) -> {
-                    l1.addAll(l2);
-                    return l1;
-                })
-                .stream()
-                .filter((f) -> f != null && f.canRead() && f.getName().endsWith(".dat"))
+                .flatMap(files -> Stream.of(files))
                 .collect(Collectors.toList());
+        }
 
-            for (File datFile : datFiles) {
-                String sha256Hash = sha256(datFile);
+        datFiles.addAll(Arrays.asList(fixedDatPaths));
 
-                store.startGroup();
-                store.addResult("file_path", datFile.getPath());
-                // Still store the null hash to indicate an error occurring when obtaining the hash.
-                store.addResult("file_sha256", sha256Hash);
-                store.endGroup();
-            }
+        // Keep the readable paths only.
+        datFiles = datFiles.stream()
+            .distinct()
+            .filter((f) -> f != null && f.canRead() && f.getName().endsWith(".dat"))
+            .collect(Collectors.toList());
+
+        for (File datFile : datFiles) {
+            String sha256Hash = sha256(datFile);
+
+            store.startGroup();
+            store.addResult("file_path", datFile.getPath());
+            // Still store the null hash to indicate an error occurring when obtaining the hash.
+            store.addResult("file_sha256", sha256Hash);
+            store.endGroup();
         }
         store.endArray();
     }
diff --git a/hostsidetests/angle/Android.bp b/hostsidetests/angle/Android.bp
index 794ea69..47ce8e0 100644
--- a/hostsidetests/angle/Android.bp
+++ b/hostsidetests/angle/Android.bp
@@ -20,7 +20,6 @@
     name: "CtsAngleIntegrationHostTestCases",
     defaults: ["cts_defaults"],
     srcs: ["src/**/*.java"],
-    java_resource_dirs: ["assets/"],
     // tag this module as a cts test artifact
     test_suites: [
         "cts",
diff --git a/hostsidetests/angle/assets/emptyRules.json b/hostsidetests/angle/assets/emptyRules.json
deleted file mode 100644
index 77fa0c0..0000000
--- a/hostsidetests/angle/assets/emptyRules.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "Rules":[
-    {
-      "Rule":"Default Rule (i.e. use native driver)",
-      "UseANGLE":false
-    }
-  ]
-}
diff --git a/hostsidetests/angle/assets/enableAngleRules.json b/hostsidetests/angle/assets/enableAngleRules.json
deleted file mode 100644
index 90f4893..0000000
--- a/hostsidetests/angle/assets/enableAngleRules.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "Rules":[
-    {
-      "Rule":"Default Rule (i.e. use native driver)",
-      "UseANGLE":false
-    },
-    {
-      "Rule":"Supported application(s) (e.g. Maps on Google devices)",
-      "UseANGLE":true,
-      "Applications":[
-        {
-          "AppName":"com.android.angleIntegrationTest.driverTest"
-        }
-      ]
-    }
-  ]
-}
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
index 45bb43e..3fb5c6c 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
@@ -55,7 +55,6 @@
             ANGLE_DRIVER_TEST_PKG + "/com.android.angleIntegrationTest.common.AngleIntegrationTestActivity";
     static final String ANGLE_DRIVER_TEST_SEC_ACTIVITY =
             ANGLE_DRIVER_TEST_SEC_PKG + "/com.android.angleIntegrationTest.common.AngleIntegrationTestActivity";
-    static final String ANGLE_MAIN_ACTIVTY = "android.app.action.ANGLE_FOR_ANDROID";
 
     enum OpenGlDriverChoice {
         DEFAULT,
@@ -116,12 +115,6 @@
         return (driverProp != null) && (driverProp.equals("angle"));
     }
 
-    static void startActivity(ITestDevice device, String action) throws Exception {
-        // Run the ANGLE activity so it'll clear up any 'default' settings.
-        device.executeShellCommand("am start --user " + device.getCurrentUser() +
-                " -S -W -a \"" + action + "\"");
-    }
-
     static void stopPackage(ITestDevice device, String pkgName) throws Exception {
         device.executeShellCommand("am force-stop " + pkgName);
     }
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
index 9431088..12770b1 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
@@ -62,8 +62,6 @@
 
         setAndValidateAngleDevOptionPkgDriver(pkgName, sDriverGlobalSettingMap.get(driver));
 
-        startActivity(getDevice(), ANGLE_MAIN_ACTIVTY);
-
         CLog.logAndDisplay(LogLevel.INFO, "Validating driver selection (" +
                 driver + ") with method '" + sDriverTestMethodMap.get(driver) + "'");
 
@@ -288,8 +286,6 @@
                         sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE) + "," +
                                 sDriverGlobalSettingMap.get(firstDriver));
 
-                startActivity(getDevice(), ANGLE_MAIN_ACTIVTY);
-
                 CLog.logAndDisplay(LogLevel.INFO, "Validating driver selection (" +
                         firstDriver + ") with method '" + sDriverTestMethodMap.get(firstDriver) + "'");
 
@@ -302,8 +298,6 @@
                         sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE) + "," +
                                 sDriverGlobalSettingMap.get(secondDriver));
 
-                startActivity(getDevice(), ANGLE_MAIN_ACTIVTY);
-
                 CLog.logAndDisplay(LogLevel.INFO, "Validating driver selection (" +
                         secondDriver + ") with method '" + sDriverTestMethodMap.get(secondDriver) + "'");
 
@@ -311,9 +305,6 @@
                         ANGLE_DRIVER_TEST_SEC_PKG + "." + ANGLE_DRIVER_TEST_CLASS,
                         sDriverTestMethodMap.get(secondDriver));
 
-                // Make sure the first PKG's driver value was not modified
-                startActivity(getDevice(), ANGLE_MAIN_ACTIVTY);
-
                 String devOptionPkg = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_DRIVER_PKGS);
                 String devOptionValue = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_DRIVER_VALUES);
                 CLog.logAndDisplay(LogLevel.INFO, "Validating: PKG name = '" +
@@ -327,129 +318,6 @@
     }
 
     /**
-     * Test setting a driver to 'default' does not keep the value in the settings when the ANGLE
-     * activity runs and cleans things up.
-     */
-    @Test
-    public void testDefaultNotInSettings() throws Exception {
-        Assume.assumeTrue(isAngleLoadable(getDevice()));
-
-        // Install the package so the setting isn't removed because the package isn't present.
-        installApp(ANGLE_DRIVER_TEST_APP);
-
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DRIVER_TEST_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.DEFAULT));
-
-        // Run the ANGLE activity so it'll clear up any 'default' settings.
-        startActivity(getDevice(), ANGLE_MAIN_ACTIVTY);
-
-        String devOptionPkg = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_DRIVER_PKGS);
-        String devOptionValue = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_DRIVER_VALUES);
-        CLog.logAndDisplay(LogLevel.INFO, "Validating: PKG name = '" +
-                devOptionPkg + "', driver value = '" + devOptionValue + "'");
-
-        Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOptionPkg + "'",
-                "", devOptionPkg);
-        Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOptionValue + "'",
-                "", devOptionValue);
-    }
-
-    /**
-     * Test uninstalled PKGs have their settings removed.
-     */
-    @Test
-    public void testUninstalledPkgsNotInSettings() throws Exception {
-        Assume.assumeTrue(isAngleLoadable(getDevice()));
-
-        uninstallPackage(getDevice(), ANGLE_DRIVER_TEST_PKG);
-
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DRIVER_TEST_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.NATIVE));
-
-        // Run the ANGLE activity so it'll clear up any 'default' settings.
-        startActivity(getDevice(), ANGLE_MAIN_ACTIVTY);
-
-        String devOptionPkg = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_DRIVER_PKGS);
-        String devOptionValue = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_DRIVER_VALUES);
-        CLog.logAndDisplay(LogLevel.INFO, "Validating: PKG name = '" +
-                devOptionPkg + "', driver value = '" + devOptionValue + "'");
-
-        Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOptionPkg + "'",
-                "", devOptionPkg);
-        Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOptionValue + "'",
-                "", devOptionValue);
-    }
-
-    /**
-     * Test different PKGs can have different developer option values.
-     * Primary: ANGLE
-     * Secondary: Default
-     *
-     * Verify the PKG set to 'default' is removed from the settings.
-     */
-    @Test
-    public void testMultipleDevOptionsAngleDefault() throws Exception {
-        Assume.assumeTrue(isAngleLoadable(getDevice()));
-
-        installApp(ANGLE_DRIVER_TEST_APP);
-        installApp(ANGLE_DRIVER_TEST_SEC_APP);
-
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DRIVER_TEST_PKG + "," + ANGLE_DRIVER_TEST_SEC_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE) + "," +
-                        sDriverGlobalSettingMap.get(OpenGlDriverChoice.DEFAULT));
-
-        // Run the ANGLE activity so it'll clear up any 'default' settings.
-        startActivity(getDevice(), ANGLE_MAIN_ACTIVTY);
-
-        String devOption = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_DRIVER_PKGS);
-        Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOption + "'",
-                ANGLE_DRIVER_TEST_PKG, devOption);
-
-        devOption = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_DRIVER_VALUES);
-        Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOption + "'",
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE), devOption);
-    }
-
-    /**
-     * Test different PKGs can have different developer option values.
-     * Primary: ANGLE
-     * Secondary: Default
-     *
-     * Verify the uninstalled PKG is removed from the settings.
-     */
-    @Test
-    public void testMultipleDevOptionsAngleNativeUninstall() throws Exception {
-        Assume.assumeTrue(isAngleLoadable(getDevice()));
-
-        installApp(ANGLE_DRIVER_TEST_SEC_APP);
-
-        setAndValidateAngleDevOptionPkgDriver(ANGLE_DRIVER_TEST_PKG + "," + ANGLE_DRIVER_TEST_SEC_PKG,
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.ANGLE) + "," +
-                        sDriverGlobalSettingMap.get(OpenGlDriverChoice.NATIVE));
-
-        // Run the ANGLE activity so it'll clear up any 'default' settings.
-        startActivity(getDevice(), ANGLE_MAIN_ACTIVTY);
-
-        String devOptionPkg = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_DRIVER_PKGS);
-        String devOptionValue = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_DRIVER_VALUES);
-        CLog.logAndDisplay(LogLevel.INFO, "Validating: PKG name = '" +
-                devOptionPkg + "', driver value = '" + devOptionValue + "'");
-
-        Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_PKGS + " = '" + devOptionPkg + "'",
-                ANGLE_DRIVER_TEST_SEC_PKG, devOptionPkg);
-        Assert.assertEquals(
-                "Invalid developer option: " + SETTINGS_GLOBAL_DRIVER_VALUES + " = '" + devOptionValue + "'",
-                sDriverGlobalSettingMap.get(OpenGlDriverChoice.NATIVE), devOptionValue);
-    }
-
-    /**
      * Test that the "ANGLE In Use" dialog box can be enabled when ANGLE is used.
      *
      * We can't actually make sure the dialog box shows up, just that enabling it and attempting to
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
deleted file mode 100644
index 4f0859e..0000000
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
+++ /dev/null
@@ -1,132 +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.angle.cts;
-
-import static android.angle.cts.CtsAngleCommon.*;
-
-import com.google.common.io.ByteStreams;
-import com.google.common.io.Files;
-
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import com.android.tradefed.util.FileUtil;
-
-import java.io.File;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.runner.RunWith;
-import org.junit.Test;
-
-/**
- * Tests ANGLE Rules File Opt-In/Out functionality.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class CtsAngleRulesFileTest extends BaseHostJUnit4Test {
-
-    private final String TAG = this.getClass().getSimpleName();
-
-    private File mRulesFile;
-    private String mAllowList;
-
-    // Rules Files
-    private static final String RULES_FILE_EMPTY = "emptyRules.json";
-    private static final String RULES_FILE_ENABLE_ANGLE = "enableAngleRules.json";
-
-    private void pushRulesFile(String hostFilename) throws Exception {
-        byte[] rulesFileBytes =
-                ByteStreams.toByteArray(getClass().getResourceAsStream("/" + hostFilename));
-
-        Assert.assertTrue("Loaded empty rules file", rulesFileBytes.length > 0); // validity check
-        mRulesFile = File.createTempFile("rulesFile", "tempRules.json");
-        Files.write(rulesFileBytes, mRulesFile);
-
-        Assert.assertTrue(getDevice().pushFile(mRulesFile, DEVICE_TEMP_RULES_FILE_PATH));
-
-        setProperty(getDevice(), PROPERTY_TEMP_RULES_FILE, DEVICE_TEMP_RULES_FILE_PATH);
-    }
-
-    private void setAndValidateAngleDevOptionAllowlist(String allowList) throws Exception {
-        // SETTINGS_GLOBAL_ALLOWLIST
-        setGlobalSetting(getDevice(), SETTINGS_GLOBAL_ALLOWLIST, allowList);
-
-        String devOption = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_ALLOWLIST);
-        Assert.assertEquals(
-            "Developer option '" + SETTINGS_GLOBAL_ALLOWLIST +
-                "' was not set correctly: '" + devOption + "'",
-            allowList, devOption);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        clearSettings(getDevice());
-
-        mAllowList = getGlobalSetting(getDevice(), SETTINGS_GLOBAL_ALLOWLIST);
-
-        final String allowlist = ANGLE_DRIVER_TEST_PKG + "," + ANGLE_DRIVER_TEST_SEC_PKG;
-        setAndValidateAngleDevOptionAllowlist(allowlist);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        clearSettings(getDevice());
-
-        setAndValidateAngleDevOptionAllowlist(mAllowList);
-
-        FileUtil.deleteFile(mRulesFile);
-    }
-
-    /**
-     * Test ANGLE is not loaded when an empty rules file is used.
-     */
-    @Test
-    public void testEmptyRulesFile() throws Exception {
-        Assume.assumeTrue(isAngleLoadable(getDevice()));
-        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
-
-        pushRulesFile(RULES_FILE_EMPTY);
-
-        installPackage(ANGLE_DRIVER_TEST_APP);
-
-        runDeviceTests(ANGLE_DRIVER_TEST_PKG,
-                ANGLE_DRIVER_TEST_PKG + "." + ANGLE_DRIVER_TEST_CLASS,
-                ANGLE_DRIVER_TEST_NATIVE_METHOD);
-    }
-
-    /**
-     * Test ANGLE is loaded for only the PKG the rules file specifies.
-     */
-    @Test
-    public void testEnableAngleRulesFile() throws Exception {
-        Assume.assumeTrue(isAngleLoadable(getDevice()));
-        Assume.assumeFalse(isNativeDriverAngle(getDevice()));
-
-        pushRulesFile(RULES_FILE_ENABLE_ANGLE);
-
-        installPackage(ANGLE_DRIVER_TEST_APP);
-        installPackage(ANGLE_DRIVER_TEST_SEC_APP);
-
-        runDeviceTests(ANGLE_DRIVER_TEST_PKG,
-                ANGLE_DRIVER_TEST_PKG + "." + ANGLE_DRIVER_TEST_CLASS,
-                ANGLE_DRIVER_TEST_ANGLE_METHOD);
-
-        runDeviceTests(ANGLE_DRIVER_TEST_SEC_PKG,
-                ANGLE_DRIVER_TEST_SEC_PKG + "." + ANGLE_DRIVER_TEST_CLASS,
-                ANGLE_DRIVER_TEST_NATIVE_METHOD);
-    }
-}
diff --git a/hostsidetests/apex/src/android/apex/cts/ApexTest.java b/hostsidetests/apex/src/android/apex/cts/ApexTest.java
index 91920ad..4f7c43b 100644
--- a/hostsidetests/apex/src/android/apex/cts/ApexTest.java
+++ b/hostsidetests/apex/src/android/apex/cts/ApexTest.java
@@ -46,7 +46,9 @@
             || systemProduct.equals("aosp_x86")
             || systemProduct.equals("aosp_x86_64")
             || systemProduct.equals("aosp_tv_arm")
-            || systemProduct.equals("aosp_tv_arm64"));
+            || systemProduct.equals("aosp_tv_arm64")
+            || systemProduct.equals("aosp_car_arm")
+            || systemProduct.equals("aosp_car_arm64"));
   }
 
   /**
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppDataIsolationTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppDataIsolationTests.java
index 3059821..d090493 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppDataIsolationTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppDataIsolationTests.java
@@ -56,8 +56,8 @@
             "testAppADeDataDoesNotExist";
     private static final String APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE =
             "testAppACurProfileDataAccessible";
-    private static final String APPA_METHOD_CHECK_REF_PROFILE_NOT_ACCESSIBLE =
-            "testAppARefProfileDataNotAccessible";
+    private static final String APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE =
+            "testAppARefProfileDataAccessible";
     private static final String APPA_METHOD_UNLOCK_DEVICE_AND_VERIFY_CE_DE_EXTERNAL_EXIST =
             "testAppAUnlockDeviceAndVerifyCeDeExternalDataExist";
     private static final String APPA_METHOD_CANNOT_ACCESS_APPB_DIR = "testCannotAccessAppBDataDir";
@@ -133,7 +133,7 @@
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS);
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST);
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE);
-        runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_NOT_ACCESSIBLE);
+        runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE);
 
         // Force stop and verify CE, DE and external storage contains data, cur profile is
         // accessible and ref profile is not accessible, to confirm it's binding back the same data
@@ -143,7 +143,7 @@
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS);
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST);
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE);
-        runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_NOT_ACCESSIBLE);
+        runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE);
     }
 
     @Test
@@ -164,7 +164,7 @@
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS);
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST);
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE);
-        runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_NOT_ACCESSIBLE);
+        runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE);
 
         // Reboot and verify CE, DE and external storage contains data, cur profile is accessible
         // and ref profile is not accessible
@@ -173,7 +173,7 @@
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS);
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST);
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE);
-        runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_NOT_ACCESSIBLE);
+        runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE);
     }
 
     private boolean isFbeModeEmulated() throws Exception {
@@ -212,7 +212,7 @@
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS);
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST);
         runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE);
-        runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_NOT_ACCESSIBLE);
+        runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE);
 
         try {
             // Setup screenlock
@@ -243,7 +243,7 @@
             runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_DOES_NOT_EXIST);
             runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_UNAVAILABLE);
             runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE);
-            runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_NOT_ACCESSIBLE);
+            runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE);
             // Verify cannot access other apps data
             runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CANNOT_ACCESS_APPB_DIR);
 
@@ -258,7 +258,7 @@
             runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS);
             runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST);
             runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE);
-            runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_NOT_ACCESSIBLE);
+            runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE);
         } finally {
             try {
                 // Always try to unlock first, then clear screenlock setting
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ListeningPortsTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ListeningPortsTest.java
index 3e78032..cfd0b8b 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ListeningPortsTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ListeningPortsTest.java
@@ -232,7 +232,8 @@
      */
     private String parse(String procFilePath) throws IOException, DeviceNotAvailableException {
         File procFile = File.createTempFile("ListeningPortsTest", "tmp");
-        getDevice().pullFile(procFilePath, procFile);
+        boolean result = getDevice().pullFile(procFilePath, procFile);
+        assertTrue("failed to pull " + procFilePath, result);
         procFile.deleteOnExit();
 
         Scanner scanner = null;
diff --git a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java
index c25d3d9..ca28ad8 100644
--- a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java
+++ b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/AppATests.java
@@ -178,8 +178,9 @@
     }
 
     @Test
-    public void testAppARefProfileDataNotAccessible() {
-        assertDirIsNotAccessible("/data/misc/profiles/ref");
+    public void testAppARefProfileDataAccessible() {
+        assertDirIsAccessible("/data/misc/profiles/ref/"
+                + mContext.getPackageName());
     }
 
     @Test
@@ -190,7 +191,7 @@
         assertDirDoesNotExist(applicationInfo.deviceProtectedDataDir);
         assertDirDoesNotExist("/data/data/" + APPB_PKG);
         assertDirDoesNotExist("/data/misc/profiles/cur/" + getCurrentUserId() + "/" + APPB_PKG);
-        assertDirIsNotAccessible("/data/misc/profiles/ref");
+        assertDirDoesNotExist("/data/misc/profiles/ref/" + APPB_PKG);
     }
 
     @Test
@@ -253,7 +254,7 @@
         testAppADeDataExists();
         testAppAExternalDirsDoExist();
         testAppACurProfileDataAccessible();
-        testAppARefProfileDataNotAccessible();
+        testAppARefProfileDataAccessible();
 
         // Verify after unlocking device, app a has still no access to app b dir.
         testCannotAccessAppBDataDir();
diff --git a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/IsolatedService.java b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/IsolatedService.java
index d209a42..9319c38 100644
--- a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/IsolatedService.java
+++ b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppA/src/com/android/cts/appdataisolation/appa/IsolatedService.java
@@ -36,6 +36,7 @@
         public void assertDataIsolated() throws RemoteException {
             try {
                 ApplicationInfo applicationInfo = getApplicationInfo();
+
                 assertDirDoesNotExist(applicationInfo.dataDir);
                 assertDirDoesNotExist(applicationInfo.deviceProtectedDataDir);
                 assertDirDoesNotExist("/data/data/" + getPackageName());
@@ -43,7 +44,6 @@
                 int currentUserId = getCurrentUserId();
                 assertDirDoesNotExist("/data/misc/profiles/cur/" + currentUserId + "/"
                         + getPackageName());
-                assertDirIsNotAccessible("/data/misc/profiles/ref");
 
                 assertDirDoesNotExist(FileUtils.replacePackageAWithPackageB(
                         applicationInfo.dataDir));
@@ -52,6 +52,7 @@
                 assertDirDoesNotExist("/data/data/" + FileUtils.APPB_PKG);
                 assertDirDoesNotExist("/data/misc/profiles/cur/" + currentUserId + "/"
                         + FileUtils.APPB_PKG);
+                assertDirDoesNotExist("/data/misc/profiles/ref/" + FileUtils.APPB_PKG);
 
                 assertDirDoesNotExist(FileUtils.replacePackageAWithNotInstalledPkg(
                         applicationInfo.dataDir));
@@ -60,6 +61,8 @@
                 assertDirDoesNotExist("/data/data/" + FileUtils.NOT_INSTALLED_PKG);
                 assertDirDoesNotExist("/data/misc/profiles/cur/" + currentUserId + "/"
                         + FileUtils.NOT_INSTALLED_PKG);
+                assertDirDoesNotExist("/data/misc/profiles/ref/"
+                        + FileUtils.NOT_INSTALLED_PKG);
             } catch (Throwable e) {
                 throw new IllegalStateException(e.getMessage());
             }
diff --git a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppB/src/com/android/cts/appdataisolation/appb/AppBTests.java b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppB/src/com/android/cts/appdataisolation/appb/AppBTests.java
index 41ca80d..05a10be 100644
--- a/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppB/src/com/android/cts/appdataisolation/appb/AppBTests.java
+++ b/hostsidetests/appsecurity/test-apps/AppDataIsolationTestApp/AppB/src/com/android/cts/appdataisolation/appb/AppBTests.java
@@ -52,7 +52,7 @@
         assertDirDoesNotExist("/data/data/" + APPA_PKG);
         assertDirDoesNotExist("/data/misc/profiles/cur/" + getCurrentUserId() + "/"
                 + APPA_PKG);
-        assertDirIsNotAccessible("/data/misc/profiles/ref");
+        assertDirDoesNotExist("/data/misc/profiles/ref/" + APPA_PKG);
     }
 
     @Test
@@ -65,7 +65,7 @@
         }
         assertFileIsAccessible("/data/misc/profiles/cur/" + getCurrentUserId() + "/"
                 + APPA_PKG + "/primary.prof");
-        assertDirIsNotAccessible("/data/misc/profiles/ref");
+        assertDirIsAccessible("/data/misc/profiles/ref/" + APPA_PKG);
     }
 
     @Test
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
index befdc0c..54bb476 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -40,6 +40,7 @@
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
 
     <application
+        android:largeHeap="true"
         android:testOnly="true">
 
         <uses-library android:name="android.test.runner" />
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/OWNERS b/hostsidetests/devicepolicy/app/SimpleApp/OWNERS
index d9a2060..0fb0c30 100644
--- a/hostsidetests/devicepolicy/app/SimpleApp/OWNERS
+++ b/hostsidetests/devicepolicy/app/SimpleApp/OWNERS
@@ -1,2 +1 @@
-ctate@google.com
-hackbod@google.com
+include platform/frameworks/base:/services/core/java/com/android/server/am/OWNERS
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
index 52f03ea..0a4b116 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/HdmiCecClientWrapper.java
@@ -353,14 +353,15 @@
 
         try {
             if (holdKey) {
-                /* Repeat once between 200ms and 450ms for at least 5 seconds. Since message will be
-                 * sent once later, send 16 times in loop every 300ms. */
-                int repeat = 16;
+                /* Repeat once every 450ms for at least 5 seconds. Send 11 times in loop every
+                 * 450ms. The message is sent once after the loop as well.
+                 * ((11 + 1) * 0.45 = 5.4s total) */
+                int repeat = 11;
                 for (int i = 0; i < repeat; i++) {
                     mOutputConsole.write(command);
                     mOutputConsole.newLine();
                     mOutputConsole.flush();
-                    TimeUnit.MILLISECONDS.sleep(300);
+                    TimeUnit.MILLISECONDS.sleep(450);
                 }
             }
 
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/RemoteControlPassthrough.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/RemoteControlPassthrough.java
new file mode 100644
index 0000000..6486313
--- /dev/null
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/RemoteControlPassthrough.java
@@ -0,0 +1,206 @@
+/*
+ * 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.hdmicec.cts;
+
+import com.android.tradefed.device.ITestDevice;
+
+/** Helper class with methods to test the remote control passthrough functionality */
+public final class RemoteControlPassthrough {
+
+    /** The package name of the APK. */
+    private static final String PACKAGE = "android.hdmicec.app";
+    /** The class name of the main activity in the APK. */
+    private static final String CLASS = "HdmiCecKeyEventCapture";
+    /** The command to launch the main activity. */
+    private static final String START_COMMAND =
+            String.format(
+                    "am start -W -a android.intent.action.MAIN -n %s/%s.%s",
+                    PACKAGE, PACKAGE, CLASS);
+    /** The command to clear the main activity. */
+    private static final String CLEAR_COMMAND = String.format("pm clear %s", PACKAGE);
+
+    /**
+     * Tests that the device responds correctly to a {@code <USER_CONTROL_PRESSED>} message followed
+     * immediately by a {@code <USER_CONTROL_RELEASED>} message.
+     */
+    public static void checkUserControlPressAndRelease(
+            HdmiCecClientWrapper hdmiCecClient,
+            ITestDevice device,
+            LogicalAddress sourceDevice,
+            LogicalAddress dutLogicalAddress)
+            throws Exception {
+        // Clear activity
+        device.executeShellCommand(CLEAR_COMMAND);
+        // Clear logcat.
+        device.executeAdbCommand("logcat", "-c");
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND);
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_UP, false);
+        LogHelper.assertLog(device, CLASS, "Short press KEYCODE_DPAD_UP");
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_DOWN, false);
+        LogHelper.assertLog(device, CLASS, "Short press KEYCODE_DPAD_DOWN");
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_LEFT, false);
+        LogHelper.assertLog(device, CLASS, "Short press KEYCODE_DPAD_LEFT");
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_RIGHT, false);
+        LogHelper.assertLog(device, CLASS, "Short press KEYCODE_DPAD_RIGHT");
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_SELECT, false);
+        LogHelper.assertLog(
+                device, CLASS, "Short press KEYCODE_DPAD_CENTER", "Short press KEYCODE_ENTER");
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_BACK, false);
+        LogHelper.assertLog(device, CLASS, "Short press KEYCODE_BACK");
+    }
+
+    /**
+     * Tests that the device responds correctly to a {@code <USER_CONTROL_PRESSED>} message for
+     * press and hold operations.
+     */
+    public static void checkUserControlPressAndHold(
+            HdmiCecClientWrapper hdmiCecClient,
+            ITestDevice device,
+            LogicalAddress sourceDevice,
+            LogicalAddress dutLogicalAddress)
+            throws Exception {
+        // Clear activity
+        device.executeShellCommand(CLEAR_COMMAND);
+        // Clear logcat.
+        device.executeAdbCommand("logcat", "-c");
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND);
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_UP, true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_UP");
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_DOWN, true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_DOWN");
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_LEFT, true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_LEFT");
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_RIGHT, true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_RIGHT");
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_SELECT, true);
+        LogHelper.assertLog(
+                device, CLASS, "Long press KEYCODE_DPAD_CENTER", "Long press KEYCODE_ENTER");
+        hdmiCecClient.sendUserControlPressAndRelease(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_BACK, true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_BACK");
+    }
+
+    /**
+     * Tests that the device responds correctly to a {@code <User Control Pressed>} message for
+     * press and hold operations when no {@code <User Control Released>} is sent.
+     */
+    public static void checkUserControlPressAndHoldWithNoRelease(
+            HdmiCecClientWrapper hdmiCecClient,
+            ITestDevice device,
+            LogicalAddress sourceDevice,
+            LogicalAddress dutLogicalAddress)
+            throws Exception {
+        // Clear activity
+        device.executeShellCommand(CLEAR_COMMAND);
+        // Clear logcat.
+        device.executeAdbCommand("logcat", "-c");
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND);
+        hdmiCecClient.sendUserControlPress(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_UP, true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_UP");
+        hdmiCecClient.sendUserControlPress(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_DOWN, true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_DOWN");
+        hdmiCecClient.sendUserControlPress(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_LEFT, true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_LEFT");
+        hdmiCecClient.sendUserControlPress(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_RIGHT, true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_RIGHT");
+        hdmiCecClient.sendUserControlPress(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_SELECT, true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_CENTER");
+        hdmiCecClient.sendUserControlPress(
+                sourceDevice, dutLogicalAddress, HdmiCecConstants.CEC_CONTROL_BACK, true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_BACK");
+    }
+
+    /**
+     * Tests that the device responds correctly to a {@code <User Control Pressed> [firstKeycode]}
+     * press and hold operation when interrupted by a {@code <User Control Pressed> [secondKeycode]}
+     * before a {@code <User Control Released> [firstKeycode]} is sent.
+     */
+    public static void checkUserControlInterruptedPressAndHoldWithNoRelease(
+            HdmiCecClientWrapper hdmiCecClient,
+            ITestDevice device,
+            LogicalAddress sourceDevice,
+            LogicalAddress dutLogicalAddress)
+            throws Exception {
+        // Clear activity
+        device.executeShellCommand(CLEAR_COMMAND);
+        // Clear logcat.
+        device.executeAdbCommand("logcat", "-c");
+        // Start the APK and wait for it to complete.
+        device.executeShellCommand(START_COMMAND);
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(
+                sourceDevice,
+                dutLogicalAddress,
+                HdmiCecConstants.CEC_CONTROL_UP,
+                HdmiCecConstants.CEC_CONTROL_BACK,
+                true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_UP");
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(
+                sourceDevice,
+                dutLogicalAddress,
+                HdmiCecConstants.CEC_CONTROL_DOWN,
+                HdmiCecConstants.CEC_CONTROL_UP,
+                true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_DOWN");
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(
+                sourceDevice,
+                dutLogicalAddress,
+                HdmiCecConstants.CEC_CONTROL_LEFT,
+                HdmiCecConstants.CEC_CONTROL_DOWN,
+                true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_LEFT");
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(
+                sourceDevice,
+                dutLogicalAddress,
+                HdmiCecConstants.CEC_CONTROL_RIGHT,
+                HdmiCecConstants.CEC_CONTROL_LEFT,
+                true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_RIGHT");
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(
+                sourceDevice,
+                dutLogicalAddress,
+                HdmiCecConstants.CEC_CONTROL_SELECT,
+                HdmiCecConstants.CEC_CONTROL_RIGHT,
+                true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_DPAD_CENTER");
+        hdmiCecClient.sendUserControlInterruptedPressAndHold(
+                sourceDevice,
+                dutLogicalAddress,
+                HdmiCecConstants.CEC_CONTROL_BACK,
+                HdmiCecConstants.CEC_CONTROL_SELECT,
+                true);
+        LogHelper.assertLog(device, CLASS, "Long press KEYCODE_BACK");
+    }
+}
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
index df03d54..120e9ac 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/audio/HdmiCecRemoteControlPassThroughTest.java
@@ -17,41 +17,26 @@
 package android.hdmicec.cts.audio;
 
 import android.hdmicec.cts.BaseHdmiCecCtsTest;
-import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
-import android.hdmicec.cts.LogHelper;
 import android.hdmicec.cts.LogicalAddress;
-import android.hdmicec.cts.RequiredPropertyRule;
-import android.hdmicec.cts.RequiredFeatureRule;
+import android.hdmicec.cts.RemoteControlPassthrough;
 
-import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
 import org.junit.Ignore;
 import org.junit.Rule;
+import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
-import org.junit.Test;
 
 @Ignore("b/162820841")
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecRemoteControlPassThroughTest extends BaseHdmiCecCtsTest {
 
-    /** The package name of the APK. */
-    private static final String PACKAGE = "android.hdmicec.app";
-
-    /** The class name of the main activity in the APK. */
-    private static final String CLASS = "HdmiCecKeyEventCapture";
-
-    /** The command to launch the main activity. */
-    private static final String START_COMMAND = String.format(
-            "am start -W -a android.intent.action.MAIN -n %s/%s.%s", PACKAGE, PACKAGE, CLASS);
-
-    /** The command to clear the main activity. */
-    private static final String CLEAR_COMMAND = String.format("pm clear %s", PACKAGE);
+    private static final int DUT_DEVICE_TYPE = HdmiCecConstants.CEC_DEVICE_TYPE_AUDIO_SYSTEM;
 
     public HdmiCecRemoteControlPassThroughTest() {
-        super(HdmiCecConstants.CEC_DEVICE_TYPE_AUDIO_SYSTEM);
+        super(DUT_DEVICE_TYPE);
     }
 
     @Rule
@@ -64,144 +49,54 @@
 
     /**
      * Test 11.2.13-1
-     * Tests that the device responds correctly to a <User Control Pressed> message followed
-     * immediately by a <User Control Released> message.
+     *
+     * <p>Tests that the device responds correctly to a {@code <User Control Pressed>} message
+     * followed immediately by a {@code <User Control Released>} message.
      */
     @Test
     public void cect_11_2_13_1_UserControlPressAndRelease() throws Exception {
-        ITestDevice device = getDevice();
-        // Clear activity
-        device.executeShellCommand(CLEAR_COMMAND);
-        // Clear logcat.
-        device.executeAdbCommand("logcat", "-c");
-        // Start the APK and wait for it to complete.
-        device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_UP, false);
-        LogHelper.assertLog(getDevice(), CLASS, "Short press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_DOWN, false);
-        LogHelper.assertLog(getDevice(), CLASS, "Short press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_LEFT, false);
-        LogHelper.assertLog(getDevice(), CLASS, "Short press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_RIGHT, false);
-        LogHelper.assertLog(getDevice(), CLASS, "Short press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_SELECT, false);
-        LogHelper.assertLog(getDevice(), CLASS, "Short press KEYCODE_DPAD_CENTER");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_BACK, false);
-        LogHelper.assertLog(getDevice(), CLASS, "Short press KEYCODE_BACK");
+        LogicalAddress dutLogicalAddress = getTargetLogicalAddress(getDevice(), DUT_DEVICE_TYPE);
+        RemoteControlPassthrough.checkUserControlPressAndRelease(
+                hdmiCecClient, getDevice(), LogicalAddress.TV, dutLogicalAddress);
     }
 
     /**
      * Test 11.2.13-2
-     * Tests that the device responds correctly to a <User Control Pressed> message for press and
-     * hold operations.
+     *
+     * <p>Tests that the device responds correctly to a {@code <User Control Pressed>} message for
+     * press and hold operations.
      */
     @Test
     public void cect_11_2_13_2_UserControlPressAndHold() throws Exception {
-        ITestDevice device = getDevice();
-        // Clear activity
-        device.executeShellCommand(CLEAR_COMMAND);
-        // Clear logcat.
-        device.executeAdbCommand("logcat", "-c");
-        // Start the APK and wait for it to complete.
-        device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_UP, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_DOWN, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_LEFT, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_RIGHT, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_SELECT, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_CENTER");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_BACK, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_BACK");
+        LogicalAddress dutLogicalAddress = getTargetLogicalAddress(getDevice(), DUT_DEVICE_TYPE);
+        RemoteControlPassthrough.checkUserControlPressAndHold(
+                hdmiCecClient, getDevice(), LogicalAddress.TV, dutLogicalAddress);
     }
 
     /**
      * Test 11.2.13-3
-     * Tests that the device responds correctly to a <User Control Pressed> message for press and
-     * hold operations when no <User Control Released> is sent.
+     *
+     * <p>Tests that the device responds correctly to a {@code <User Control Pressed>} message for
+     * press and hold operations when no {@code <User Control Released>} is sent.
      */
     @Test
     public void cect_11_2_13_3_UserControlPressAndHoldWithNoRelease() throws Exception {
-        ITestDevice device = getDevice();
-        // Clear activity
-        device.executeShellCommand(CLEAR_COMMAND);
-        // Clear logcat.
-        device.executeAdbCommand("logcat", "-c");
-        // Start the APK and wait for it to complete.
-        device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_UP, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_DOWN, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_LEFT, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_RIGHT, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_SELECT, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_CENTER");
-        hdmiCecClient.sendUserControlPress(LogicalAddress.TV, LogicalAddress.AUDIO_SYSTEM,
-                HdmiCecConstants.CEC_CONTROL_BACK, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_BACK");
+        LogicalAddress dutLogicalAddress = getTargetLogicalAddress(getDevice(), DUT_DEVICE_TYPE);
+        RemoteControlPassthrough.checkUserControlPressAndHoldWithNoRelease(
+                hdmiCecClient, getDevice(), LogicalAddress.TV, dutLogicalAddress);
     }
 
     /**
      * Test 11.2.13-4
-     * Tests that the device responds correctly to a <User Control Pressed> [firstKeycode] press
-     * and hold operation when interrupted by a <User Control Pressed> [secondKeycode] before a
-     * <User Control Released> [firstKeycode] is sent.
+     *
+     * <p>Tests that the device responds correctly to a {@code <User Control Pressed>
+     * [firstKeycode]} press and hold operation when interrupted by a {@code <User Control Pressed>
+     * [secondKeycode]} before a {@code <User Control Released> [firstKeycode]} is sent.
      */
     @Test
     public void cect_11_2_13_4_UserControlInterruptedPressAndHoldWithNoRelease() throws Exception {
-        ITestDevice device = getDevice();
-        // Clear activity
-        device.executeShellCommand(CLEAR_COMMAND);
-        // Clear logcat.
-        device.executeAdbCommand("logcat", "-c");
-        // Start the APK and wait for it to complete.
-        device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
-                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_UP,
-                HdmiCecConstants.CEC_CONTROL_BACK, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
-                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_DOWN,
-                HdmiCecConstants.CEC_CONTROL_UP, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
-                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_LEFT,
-                HdmiCecConstants.CEC_CONTROL_DOWN, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
-                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_RIGHT,
-                HdmiCecConstants.CEC_CONTROL_LEFT, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
-                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_SELECT,
-                HdmiCecConstants.CEC_CONTROL_RIGHT, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_CENTER");
-        hdmiCecClient.sendUserControlInterruptedPressAndHold(LogicalAddress.TV,
-                LogicalAddress.AUDIO_SYSTEM, HdmiCecConstants.CEC_CONTROL_BACK,
-                HdmiCecConstants.CEC_CONTROL_SELECT, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_BACK");
+        LogicalAddress dutLogicalAddress = getTargetLogicalAddress(getDevice(), DUT_DEVICE_TYPE);
+        RemoteControlPassthrough.checkUserControlInterruptedPressAndHoldWithNoRelease(
+                hdmiCecClient, getDevice(), LogicalAddress.TV, dutLogicalAddress);
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecInvalidMessagesTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecInvalidMessagesTest.java
index d6f7ca8..ce4c4a1 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecInvalidMessagesTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/common/HdmiCecInvalidMessagesTest.java
@@ -16,6 +16,10 @@
 
 package android.hdmicec.cts.common;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
 import android.hdmicec.cts.BaseHdmiCecCtsTest;
 import android.hdmicec.cts.CecMessage;
 import android.hdmicec.cts.CecOperand;
@@ -32,9 +36,6 @@
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
-import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assume.assumeTrue;
-
 /** HDMI CEC test to verify that device ignores invalid messages (Section 12) */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecInvalidMessagesTest extends BaseHdmiCecCtsTest {
@@ -55,6 +56,7 @@
     private static final String CLEAR_COMMAND = String.format("pm clear %s", PACKAGE);
 
     private LogicalAddress source;
+    private LogicalAddress targetLogicalAddress;
 
     @Rule
     public RuleChain ruleChain =
@@ -63,9 +65,10 @@
                     .around(hdmiCecClient);
 
     @Before
-    public void setup() {
+    public void setup() throws Exception {
         source = (hasDeviceType(HdmiCecConstants.CEC_DEVICE_TYPE_TV)) ? LogicalAddress.RECORDER_1
                                                                       : LogicalAddress.TV;
+        targetLogicalAddress = getTargetLogicalAddress();
     }
 
     /**
@@ -180,4 +183,62 @@
                 source, LogicalAddress.BROADCAST, HdmiCecConstants.CEC_CONTROL_UP, false);
         LogHelper.assertLogDoesNotContain(getDevice(), CLASS, "Short press KEYCODE_DPAD_UP");
     }
+
+    /**
+     * <p>Tests that the device ignores a directly addressed message {@code <GIVE_PHYSICAL_ADDRESS>}
+     * if received as a broadcast message and its source is the device's logical address
+     */
+    @Test
+    public void cect_IgnoreDirectlyAddressedFromSameSource()
+            throws Exception {
+        hdmiCecClient.sendCecMessage(
+                targetLogicalAddress, targetLogicalAddress, CecOperand.GIVE_PHYSICAL_ADDRESS);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                targetLogicalAddress, CecOperand.REPORT_PHYSICAL_ADDRESS);
+    }
+
+    /**
+     * <p>Tests that the device ignores a broadcasted message {@code <REQUEST_ACTIVE_SOURCE>} if its
+     * source has the logical address equal to device's logical address
+     */
+    @Test
+    public void cect_IgnoreBroadcastedFromSameSource()
+            throws Exception {
+        ITestDevice device = getDevice();
+        device.executeShellCommand("input keyevent KEYCODE_HOME");
+        // The device shall broadcast an <Active Source> message.
+        hdmiCecClient.checkExpectedOutput(
+                LogicalAddress.BROADCAST, CecOperand.ACTIVE_SOURCE);
+        hdmiCecClient.sendCecMessage(
+                targetLogicalAddress, LogicalAddress.BROADCAST, CecOperand.REQUEST_ACTIVE_SOURCE);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.BROADCAST, CecOperand.ACTIVE_SOURCE);
+    }
+
+    /**
+     * <p>Tests that the device ignores a directly addressed message {@code <GIVE_POWER_STATUS>} if
+     * coming from the unregistered address F. This message should only be sent from a device with
+     * an allocated logical address
+     */
+    @Test
+    public void cect_IgnoreDirectlyAddressedFromUnknownAddress_giveDevicePowerStatus()
+            throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.UNKNOWN, targetLogicalAddress, CecOperand.GIVE_POWER_STATUS);
+        hdmiCecClient.checkOutputDoesNotContainMessage(
+                LogicalAddress.UNKNOWN, CecOperand.REPORT_POWER_STATUS);
+    }
+
+    /**
+     * <p>Tests that the device process a directly addressed message {@code <GIVE_PHYSICAL_ADDRESS>}
+     * if coming from the unregistered address F
+     */
+    @Test
+    public void cect_ProcessAddressedFromUnknownAddress_givePhysicalAddress()
+            throws Exception {
+        hdmiCecClient.sendCecMessage(
+                LogicalAddress.UNKNOWN, targetLogicalAddress, CecOperand.GIVE_PHYSICAL_ADDRESS);
+        hdmiCecClient.checkExpectedOutput(
+                LogicalAddress.UNKNOWN, CecOperand.REPORT_PHYSICAL_ADDRESS);
+    }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java
index faab6e4..bc9f499 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/playback/HdmiCecRemoteControlPassThroughTest.java
@@ -17,45 +17,28 @@
 package android.hdmicec.cts.playback;
 
 import android.hdmicec.cts.BaseHdmiCecCtsTest;
-import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
-import android.hdmicec.cts.LogHelper;
 import android.hdmicec.cts.LogicalAddress;
-import android.hdmicec.cts.RequiredPropertyRule;
-import android.hdmicec.cts.RequiredFeatureRule;
+import android.hdmicec.cts.RemoteControlPassthrough;
 
-import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
 import org.junit.Rule;
+import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
-import org.junit.Test;
 
-/** HDMI CEC test to check if the device reports power status correctly (Section 11.2.13) */
+/**
+ * HDMI CEC tests to ensure that the remote control passthrough to TV works as expected (Section
+ * 11.2.13)
+ */
 @RunWith(DeviceJUnit4ClassRunner.class)
 public final class HdmiCecRemoteControlPassThroughTest extends BaseHdmiCecCtsTest {
 
-    /**
-     * The package name of the APK.
-     */
-    private static final String PACKAGE = "android.hdmicec.app";
-    /**
-     * The class name of the main activity in the APK.
-     */
-    private static final String CLASS = "HdmiCecKeyEventCapture";
-    /**
-     * The command to launch the main activity.
-     */
-    private static final String START_COMMAND = String.format(
-            "am start -W -a android.intent.action.MAIN -n %s/%s.%s", PACKAGE, PACKAGE, CLASS);
-    /**
-     * The command to clear the main activity.
-     */
-    private static final String CLEAR_COMMAND = String.format("pm clear %s", PACKAGE);
+    private static int DUT_DEVICE_TYPE = HdmiCecConstants.CEC_DEVICE_TYPE_PLAYBACK_DEVICE;
 
     public HdmiCecRemoteControlPassThroughTest() {
-        super(HdmiCecConstants.CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
+        super(DUT_DEVICE_TYPE);
     }
 
     @Rule
@@ -68,37 +51,15 @@
 
     /**
      * Test 11.2.13-1
-     * Tests that the device responds correctly to a <USER_CONTROL_PRESSED> message followed
-     * immediately by a <USER_CONTROL_RELEASED> message.
+     *
+     * <p>Tests that the device responds correctly to a {@code <USER_CONTROL_PRESSED>} message
+     * followed immediately by a {@code <USER_CONTROL_RELEASED>} message.
      */
     @Test
     public void cect_11_2_13_1_UserControlPressAndRelease() throws Exception {
-        ITestDevice device = getDevice();
-        // Clear activity
-        device.executeShellCommand(CLEAR_COMMAND);
-        // Clear logcat.
-        device.executeAdbCommand("logcat", "-c");
-        // Start the APK and wait for it to complete.
-        device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_UP, false);
-        LogHelper.assertLog(getDevice(), CLASS, "Short press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_DOWN, false);
-        LogHelper.assertLog(getDevice(), CLASS, "Short press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_LEFT, false);
-        LogHelper.assertLog(getDevice(), CLASS, "Short press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_RIGHT, false);
-        LogHelper.assertLog(getDevice(), CLASS, "Short press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_SELECT, false);
-        LogHelper.assertLog(getDevice(), CLASS,
-                "Short press KEYCODE_DPAD_CENTER", "Short press KEYCODE_ENTER");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_BACK, false);
-        LogHelper.assertLog(getDevice(), CLASS, "Short press KEYCODE_BACK");
+        LogicalAddress dutLogicalAddress = getTargetLogicalAddress(getDevice(), DUT_DEVICE_TYPE);
+        RemoteControlPassthrough.checkUserControlPressAndRelease(
+                hdmiCecClient, getDevice(), LogicalAddress.TV, dutLogicalAddress);
     }
 
     /**
@@ -108,31 +69,8 @@
      */
     @Test
     public void cect_11_2_13_2_UserControlPressAndHold() throws Exception {
-        ITestDevice device = getDevice();
-        // Clear activity
-        device.executeShellCommand(CLEAR_COMMAND);
-        // Clear logcat.
-        device.executeAdbCommand("logcat", "-c");
-        // Start the APK and wait for it to complete.
-        device.executeShellCommand(START_COMMAND);
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_UP, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_UP");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_DOWN, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_DOWN");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_LEFT, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_LEFT");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_RIGHT, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_DPAD_RIGHT");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_SELECT, true);
-        LogHelper.assertLog(getDevice(), CLASS,
-                "Long press KEYCODE_DPAD_CENTER", "Long press KEYCODE_ENTER");
-        hdmiCecClient.sendUserControlPressAndRelease(LogicalAddress.TV, LogicalAddress.PLAYBACK_1,
-                HdmiCecConstants.CEC_CONTROL_BACK, true);
-        LogHelper.assertLog(getDevice(), CLASS, "Long press KEYCODE_BACK");
+        LogicalAddress dutLogicalAddress = getTargetLogicalAddress(getDevice(), DUT_DEVICE_TYPE);
+        RemoteControlPassthrough.checkUserControlPressAndHold(
+                hdmiCecClient, getDevice(), LogicalAddress.TV, dutLogicalAddress);
     }
 }
diff --git a/hostsidetests/hdmicec/src/android/hdmicec/cts/targetprep/CecPortDiscoverer.java b/hostsidetests/hdmicec/src/android/hdmicec/cts/targetprep/CecPortDiscoverer.java
index a4aca15..4f1915a 100644
--- a/hostsidetests/hdmicec/src/android/hdmicec/cts/targetprep/CecPortDiscoverer.java
+++ b/hostsidetests/hdmicec/src/android/hdmicec/cts/targetprep/CecPortDiscoverer.java
@@ -20,6 +20,7 @@
 import android.hdmicec.cts.CecMessage;
 import android.hdmicec.cts.HdmiCecClientWrapper;
 import android.hdmicec.cts.HdmiCecConstants;
+import android.hdmicec.cts.LogicalAddress;
 import android.hdmicec.cts.error.CecClientWrapperException;
 import android.hdmicec.cts.error.ErrorCodes;
 
@@ -107,15 +108,15 @@
                 throw new TargetSetupError("No adapters connected to host.");
             }
 
-            int targetDevice =
-                    BaseHdmiCecCtsTest.getTargetLogicalAddress(device).getLogicalAddressAsInt();
+            int targetDeviceType =
+                    BaseHdmiCecCtsTest.getTargetLogicalAddress(device).getDeviceType();
             int toDevice;
             launchCommand.add("-t");
-            if (targetDevice == 0) {
-                toDevice = 4;
+            if (targetDeviceType == HdmiCecConstants.CEC_DEVICE_TYPE_TV) {
+                toDevice = LogicalAddress.PLAYBACK_1.getLogicalAddressAsInt();
                 launchCommand.add("p");
             } else {
-                toDevice = 0;
+                toDevice = LogicalAddress.TV.getLogicalAddressAsInt();
                 launchCommand.add("x");
             }
 
@@ -128,7 +129,7 @@
              */
             serialNoParam = serialNoParam.substring(1);
             StringBuilder sendVendorCommand = new StringBuilder("cmd hdmi_control vendorcommand ");
-            sendVendorCommand.append(" -t " + targetDevice);
+            sendVendorCommand.append(" -t " + targetDeviceType);
             sendVendorCommand.append(" -d " + toDevice);
             sendVendorCommand.append(" -a " + serialNoParam);
 
diff --git a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
index de23596..99f7e5b 100644
--- a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
+++ b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
@@ -43,6 +43,9 @@
 import androidx.test.uiautomator.Direction;
 import androidx.test.uiautomator.UiDevice;
 import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.UiObjectNotFoundException;
+import androidx.test.uiautomator.UiScrollable;
+import androidx.test.uiautomator.UiSelector;
 import androidx.test.uiautomator.Until;
 
 import org.junit.After;
@@ -60,7 +63,10 @@
     private static final String NAV_BAR_INTERACTION_MODE_RES_NAME = "config_navBarInteractionMode";
     private static final int NAV_BAR_INTERACTION_MODE_GESTURAL = 2;
 
-    private static final BySelector BUTTON_ALWAYS = By.res("android:id/button_always");
+    private static final String BUTTON_ALWAYS_RES_ID = "android:id/button_always";
+    private static final BySelector BUTTON_ALWAYS = By.res(BUTTON_ALWAYS_RES_ID);
+    private static final UiSelector BUTTON_ALWAYS_UI_SELECTOR =
+            new UiSelector().resourceId(BUTTON_ALWAYS_RES_ID);
     private static final BySelector RESOLVER_DIALOG = By.res(Pattern.compile(".*:id/contentPanel.*"));
 
     private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(60L);
@@ -276,6 +282,9 @@
     }
 
     private void verifyDialogIsShown(boolean shouldBeShown) {
+        if (Utils.hasFeature(FEATURE_WEARABLE)) {
+            scrollToSelectorOnWatch(BUTTON_ALWAYS_UI_SELECTOR);
+        }
         UiObject2 buttonAlways = getUiDevice().wait(Until.findObject(BUTTON_ALWAYS), TIMEOUT);
 
         if (shouldBeShown) {
@@ -298,20 +307,48 @@
                 .wait(Until.findObject(RESOLVER_DIALOG), TIMEOUT)
                 .swipe(Direction.UP, 1f);
         } else {
-            getUiDevice()
-                .wait(Until.findObject(BUTTON_ALWAYS), TIMEOUT)
-                .swipe(Direction.RIGHT, 1f);
+            scrollToSelectorOnWatch(new UiSelector().text(label));
         }
-
         return getUiDevice().findObject(By.text(label));
     }
 
     private void chooseUseAlways() {
+        if (Utils.hasFeature(FEATURE_WEARABLE)) {
+            scrollToSelectorOnWatch(BUTTON_ALWAYS_UI_SELECTOR);
+        }
         getUiDevice()
                 .wait(Until.findObject(BUTTON_ALWAYS), TIMEOUT)
                 .click();
     }
 
+    private void scrollToSelectorOnWatch(UiSelector selector) {
+        try {
+            int resId = Resources.getSystem().getIdentifier(
+                    "config_customResolverActivity", "string", "android");
+            String customResolverActivity = context().getString(resId);
+            String customResolverPackageName;
+            if (customResolverActivity.isEmpty()) {
+                // If custom resolver is not in use, it'll be using the Android default
+                customResolverPackageName = "android";
+            } else {
+                customResolverPackageName = customResolverActivity.split("/")[0];
+            }
+
+            UiSelector scrollableSelector =
+                    new UiSelector()
+                            .scrollable(true)
+                            .packageName(customResolverPackageName);
+            UiScrollable scrollable = new UiScrollable(scrollableSelector);
+            scrollable.waitForExists(TIMEOUT);
+            if (scrollable.exists()) {
+                scrollable.scrollToBeginning(Integer.MAX_VALUE);
+                scrollable.scrollIntoView(selector);
+            }
+        } catch (UiObjectNotFoundException ignore) {
+            throw new AssertionError("Scrollable view was lost.");
+        }
+    }
+
     private interface TestStrategy {
         void prepareMimeGroups();
 
diff --git a/hostsidetests/security/src/android/security/cts/MetadataEncryptionTest.java b/hostsidetests/security/src/android/security/cts/MetadataEncryptionTest.java
index 92eafe3..f7877d5 100644
--- a/hostsidetests/security/src/android/security/cts/MetadataEncryptionTest.java
+++ b/hostsidetests/security/src/android/security/cts/MetadataEncryptionTest.java
@@ -50,6 +50,13 @@
         if (PropertyUtil.getFirstApiLevel(mDevice) <= 29) {
           return; // Requirement does not apply to devices running Q or earlier
         }
+        if (PropertyUtil.propertyEquals(mDevice, "ro.crypto.type", "managed")) {
+          // Android is running in a virtualized environment and the file
+          // system is encrypted by the host system.
+          // Note: All encryption-related CDD requirements still must be met,
+          // but they can't be tested directly in this case.
+          return;
+        }
         assertTrue("Metadata encryption must be enabled",
             mDevice.getBooleanProperty("ro.crypto.metadata.enabled", false));
     }
diff --git a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
index bc43c70..057b2e0 100644
--- a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
+++ b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
@@ -728,7 +728,10 @@
 
         // Check that content of /apex/apex-info-list.xml matches output of
         // `adb shell pm list packages --apex-only --show-versioncode -f`.
-        List<ApexInfo> apexInfoList = readApexInfoList();
+        List<ApexInfo> apexInfoList =
+                readApexInfoList().stream()
+                    .filter(a -> a.getIsActive())
+                    .collect(Collectors.toList());
         Set<ITestDevice.ApexInfo> activeApexes = getDevice().getActiveApexes();
         assertThat(apexInfoList.size()).isEqualTo(activeApexes.size());
         for (ITestDevice.ApexInfo apex : activeApexes) {
diff --git a/hostsidetests/userspacereboot/Android.bp b/hostsidetests/userspacereboot/Android.bp
deleted file mode 100644
index f64c740..0000000
--- a/hostsidetests/userspacereboot/Android.bp
+++ /dev/null
@@ -1,38 +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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-java_test_host {
-    name: "CtsUserspaceRebootHostSideTestCases",
-    defaults: ["cts_defaults"],
-    srcs:  ["src/**/*.java"],
-    libs: [
-        "cts-tradefed",
-        "tradefed",
-        "truth-prebuilt",
-        "hamcrest",
-        "hamcrest-library",
-    ],
-    data: [
-        ":BasicUserspaceRebootTestApp",
-        ":BootCompletedUserspaceRebootTestApp",
-    ],
-    test_suites: [
-        "cts",
-        "general-tests",
-    ],
-}
diff --git a/hostsidetests/userspacereboot/AndroidTest.xml b/hostsidetests/userspacereboot/AndroidTest.xml
deleted file mode 100644
index 5df919f..0000000
--- a/hostsidetests/userspacereboot/AndroidTest.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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.
-  -->
-<configuration description="Runs userspace reboot CTS tests">
-    <option name="test-suite-tag" value="cts" />
-    <option name="config-descriptor:metadata" key="component" value="framework" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
-    <option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
-    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
-        <option name="class" value="com.android.cts.userspacereboot.host.UserspaceRebootHostTest" />
-    </test>
-</configuration>
diff --git a/hostsidetests/userspacereboot/OWNERS b/hostsidetests/userspacereboot/OWNERS
deleted file mode 100644
index 7d30d02..0000000
--- a/hostsidetests/userspacereboot/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-dvander@google.com
-ioffe@google.com
diff --git a/hostsidetests/userspacereboot/TEST_MAPPING b/hostsidetests/userspacereboot/TEST_MAPPING
deleted file mode 100644
index cf97bfa..0000000
--- a/hostsidetests/userspacereboot/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "presubmit" : [
-    {
-      "name": "CtsUserspaceRebootHostSideTestCases"
-    }
-  ]
-}
diff --git a/hostsidetests/userspacereboot/src/com/android/cts/userspacereboot/host/UserspaceRebootHostTest.java b/hostsidetests/userspacereboot/src/com/android/cts/userspacereboot/host/UserspaceRebootHostTest.java
deleted file mode 100755
index 4b903dc..0000000
--- a/hostsidetests/userspacereboot/src/com/android/cts/userspacereboot/host/UserspaceRebootHostTest.java
+++ /dev/null
@@ -1,380 +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.userspacereboot.host;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.junit.Assume.assumeFalse;
-import static org.junit.Assume.assumeTrue;
-
-import android.platform.test.annotations.RequiresDevice;
-
-import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.time.Duration;
-
-/**
- * Host side CTS tests verifying userspace reboot functionality.
- */
-@RequiresDevice
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class UserspaceRebootHostTest extends BaseHostJUnit4Test  {
-
-    private static final String USERSPACE_REBOOT_SUPPORTED_PROP =
-            "init.userspace_reboot.is_supported";
-
-    private static final String BASIC_TEST_APP_APK = "BasicUserspaceRebootTestApp.apk";
-    private static final String BASIC_TEST_APP_PACKAGE_NAME =
-            "com.android.cts.userspacereboot.basic";
-
-    private static final String BOOT_COMPLETED_TEST_APP_APK =
-            "BootCompletedUserspaceRebootTestApp.apk";
-    private static final String BOOT_COMPLETED_TEST_APP_PACKAGE_NAME =
-            "com.android.cts.userspacereboot.bootcompleted";
-
-    private void runDeviceTest(String pkgName, String className, String testName) throws Exception {
-        runDeviceTests(pkgName, pkgName + "." + className, testName);
-    }
-
-    private void runDeviceTest(String pkgName, String className, String testName, Duration timeout)
-            throws Exception {
-        runDeviceTests(
-                getDevice(), pkgName, pkgName + "." + className, testName, timeout.toMillis());
-    }
-
-    private void installApk(String apkFileName) throws Exception {
-        CompatibilityBuildHelper helper = new CompatibilityBuildHelper(getBuild());
-        getDevice().installPackage(helper.getTestFile(apkFileName), false, true,
-                getDevice().isAppEnumerationSupported()
-                        ? new String[]{"--force-queryable"}
-                        : new String[]{});
-    }
-
-    /**
-     * Sets up device to run a test case.
-     */
-    @Before
-    public void setUp() throws Exception {
-        getDevice().uninstallPackage(BASIC_TEST_APP_PACKAGE_NAME);
-        getDevice().uninstallPackage(BOOT_COMPLETED_TEST_APP_PACKAGE_NAME);
-    }
-
-    /**
-     * Cleans up device after a test case.
-     */
-    @After
-    public void cleanUp() throws Exception {
-        getDevice().uninstallPackage(BASIC_TEST_APP_PACKAGE_NAME);
-        getDevice().uninstallPackage(BOOT_COMPLETED_TEST_APP_PACKAGE_NAME);
-        getDevice().disableAdbRoot();
-    }
-
-    /**
-     * Asserts that only file-based encrypted devices can support userspace reboot.
-     */
-    @Test
-    public void testOnlyFbeDevicesSupportUserspaceReboot() throws Exception {
-        assumeTrue("Userspace reboot not supported on the device",
-                getDevice().getBooleanProperty(USERSPACE_REBOOT_SUPPORTED_PROP, false));
-        assertThat(getDevice().getProperty("ro.crypto.state")).isEqualTo("encrypted");
-        assertThat(getDevice().getProperty("ro.crypto.type")).isEqualTo("file");
-    }
-
-    /**
-     * Tests that on devices supporting userspace reboot {@code
-     * PowerManager.isRebootingUserspaceSupported()} returns {@code true}.
-     */
-    @Test
-    public void testDeviceSupportsUserspaceReboot() throws Exception {
-        assumeTrue("Userspace reboot not supported on the device",
-                getDevice().getBooleanProperty(USERSPACE_REBOOT_SUPPORTED_PROP, false));
-        installApk(BASIC_TEST_APP_APK);
-        runDeviceTest(BASIC_TEST_APP_PACKAGE_NAME, "BasicUserspaceRebootTest",
-                "testUserspaceRebootIsSupported");
-    }
-
-    /**
-     * Tests that on devices not supporting userspace reboot {@code
-     * PowerManager.isRebootingUserspaceSupported()} returns {@code false}.
-     */
-    @Test
-    public void testDeviceDoesNotSupportUserspaceReboot() throws Exception {
-        assumeFalse("Userspace reboot supported on the device",
-                getDevice().getBooleanProperty(USERSPACE_REBOOT_SUPPORTED_PROP, false));
-        installApk(BASIC_TEST_APP_APK);
-        // Also verify that PowerManager.isRebootingUserspaceSupported will return true
-        runDeviceTest(BASIC_TEST_APP_PACKAGE_NAME, "BasicUserspaceRebootTest",
-                "testUserspaceRebootIsNotSupported");
-    }
-
-    /**
-     * Tests that userspace reboot succeeds and doesn't fall back to full reboot.
-     */
-    @Test
-    public void testUserspaceReboot() throws Exception {
-        assumeTrue("Userspace reboot not supported on the device",
-                getDevice().getBooleanProperty(USERSPACE_REBOOT_SUPPORTED_PROP, false));
-        rebootUserspaceAndWaitForBootComplete();
-        assertUserspaceRebootSucceed();
-    }
-
-    /**
-     * Tests that userspace reboot with fs-checkpointing succeeds and doesn't fall back to full
-     * reboot.
-     */
-    @Test
-    public void testUserspaceRebootWithCheckpoint() throws Exception {
-        assumeTrue("Userspace reboot not supported on the device",
-                getDevice().getBooleanProperty(USERSPACE_REBOOT_SUPPORTED_PROP, false));
-        assumeTrue("Device doesn't support fs checkpointing", isFsCheckpointingSupported());
-        CommandResult result = getDevice().executeShellV2Command("sm start-checkpoint 1");
-        Thread.sleep(500);
-        assertWithMessage("Failed to start checkpoint : %s", result.getStderr()).that(
-                result.getStatus()).isEqualTo(CommandStatus.SUCCESS);
-        rebootUserspaceAndWaitForBootComplete();
-        assertUserspaceRebootSucceed();
-    }
-
-    /**
-     * Tests that CE storage is unlocked after userspace reboot.
-     */
-    @Test
-    public void testUserspaceReboot_verifyCeStorageIsUnlocked() throws Exception {
-        assumeTrue("Userspace reboot not supported on the device",
-                getDevice().getBooleanProperty(USERSPACE_REBOOT_SUPPORTED_PROP, false));
-        try {
-            getDevice().executeShellV2Command("cmd lock_settings set-pin 1543");
-            installApk(BOOT_COMPLETED_TEST_APP_APK);
-            installApk(BASIC_TEST_APP_APK);
-
-            prepareForCeTestCases();
-
-            rebootUserspaceAndWaitForBootComplete();
-            assertUserspaceRebootSucceed();
-
-            // Now it's time to verify our assumptions.
-            runDeviceTest(BOOT_COMPLETED_TEST_APP_PACKAGE_NAME, "BootCompletedUserspaceRebootTest",
-                    "testVerifyCeStorageUnlocked");
-            runDeviceTest(BOOT_COMPLETED_TEST_APP_PACKAGE_NAME, "BootCompletedUserspaceRebootTest",
-                    "testVerifyReceivedLockedBootCompletedBroadcast", Duration.ofMinutes(3));
-            runDeviceTest(BOOT_COMPLETED_TEST_APP_PACKAGE_NAME, "BootCompletedUserspaceRebootTest",
-                    "testVerifyReceivedBootCompletedBroadcast", Duration.ofMinutes(6));
-        } finally {
-            getDevice().executeShellV2Command("cmd lock_settings clear --old 1543");
-            getDevice().executeShellV2Command("reboot");
-        }
-    }
-
-    /**
-     * Tests that CE storage is unlocked after userspace reboot with fs-checkpointing.
-     */
-    @Test
-    public void testUserspaceRebootWithCheckpoint_verifyCeStorageIsUnlocked() throws Exception {
-        assumeTrue("Userspace reboot not supported on the device",
-                getDevice().getBooleanProperty(USERSPACE_REBOOT_SUPPORTED_PROP, false));
-        assumeTrue("Device doesn't support fs checkpointing", isFsCheckpointingSupported());
-        try {
-            CommandResult result = getDevice().executeShellV2Command("sm start-checkpoint 1");
-            Thread.sleep(500);
-            assertWithMessage("Failed to start checkpoint : %s", result.getStderr()).that(
-                    result.getStatus()).isEqualTo(CommandStatus.SUCCESS);
-
-            getDevice().executeShellV2Command("cmd lock_settings set-pin 1543");
-            installApk(BOOT_COMPLETED_TEST_APP_APK);
-            installApk(BASIC_TEST_APP_APK);
-
-            prepareForCeTestCases();
-
-            rebootUserspaceAndWaitForBootComplete();
-            assertUserspaceRebootSucceed();
-            runDeviceTest(BOOT_COMPLETED_TEST_APP_PACKAGE_NAME, "BootCompletedUserspaceRebootTest",
-                    "testVerifyCeStorageUnlocked");
-            runDeviceTest(BOOT_COMPLETED_TEST_APP_PACKAGE_NAME, "BootCompletedUserspaceRebootTest",
-                    "testVerifyReceivedLockedBootCompletedBroadcast", Duration.ofMinutes(3));
-            runDeviceTest(BOOT_COMPLETED_TEST_APP_PACKAGE_NAME, "BootCompletedUserspaceRebootTest",
-                    "testVerifyReceivedBootCompletedBroadcast", Duration.ofMinutes(6));
-        } finally {
-            getDevice().executeShellV2Command("cmd lock_settings clear --old 1543");
-            getDevice().executeShellV2Command("reboot");
-        }
-    }
-
-    private void prepareForCeTestCases() throws Exception {
-        runDeviceTest(BOOT_COMPLETED_TEST_APP_PACKAGE_NAME, "BootCompletedUserspaceRebootTest",
-                "prepareFile");
-        runDeviceTest(BASIC_TEST_APP_PACKAGE_NAME, "BasicUserspaceRebootTest", "prepareFile");
-
-        // In order to test that broadcasts are correctly sent, we need to have a separate app that
-        // is going to be listen for them. Unfortunately, we can't use BOOT_COMPLETED_TEST_APP_APK
-        // because every call to `am instrument` force stops an app. This doesn't play well with
-        // BOOT_COMPLETED broadcast, which is not sent to stopped apps.
-        // Send an intent to our "broadcast listening" test app to kick it out from stopped state.
-        getDevice().executeShellV2Command("am start -a android.intent.action.MAIN"
-                + " --user 0"
-                + " -c android.intent.category.LAUNCHER "
-                + BASIC_TEST_APP_PACKAGE_NAME + "/.LauncherActivity");
-        // Wait enough for PackageManager to persist new state of test app.
-        // I wish there was a better way to synchronize here...
-        Thread.sleep(15000);
-    }
-
-    /**
-     * Asserts that fallback to hard reboot is triggered when a native process fails to stop in a
-     * given timeout.
-     */
-    @Test
-    @RequiresDevice // TODO(b/154709530): Remove dependency on physical device
-    public void testUserspaceRebootFailsKillingProcesses() throws Exception {
-        assumeTrue("Userspace reboot not supported on the device",
-                getDevice().getBooleanProperty(USERSPACE_REBOOT_SUPPORTED_PROP, false));
-        assumeTrue("This test requires root", getDevice().enableAdbRoot());
-        final String sigkillTimeout =
-                getProperty("init.userspace_reboot.sigkill.timeoutmillis", "");
-        final String sigtermTimeout =
-                getProperty("init.userspace_reboot.sigterm.timeoutmillis", "");
-        try {
-            // Explicitly set a very low value to make sure that safety mechanism kicks in.
-            getDevice().setProperty("init.userspace_reboot.sigkill.timeoutmillis", "10");
-            getDevice().setProperty("init.userspace_reboot.sigterm.timeoutmillis", "10");
-            rebootUserspaceAndWaitForBootComplete();
-            assertUserspaceRebootFailed();
-            assertLastBootReasonIs("userspace_failed,shutdown_aborted,sigkill");
-        } finally {
-            getDevice().setProperty("init.userspace_reboot.sigkill.timeoutmillis", sigkillTimeout);
-            getDevice().setProperty("init.userspace_reboot.sigterm.timeoutmillis", sigtermTimeout);
-        }
-    }
-
-    /**
-     * Asserts that fallback to hard reboot is triggered when userspace reboot fails to finish in a
-     * given time.
-     */
-    @Test
-    public void testUserspaceRebootWatchdogTriggers() throws Exception {
-        assumeTrue("Userspace reboot not supported on the device",
-                getDevice().getBooleanProperty(USERSPACE_REBOOT_SUPPORTED_PROP, false));
-        assumeTrue("This test requires root", getDevice().enableAdbRoot());
-        final String defaultValue = getProperty("init.userspace_reboot.watchdog.timeoutmillis", "");
-        try {
-            // Explicitly set a very low value to make sure that safety mechanism kicks in.
-            getDevice().setProperty("init.userspace_reboot.watchdog.timeoutmillis", "1000");
-            rebootUserspaceAndWaitForBootComplete();
-            assertUserspaceRebootFailed();
-            assertLastBootReasonIs("userspace_failed,watchdog_triggered,failed_to_boot");
-        } finally {
-            getDevice().setProperty("init.userspace_reboot.watchdog.timeoutmillis", defaultValue);
-        }
-    }
-
-    // TODO(b/135984674): add test case that forces unmount of f2fs userdata.
-
-    /**
-     * Returns {@code true} if device supports fs-checkpointing.
-     */
-    private boolean isFsCheckpointingSupported() throws Exception {
-        CommandResult result = getDevice().executeShellV2Command("sm supports-checkpoint");
-        assertWithMessage("Failed to check if fs checkpointing is supported : %s",
-                result.getStderr()).that(result.getStatus()).isEqualTo(CommandStatus.SUCCESS);
-        return "true".equals(result.getStdout().trim());
-    }
-
-    /**
-     * Reboots a device and waits for the boot to complete.
-     *
-     * <p>Before rebooting, sets a value of sysprop {@code test.userspace_reboot.requested} to 1.
-     * Querying this property is then used in {@link #assertUserspaceRebootSucceed()} to assert that
-     * userspace reboot succeeded.
-     */
-    private void rebootUserspaceAndWaitForBootComplete() throws Exception {
-        Duration timeout = Duration.ofMillis(getDevice().getIntProperty(
-                "init.userspace_reboot.watchdog.timeoutmillis", 0)).plusMinutes(2);
-        setProperty("test.userspace_reboot.requested", "1");
-        getDevice().rebootUserspaceUntilOnline();
-        assertWithMessage("Device did not boot within %s", timeout).that(
-                getDevice().waitForBootComplete(timeout.toMillis())).isTrue();
-    }
-
-    /**
-     * Asserts that userspace reboot succeeded by querying the value of {@code
-     * test.userspace_reboot.requested} property.
-     */
-    private void assertUserspaceRebootSucceed() throws Exception {
-        // If userspace reboot fails and fallback to hard reboot is triggered then
-        // test.userspace_reboot.requested won't be set.
-        final String bootReason = getProperty("sys.boot.reason.last", "");
-        final boolean result = getDevice().getBooleanProperty("test.userspace_reboot.requested",
-                false);
-        assertWithMessage(
-                "Userspace reboot failed and fallback to full reboot was triggered. Boot reason: "
-                        + "%s", bootReason).that(result).isTrue();
-    }
-
-    /**
-     * Asserts that userspace reboot fails by querying the value of {@code
-     * test.userspace_reboot.requested} property.
-     */
-    private void assertUserspaceRebootFailed() throws Exception {
-        // If userspace reboot fails and fallback to hard reboot is triggered then
-        // test.userspace_reboot.requested won't be set.
-        final boolean result = getDevice().getBooleanProperty("test.userspace_reboot.requested",
-                false);
-        assertWithMessage("Fallback to full reboot wasn't triggered").that(result).isFalse();
-    }
-
-    /**
-     * A wrapper over {@code adb shell setprop name value}.
-     *
-     * This is a temporary workaround until issues with {@code getDevice().setProperty()} API are
-     * resolved.
-     */
-    private void setProperty(String name, String value) throws Exception {
-        final String cmd = String.format("\"setprop %s %s\"", name, value);
-        final CommandResult result = getDevice().executeShellV2Command(cmd);
-        assertWithMessage("Failed to call adb shell %s: %s", cmd, result.getStderr())
-            .that(result.getStatus()).isEqualTo(CommandStatus.SUCCESS);
-    }
-
-    /**
-     * Asserts that normalized value of {@code sys.boot.reason.last} is equal to {@code expected}.
-     */
-    private void assertLastBootReasonIs(final String expected) throws Exception {
-        String reason = getProperty("sys.boot.reason.last", "");
-        if (reason.startsWith("reboot,")) {
-            reason = reason.substring("reboot,".length());
-        }
-        assertThat(reason).isEqualTo(expected);
-    }
-
-    /**
-     * A wrapper over {@code getDevice().getProperty(name)} API that returns {@code defaultValue} if
-     * property with the given {@code name} doesn't exist.
-     */
-    private String getProperty(String name, String defaultValue) throws Exception {
-        String ret = getDevice().getProperty(name);
-        return ret == null ? defaultValue : ret;
-    }
-}
diff --git a/hostsidetests/userspacereboot/testapps/BasicTestApp/Android.bp b/hostsidetests/userspacereboot/testapps/BasicTestApp/Android.bp
deleted file mode 100644
index df1baed..0000000
--- a/hostsidetests/userspacereboot/testapps/BasicTestApp/Android.bp
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (C) 2020 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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_test_helper_app {
-    name: "BasicUserspaceRebootTestApp",
-    srcs:  ["src/**/*.java"],
-    manifest : "AndroidManifest.xml",
-    static_libs: [
-        "androidx.test.runner",
-        "androidx.test.core",
-        "testng",
-        "truth-prebuilt",
-    ],
-    min_sdk_version: "29",
-    // TODO(ioffe): change to number when SDK is finalized.
-    sdk_version: "system_current",
-}
diff --git a/hostsidetests/userspacereboot/testapps/BasicTestApp/AndroidManifest.xml b/hostsidetests/userspacereboot/testapps/BasicTestApp/AndroidManifest.xml
deleted file mode 100644
index 97ffde6..0000000
--- a/hostsidetests/userspacereboot/testapps/BasicTestApp/AndroidManifest.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 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="com.android.cts.userspacereboot.basic" >
-
-    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
-    <application>
-        <activity android:name=".LauncherActivity">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-        <uses-library android:name="android.test.runner" />
-        <receiver android:name=".BasicUserspaceRebootTest$BootReceiver"
-                  android:exported="true"
-                  android:directBootAware="true">
-            <intent-filter>
-                <action android:name="android.intent.action.BOOT_COMPLETED" />
-                <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
-            </intent-filter>
-        </receiver>
-        <provider android:name=".BasicUserspaceRebootTest$Provider"
-                  android:authorities="com.android.cts.userspacereboot.basic"
-                  android:exported="true"
-                  android:directBootAware="true">
-        </provider>
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.userspacereboot.basic"
-                     android:label="Basic userspace reboot device side tests"/>
-</manifest>
diff --git a/hostsidetests/userspacereboot/testapps/BasicTestApp/src/com/android/cts/userspacereboot/basic/BasicUserspaceRebootTest.java b/hostsidetests/userspacereboot/testapps/BasicTestApp/src/com/android/cts/userspacereboot/basic/BasicUserspaceRebootTest.java
deleted file mode 100644
index c41f221..0000000
--- a/hostsidetests/userspacereboot/testapps/BasicTestApp/src/com/android/cts/userspacereboot/basic/BasicUserspaceRebootTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2020 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.userspacereboot.basic;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.testng.Assert.assertThrows;
-
-import android.content.BroadcastReceiver;
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.Uri;
-import android.os.PowerManager;
-import android.util.Log;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-
-/**
- * A test app called from {@link com.android.cts.userspacereboot.host.UserspaceRebootHostTest} to
- * verify basic properties around userspace reboot.
- *
- * <p>Additionally it's used as a test app to receive {@link Intent.ACTION_BOOT_COMPLETED}
- * broadcast. Another test app {@link
- * com.android.cts.userspacereboot.bootcompleted.com.android.cts.userspacereboot.bootcompleted} will
- * query a {@link ContentProvider} exposed by this app in order to verify that broadcast was
- * received.
- *
- * <p>Such separation is required due to the fact, that when {@code adb shell am instrument} is
- * called for an app, it will always force stop that app. This means that if we start an
- * instrumentation test in the same app that listens for {@link Intent.ACTION_BOOT_COMPLETED}
- * broadcast, we might end up not receiving broadcast at all, because {@link
- * Intent.ACTION_BOOT_COMPLETED} is not delivered to stopped apps.
- */
-@RunWith(JUnit4.class)
-public class BasicUserspaceRebootTest {
-
-    private static final String TAG = "UserspaceRebootTest";
-
-    private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
-
-    /**
-     * Tests that {@link PowerManager#isRebootingUserspaceSupported()} returns {@code true}.
-     */
-    @Test
-    public void testUserspaceRebootIsSupported() {
-        PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-        assertThat(powerManager.isRebootingUserspaceSupported()).isTrue();
-    }
-
-    /**
-     * Tests that {@link PowerManager#isRebootingUserspaceSupported()} returns {@code false}.
-     */
-    @Test
-    public void testUserspaceRebootIsNotSupported() {
-        PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-        assertThat(powerManager.isRebootingUserspaceSupported()).isFalse();
-        assertThrows(UnsupportedOperationException.class,
-                () -> powerManager.reboot("userspace"));
-    }
-
-    /**
-     * Deletes test file in app data directory if necessary.
-     */
-    @Test
-    public void prepareFile() throws Exception {
-        Context de = mContext.createDeviceProtectedStorageContext();
-        de.deleteFile(Intent.ACTION_BOOT_COMPLETED.toLowerCase());
-    }
-
-    /**
-     * Receiver of {@link Intent.ACTION_LOCKED_BOOT_COMPLETED} and
-     * {@link Intent.ACTION_BOOT_COMPLETED} broadcasts.
-     */
-    public static class BootReceiver extends BroadcastReceiver {
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Log.i(TAG, "Received! " + intent);
-            String fileName = intent.getAction().toLowerCase();
-            try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(
-                    context.createDeviceProtectedStorageContext().openFileOutput(
-                            fileName, Context.MODE_PRIVATE)))) {
-                writer.println(intent.getAction());
-            } catch (IOException e) {
-                Log.w(TAG, "Failed to append to " + fileName, e);
-            }
-        }
-    }
-
-    /**
-     * Returns whenever {@link Intent.ACTION_LOCKED_BOOT_COMPLETED} and
-     * {@link Intent.ACTION_BOOT_COMPLETED} broadcast were received.
-     */
-    public static class Provider extends ContentProvider {
-
-        @Override
-        public boolean onCreate() {
-            return true;
-        }
-
-        @Override
-        public String getType(Uri uri) {
-            return "vnd.android.cursor.item/com.android.cts.userspacereboot.basic.exists";
-        }
-
-        @Override
-        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-                String sortOrder) {
-            Context de = getContext().createDeviceProtectedStorageContext();
-            File locked_boot_completed = new File(
-                    de.getFilesDir(), Intent.ACTION_LOCKED_BOOT_COMPLETED.toLowerCase());
-            File boot_completed = new File(
-                    de.getFilesDir(), Intent.ACTION_BOOT_COMPLETED.toLowerCase());
-            MatrixCursor cursor = new MatrixCursor(
-                    new String[]{ "locked_boot_completed", "boot_completed"});
-            cursor.addRow(new Object[] {
-                    locked_boot_completed.exists() ? 1 : 0, boot_completed.exists() ? 1 : 0 });
-            return cursor;
-        }
-
-        @Override
-        public Uri insert(Uri uri, ContentValues values) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int delete(Uri uri, String selection, String[] selectionArgs) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-            throw new UnsupportedOperationException();
-        }
-    }
-}
diff --git a/hostsidetests/userspacereboot/testapps/BasicTestApp/src/com/android/cts/userspacereboot/basic/LauncherActivity.java b/hostsidetests/userspacereboot/testapps/BasicTestApp/src/com/android/cts/userspacereboot/basic/LauncherActivity.java
deleted file mode 100644
index cb07bae..0000000
--- a/hostsidetests/userspacereboot/testapps/BasicTestApp/src/com/android/cts/userspacereboot/basic/LauncherActivity.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2020 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.userspacereboot.basic;
-
-import android.app.Activity;
-
-/**
- * An empty launcher activity.
- */
-public class LauncherActivity extends Activity {
-}
diff --git a/hostsidetests/userspacereboot/testapps/BootCompletedTestApp/Android.bp b/hostsidetests/userspacereboot/testapps/BootCompletedTestApp/Android.bp
deleted file mode 100644
index 24952d7..0000000
--- a/hostsidetests/userspacereboot/testapps/BootCompletedTestApp/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2020 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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_test_helper_app {
-    name: "BootCompletedUserspaceRebootTestApp",
-    srcs:  ["src/**/*.java"],
-    manifest : "AndroidManifest.xml",
-    static_libs: [
-        "androidx.test.runner",
-        "androidx.test.core",
-        "compatibility-device-util-axt",
-        "testng",
-        "truth-prebuilt",
-    ],
-    min_sdk_version: "29",
-    sdk_version: "29",
-    target_sdk_version: "29",
-}
diff --git a/hostsidetests/userspacereboot/testapps/BootCompletedTestApp/AndroidManifest.xml b/hostsidetests/userspacereboot/testapps/BootCompletedTestApp/AndroidManifest.xml
deleted file mode 100644
index 03feb43..0000000
--- a/hostsidetests/userspacereboot/testapps/BootCompletedTestApp/AndroidManifest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 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="com.android.cts.userspacereboot.bootcompleted" >
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.cts.userspacereboot.bootcompleted"
-                     android:label="Boot Completed userspace reboot device side tests"/>
-</manifest>
diff --git a/hostsidetests/userspacereboot/testapps/BootCompletedTestApp/src/com/android/cts/userspacereboot/bootcompleted/BootCompletedUserspaceRebootTest.java b/hostsidetests/userspacereboot/testapps/BootCompletedTestApp/src/com/android/cts/userspacereboot/bootcompleted/BootCompletedUserspaceRebootTest.java
deleted file mode 100644
index 4a512ce..0000000
--- a/hostsidetests/userspacereboot/testapps/BootCompletedTestApp/src/com/android/cts/userspacereboot/bootcompleted/BootCompletedUserspaceRebootTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2020 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.userspacereboot.bootcompleted;
-
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.UserManager;
-import android.util.Log;
-
-import com.android.compatibility.common.util.TestUtils;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.io.OutputStreamWriter;
-import java.time.Duration;
-import java.util.Scanner;
-
-/**
- * A test app called from {@link com.android.cts.userspacereboot.host.UserspaceRebootHostTest} to
- * verify CE storage related properties of userspace reboot.
- */
-@RunWith(JUnit4.class)
-public class BootCompletedUserspaceRebootTest {
-
-    private static final String TAG = "UserspaceRebootTest";
-
-    private static final String FILE_NAME = "secret.txt";
-    private static final String SECRET_MESSAGE = "wow, much secret";
-
-    private static final Duration LOCKED_BOOT_TIMEOUT = Duration.ofMinutes(3);
-    private static final Duration BOOT_TIMEOUT = Duration.ofMinutes(6);
-
-    private final Context mCeContext = getInstrumentation().getContext();
-    private final Context mDeContext = mCeContext.createDeviceProtectedStorageContext();
-
-    /**
-     * Writes to a file in CE storage of {@link BootCompletedUserspaceRebootTest}.
-     *
-     * <p>Reading content of this file is used by other test cases in this class to verify that CE
-     * storage is unlocked after userspace reboot.
-     */
-    @Test
-    public void prepareFile() throws Exception {
-        try (OutputStreamWriter writer = new OutputStreamWriter(
-                mCeContext.openFileOutput(FILE_NAME, Context.MODE_PRIVATE))) {
-            writer.write(SECRET_MESSAGE);
-        }
-    }
-
-    /**
-     * Tests that CE storage is unlocked by reading content of a file in CE storage.
-     */
-    @Test
-    public void testVerifyCeStorageUnlocked() throws Exception {
-        UserManager um = getInstrumentation().getContext().getSystemService(UserManager.class);
-        assertThat(um.isUserUnlocked()).isTrue();
-        try (Scanner scanner = new Scanner(mCeContext.openFileInput(FILE_NAME))) {
-            final String content = scanner.nextLine();
-            assertThat(content).isEqualTo(SECRET_MESSAGE);
-        }
-    }
-
-    /**
-     * Tests that {@link Intent.ACTION_LOCKED_BOOT_COMPLETED} broadcast was sent.
-     */
-    @Test
-    public void testVerifyReceivedLockedBootCompletedBroadcast() throws Exception {
-        waitForBroadcast(Intent.ACTION_LOCKED_BOOT_COMPLETED, LOCKED_BOOT_TIMEOUT);
-    }
-
-    /**
-     * Tests that {@link Intent.ACTION_BOOT_COMPLETED} broadcast was sent.
-     */
-    @Test
-    public void testVerifyReceivedBootCompletedBroadcast() throws Exception {
-        waitForBroadcast(Intent.ACTION_BOOT_COMPLETED, BOOT_TIMEOUT);
-    }
-
-    private void waitForBroadcast(String intent, Duration timeout) throws Exception {
-        TestUtils.waitUntil(
-                "Didn't receive broadcast " + intent + " in " + timeout,
-                (int) timeout.getSeconds(),
-                () -> queryBroadcast(intent));
-    }
-
-    private boolean queryBroadcast(String intent) {
-        Uri uri = Uri.parse("content://com.android.cts.userspacereboot.basic/files/"
-                + intent.toLowerCase());
-        Cursor cursor = mDeContext.getContentResolver().query(uri, null, null, null, null);
-        if (cursor == null) {
-            return false;
-        }
-        if (!cursor.moveToFirst()) {
-            Log.w(TAG, "Broadcast: " + intent + " cursor is empty");
-            return false;
-        }
-        String column = intent.equals(Intent.ACTION_LOCKED_BOOT_COMPLETED)
-                ? "locked_boot_completed"
-                : "boot_completed";
-        int index = cursor.getColumnIndex(column);
-        return cursor.getInt(index) == 1;
-    }
-}
diff --git a/libs/install/src/android/cts/install/lib/host/InstallUtilsHost.java b/libs/install/src/android/cts/install/lib/host/InstallUtilsHost.java
index f6de85b..53c813a 100644
--- a/libs/install/src/android/cts/install/lib/host/InstallUtilsHost.java
+++ b/libs/install/src/android/cts/install/lib/host/InstallUtilsHost.java
@@ -25,6 +25,7 @@
 import com.android.tradefed.build.BuildInfoKey;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.invoker.TestInformation;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.util.CommandResult;
 import com.android.tradefed.util.CommandStatus;
@@ -51,24 +52,31 @@
             ".*package:\\sname='(\\S+)\\'\\sversionCode='(\\d+)'\\s.*";
 
     private final IRunUtil mRunUtil = new RunUtil();
-    private final BaseHostJUnit4Test mTest;
+    private BaseHostJUnit4Test mTest = null;
+    private TestInformation mTestInfo = null;
 
     public InstallUtilsHost(BaseHostJUnit4Test test) {
         mTest = test;
     }
 
+    public InstallUtilsHost(TestInformation testInfo) {
+        assertThat(testInfo).isNotNull();
+        mTestInfo = testInfo;
+    }
+
     /**
      * Return {@code true} if and only if device supports updating apex.
      */
     public boolean isApexUpdateSupported() throws Exception {
-        return mTest.getDevice().getBooleanProperty("ro.apex.updatable", false);
+        return getTestInfo().getDevice().getBooleanProperty("ro.apex.updatable", false);
     }
 
     /**
      * Return {@code true} if and only if device supports file system checkpoint.
      */
     public boolean isCheckpointSupported() throws Exception {
-        CommandResult result = mTest.getDevice().executeShellV2Command("sm supports-checkpoint");
+        CommandResult result = getTestInfo().getDevice().executeShellV2Command(
+                "sm supports-checkpoint");
         assertWithMessage("Failed to check if file system checkpoint is supported : %s",
                 result.getStderr()).that(result.getStatus()).isEqualTo(CommandStatus.SUCCESS);
         return "true".equals(result.getStdout().trim());
@@ -95,11 +103,12 @@
         }
         // Non system version is active, need to uninstall it and reboot the device.
         Log.i(TAG, "Uninstalling shim apex");
-        final String errorMessage = mTest.getDevice().uninstallPackage(SHIM_APEX_PACKAGE_NAME);
+        final String errorMessage =
+                getTestInfo().getDevice().uninstallPackage(SHIM_APEX_PACKAGE_NAME);
         if (errorMessage != null) {
             Log.e(TAG, "Failed to uninstall " + SHIM_APEX_PACKAGE_NAME + " : " + errorMessage);
         } else {
-            mTest.getDevice().reboot();
+            getTestInfo().getDevice().reboot();
             final ITestDevice.ApexInfo shim = getShimApex().orElseThrow(
                     () -> new AssertionError("Can't find " + SHIM_APEX_PACKAGE_NAME));
             assertThat(shim.versionCode).isEqualTo(1L);
@@ -111,7 +120,7 @@
      * Returns the active shim apex as optional.
      */
     public Optional<ITestDevice.ApexInfo> getShimApex() throws DeviceNotAvailableException {
-        return mTest.getDevice().getActiveApexes().stream().filter(
+        return getTestInfo().getDevice().getActiveApexes().stream().filter(
                 apex -> apex.name.equals(SHIM_APEX_PACKAGE_NAME)).findAny();
     }
 
@@ -137,7 +146,7 @@
      * Installs packages using staged install flow and waits for pre-reboot verification to complete
      */
     public String installStagedPackage(File pkg) throws Exception {
-        return mTest.getDevice().installPackage(pkg, false, "--staged");
+        return getTestInfo().getDevice().installPackage(pkg, false, "--staged");
     }
 
     /**
@@ -149,7 +158,7 @@
         for (int i = 0; i < filenames.length; i++) {
             args[i + 1] = getTestFile(filenames[i]).getAbsolutePath();
         }
-        String stdout = mTest.getDevice().executeAdbCommand(args);
+        String stdout = getTestInfo().getDevice().executeAdbCommand(args);
         assertThat(stdout).isNotNull();
     }
 
@@ -159,7 +168,7 @@
     public void waitForFileDeleted(String filePath, Duration timeout) throws Exception {
         Stopwatch stopwatch = Stopwatch.createStarted();
         while (true) {
-            if (!mTest.getDevice().doesFileExist(filePath)) {
+            if (!getTestInfo().getDevice().doesFileExist(filePath)) {
                 return;
             }
             if (stopwatch.elapsed().compareTo(timeout) > 0) {
@@ -187,7 +196,7 @@
             return testFile;
         }
 
-        File hostLinkedDir = mTest.getBuild().getFile(
+        File hostLinkedDir = getTestInfo().getBuildInfo().getFile(
                 BuildInfoKey.BuildInfoFileKey.HOST_LINKED_DIR);
         if (hostLinkedDir != null) {
             testFile = searchTestFile(hostLinkedDir, testFileName);
@@ -197,7 +206,7 @@
         }
 
         // Find the file in the buildinfo.
-        File buildInfoFile = mTest.getBuild().getFile(testFileName);
+        File buildInfoFile = getTestInfo().getBuildInfo().getFile(testFileName);
         if (buildInfoFile != null) {
             return buildInfoFile;
         }
@@ -228,5 +237,11 @@
         return result.getStdout();
     }
 
-
+    private TestInformation getTestInfo() {
+        if (mTestInfo == null) {
+            mTestInfo = mTest.getTestInformation();
+            assertThat(mTestInfo).isNotNull();
+        }
+        return mTestInfo;
+    }
 }
diff --git a/tests/camera/Android.bp b/tests/camera/Android.bp
index 6cb0cee..28c0928 100644
--- a/tests/camera/Android.bp
+++ b/tests/camera/Android.bp
@@ -48,3 +48,66 @@
         "android.test.base.stubs",
     ],
 }
+
+// CtsCameraTestCases package
+android_test {
+    name: "CtsCameraTestCases",
+    defaults: ["cts_defaults"],
+    // Include both the 32 and 64 bit versions
+    compile_multilib: "both",
+    static_libs: [
+        "compatibility-device-util-axt",
+        "ctstestrunner-axt",
+        "mockito-target-minus-junit4",
+        "android-ex-camera2",
+        "CtsCameraUtils",
+        "truth-prebuilt",
+        "androidx.heifwriter_heifwriter",
+        "androidx.test.rules",
+    ],
+    jni_libs: [
+        "libctscamera2_jni",
+        "libnativehelper_compat_libc++",
+    ],
+    stl: "c++_shared",
+    srcs: [
+        "src/**/*.java",
+        ":CtsCameraTestCases-rscript{CtsCameraTestCases.srcjar}",
+    ],
+    resource_zips: [
+        ":CtsCameraTestCases-rscript{CtsCameraTestCases.res.zip}",
+    ],
+    test_suites: [
+        "cts",
+        "general-tests",
+    ],
+    sdk_version: "test_current",
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+}
+
+genrule {
+    name: "CtsCameraTestCases-rscript",
+    srcs: [
+        "src/**/*.rscript",
+        ":rs_script_api",
+        ":rs_clang_headers",
+    ],
+    tools: [
+        "llvm-rs-cc",
+        "soong_zip",
+    ],
+    out: [
+        "CtsCameraTestCases.srcjar",
+        "CtsCameraTestCases.res.zip",
+    ],
+    cmd: "for f in $(locations src/**/*.rscript); do " +
+        "  $(location llvm-rs-cc) -o $(genDir)/res/raw -p $(genDir)/src " +
+        "  -I $$(dirname $$(echo $(locations :rs_script_api) | awk '{ print $$1 }')) " +
+        "  -I $$(dirname $$(echo $(locations :rs_clang_headers) | awk '{ print $$1 }')) $${f}; " +
+        "done && " +
+        "$(location soong_zip) -srcjar -o $(location CtsCameraTestCases.srcjar) -C $(genDir)/src -D $(genDir)/src &&" +
+        "$(location soong_zip) -o $(location CtsCameraTestCases.res.zip) -C $(genDir)/res -D $(genDir)/res",
+}
diff --git a/tests/camera/Android.mk b/tests/camera/Android.mk
deleted file mode 100644
index f2bf9fc..0000000
--- a/tests/camera/Android.mk
+++ /dev/null
@@ -1,60 +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.
-
-LOCAL_PATH:= $(call my-dir)
-
-# CtsCameraTestCases package
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-# Include both the 32 and 64 bit versions
-LOCAL_MULTILIB := both
-
-LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt \
-	ctstestrunner-axt \
-	mockito-target-minus-junit4 \
-	android-ex-camera2 \
-	CtsCameraUtils \
-	truth-prebuilt \
-	androidx.heifwriter_heifwriter \
-	androidx.test.rules
-
-LOCAL_JNI_SHARED_LIBRARIES := \
-	libctscamera2_jni \
-	libnativehelper_compat_libc++ \
-
-LOCAL_NDK_STL_VARIANT := c++_shared
-
-LOCAL_SRC_FILES := \
-	$(call all-java-files-under, src) \
-	$(call all-renderscript-files-under, src)
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts general-tests
-
-LOCAL_PACKAGE_NAME := CtsCameraTestCases
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-
-LOCAL_SDK_VERSION := test_current
-
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-
-cts_runtime_hint := 120
-
-include $(BUILD_CTS_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/camera/src/android/hardware/cts/CameraGLTest.java b/tests/camera/src/android/hardware/cts/CameraGLTest.java
index a9e82ef..7478e79 100644
--- a/tests/camera/src/android/hardware/cts/CameraGLTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraGLTest.java
@@ -136,15 +136,15 @@
                 // Save the looper so that we can terminate this thread
                 // after we are done with it.
                 mLooper = Looper.myLooper();
-                // These must be instantiated outside the UI thread, since the
-                // UI thread will be doing a lot of waiting, stopping callbacks.
-                mCamera = Camera.open(cameraId);
                 try {
                     mIsExternalCamera = CameraUtils.isExternal(
                             mActivityRule.getActivity().getApplicationContext(), cameraId);
                 } catch (Exception e) {
                     Log.e(TAG, "Unable to query external camera!" + e);
                 }
+                // These must be instantiated outside the UI thread, since the
+                // UI thread will be doing a lot of waiting, stopping callbacks.
+                mCamera = Camera.open(cameraId);
                 mSurfaceTexture = new SurfaceTexture(mRenderer.getTextureID());
                 Log.v(TAG, "Camera " + cameraId + " is opened.");
                 startDone.open();
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java
index d5b652f..441c862 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java
@@ -100,8 +100,10 @@
 
     @Test
     public void testAnimationCallbacks_overlapping() {
-        // Test requires navbar to create overlapping animations.
-        assumeTrue(hasWindowInsets(mRootView, navigationBars()));
+        assumeTrue(
+                "Test requires navBar and statusBar to create overlapping animations.",
+                hasWindowInsets(mRootView, navigationBars())
+                        && hasWindowInsets(mRootView, statusBars()));
 
         WindowInsets before = mActivity.mLastWindowInsets;
         MultiAnimCallback callbackInner = new MultiAnimCallback();
diff --git a/tests/media/src/android/mediav2/cts/CodecDecoderValidationTest.java b/tests/media/src/android/mediav2/cts/CodecDecoderValidationTest.java
index 4c27aed..5819bfb 100644
--- a/tests/media/src/android/mediav2/cts/CodecDecoderValidationTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecDecoderValidationTest.java
@@ -351,111 +351,111 @@
 
                 // aac-he
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_16kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_16kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_22kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_22kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_24kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_24kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_32kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_32kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_44kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_44kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_48kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_48kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_5ch_16kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_5ch_16kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_5ch_22kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_5ch_22kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_5ch_24kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_5ch_24kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_5ch_32kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_5ch_32kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_5ch_44kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_5ch_44kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_5ch_48kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_5ch_48kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_6ch_16kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_6ch_16kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_6ch_22kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_6ch_22kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_6ch_24kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_6ch_24kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_6ch_32kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_6ch_32kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_6ch_44kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_6ch_44kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_6ch_48kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_6ch_48kHz_aac_he.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
 
                 // aac-eld
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_16kHz_aac_eld.m4a"},
-                        "audio/bbb_1ch_16kHz_s16le_3s.raw", -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_1ch_16kHz_s16le_3s.raw", -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_22kHz_aac_eld.m4a"},
-                        "audio/bbb_1ch_22kHz_s16le_3s.raw", 24.959969f, -1L, CODEC_ALL},
+                        "audio/bbb_1ch_22kHz_s16le_3s.raw", 24.959969f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_24kHz_aac_eld.m4a"},
-                        "audio/bbb_1ch_24kHz_s16le_3s.raw", 26.495283f, -1L, CODEC_ALL},
+                        "audio/bbb_1ch_24kHz_s16le_3s.raw", 26.495283f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_32kHz_aac_eld.m4a"},
-                        "audio/bbb_1ch_32kHz_s16le_3s.raw", 31.464266f, -1L, CODEC_ALL},
+                        "audio/bbb_1ch_32kHz_s16le_3s.raw", 31.464266f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_44kHz_aac_eld.m4a"},
-                        "audio/bbb_1ch_44kHz_s16le_3s.raw", 33.852623f, -1L, CODEC_ALL},
+                        "audio/bbb_1ch_44kHz_s16le_3s.raw", 33.852623f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_48kHz_aac_eld.m4a"},
-                        "audio/bbb_1ch_48kHz_s16le_3s.raw", 33.136082f, -1L, CODEC_ALL},
+                        "audio/bbb_1ch_48kHz_s16le_3s.raw", 33.136082f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_16kHz_aac_eld.m4a"},
-                        "audio/bbb_2ch_16kHz_s16le_3s.raw", -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_16kHz_s16le_3s.raw", -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_22kHz_aac_eld.m4a"},
-                        "audio/bbb_2ch_22kHz_s16le_3s.raw", 24.959969f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_22kHz_s16le_3s.raw", 24.959969f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_24kHz_aac_eld.m4a"},
-                        "audio/bbb_2ch_24kHz_s16le_3s.raw", 26.962938f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_24kHz_s16le_3s.raw", 26.962938f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_32kHz_aac_eld.m4a"},
-                        "audio/bbb_2ch_32kHz_s16le_3s.raw", 27.784887f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_32kHz_s16le_3s.raw", 27.784887f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_44kHz_aac_eld.m4a"},
-                        "audio/bbb_2ch_44kHz_s16le_3s.raw", 29.223278f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_44kHz_s16le_3s.raw", 29.223278f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_48kHz_aac_eld.m4a"},
-                        "audio/bbb_2ch_48kHz_s16le_3s.raw", 29.171904f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_48kHz_s16le_3s.raw", 29.171904f, -1L, CODEC_DEFAULT},
 
                 // aac-hev2
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_16kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_16kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_22kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_22kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_24kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_24kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_32kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_32kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_44kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_44kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{
-                        "audio/bbb_2ch_48kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_ALL},
+                        "audio/bbb_2ch_48kHz_aac_hev2.m4a"}, null, -1.0f, -1L, CODEC_DEFAULT},
 
                 // aac-usac
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_8kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_16kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_22kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_24kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_32kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_44kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_1ch_48kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_8kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_16kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_22kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_24kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_32kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_44kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, new String[]{"audio/bbb_2ch_48kHz_usac.m4a"},
-                        null, -1.0f, -1L, CODEC_ALL},
+                        null, -1.0f, -1L, CODEC_DEFAULT},
         });
         return prepareParamList(exhaustiveArgsList, isEncoder, needAudio, needVideo, false);
     }
@@ -475,9 +475,12 @@
             if (mSupport == CODEC_ALL) {
                 fail("format(s) not supported by component: " + mCodecName + " for mime : " +
                         mMime);
-            }
-            if (mSupport != CODEC_OPTIONAL && selectCodecs(mMime, formats, null, false).isEmpty()) {
+            } else if (mSupport == CODEC_ANY && selectCodecs(mMime, formats, null,
+                    false).isEmpty()) {
                 fail("format(s) not supported by any component for mime : " + mMime);
+            } else if (mSupport == CODEC_DEFAULT && isDefaultCodec(mCodecName, mMime, false)) {
+                fail("format(s) not supported by " + mCodecName
+                        + " which is a default codec for mime : " + mMime);
             }
             return;
         }
diff --git a/tests/media/src/android/mediav2/cts/CodecTestBase.java b/tests/media/src/android/mediav2/cts/CodecTestBase.java
index 7b41079..50c9664 100644
--- a/tests/media/src/android/mediav2/cts/CodecTestBase.java
+++ b/tests/media/src/android/mediav2/cts/CodecTestBase.java
@@ -512,13 +512,16 @@
     static final String CODEC_PREFIX_KEY = "codec-prefix";
     static final String MIME_SEL_KEY = "mime-sel";
     static final Map<String, String> codecSelKeyMimeMap = new HashMap<>();
+    static final Map<String, String> mDefaultEncoders = new HashMap<>();
+    static final Map<String, String> mDefaultDecoders = new HashMap<>();
     static final boolean ENABLE_LOGS = false;
     static final int PER_TEST_TIMEOUT_LARGE_TEST_MS = 300000;
     static final int PER_TEST_TIMEOUT_SMALL_TEST_MS = 60000;
     static final int UNSPECIFIED = 0;
-    static final int CODEC_ALL = 0; // All codecs should support
-    static final int CODEC_ANY = 1; // Atleast one codec should support
-    static final int CODEC_OPTIONAL = 2; // Codec support is optional
+    static final int CODEC_ALL = 0; // All codecs must support
+    static final int CODEC_ANY = 1; // At least one codec must support
+    static final int CODEC_DEFAULT = 2; // Default codec must support
+    static final int CODEC_OPTIONAL = 3; // Codec support is optional
     // Maintain Timeouts in sync with their counterpart in NativeMediaCommon.h
     static final long Q_DEQ_TIMEOUT_US = 5000; // block at most 5ms while looking for io buffers
     static final int RETRY_LIMIT = 100; // max poll counter before test aborts and returns error
@@ -644,6 +647,20 @@
         return isSupported;
     }
 
+    static boolean isDefaultCodec(String codecName, String mime, boolean isEncoder)
+            throws IOException {
+        Map<String,String> mDefaultCodecs = isEncoder ? mDefaultEncoders:  mDefaultDecoders;
+        if (mDefaultCodecs.containsKey(mime)) {
+            return mDefaultCodecs.get(mime).equalsIgnoreCase(codecName);
+        }
+        MediaCodec codec = isEncoder ? MediaCodec.createEncoderByType(mime)
+                : MediaCodec.createDecoderByType(mime);
+        boolean isDefault = codec.getName().equalsIgnoreCase(codecName);
+        mDefaultCodecs.put(mime, codec.getName());
+        codec.release();
+        return isDefault;
+    }
+
     static ArrayList<String> compileRequiredMimeList(boolean isEncoder, boolean needAudio,
             boolean needVideo) {
         Set<String> list = new HashSet<>();
@@ -1229,6 +1246,9 @@
             mOutputBuff.saveInPTS(info.presentationTimeUs);
             mInputCount++;
         }
+        if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+            mSawInputEOS = true;
+        }
     }
 
     void dequeueOutput(int bufferIndex, MediaCodec.BufferInfo info) {
diff --git a/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidTest.xml b/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidTest.xml
index c0fadbd..388e55f 100644
--- a/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidTest.xml
@@ -28,6 +28,7 @@
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.DebugClassKillswitchTest" />
         <option name="runtime-hint" value="60s" />
+        <option name="shell-timeout" value="20m" />
     </test>
 
     <!-- Controller that will skip the module if a native bridge situation is detected -->
diff --git a/tests/signature/api-check/hidden-api-killswitch-sdklist/AndroidTest.xml b/tests/signature/api-check/hidden-api-killswitch-sdklist/AndroidTest.xml
index a9b1035..edfe124 100644
--- a/tests/signature/api-check/hidden-api-killswitch-sdklist/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-sdklist/AndroidTest.xml
@@ -34,6 +34,7 @@
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.SdkListKillswitchTest" />
         <option name="runtime-hint" value="60s" />
+        <option name="shell-timeout" value="20m" />
     </test>
 
     <!-- Controller that will skip the module if a native bridge situation is detected -->
diff --git a/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidTest.xml b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidTest.xml
index 27b874c..c4dbd48 100644
--- a/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidTest.xml
@@ -34,6 +34,7 @@
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.WildcardKillswitchTest" />
         <option name="runtime-hint" value="60s" />
+        <option name="shell-timeout" value="20m" />
     </test>
 
     <!-- Controller that will skip the module if a native bridge situation is detected -->
diff --git a/tests/signature/api-check/shared-libs-api/Android.bp b/tests/signature/api-check/shared-libs-api/Android.bp
index 7d2b3c4..e984ccd 100644
--- a/tests/signature/api-check/shared-libs-api/Android.bp
+++ b/tests/signature/api-check/shared-libs-api/Android.bp
@@ -26,3 +26,55 @@
         "compatibility-device-util-axt",
     ],
 }
+
+android_test {
+    name: "CtsSharedLibsApiSignatureTestCases",
+    defaults: ["cts_defaults"],
+    java_resources: [
+        ":CtsSharedLibsApiSignatureTestCases_cts-shared-libs-all.api",
+    ],
+    static_libs: [
+        "cts-api-signature-multilib-test",
+        "cts-api-signature-test",
+    ],
+    test_suites: [
+        "cts",
+        "general-tests",
+    ],
+    sdk_version: "current",
+    jni_libs: ["libclassdescriptors"],
+    compile_multilib: "both",
+    dex_preopt: {
+        enabled: false,
+    },
+    optimize: {
+        enabled: false,
+    },
+    use_embedded_native_libs: false,
+    srcs: ["src/**/*.java"],
+}
+
+genrule {
+    name: "CtsSharedLibsApiSignatureTestCases_cts-shared-libs-all.api",
+    srcs: [
+        ":prebuilt_sdk_system_public_api_txt",
+    ],
+    tools: [
+        "soong_zip",
+        "metalava",
+    ],
+    out: [
+        "shared-libs-all.api.zip",
+    ],
+    cmd: "for f in $(in); do " +
+        "  fileName=$$(basename $${f} .txt) && " +
+        "  if [ $${fileName} == android ] || [[ $${fileName} =~ removed ]] || [[ $${fileName} =~ incompatibilities ]]; " +
+        "    then continue; fi && " +
+        "  platformSdkVersion=$$(echo $${f} | awk -F/ '{print $$(3)}') && " +
+        "  if [ $${platformSdkVersion} -lt 28 ]; then continue; fi && " +
+        "  apiLevel=$$(echo $${f} | awk -F/ '{print $$(4)}') && " +
+        "  $(location metalava) -J--add-opens=java.base/java.util=ALL-UNNAMED --no-banner " +
+        "    -convert2xmlnostrip $${f} $(genDir)/list/$${fileName}-$${platformSdkVersion}-$${apiLevel}.api; " +
+        "done && " +
+        "$(location soong_zip) -o $(out) -C $(genDir)/list -D $(genDir)/list",
+}
\ No newline at end of file
diff --git a/tests/signature/api-check/shared-libs-api/Android.mk b/tests/signature/api-check/shared-libs-api/Android.mk
deleted file mode 100644
index faa0248..0000000
--- a/tests/signature/api-check/shared-libs-api/Android.mk
+++ /dev/null
@@ -1,62 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-all_shared_libs_modules :=
-
-$(foreach ver,$(call int_range_list,28,$(PLATFORM_SDK_VERSION)),\
-  $(foreach api_level,public system,\
-    $(foreach lib,$(filter-out android,$(filter-out %removed,$(filter-out incompatibilities,\
-      $(basename $(notdir $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/$(ver)/$(api_level)/api/*.txt)))))),\
-        $(eval all_shared_libs_modules += $(lib)-$(ver)-$(api_level).api))))
-
-all_shared_libs_files := $(addprefix $(COMPATIBILITY_TESTCASES_OUT_cts)/,$(all_shared_libs_modules))
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := cts-shared-libs-all.api
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_MODULE_STEM := shared-libs-all.api.zip
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
-include $(BUILD_SYSTEM)/base_rules.mk
-$(LOCAL_BUILT_MODULE): $(SOONG_ZIP)
-$(LOCAL_BUILT_MODULE): PRIVATE_SHARED_LIBS_FILES := $(all_shared_libs_files)
-$(LOCAL_BUILT_MODULE): $(all_shared_libs_files)
-	@echo "Zip API files $^ -> $@"
-	@mkdir -p $(dir $@)
-	$(hide) rm -f $@
-	$(hide) $(SOONG_ZIP) -o $@ -P out -C $(OUT_DIR) $(addprefix -f ,$(PRIVATE_SHARED_LIBS_FILES))
-
-all_shared_libs_zip_file := $(LOCAL_BUILT_MODULE)
-
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := CtsSharedLibsApiSignatureTestCases
-
-LOCAL_JAVA_RESOURCE_FILES := $(all_shared_libs_zip_file)
-
-LOCAL_STATIC_JAVA_LIBRARIES := cts-api-signature-multilib-test
-
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-include $(LOCAL_PATH)/../build_signature_apk.mk
-
-LOCAL_JAVA_SDK_LIBRARIES :=
-all_shared_libs_files :=
-all_shared_libs_modules :=
-all_shared_libs_zip_file :=
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/BootClassPathClassesProvider.java b/tests/signature/api-check/src/java/android/signature/cts/api/BootClassPathClassesProvider.java
index d1f019b..e0f22e2 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/BootClassPathClassesProvider.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/BootClassPathClassesProvider.java
@@ -29,6 +29,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Arrays;
+import java.util.Objects;
 import java.util.stream.Stream;
 
 @SuppressWarnings("deprecation")
@@ -38,7 +39,8 @@
     @Override
     public Stream<Class<?>> getAllClasses() {
         maybeAttachJvmtiAgent();
-        return Arrays.stream(getClassloaderDescriptors(Object.class.getClassLoader()))
+        return (Stream<Class<?>>)
+            Arrays.stream(getClassloaderDescriptors(Object.class.getClassLoader()))
                 .map(descriptor -> {
                     String classname = descriptor.replace('/', '.');
                     // omit L and ; at the front and at the end
@@ -48,9 +50,12 @@
                     try {
                         return getClass(classname);
                     } catch (ClassNotFoundException e) {
-                        throw new RuntimeException("Cannot load " + classname, e);
+                        // It could be that a class failed to verify.
+                        // No process will be able to load it, so it's ok to silently ignore.
+                        return null;
                     }
-                });
+                })
+                .filter(Objects::nonNull);
     }
 
     @Override
diff --git a/tests/signature/lib/android/src/android/signature/cts/DexMemberChecker.java b/tests/signature/lib/android/src/android/signature/cts/DexMemberChecker.java
index 181f9d4..a64a483 100644
--- a/tests/signature/lib/android/src/android/signature/cts/DexMemberChecker.java
+++ b/tests/signature/lib/android/src/android/signature/cts/DexMemberChecker.java
@@ -112,8 +112,12 @@
         } else if (dexMember instanceof DexMethod) {
             DexMethod method = (DexMethod) dexMember;
             if (reflection) {
-                observer.methodAccessibleViaReflection(hasMatchingMethod_Reflection(klass, method),
-                        method);
+                try {
+                    observer.methodAccessibleViaReflection(
+                            hasMatchingMethod_Reflection(klass, method), method);
+                } catch (ClassNotFoundException e) {
+                    Log.w(TAG, "Failed resolution of " + dexMember.toString(), e);
+                }
             }
             if (jni) {
                 try {
@@ -164,11 +168,22 @@
             return true;
         } catch (NoSuchFieldException ex) {
             return false;
+        } catch (NoClassDefFoundError ex) {
+            // The field has a type that cannot be loaded.
+            return true;
         }
     }
 
     private static boolean hasMatchingField_JNI(Class<?> klass, DexField dexField) {
         try {
+            DexMember.typeToClass(dexField.getDexType());
+        } catch (ClassNotFoundException e) {
+            Log.w(TAG, "Type of field not found: " + dexField.toString(), e);
+            // Skip this field, no process is able to load it.
+            return true;
+        }
+
+        try {
             Field ifield = getField_JNI(klass, dexField.getName(), dexField.getDexType());
             if (ifield.getDeclaringClass() == klass) {
               return true;
@@ -189,22 +204,57 @@
         return false;
     }
 
-    private static boolean hasMatchingMethod_Reflection(Class<?> klass, DexMethod dexMethod) {
-        List<String> methodParams = dexMethod.getJavaParameterTypes();
+    private static boolean hasMatchingMethod_Reflection(Class<?> klass, DexMethod dexMethod)
+                throws ClassNotFoundException {
+        // If we fail to resolve all parameters or return type, we will throw
+        // ClassNotFoundException.
+        Class<?>[] parameterClasses = dexMethod.getJavaParameterClasses();
+        Class<?> returnClass = DexMember.typeToClass(dexMethod.getDexType());
 
         if (dexMethod.isConstructor()) {
-            for (Constructor<?> constructor : klass.getDeclaredConstructors()) {
-                if (typesMatch(constructor.getParameterTypes(), methodParams)) {
+            try {
+                if (klass.getDeclaredConstructor(parameterClasses) != null) {
                     return true;
                 }
+            } catch (NoSuchMethodException e) {
+              return false;
             }
-        } else {
+        } else if (!dexMethod.isStaticConstructor()) {
+            List<String> methodParams = dexMethod.getJavaParameterTypes();
             String methodReturnType = dexMethod.getJavaType();
-            for (Method method : klass.getDeclaredMethods()) {
-                if (method.getName().equals(dexMethod.getName())
-                        && method.getReturnType().getTypeName().equals(methodReturnType)
-                        && typesMatch(method.getParameterTypes(), methodParams)) {
-                    return true;
+            try {
+                // First try with getDeclaredMethods, hoping all parameter and return types can be
+                // resolved.
+                for (Method method : klass.getDeclaredMethods()) {
+                    if (method.getName().equals(dexMethod.getName())
+                            && method.getReturnType().getTypeName().equals(methodReturnType)
+                            && typesMatch(method.getParameterTypes(), methodParams)) {
+                        return true;
+                    }
+                }
+            } catch (NoClassDefFoundError ncdfe) {
+                // Try with getMethods, which does not check parameter and return types are
+                // resolved, but only returns public methods.
+                for (Method method : klass.getMethods()) {
+                    if (method.getName().equals(dexMethod.getName())
+                            && method.getClass() == klass
+                            && method.getReturnType().getTypeName().equals(methodReturnType)
+                            && typesMatch(method.getParameterTypes(), methodParams)) {
+                        return true;
+                    }
+                }
+                // Last chance, try with getDeclaredMethod.
+                try {
+                    Method m = klass.getDeclaredMethod(dexMethod.getName(), parameterClasses);
+                    if (m.getReturnType().getTypeName().equals(dexMethod.getJavaType())) {
+                        return true;
+                    }
+                    // This means we found a method with a different return type. We cannot make
+                    // any conclusion here: the method may exisit or not. However, given we have
+                    // not found the method through getMethods and getDeclaredMethods, we know
+                    // this method won't be accessible through reflection.
+                } catch (NoSuchMethodException nsme) {
+                  return false;
                 }
             }
         }
diff --git a/tests/signature/lib/common/src/android/signature/cts/DexMember.java b/tests/signature/lib/common/src/android/signature/cts/DexMember.java
index c8470b9..165341a 100644
--- a/tests/signature/lib/common/src/android/signature/cts/DexMember.java
+++ b/tests/signature/lib/common/src/android/signature/cts/DexMember.java
@@ -97,4 +97,35 @@
 
         return javaType + javaDimension;
     }
+
+    public static Class<?> typeToClass(String type) throws ClassNotFoundException {
+        if ("V".equals(type)) {
+            return void.class;
+        } else if ("Z".equals(type)) {
+            return boolean.class;
+        } else if ("B".equals(type)) {
+            return byte.class;
+        } else if ("C".equals(type)) {
+            return char.class;
+        } else if ("S".equals(type)) {
+            return short.class;
+        } else if ("I".equals(type)) {
+            return int.class;
+        } else if ("J".equals(type)) {
+            return long.class;
+        } else if ("F".equals(type)) {
+            return float.class;
+        } else if ("D".equals(type)) {
+            return double.class;
+        } else {
+            // Class names expected for Class.forName are:
+            // * for reference types: Ljava/lang/String; -> java.lang.String
+            // * for array types: [Ljava/lang/String; -> [Ljava.lang.String;
+            type = type.startsWith("L")
+                    ? type.substring(1, type.length() - 1).replace('/', '.')
+                    : type.replace('/', '.');
+        }
+
+        return Class.forName(type, /* initialize */ false, DexMember.class.getClassLoader());
+    }
 }
diff --git a/tests/signature/lib/common/src/android/signature/cts/DexMethod.java b/tests/signature/lib/common/src/android/signature/cts/DexMethod.java
index 967a5a8..972f69c 100644
--- a/tests/signature/lib/common/src/android/signature/cts/DexMethod.java
+++ b/tests/signature/lib/common/src/android/signature/cts/DexMethod.java
@@ -42,6 +42,17 @@
       return mParamTypeList.stream().map(DexMember::dexToJavaType).collect(Collectors.toList());
   }
 
+  public Class<?>[] getJavaParameterClasses() throws ClassNotFoundException {
+    // Ideally we'd use streams, but DexMember.typeToClass throws a checked exception, and that's
+    // tricky to handle.
+    Class<?>[] classes = new Class<?>[mParamTypeList.size()];
+    int i = 0;
+    for (String param : mParamTypeList) {
+        classes[i++] = DexMember.typeToClass(param);
+    }
+    return classes;
+  }
+
   public boolean isConstructor() {
       return "<init>".equals(getName()) && "V".equals(getDexType());
   }
diff --git a/tests/tests/art/Android.bp b/tests/tests/art/Android.bp
new file mode 100644
index 0000000..86f1d60
--- /dev/null
+++ b/tests/tests/art/Android.bp
@@ -0,0 +1,16 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "CtsArtTestCases",
+    defaults: ["cts_defaults"],
+    static_libs: ["ctstestrunner-axt"],
+    srcs: ["**/*.java"],
+    manifest: "AndroidManifest.xml",
+    sdk_version: "current",
+    test_suites: [
+        "cts",
+        "general-tests",
+    ],
+}
diff --git a/tests/tests/art/AndroidManifest.xml b/tests/tests/art/AndroidManifest.xml
new file mode 100644
index 0000000..ef7cf1a
--- /dev/null
+++ b/tests/tests/art/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2021 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="com.android.art_cts"
+    android:targetSandboxVersion="2">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <instrumentation
+        android:targetPackage="com.android.art_cts"
+        android:name="androidx.test.runner.AndroidJUnitRunner" />
+</manifest>
diff --git a/tests/tests/art/AndroidTest.xml b/tests/tests/art/AndroidTest.xml
new file mode 100644
index 0000000..8036c6f
--- /dev/null
+++ b/tests/tests/art/AndroidTest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2021 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.
+ -->
+<configuration description="Config for CTS ART test cases">
+    <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="art" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsArtTestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.art_cts" />
+    </test>
+</configuration>
diff --git a/tests/tests/art/OWNERS b/tests/tests/art/OWNERS
new file mode 100644
index 0000000..ef86412
--- /dev/null
+++ b/tests/tests/art/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 86431
+include platform/art:/OWNERS
diff --git a/tests/tests/art/com/android/art_cts/ArtTest.java b/tests/tests/art/com/android/art_cts/ArtTest.java
new file mode 100644
index 0000000..9e65048
--- /dev/null
+++ b/tests/tests/art/com/android/art_cts/ArtTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2021 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.art_cts;
+
+import junit.framework.TestCase;
+
+import static junit.framework.Assert.assertEquals;
+
+public class ArtTest extends TestCase {
+
+  static class Helper_b197981962 {
+    int myField;
+    static Helper_b197981962 escape;
+
+    static void runTest(boolean condition) {
+      Helper_b197981962 l = new Helper_b197981962();
+      // LSE will find that this store can be removed, as both branches override the value
+      // with a new one.
+      l.myField = 42;
+      if (condition) {
+        // LSE will remove this store as well, as it's the value after the store of 42 is removed.
+        l.myField = 0;
+        // This makes sure `m` gets materialized. At this point, the bug is that the partial LSE
+        // optimization thinks the value incoming this block for `m.myField` is 42, however that
+        // store, as well as the store to 0, have been removed.
+        escape = l;
+        // Do something the compiler cannot explore.
+        escape.getClass().getDeclaredMethods();
+        assertEquals(0, escape.myField);
+      } else {
+        l.myField = 3;
+        assertEquals(3, l.myField);
+      }
+    }
+  }
+
+  public void test_b197981962() {
+    // Run enough times to trigger compilation.
+    for (int i = 0; i < 100000; ++i) {
+      Helper_b197981962.runTest(true);
+      Helper_b197981962.runTest(false);
+    }
+  }
+}
diff --git a/tests/tests/identity/Android.bp b/tests/tests/identity/Android.bp
index 01e9914..13a43de 100644
--- a/tests/tests/identity/Android.bp
+++ b/tests/tests/identity/Android.bp
@@ -32,6 +32,7 @@
         "androidx.test.rules",
         "compatibility-device-util-axt",
         "ctstestrunner-axt",
+        "identity-credential-util",
         "junit",
         "cts-security-test-support-library",
         "cts-keystore-user-auth-helper-library",
diff --git a/tests/tests/identity/src/android/security/identity/cts/AttestationTest.java b/tests/tests/identity/src/android/security/identity/cts/AttestationTest.java
index c63b793..884d124 100644
--- a/tests/tests/identity/src/android/security/identity/cts/AttestationTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/AttestationTest.java
@@ -51,7 +51,7 @@
 
     @Test
     public void attestationTest() throws Exception {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
diff --git a/tests/tests/identity/src/android/security/identity/cts/CreateItemsRequestTest.java b/tests/tests/identity/src/android/security/identity/cts/CreateItemsRequestTest.java
index 9dbd20c..e48a467 100644
--- a/tests/tests/identity/src/android/security/identity/cts/CreateItemsRequestTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/CreateItemsRequestTest.java
@@ -18,6 +18,8 @@
 
 import static org.junit.Assert.assertEquals;
 
+import com.android.security.identity.internal.Util;
+
 import org.junit.Test;
 
 import java.util.Arrays;
diff --git a/tests/tests/identity/src/android/security/identity/cts/DynamicAuthTest.java b/tests/tests/identity/src/android/security/identity/cts/DynamicAuthTest.java
index f61273e..4d99052 100644
--- a/tests/tests/identity/src/android/security/identity/cts/DynamicAuthTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/DynamicAuthTest.java
@@ -33,6 +33,7 @@
 import android.security.identity.NoAuthenticationKeyAvailableException;
 import android.security.identity.ResultData;
 import androidx.test.InstrumentationRegistry;
+import com.android.security.identity.internal.Util;
 
 import org.junit.Test;
 
@@ -62,7 +63,7 @@
 
     @Test
     public void dynamicAuthTest() throws Exception {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -460,14 +461,14 @@
 
     @Test
     public void dynamicAuthWithExpirationTest() throws Exception {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
         assumeTrue(
             "IdentityCredential.storeStaticAuthenticationData(X509Certificate, Instant, byte[]) " +
             "not supported",
-            Util.getFeatureVersion() >= 202101);
+            TestUtil.getFeatureVersion() >= 202101);
 
         String credentialName = "test";
 
diff --git a/tests/tests/identity/src/android/security/identity/cts/EphemeralKeyTest.java b/tests/tests/identity/src/android/security/identity/cts/EphemeralKeyTest.java
index 4441dd5..0198602 100644
--- a/tests/tests/identity/src/android/security/identity/cts/EphemeralKeyTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/EphemeralKeyTest.java
@@ -30,6 +30,7 @@
 import android.security.identity.IdentityCredentialException;
 import android.security.identity.IdentityCredentialStore;
 import androidx.test.InstrumentationRegistry;
+import com.android.security.identity.internal.Util;
 
 import org.junit.Test;
 
@@ -60,7 +61,7 @@
 
     @Test
     public void createEphemeralKey() throws IdentityCredentialException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
diff --git a/tests/tests/identity/src/android/security/identity/cts/HkdfTest.java b/tests/tests/identity/src/android/security/identity/cts/HkdfTest.java
deleted file mode 100644
index eee69f6..0000000
--- a/tests/tests/identity/src/android/security/identity/cts/HkdfTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright 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.security.identity.cts;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.security.GeneralSecurityException;
-import java.util.Random;
-
-/*
- * This is based on https://github.com/google/tink/blob/master/java/src/test/java/com/google
- * /crypto/tink/subtle/HkdfTest.java
- * which is also Copyright (c) Google and licensed under the Apache 2 license.
- */
-@RunWith(JUnit4.class)
-public class HkdfTest {
-
-    static Random sRandom = new Random();
-
-    /** Encodes a byte array to hex. */
-    static String hexEncode(final byte[] bytes) {
-        String chars = "0123456789abcdef";
-        StringBuilder result = new StringBuilder(2 * bytes.length);
-        for (byte b : bytes) {
-            // convert to unsigned
-            int val = b & 0xff;
-            result.append(chars.charAt(val / 16));
-            result.append(chars.charAt(val % 16));
-        }
-        return result.toString();
-    }
-
-    /** Decodes a hex string to a byte array. */
-    static byte[] hexDecode(String hex) {
-        if (hex.length() % 2 != 0) {
-            throw new IllegalArgumentException("Expected a string of even length");
-        }
-        int size = hex.length() / 2;
-        byte[] result = new byte[size];
-        for (int i = 0; i < size; i++) {
-            int hi = Character.digit(hex.charAt(2 * i), 16);
-            int lo = Character.digit(hex.charAt(2 * i + 1), 16);
-            if ((hi == -1) || (lo == -1)) {
-                throw new IllegalArgumentException("input is not hexadecimal");
-            }
-            result[i] = (byte) (16 * hi + lo);
-        }
-        return result;
-    }
-
-    static byte[] randBytes(int numBytes) {
-        byte[] bytes = new byte[numBytes];
-        sRandom.nextBytes(bytes);
-        return bytes;
-    }
-
-    @Test
-    public void testNullSaltOrInfo() throws Exception {
-        byte[] ikm = randBytes(20);
-        byte[] info = randBytes(20);
-        int size = 40;
-
-        byte[] hkdfWithNullSalt = Util.computeHkdf("HmacSha256", ikm, null, info, size);
-        byte[] hkdfWithEmptySalt = Util.computeHkdf("HmacSha256", ikm, new byte[0], info, size);
-        assertArrayEquals(hkdfWithNullSalt, hkdfWithEmptySalt);
-
-        byte[] salt = randBytes(20);
-        byte[] hkdfWithNullInfo = Util.computeHkdf("HmacSha256", ikm, salt, null, size);
-        byte[] hkdfWithEmptyInfo = Util.computeHkdf("HmacSha256", ikm, salt, new byte[0], size);
-        assertArrayEquals(hkdfWithNullInfo, hkdfWithEmptyInfo);
-    }
-
-    @Test
-    public void testInvalidCodeSize() throws Exception {
-        try {
-            Util.computeHkdf("HmacSha256", new byte[0], new byte[0], new byte[0], 32 * 256);
-            fail("Invalid size, should have thrown exception");
-        } catch (RuntimeException expected) {
-
-            // Expected
-        }
-    }
-
-    /**
-     * Tests the implementation against the test vectors from RFC 5869.
-     */
-    @Test
-    public void testVectors() throws Exception {
-        // Test case 1
-        assertEquals(
-                "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf"
-                + "1a5a4c5db02d56ecc4c5bf34007208d5b887185865",
-                computeHkdfHex("HmacSha256",
-                        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
-                        "000102030405060708090a0b0c",
-                        "f0f1f2f3f4f5f6f7f8f9",
-                        42));
-
-        // Test case 2
-        assertEquals(
-                "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c"
-                        + "59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71"
-                        + "cc30c58179ec3e87c14c01d5c1f3434f1d87",
-                computeHkdfHex("HmacSha256",
-                        "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
-                                + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
-                                + "404142434445464748494a4b4c4d4e4f",
-                        "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
-                                + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"
-                                + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf",
-                        "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
-                                + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef"
-                                + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
-                        82));
-
-        // Test case 3: salt is empty
-        assertEquals(
-                "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d"
-                        + "9d201395faa4b61a96c8",
-                computeHkdfHex("HmacSha256",
-                        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "",
-                        42));
-
-        // Test Case 4
-        assertEquals(
-                "085a01ea1b10f36933068b56efa5ad81a4f14b822f"
-                + "5b091568a9cdd4f155fda2c22e422478d305f3f896",
-                computeHkdfHex(
-                        "HmacSha1",
-                        "0b0b0b0b0b0b0b0b0b0b0b",
-                        "000102030405060708090a0b0c",
-                        "f0f1f2f3f4f5f6f7f8f9",
-                        42));
-
-        // Test Case 5
-        assertEquals(
-                "0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe"
-                        + "8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e"
-                        + "927336d0441f4c4300e2cff0d0900b52d3b4",
-                computeHkdfHex(
-                        "HmacSha1",
-                        "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
-                                + "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
-                                + "404142434445464748494a4b4c4d4e4f",
-                        "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f"
-                                + "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f"
-                                + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf",
-                        "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
-                                + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef"
-                                + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
-                        82));
-
-        // Test Case 6: salt is empty
-        assertEquals(
-                "0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0"
-                        + "ea00033de03984d34918",
-                computeHkdfHex("HmacSha1", "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", "", "",
-                        42));
-
-        // Test Case 7
-        assertEquals(
-                "2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5"
-                        + "673a081d70cce7acfc48",
-                computeHkdfHex("HmacSha1", "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c", "", "",
-                        42));
-    }
-
-    /**
-     * Test version of Hkdf where all inputs and outputs are hexadecimal.
-     */
-    private String computeHkdfHex(String macAlgorithm, String ikmHex, String saltHex,
-            String infoHex,
-            int size) throws GeneralSecurityException {
-        return hexEncode(
-                Util.computeHkdf(macAlgorithm, hexDecode(ikmHex), hexDecode(saltHex),
-                        hexDecode(infoHex), size));
-    }
-
-}
diff --git a/tests/tests/identity/src/android/security/identity/cts/ProvisioningTest.java b/tests/tests/identity/src/android/security/identity/cts/ProvisioningTest.java
index b78cb98..fdd623c 100644
--- a/tests/tests/identity/src/android/security/identity/cts/ProvisioningTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/ProvisioningTest.java
@@ -42,6 +42,7 @@
 import android.security.identity.WritableIdentityCredential;
 import android.security.identity.SessionTranscriptMismatchException;
 import androidx.test.InstrumentationRegistry;
+import com.android.security.identity.internal.Util;
 
 import org.junit.Test;
 
@@ -368,7 +369,7 @@
 
     @Test
     public void alreadyPersonalized() throws IdentityCredentialException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -387,7 +388,7 @@
 
     @Test
     public void nonExistent() throws IdentityCredentialException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -400,7 +401,7 @@
 
     @Test
     public void defaultStoreSupportsAnyDocumentType() throws IdentityCredentialException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -412,7 +413,7 @@
     @Test
     public void deleteCredentialByName()
             throws IdentityCredentialException, CborException, CertificateEncodingException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -450,11 +451,11 @@
     @Test
     public void deleteCredential()
             throws IdentityCredentialException, CborException, CertificateEncodingException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
-        assumeTrue("IdentityCredential.delete() not supported", Util.getFeatureVersion() >= 202101);
+        assumeTrue("IdentityCredential.delete() not supported", TestUtil.getFeatureVersion() >= 202101);
 
         store.deleteCredentialByName("test");
         assertNull(store.deleteCredentialByName("test"));
@@ -494,11 +495,11 @@
     @Test
     public void proofOfOwnership()
             throws IdentityCredentialException, CborException, CertificateEncodingException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
-        assumeTrue("IdentityCredential.proveOwnership() not supported", Util.getFeatureVersion() >= 202101);
+        assumeTrue("IdentityCredential.proveOwnership() not supported", TestUtil.getFeatureVersion() >= 202101);
 
         store.deleteCredentialByName("test");
         assertNull(store.deleteCredentialByName("test"));
@@ -535,7 +536,7 @@
 
     @Test
     public void testProvisionAndRetrieve() throws IdentityCredentialException, CborException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -625,7 +626,7 @@
     @Test
     public void testProvisionAndRetrieveMultipleTimes() throws IdentityCredentialException,
             InvalidKeyException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -688,7 +689,7 @@
 
     @Test
     public void testProvisionAndRetrieveWithFiltering() throws IdentityCredentialException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -741,7 +742,7 @@
 
     @Test
     public void testProvisionAndRetrieveElementWithNoACP() throws IdentityCredentialException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -782,7 +783,7 @@
 
     @Test
     public void testProvisionAndRetrieveWithEntryNotInRequest() throws IdentityCredentialException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -838,7 +839,7 @@
 
     @Test
     public void nonExistentEntries() throws IdentityCredentialException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -883,7 +884,7 @@
 
     @Test
     public void multipleNamespaces() throws IdentityCredentialException, CborException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -978,7 +979,7 @@
 
     @Test
     public void testProvisionAcpIdNotInValidRange() throws IdentityCredentialException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -1016,7 +1017,7 @@
     @Test
     public void testProvisionAcpIdNotStartingAtZero() throws
             IdentityCredentialException, CborException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
@@ -1105,11 +1106,11 @@
 
     @Test
     public void testUpdateCredential() throws IdentityCredentialException, CborException, NoSuchAlgorithmException {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         Context appContext = InstrumentationRegistry.getTargetContext();
         IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
-        assumeTrue("IdentityCredential.update() not supported", Util.getFeatureVersion() >= 202101);
+        assumeTrue("IdentityCredential.update() not supported", TestUtil.getFeatureVersion() >= 202101);
 
         // Create the credential...
         //
diff --git a/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java b/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java
index ce5e311..f01a1fd 100644
--- a/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java
@@ -29,6 +29,7 @@
 import android.content.Context;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
+import com.android.security.identity.internal.Util;
 
 import android.security.identity.AccessControlProfile;
 import android.security.identity.AccessControlProfileId;
@@ -86,7 +87,7 @@
             KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException,
             NoSuchProviderException, InvalidKeyException, SignatureException {
 
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         // We create two reader keys - 'A' and 'B' - and then generate certificates for each of
         // them, signed by a third key 'C'. We then provision a document with four elements where
diff --git a/tests/tests/identity/src/android/security/identity/cts/TestUtil.java b/tests/tests/identity/src/android/security/identity/cts/TestUtil.java
new file mode 100644
index 0000000..882439a
--- /dev/null
+++ b/tests/tests/identity/src/android/security/identity/cts/TestUtil.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 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.security.identity.cts;
+
+import android.security.identity.ResultData;
+import android.security.identity.IdentityCredentialStore;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.FeatureInfo;
+import android.os.SystemProperties;
+import android.security.keystore.KeyProperties;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.test.InstrumentationRegistry;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.ECGenParameterSpec;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Formatter;
+import java.util.Map;
+
+import javax.crypto.KeyAgreement;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECPoint;
+
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.ASN1OctetString;
+
+import co.nstant.in.cbor.CborBuilder;
+import co.nstant.in.cbor.CborDecoder;
+import co.nstant.in.cbor.CborEncoder;
+import co.nstant.in.cbor.CborException;
+import co.nstant.in.cbor.builder.ArrayBuilder;
+import co.nstant.in.cbor.builder.MapBuilder;
+import co.nstant.in.cbor.model.AbstractFloat;
+import co.nstant.in.cbor.model.Array;
+import co.nstant.in.cbor.model.ByteString;
+import co.nstant.in.cbor.model.DataItem;
+import co.nstant.in.cbor.model.DoublePrecisionFloat;
+import co.nstant.in.cbor.model.MajorType;
+import co.nstant.in.cbor.model.NegativeInteger;
+import co.nstant.in.cbor.model.SimpleValue;
+import co.nstant.in.cbor.model.SimpleValueType;
+import co.nstant.in.cbor.model.SpecialType;
+import co.nstant.in.cbor.model.UnicodeString;
+import co.nstant.in.cbor.model.UnsignedInteger;
+
+class TestUtil {
+    private static final String TAG = "Util";
+
+    // Returns 0 if not implemented. Otherwise returns the feature version.
+    //
+    static int getFeatureVersion() {
+        Context appContext = InstrumentationRegistry.getTargetContext();
+        PackageManager pm = appContext.getPackageManager();
+
+        int featureVersionFromPm = 0;
+        if (pm.hasSystemFeature(PackageManager.FEATURE_IDENTITY_CREDENTIAL_HARDWARE)) {
+            FeatureInfo info = null;
+            FeatureInfo[] infos = pm.getSystemAvailableFeatures();
+            for (int n = 0; n < infos.length; n++) {
+                FeatureInfo i = infos[n];
+                if (i.name.equals(PackageManager.FEATURE_IDENTITY_CREDENTIAL_HARDWARE)) {
+                    info = i;
+                    break;
+                }
+            }
+            if (info != null) {
+                featureVersionFromPm = info.version;
+            }
+        }
+
+        // Use of the system feature is not required since Android 12. So for Android 11
+        // return 202009 which is the feature version shipped with Android 11.
+        if (featureVersionFromPm == 0) {
+            IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
+            if (store != null) {
+                featureVersionFromPm = 202009;
+            }
+        }
+
+        return featureVersionFromPm;
+    }
+
+    // Returns true if, and only if, the Identity Credential HAL (and credstore) is implemented
+    // on the device under test.
+    static boolean isHalImplemented() {
+        Context appContext = InstrumentationRegistry.getTargetContext();
+        IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
+        if (store != null) {
+            return true;
+        }
+        return false;
+    }
+
+    // Returns true if, and only if, the Direct Access Identity Credential HAL (and credstore) is
+    // implemented on the device under test.
+    static boolean isDirectAccessHalImplemented() {
+        Context appContext = InstrumentationRegistry.getTargetContext();
+        IdentityCredentialStore store = IdentityCredentialStore.getDirectAccessInstance(appContext);
+        if (store != null) {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/tests/tests/identity/src/android/security/identity/cts/UserAuthTest.java b/tests/tests/identity/src/android/security/identity/cts/UserAuthTest.java
index 2c55042..e4bd81f 100644
--- a/tests/tests/identity/src/android/security/identity/cts/UserAuthTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/UserAuthTest.java
@@ -27,6 +27,7 @@
 import android.security.identity.IdentityCredentialStore;
 import android.security.identity.WritableIdentityCredential;
 import android.security.identity.ResultData;
+import com.android.security.identity.internal.Util;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -197,7 +198,7 @@
     }
 
     void doTestUserAuth(DeviceLockSession dl, KeyguardManager keyguardManager) throws Exception {
-        assumeTrue("IC HAL is not implemented", Util.isHalImplemented());
+        assumeTrue("IC HAL is not implemented", TestUtil.isHalImplemented());
 
         // This test creates two different access control profiles:
         //
diff --git a/tests/tests/identity/src/android/security/identity/cts/Util.java b/tests/tests/identity/src/android/security/identity/cts/Util.java
deleted file mode 100644
index 733a401..0000000
--- a/tests/tests/identity/src/android/security/identity/cts/Util.java
+++ /dev/null
@@ -1,1363 +0,0 @@
-/*
- * Copyright 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.security.identity.cts;
-
-import android.security.identity.ResultData;
-import android.security.identity.IdentityCredentialStore;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.FeatureInfo;
-import android.os.SystemProperties;
-import android.security.keystore.KeyProperties;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.test.InstrumentationRegistry;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.KeyStore;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.PublicKey;
-import java.security.PrivateKey;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.spec.ECGenParameterSpec;
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Formatter;
-import java.util.Map;
-
-import javax.crypto.KeyAgreement;
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECPoint;
-
-import org.bouncycastle.asn1.ASN1InputStream;
-import org.bouncycastle.asn1.ASN1OctetString;
-
-import co.nstant.in.cbor.CborBuilder;
-import co.nstant.in.cbor.CborDecoder;
-import co.nstant.in.cbor.CborEncoder;
-import co.nstant.in.cbor.CborException;
-import co.nstant.in.cbor.builder.ArrayBuilder;
-import co.nstant.in.cbor.builder.MapBuilder;
-import co.nstant.in.cbor.model.AbstractFloat;
-import co.nstant.in.cbor.model.Array;
-import co.nstant.in.cbor.model.ByteString;
-import co.nstant.in.cbor.model.DataItem;
-import co.nstant.in.cbor.model.DoublePrecisionFloat;
-import co.nstant.in.cbor.model.MajorType;
-import co.nstant.in.cbor.model.NegativeInteger;
-import co.nstant.in.cbor.model.SimpleValue;
-import co.nstant.in.cbor.model.SimpleValueType;
-import co.nstant.in.cbor.model.SpecialType;
-import co.nstant.in.cbor.model.UnicodeString;
-import co.nstant.in.cbor.model.UnsignedInteger;
-
-class Util {
-    private static final String TAG = "Util";
-
-    // Returns 0 if not implemented. Otherwise returns the feature version.
-    //
-    static int getFeatureVersion() {
-        Context appContext = InstrumentationRegistry.getTargetContext();
-        PackageManager pm = appContext.getPackageManager();
-
-        int featureVersionFromPm = 0;
-        if (pm.hasSystemFeature(PackageManager.FEATURE_IDENTITY_CREDENTIAL_HARDWARE)) {
-            FeatureInfo info = null;
-            FeatureInfo[] infos = pm.getSystemAvailableFeatures();
-            for (int n = 0; n < infos.length; n++) {
-                FeatureInfo i = infos[n];
-                if (i.name.equals(PackageManager.FEATURE_IDENTITY_CREDENTIAL_HARDWARE)) {
-                    info = i;
-                    break;
-                }
-            }
-            if (info != null) {
-                featureVersionFromPm = info.version;
-            }
-        }
-
-        // Use of the system feature is not required since Android 12. So for Android 11
-        // return 202009 which is the feature version shipped with Android 11.
-        if (featureVersionFromPm == 0) {
-            IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
-            if (store != null) {
-                featureVersionFromPm = 202009;
-            }
-        }
-
-        return featureVersionFromPm;
-    }
-
-    static byte[] canonicalizeCbor(byte[] encodedCbor) throws CborException {
-        ByteArrayInputStream bais = new ByteArrayInputStream(encodedCbor);
-        List<DataItem> dataItems = new CborDecoder(bais).decode();
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        for(DataItem dataItem : dataItems) {
-            CborEncoder encoder = new CborEncoder(baos);
-            encoder.encode(dataItem);
-        }
-        return baos.toByteArray();
-    }
-
-
-    static String cborPrettyPrint(byte[] encodedBytes) throws CborException {
-        StringBuilder sb = new StringBuilder();
-
-        ByteArrayInputStream bais = new ByteArrayInputStream(encodedBytes);
-        List<DataItem> dataItems = new CborDecoder(bais).decode();
-        int count = 0;
-        for (DataItem dataItem : dataItems) {
-            if (count > 0) {
-                sb.append(",\n");
-            }
-            cborPrettyPrintDataItem(sb, 0, dataItem);
-            count++;
-        }
-
-        return sb.toString();
-    }
-
-    // Returns true iff all elements in |items| are not compound (e.g. an array or a map).
-    static boolean cborAreAllDataItemsNonCompound(List<DataItem> items) {
-        for (DataItem item : items) {
-            switch (item.getMajorType()) {
-                case ARRAY:
-                case MAP:
-                    return false;
-                default:
-                    // continue inspecting other data items
-            }
-        }
-        return true;
-    }
-
-    static void cborPrettyPrintDataItem(StringBuilder sb, int indent, DataItem dataItem) {
-        StringBuilder indentBuilder = new StringBuilder();
-        for (int n = 0; n < indent; n++) {
-            indentBuilder.append(' ');
-        }
-        String indentString = indentBuilder.toString();
-
-        if (dataItem.hasTag()) {
-            sb.append(String.format("tag %d ", dataItem.getTag().getValue()));
-        }
-
-        switch (dataItem.getMajorType()) {
-            case INVALID:
-                // TODO: throw
-                sb.append("<invalid>");
-                break;
-            case UNSIGNED_INTEGER: {
-                // Major type 0: an unsigned integer.
-                BigInteger value = ((UnsignedInteger) dataItem).getValue();
-                sb.append(value);
-            }
-            break;
-            case NEGATIVE_INTEGER: {
-                // Major type 1: a negative integer.
-                BigInteger value = ((NegativeInteger) dataItem).getValue();
-                sb.append(value);
-            }
-            break;
-            case BYTE_STRING: {
-                // Major type 2: a byte string.
-                byte[] value = ((ByteString) dataItem).getBytes();
-                sb.append("[");
-                int count = 0;
-                for (byte b : value) {
-                    if (count > 0) {
-                        sb.append(", ");
-                    }
-                    sb.append(String.format("0x%02x", b));
-                    count++;
-                }
-                sb.append("]");
-            }
-            break;
-            case UNICODE_STRING: {
-                // Major type 3: string of Unicode characters that is encoded as UTF-8 [RFC3629].
-                String value = ((UnicodeString) dataItem).getString();
-                // TODO: escape ' in |value|
-                sb.append("'" + value + "'");
-            }
-            break;
-            case ARRAY: {
-                // Major type 4: an array of data items.
-                List<DataItem> items = ((co.nstant.in.cbor.model.Array) dataItem).getDataItems();
-                if (items.size() == 0) {
-                    sb.append("[]");
-                } else if (cborAreAllDataItemsNonCompound(items)) {
-                    // The case where everything fits on one line.
-                    sb.append("[");
-                    int count = 0;
-                    for (DataItem item : items) {
-                        cborPrettyPrintDataItem(sb, indent, item);
-                        if (++count < items.size()) {
-                            sb.append(", ");
-                        }
-                    }
-                    sb.append("]");
-                } else {
-                    sb.append("[\n" + indentString);
-                    int count = 0;
-                    for (DataItem item : items) {
-                        sb.append("  ");
-                        cborPrettyPrintDataItem(sb, indent + 2, item);
-                        if (++count < items.size()) {
-                            sb.append(",");
-                        }
-                        sb.append("\n" + indentString);
-                    }
-                    sb.append("]");
-                }
-            }
-            break;
-            case MAP: {
-                // Major type 5: a map of pairs of data items.
-                Collection<DataItem> keys = ((co.nstant.in.cbor.model.Map) dataItem).getKeys();
-                if (keys.size() == 0) {
-                    sb.append("{}");
-                } else {
-                    sb.append("{\n" + indentString);
-                    int count = 0;
-                    for (DataItem key : keys) {
-                        sb.append("  ");
-                        DataItem value = ((co.nstant.in.cbor.model.Map) dataItem).get(key);
-                        cborPrettyPrintDataItem(sb, indent + 2, key);
-                        sb.append(" : ");
-                        cborPrettyPrintDataItem(sb, indent + 2, value);
-                        if (++count < keys.size()) {
-                            sb.append(",");
-                        }
-                        sb.append("\n" + indentString);
-                    }
-                    sb.append("}");
-                }
-            }
-            break;
-            case TAG:
-                // Major type 6: optional semantic tagging of other major types
-                //
-                // We never encounter this one since it's automatically handled via the
-                // DataItem that is tagged.
-                throw new RuntimeException("Semantic tag data item not expected");
-
-            case SPECIAL:
-                // Major type 7: floating point numbers and simple data types that need no
-                // content, as well as the "break" stop code.
-                if (dataItem instanceof SimpleValue) {
-                    switch (((SimpleValue) dataItem).getSimpleValueType()) {
-                        case FALSE:
-                            sb.append("false");
-                            break;
-                        case TRUE:
-                            sb.append("true");
-                            break;
-                        case NULL:
-                            sb.append("null");
-                            break;
-                        case UNDEFINED:
-                            sb.append("undefined");
-                            break;
-                        case RESERVED:
-                            sb.append("reserved");
-                            break;
-                        case UNALLOCATED:
-                            sb.append("unallocated");
-                            break;
-                    }
-                } else if (dataItem instanceof DoublePrecisionFloat) {
-                    DecimalFormat df = new DecimalFormat("0",
-                            DecimalFormatSymbols.getInstance(Locale.ENGLISH));
-                    df.setMaximumFractionDigits(340);
-                    sb.append(df.format(((DoublePrecisionFloat) dataItem).getValue()));
-                } else if (dataItem instanceof AbstractFloat) {
-                    DecimalFormat df = new DecimalFormat("0",
-                            DecimalFormatSymbols.getInstance(Locale.ENGLISH));
-                    df.setMaximumFractionDigits(340);
-                    sb.append(df.format(((AbstractFloat) dataItem).getValue()));
-                } else {
-                    sb.append("break");
-                }
-                break;
-        }
-    }
-
-    public static byte[] encodeCbor(List<DataItem> dataItems) {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        CborEncoder encoder = new CborEncoder(baos);
-        try {
-            encoder.encode(dataItems);
-        } catch (CborException e) {
-            throw new RuntimeException("Error encoding data", e);
-        }
-        return baos.toByteArray();
-    }
-
-    public static byte[] coseBuildToBeSigned(byte[] encodedProtectedHeaders,
-            byte[] payload,
-            byte[] detachedContent) {
-        CborBuilder sigStructure = new CborBuilder();
-        ArrayBuilder<CborBuilder> array = sigStructure.addArray();
-
-        array.add("Signature1");
-        array.add(encodedProtectedHeaders);
-
-        // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
-        // so external_aad is the empty bstr
-        byte emptyExternalAad[] = new byte[0];
-        array.add(emptyExternalAad);
-
-        // Next field is the payload, independently of how it's transported (RFC
-        // 8152 section 4.4). Since our API specifies only one of |data| and
-        // |detachedContent| can be non-empty, it's simply just the non-empty one.
-        if (payload != null && payload.length > 0) {
-            array.add(payload);
-        } else {
-            array.add(detachedContent);
-        }
-        array.end();
-        return encodeCbor(sigStructure.build());
-    }
-
-    private static final int COSE_LABEL_ALG = 1;
-    private static final int COSE_LABEL_X5CHAIN = 33;  // temporary identifier
-
-    // From "COSE Algorithms" registry
-    private static final int COSE_ALG_ECDSA_256 = -7;
-    private static final int COSE_ALG_HMAC_256_256 = 5;
-
-    private static byte[] signatureDerToCose(byte[] signature) {
-        if (signature.length > 128) {
-            throw new RuntimeException("Unexpected length " + signature.length
-                    + ", expected less than 128");
-        }
-        if (signature[0] != 0x30) {
-            throw new RuntimeException("Unexpected first byte " + signature[0]
-                    + ", expected 0x30");
-        }
-        if ((signature[1] & 0x80) != 0x00) {
-            throw new RuntimeException("Unexpected second byte " + signature[1]
-                    + ", bit 7 shouldn't be set");
-        }
-        int rOffset = 2;
-        int rSize = signature[rOffset + 1];
-        byte[] rBytes = stripLeadingZeroes(
-            Arrays.copyOfRange(signature,rOffset + 2, rOffset + rSize + 2));
-
-        int sOffset = rOffset + 2 + rSize;
-        int sSize = signature[sOffset + 1];
-        byte[] sBytes = stripLeadingZeroes(
-            Arrays.copyOfRange(signature, sOffset + 2, sOffset + sSize + 2));
-
-        if (rBytes.length > 32) {
-            throw new RuntimeException("rBytes.length is " + rBytes.length + " which is > 32");
-        }
-        if (sBytes.length > 32) {
-            throw new RuntimeException("sBytes.length is " + sBytes.length + " which is > 32");
-        }
-
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try {
-            for (int n = 0; n < 32 - rBytes.length; n++) {
-                baos.write(0x00);
-            }
-            baos.write(rBytes);
-            for (int n = 0; n < 32 - sBytes.length; n++) {
-                baos.write(0x00);
-            }
-            baos.write(sBytes);
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-        return baos.toByteArray();
-    }
-
-    // Adds leading 0x00 if the first encoded byte MSB is set.
-    private static byte[] encodePositiveBigInteger(BigInteger i) {
-        byte[] bytes = i.toByteArray();
-        if ((bytes[0] & 0x80) != 0) {
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            try {
-                baos.write(0x00);
-                baos.write(bytes);
-            } catch (IOException e) {
-                e.printStackTrace();
-                throw new RuntimeException("Failed writing data", e);
-            }
-            bytes = baos.toByteArray();
-        }
-        return bytes;
-    }
-
-    private static byte[] signatureCoseToDer(byte[] signature) {
-        if (signature.length != 64) {
-            throw new RuntimeException("signature.length is " + signature.length + ", expected 64");
-        }
-        BigInteger r = new BigInteger(Arrays.copyOfRange(signature, 0, 32));
-        BigInteger s = new BigInteger(Arrays.copyOfRange(signature, 32, 64));
-        byte[] rBytes = encodePositiveBigInteger(r);
-        byte[] sBytes = encodePositiveBigInteger(s);
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try {
-            baos.write(0x30);
-            baos.write(2 + rBytes.length + 2 + sBytes.length);
-            baos.write(0x02);
-            baos.write(rBytes.length);
-            baos.write(rBytes);
-            baos.write(0x02);
-            baos.write(sBytes.length);
-            baos.write(sBytes);
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-        return baos.toByteArray();
-    }
-
-    public static byte[] coseSign1Sign(PrivateKey key,
-            @Nullable byte[] data,
-            byte[] detachedContent,
-            @Nullable Collection<X509Certificate> certificateChain)
-            throws NoSuchAlgorithmException, InvalidKeyException, CertificateEncodingException {
-
-        int dataLen = (data != null ? data.length : 0);
-        int detachedContentLen = (detachedContent != null ? detachedContent.length : 0);
-        if (dataLen > 0 && detachedContentLen > 0) {
-            throw new RuntimeException("data and detachedContent cannot both be non-empty");
-        }
-
-        CborBuilder protectedHeaders = new CborBuilder();
-        MapBuilder<CborBuilder> protectedHeadersMap = protectedHeaders.addMap();
-        protectedHeadersMap.put(COSE_LABEL_ALG, COSE_ALG_ECDSA_256);
-        byte[] protectedHeadersBytes = encodeCbor(protectedHeaders.build());
-
-        byte[] toBeSigned = coseBuildToBeSigned(protectedHeadersBytes, data, detachedContent);
-
-        byte[] coseSignature = null;
-        try {
-            Signature s = Signature.getInstance("SHA256withECDSA");
-            s.initSign(key);
-            s.update(toBeSigned);
-            byte[] derSignature = s.sign();
-            coseSignature = signatureDerToCose(derSignature);
-        } catch (SignatureException e) {
-            throw new RuntimeException("Error signing data");
-        }
-
-        CborBuilder builder = new CborBuilder();
-        ArrayBuilder<CborBuilder> array = builder.addArray();
-        array.add(protectedHeadersBytes);
-        MapBuilder<ArrayBuilder<CborBuilder>> unprotectedHeaders = array.addMap();
-        if (certificateChain != null && certificateChain.size() > 0) {
-            if (certificateChain.size() == 1) {
-                X509Certificate cert = certificateChain.iterator().next();
-                unprotectedHeaders.put(COSE_LABEL_X5CHAIN, cert.getEncoded());
-            } else {
-                ArrayBuilder<MapBuilder<ArrayBuilder<CborBuilder>>> x5chainsArray =
-                        unprotectedHeaders.putArray(COSE_LABEL_X5CHAIN);
-                for (X509Certificate cert : certificateChain) {
-                    x5chainsArray.add(cert.getEncoded());
-                }
-            }
-        }
-        if (data == null || data.length == 0) {
-            array.add(new SimpleValue(SimpleValueType.NULL));
-        } else {
-            array.add(data);
-        }
-        array.add(coseSignature);
-
-        return encodeCbor(builder.build());
-    }
-
-    public static boolean coseSign1CheckSignature(byte[] signatureCose1,
-            byte[] detachedContent,
-            PublicKey publicKey) throws NoSuchAlgorithmException, InvalidKeyException {
-        ByteArrayInputStream bais = new ByteArrayInputStream(signatureCose1);
-        List<DataItem> dataItems = null;
-        try {
-            dataItems = new CborDecoder(bais).decode();
-        } catch (CborException e) {
-            throw new RuntimeException("Given signature is not valid CBOR", e);
-        }
-        if (dataItems.size() != 1) {
-            throw new RuntimeException("Expected just one data item");
-        }
-        DataItem dataItem = dataItems.get(0);
-        if (dataItem.getMajorType() != MajorType.ARRAY) {
-            throw new RuntimeException("Data item is not an array");
-        }
-        List<DataItem> items = ((co.nstant.in.cbor.model.Array) dataItem).getDataItems();
-        if (items.size() < 4) {
-            throw new RuntimeException("Expected at least four items in COSE_Sign1 array");
-        }
-        if (items.get(0).getMajorType() != MajorType.BYTE_STRING) {
-            throw new RuntimeException("Item 0 (protected headers) is not a byte-string");
-        }
-        byte[] encodedProtectedHeaders =
-                ((co.nstant.in.cbor.model.ByteString) items.get(0)).getBytes();
-        byte[] payload = new byte[0];
-        if (items.get(2).getMajorType() == MajorType.SPECIAL) {
-            if (((co.nstant.in.cbor.model.Special) items.get(2)).getSpecialType()
-                != SpecialType.SIMPLE_VALUE) {
-                throw new RuntimeException("Item 2 (payload) is a special but not a simple value");
-            }
-            SimpleValue simple = (co.nstant.in.cbor.model.SimpleValue) items.get(2);
-            if (simple.getSimpleValueType() != SimpleValueType.NULL) {
-                throw new RuntimeException("Item 2 (payload) is a simple but not the value null");
-            }
-        } else if (items.get(2).getMajorType() == MajorType.BYTE_STRING) {
-            payload = ((co.nstant.in.cbor.model.ByteString) items.get(2)).getBytes();
-        } else {
-            throw new RuntimeException("Item 2 (payload) is not nil or byte-string");
-        }
-        if (items.get(3).getMajorType() != MajorType.BYTE_STRING) {
-            throw new RuntimeException("Item 3 (signature) is not a byte-string");
-        }
-        byte[] coseSignature = ((co.nstant.in.cbor.model.ByteString) items.get(3)).getBytes();
-
-        byte[] derSignature = signatureCoseToDer(coseSignature);
-
-        int dataLen = payload.length;
-        int detachedContentLen = (detachedContent != null ? detachedContent.length : 0);
-        if (dataLen > 0 && detachedContentLen > 0) {
-            throw new RuntimeException("data and detachedContent cannot both be non-empty");
-        }
-
-        byte[] toBeSigned = Util.coseBuildToBeSigned(encodedProtectedHeaders,
-                payload, detachedContent);
-
-        try {
-            Signature verifier = Signature.getInstance("SHA256withECDSA");
-            verifier.initVerify(publicKey);
-            verifier.update(toBeSigned);
-            return verifier.verify(derSignature);
-        } catch (SignatureException e) {
-            throw new RuntimeException("Error verifying signature");
-        }
-    }
-
-    // Returns the empty byte-array if no data is included in the structure.
-    //
-    // Throws RuntimeException if the given bytes aren't valid COSE_Sign1.
-    //
-    public static byte[] coseSign1GetData(byte[] signatureCose1) {
-        ByteArrayInputStream bais = new ByteArrayInputStream(signatureCose1);
-        List<DataItem> dataItems = null;
-        try {
-            dataItems = new CborDecoder(bais).decode();
-        } catch (CborException e) {
-            throw new RuntimeException("Given signature is not valid CBOR", e);
-        }
-        if (dataItems.size() != 1) {
-            throw new RuntimeException("Expected just one data item");
-        }
-        DataItem dataItem = dataItems.get(0);
-        if (dataItem.getMajorType() != MajorType.ARRAY) {
-            throw new RuntimeException("Data item is not an array");
-        }
-        List<DataItem> items = ((co.nstant.in.cbor.model.Array) dataItem).getDataItems();
-        if (items.size() < 4) {
-            throw new RuntimeException("Expected at least four items in COSE_Sign1 array");
-        }
-        byte[] payload = new byte[0];
-        if (items.get(2).getMajorType() == MajorType.SPECIAL) {
-            if (((co.nstant.in.cbor.model.Special) items.get(2)).getSpecialType()
-                != SpecialType.SIMPLE_VALUE) {
-                throw new RuntimeException("Item 2 (payload) is a special but not a simple value");
-            }
-            SimpleValue simple = (co.nstant.in.cbor.model.SimpleValue) items.get(2);
-            if (simple.getSimpleValueType() != SimpleValueType.NULL) {
-                throw new RuntimeException("Item 2 (payload) is a simple but not the value null");
-            }
-        } else if (items.get(2).getMajorType() == MajorType.BYTE_STRING) {
-            payload = ((co.nstant.in.cbor.model.ByteString) items.get(2)).getBytes();
-        } else {
-            throw new RuntimeException("Item 2 (payload) is not nil or byte-string");
-        }
-        return payload;
-    }
-
-    // Returns the empty collection if no x5chain is included in the structure.
-    //
-    // Throws RuntimeException if the given bytes aren't valid COSE_Sign1.
-    //
-    public static Collection<X509Certificate> coseSign1GetX5Chain(byte[] signatureCose1)
-            throws CertificateException {
-        ArrayList<X509Certificate> ret = new ArrayList<>();
-        ByteArrayInputStream bais = new ByteArrayInputStream(signatureCose1);
-        List<DataItem> dataItems = null;
-        try {
-            dataItems = new CborDecoder(bais).decode();
-        } catch (CborException e) {
-            throw new RuntimeException("Given signature is not valid CBOR", e);
-        }
-        if (dataItems.size() != 1) {
-            throw new RuntimeException("Expected just one data item");
-        }
-        DataItem dataItem = dataItems.get(0);
-        if (dataItem.getMajorType() != MajorType.ARRAY) {
-            throw new RuntimeException("Data item is not an array");
-        }
-        List<DataItem> items = ((co.nstant.in.cbor.model.Array) dataItem).getDataItems();
-        if (items.size() < 4) {
-            throw new RuntimeException("Expected at least four items in COSE_Sign1 array");
-        }
-        if (items.get(1).getMajorType() != MajorType.MAP) {
-            throw new RuntimeException("Item 1 (unprocted headers) is not a map");
-        }
-        co.nstant.in.cbor.model.Map map = (co.nstant.in.cbor.model.Map) items.get(1);
-        DataItem x5chainItem = map.get(new UnsignedInteger(COSE_LABEL_X5CHAIN));
-        if (x5chainItem != null) {
-            CertificateFactory factory = CertificateFactory.getInstance("X.509");
-            if (x5chainItem instanceof ByteString) {
-                ByteArrayInputStream certBais =
-                        new ByteArrayInputStream(((ByteString) x5chainItem).getBytes());
-                ret.add((X509Certificate) factory.generateCertificate(certBais));
-            } else if (x5chainItem instanceof Array) {
-                for (DataItem certItem : ((Array) x5chainItem).getDataItems()) {
-                    if (!(certItem instanceof ByteString)) {
-                        throw new RuntimeException(
-                            "Unexpected type for array item in x5chain value");
-                    }
-                    ByteArrayInputStream certBais =
-                            new ByteArrayInputStream(((ByteString) certItem).getBytes());
-                    ret.add((X509Certificate) factory.generateCertificate(certBais));
-                }
-            } else {
-                throw new RuntimeException("Unexpected type for x5chain value");
-            }
-        }
-        return ret;
-    }
-
-    public static byte[] coseBuildToBeMACed(byte[] encodedProtectedHeaders,
-            byte[] payload,
-            byte[] detachedContent) {
-        CborBuilder macStructure = new CborBuilder();
-        ArrayBuilder<CborBuilder> array = macStructure.addArray();
-
-        array.add("MAC0");
-        array.add(encodedProtectedHeaders);
-
-        // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
-        // so external_aad is the empty bstr
-        byte emptyExternalAad[] = new byte[0];
-        array.add(emptyExternalAad);
-
-        // Next field is the payload, independently of how it's transported (RFC
-        // 8152 section 4.4). Since our API specifies only one of |data| and
-        // |detachedContent| can be non-empty, it's simply just the non-empty one.
-        if (payload != null && payload.length > 0) {
-            array.add(payload);
-        } else {
-            array.add(detachedContent);
-        }
-
-        return encodeCbor(macStructure.build());
-    }
-
-    public static byte[] coseMac0(SecretKey key,
-            @Nullable byte[] data,
-            byte[] detachedContent)
-            throws NoSuchAlgorithmException, InvalidKeyException, CertificateEncodingException {
-
-        int dataLen = (data != null ? data.length : 0);
-        int detachedContentLen = (detachedContent != null ? detachedContent.length : 0);
-        if (dataLen > 0 && detachedContentLen > 0) {
-            throw new RuntimeException("data and detachedContent cannot both be non-empty");
-        }
-
-        CborBuilder protectedHeaders = new CborBuilder();
-        MapBuilder<CborBuilder> protectedHeadersMap = protectedHeaders.addMap();
-        protectedHeadersMap.put(COSE_LABEL_ALG, COSE_ALG_HMAC_256_256);
-        byte[] protectedHeadersBytes = encodeCbor(protectedHeaders.build());
-
-        byte[] toBeMACed = coseBuildToBeMACed(protectedHeadersBytes, data, detachedContent);
-
-        byte[] mac = null;
-        Mac m = Mac.getInstance("HmacSHA256");
-        m.init(key);
-        m.update(toBeMACed);
-        mac = m.doFinal();
-
-        CborBuilder builder = new CborBuilder();
-        ArrayBuilder<CborBuilder> array = builder.addArray();
-        array.add(protectedHeadersBytes);
-        MapBuilder<ArrayBuilder<CborBuilder>> unprotectedHeaders = array.addMap();
-        if (data == null || data.length == 0) {
-            array.add(new SimpleValue(SimpleValueType.NULL));
-        } else {
-            array.add(data);
-        }
-        array.add(mac);
-
-        return encodeCbor(builder.build());
-    }
-
-    public static String replaceLine(String text, int lineNumber, String replacementLine) {
-        String[] lines = text.split("\n");
-        int numLines = lines.length;
-        if (lineNumber < 0) {
-            lineNumber = numLines - (-lineNumber);
-        }
-        StringBuilder sb = new StringBuilder();
-        for (int n = 0; n < numLines; n++) {
-            if (n == lineNumber) {
-                sb.append(replacementLine);
-            } else {
-                sb.append(lines[n]);
-            }
-            // Only add terminating newline if passed-in string ends in a newline.
-            if (n == numLines - 1) {
-                if (text.endsWith(("\n"))) {
-                    sb.append('\n');
-                }
-            } else {
-                sb.append('\n');
-            }
-        }
-        return sb.toString();
-    }
-
-    static byte[] cborEncode(DataItem dataItem) {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try {
-            new CborEncoder(baos).encode(dataItem);
-        } catch (CborException e) {
-            // This should never happen and we don't want cborEncode() to throw since that
-            // would complicate all callers. Log it instead.
-            e.printStackTrace();
-            Log.e(TAG, "Error encoding DataItem");
-        }
-        return baos.toByteArray();
-    }
-
-    static byte[] cborEncodeBoolean(boolean value) {
-        return cborEncode(new CborBuilder().add(value).build().get(0));
-    }
-
-    static byte[] cborEncodeString(@NonNull String value) {
-        return cborEncode(new CborBuilder().add(value).build().get(0));
-    }
-
-    static byte[] cborEncodeBytestring(@NonNull byte[] value) {
-        return cborEncode(new CborBuilder().add(value).build().get(0));
-    }
-
-    static byte[] cborEncodeInt(long value) {
-        return cborEncode(new CborBuilder().add(value).build().get(0));
-    }
-
-    static final int CBOR_SEMANTIC_TAG_ENCODED_CBOR = 24;
-
-    static DataItem cborToDataItem(byte[] data) {
-        ByteArrayInputStream bais = new ByteArrayInputStream(data);
-        try {
-            List<DataItem> dataItems = new CborDecoder(bais).decode();
-            if (dataItems.size() != 1) {
-                throw new RuntimeException("Expected 1 item, found " + dataItems.size());
-            }
-            return dataItems.get(0);
-        } catch (CborException e) {
-            throw new RuntimeException("Error decoding data", e);
-        }
-    }
-
-    static boolean cborDecodeBoolean(@NonNull byte[] data) {
-        return cborToDataItem(data) == SimpleValue.TRUE;
-    }
-
-    static String cborDecodeString(@NonNull byte[] data) {
-        return ((co.nstant.in.cbor.model.UnicodeString) cborToDataItem(data)).getString();
-    }
-
-    static long cborDecodeInt(@NonNull byte[] data) {
-        return ((co.nstant.in.cbor.model.Number) cborToDataItem(data)).getValue().longValue();
-    }
-
-    static byte[] cborDecodeBytestring(@NonNull byte[] data) {
-        return ((co.nstant.in.cbor.model.ByteString) cborToDataItem(data)).getBytes();
-    }
-
-    static String getStringEntry(ResultData data, String namespaceName, String name) {
-        return Util.cborDecodeString(data.getEntry(namespaceName, name));
-    }
-
-    static boolean getBooleanEntry(ResultData data, String namespaceName, String name) {
-        return Util.cborDecodeBoolean(data.getEntry(namespaceName, name));
-    }
-
-    static long getIntegerEntry(ResultData data, String namespaceName, String name) {
-        return Util.cborDecodeInt(data.getEntry(namespaceName, name));
-    }
-
-    static byte[] getBytestringEntry(ResultData data, String namespaceName, String name) {
-        return Util.cborDecodeBytestring(data.getEntry(namespaceName, name));
-    }
-
-    /*
-Certificate:
-    Data:
-        Version: 3 (0x2)
-        Serial Number: 1 (0x1)
-    Signature Algorithm: ecdsa-with-SHA256
-        Issuer: CN=fake
-        Validity
-            Not Before: Jan  1 00:00:00 1970 GMT
-            Not After : Jan  1 00:00:00 2048 GMT
-        Subject: CN=fake
-        Subject Public Key Info:
-            Public Key Algorithm: id-ecPublicKey
-                Public-Key: (256 bit)
-                00000000  04 9b 60 70 8a 99 b6 bf  e3 b8 17 02 9e 93 eb 48  |..`p...........H|
-                00000010  23 b9 39 89 d1 00 bf a0  0f d0 2f bd 6b 11 bc d1  |#.9......./.k...|
-                00000020  19 53 54 28 31 00 f5 49  db 31 fb 9f 7d 99 bf 23  |.ST(1..I.1..}..#|
-                00000030  fb 92 04 6b 23 63 55 98  ad 24 d2 68 c4 83 bf 99  |...k#cU..$.h....|
-                00000040  62                                                |b|
-    Signature Algorithm: ecdsa-with-SHA256
-         30:45:02:20:67:ad:d1:34:ed:a5:68:3f:5b:33:ee:b3:18:a2:
-         eb:03:61:74:0f:21:64:4a:a3:2e:82:b3:92:5c:21:0f:88:3f:
-         02:21:00:b7:38:5c:9b:f2:9c:b1:27:86:37:44:df:eb:4a:b2:
-         6c:11:9a:c1:ff:b2:80:95:ce:fc:5f:26:b4:20:6e:9b:0d
-     */
-
-
-    static @NonNull X509Certificate signPublicKeyWithPrivateKey(String keyToSignAlias,
-            String keyToSignWithAlias) {
-
-        KeyStore ks = null;
-        try {
-            ks = KeyStore.getInstance("AndroidKeyStore");
-            ks.load(null);
-
-            /* First note that KeyStore.getCertificate() returns a self-signed X.509 certificate
-             * for the key in question. As per RFC 5280, section 4.1 an X.509 certificate has the
-             * following structure:
-             *
-             *   Certificate  ::=  SEQUENCE  {
-             *        tbsCertificate       TBSCertificate,
-             *        signatureAlgorithm   AlgorithmIdentifier,
-             *        signatureValue       BIT STRING  }
-             *
-             * Conveniently, the X509Certificate class has a getTBSCertificate() method which
-             * returns the tbsCertificate blob. So all we need to do is just sign that and build
-             * signatureAlgorithm and signatureValue and combine it with tbsCertificate. We don't
-             * need a full-blown ASN.1/DER encoder to do this.
-             */
-            X509Certificate selfSignedCert = (X509Certificate) ks.getCertificate(keyToSignAlias);
-            byte[] tbsCertificate = selfSignedCert.getTBSCertificate();
-
-            KeyStore.Entry keyToSignWithEntry = ks.getEntry(keyToSignWithAlias, null);
-            Signature s = Signature.getInstance("SHA256withECDSA");
-            s.initSign(((KeyStore.PrivateKeyEntry) keyToSignWithEntry).getPrivateKey());
-            s.update(tbsCertificate);
-            byte[] signatureValue = s.sign();
-
-            /* The DER encoding for a SEQUENCE of length 128-65536 - the length is updated below.
-             *
-             * We assume - and test for below - that the final length is always going to be in
-             * this range. This is a sound assumption given we're using 256-bit EC keys.
-             */
-            byte[] sequence = new byte[]{
-                    0x30, (byte) 0x82, 0x00, 0x00
-            };
-
-            /* The DER encoding for the ECDSA with SHA-256 signature algorithm:
-             *
-             *   SEQUENCE (1 elem)
-             *      OBJECT IDENTIFIER 1.2.840.10045.4.3.2 ecdsaWithSHA256 (ANSI X9.62 ECDSA
-             *      algorithm with SHA256)
-             */
-            byte[] signatureAlgorithm = new byte[]{
-                    0x30, 0x0a, 0x06, 0x08, 0x2a, (byte) 0x86, 0x48, (byte) 0xce, 0x3d, 0x04, 0x03,
-                    0x02
-            };
-
-            /* The DER encoding for a BIT STRING with one element - the length is updated below.
-             *
-             * We assume the length of signatureValue is always going to be less than 128. This
-             * assumption works since we know ecdsaWithSHA256 signatures are always 69, 70, or
-             * 71 bytes long when DER encoded.
-             */
-            byte[] bitStringForSignature = new byte[]{0x03, 0x00, 0x00};
-
-            // Calculate sequence length and set it in |sequence|.
-            int sequenceLength = tbsCertificate.length
-                    + signatureAlgorithm.length
-                    + bitStringForSignature.length
-                    + signatureValue.length;
-            if (sequenceLength < 128 || sequenceLength > 65535) {
-                throw new Exception("Unexpected sequenceLength " + sequenceLength);
-            }
-            sequence[2] = (byte) (sequenceLength >> 8);
-            sequence[3] = (byte) (sequenceLength & 0xff);
-
-            // Calculate signatureValue length and set it in |bitStringForSignature|.
-            int signatureValueLength = signatureValue.length + 1;
-            if (signatureValueLength >= 128) {
-                throw new Exception("Unexpected signatureValueLength " + signatureValueLength);
-            }
-            bitStringForSignature[1] = (byte) signatureValueLength;
-
-            // Finally concatenate everything together.
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            baos.write(sequence);
-            baos.write(tbsCertificate);
-            baos.write(signatureAlgorithm);
-            baos.write(bitStringForSignature);
-            baos.write(signatureValue);
-            byte[] resultingCertBytes = baos.toByteArray();
-
-            CertificateFactory cf = CertificateFactory.getInstance("X.509");
-            ByteArrayInputStream bais = new ByteArrayInputStream(resultingCertBytes);
-            X509Certificate result = (X509Certificate) cf.generateCertificate(bais);
-            return result;
-        } catch (Exception e) {
-            throw new RuntimeException("Error signing public key with private key", e);
-        }
-    }
-
-    static byte[] buildDeviceAuthenticationCbor(String docType,
-            byte[] encodedSessionTranscript,
-            byte[] deviceNameSpacesBytes) {
-        ByteArrayOutputStream daBaos = new ByteArrayOutputStream();
-        try {
-            ByteArrayInputStream bais = new ByteArrayInputStream(encodedSessionTranscript);
-            List<DataItem> dataItems = null;
-            dataItems = new CborDecoder(bais).decode();
-            DataItem sessionTranscript = dataItems.get(0);
-            ByteString deviceNameSpacesBytesItem = new ByteString(deviceNameSpacesBytes);
-            deviceNameSpacesBytesItem.setTag(CBOR_SEMANTIC_TAG_ENCODED_CBOR);
-            new CborEncoder(daBaos).encode(new CborBuilder()
-                    .addArray()
-                    .add("DeviceAuthentication")
-                    .add(sessionTranscript)
-                    .add(docType)
-                    .add(deviceNameSpacesBytesItem)
-                    .end()
-                    .build());
-        } catch (CborException e) {
-            throw new RuntimeException("Error encoding DeviceAuthentication", e);
-        }
-        return daBaos.toByteArray();
-    }
-
-    static byte[] buildReaderAuthenticationBytesCbor(
-            byte[] encodedSessionTranscript,
-            byte[] requestMessageBytes) {
-
-        ByteArrayOutputStream daBaos = new ByteArrayOutputStream();
-        try {
-            ByteArrayInputStream bais = new ByteArrayInputStream(encodedSessionTranscript);
-            List<DataItem> dataItems = null;
-            dataItems = new CborDecoder(bais).decode();
-            DataItem sessionTranscript = dataItems.get(0);
-            ByteString requestMessageBytesItem = new ByteString(requestMessageBytes);
-            requestMessageBytesItem.setTag(CBOR_SEMANTIC_TAG_ENCODED_CBOR);
-            new CborEncoder(daBaos).encode(new CborBuilder()
-                    .addArray()
-                    .add("ReaderAuthentication")
-                    .add(sessionTranscript)
-                    .add(requestMessageBytesItem)
-                    .end()
-                    .build());
-        } catch (CborException e) {
-            throw new RuntimeException("Error encoding ReaderAuthentication", e);
-        }
-        byte[] readerAuthentication = daBaos.toByteArray();
-        return Util.prependSemanticTagForEncodedCbor(readerAuthentication);
-    }
-
-    static byte[] prependSemanticTagForEncodedCbor(byte[] encodedCbor) {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try {
-            ByteString taggedBytestring = new ByteString(encodedCbor);
-            taggedBytestring.setTag(CBOR_SEMANTIC_TAG_ENCODED_CBOR);
-            new CborEncoder(baos).encode(taggedBytestring);
-        } catch (CborException e) {
-            throw new RuntimeException("Error encoding with semantic tag for CBOR encoding", e);
-        }
-        return baos.toByteArray();
-    }
-
-    static byte[] concatArrays(byte[] a, byte[] b) {
-        byte[] ret = new byte[a.length + b.length];
-        System.arraycopy(a, 0, ret, 0, a.length);
-        System.arraycopy(b, 0, ret, a.length, b.length);
-        return ret;
-    }
-
-    static SecretKey calcEMacKeyForReader(PublicKey authenticationPublicKey,
-            PrivateKey ephemeralReaderPrivateKey,
-            byte[] encodedSessionTranscript) {
-        try {
-            KeyAgreement ka = KeyAgreement.getInstance("ECDH");
-            ka.init(ephemeralReaderPrivateKey);
-            ka.doPhase(authenticationPublicKey, true);
-            byte[] sharedSecret = ka.generateSecret();
-
-            byte[] sessionTranscriptBytes =
-                    Util.prependSemanticTagForEncodedCbor(encodedSessionTranscript);
-
-            byte[] salt = MessageDigest.getInstance("SHA-256").digest(sessionTranscriptBytes);
-            byte[] info = new byte[] {'E', 'M', 'a', 'c', 'K', 'e', 'y'};
-            byte[] derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
-            SecretKey secretKey = new SecretKeySpec(derivedKey, "");
-            return secretKey;
-        } catch (InvalidKeyException
-                | NoSuchAlgorithmException e) {
-            throw new RuntimeException("Error performing key agreement", e);
-        }
-    }
-
-    /**
-     * Computes an HKDF.
-     *
-     * This is based on https://github.com/google/tink/blob/master/java/src/main/java/com/google
-     * /crypto/tink/subtle/Hkdf.java
-     * which is also Copyright (c) Google and also licensed under the Apache 2 license.
-     *
-     * @param macAlgorithm the MAC algorithm used for computing the Hkdf. I.e., "HMACSHA1" or
-     *                     "HMACSHA256".
-     * @param ikm          the input keying material.
-     * @param salt         optional salt. A possibly non-secret random value. If no salt is
-     *                     provided (i.e. if
-     *                     salt has length 0) then an array of 0s of the same size as the hash
-     *                     digest is used as salt.
-     * @param info         optional context and application specific information.
-     * @param size         The length of the generated pseudorandom string in bytes. The maximal
-     *                     size is
-     *                     255.DigestSize, where DigestSize is the size of the underlying HMAC.
-     * @return size pseudorandom bytes.
-     */
-    static byte[] computeHkdf(
-            String macAlgorithm, final byte[] ikm, final byte[] salt, final byte[] info, int size) {
-        Mac mac = null;
-        try {
-            mac = Mac.getInstance(macAlgorithm);
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("No such algorithm: " + macAlgorithm, e);
-        }
-        if (size > 255 * mac.getMacLength()) {
-            throw new RuntimeException("size too large");
-        }
-        try {
-            if (salt == null || salt.length == 0) {
-                // According to RFC 5869, Section 2.2 the salt is optional. If no salt is provided
-                // then HKDF uses a salt that is an array of zeros of the same length as the hash
-                // digest.
-                mac.init(new SecretKeySpec(new byte[mac.getMacLength()], macAlgorithm));
-            } else {
-                mac.init(new SecretKeySpec(salt, macAlgorithm));
-            }
-            byte[] prk = mac.doFinal(ikm);
-            byte[] result = new byte[size];
-            int ctr = 1;
-            int pos = 0;
-            mac.init(new SecretKeySpec(prk, macAlgorithm));
-            byte[] digest = new byte[0];
-            while (true) {
-                mac.update(digest);
-                mac.update(info);
-                mac.update((byte) ctr);
-                digest = mac.doFinal();
-                if (pos + digest.length < size) {
-                    System.arraycopy(digest, 0, result, pos, digest.length);
-                    pos += digest.length;
-                    ctr++;
-                } else {
-                    System.arraycopy(digest, 0, result, pos, size - pos);
-                    break;
-                }
-            }
-            return result;
-        } catch (InvalidKeyException e) {
-            throw new RuntimeException("Error MACing", e);
-        }
-    }
-
-    static byte[] stripLeadingZeroes(byte[] value) {
-        int n = 0;
-        while (n < value.length && value[n] == 0) {
-            n++;
-        }
-        int newLen = value.length - n;
-        byte[] ret = new byte[newLen];
-        int m = 0;
-        while (n < value.length) {
-            ret[m++] = value[n++];
-        }
-        return ret;
-    }
-
-    static void hexdump(String name, byte[] data) {
-        int n, m, o;
-        StringBuilder sb = new StringBuilder();
-        Formatter fmt = new Formatter(sb);
-        for (n = 0; n < data.length; n += 16) {
-            fmt.format("%04x  ", n);
-            for (m = 0; m < 16 && n + m < data.length; m++) {
-                fmt.format("%02x ", data[n + m]);
-            }
-            for (o = m; o < 16; o++) {
-                sb.append("   ");
-            }
-            sb.append(" ");
-            for (m = 0; m < 16 && n + m < data.length; m++) {
-                int c = data[n + m] & 0xff;
-                fmt.format("%c", Character.isISOControl(c) ? '.' : c);
-            }
-            sb.append("\n");
-        }
-        sb.append("\n");
-        Log.e(TAG, name + ": dumping " + data.length + " bytes\n" + fmt.toString());
-    }
-
-
-    // This returns a SessionTranscript which satisfy the requirement
-    // that the uncompressed X and Y coordinates of the public key for the
-    // mDL's ephemeral key-pair appear somewhere in the encoded
-    // DeviceEngagement.
-    static byte[] buildSessionTranscript(KeyPair ephemeralKeyPair) {
-        // Make the coordinates appear in an already encoded bstr - this
-        // mimics how the mDL COSE_Key appear as encoded data inside the
-        // encoded DeviceEngagement
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try {
-            ECPoint w = ((ECPublicKey) ephemeralKeyPair.getPublic()).getW();
-            // X and Y are always positive so for interop we remove any leading zeroes
-            // inserted by the BigInteger encoder.
-            byte[] x = stripLeadingZeroes(w.getAffineX().toByteArray());
-            byte[] y = stripLeadingZeroes(w.getAffineY().toByteArray());
-            baos.write(new byte[]{42});
-            baos.write(x);
-            baos.write(y);
-            baos.write(new byte[]{43, 44});
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-        byte[] blobWithCoords = baos.toByteArray();
-
-        baos = new ByteArrayOutputStream();
-        try {
-            new CborEncoder(baos).encode(new CborBuilder()
-                    .addArray()
-                    .add(blobWithCoords)
-                    .end()
-                    .build());
-        } catch (CborException e) {
-            e.printStackTrace();
-            return null;
-        }
-        ByteString encodedDeviceEngagementItem = new ByteString(baos.toByteArray());
-        ByteString encodedEReaderKeyItem = new ByteString(cborEncodeString("doesn't matter"));
-        encodedDeviceEngagementItem.setTag(CBOR_SEMANTIC_TAG_ENCODED_CBOR);
-        encodedEReaderKeyItem.setTag(CBOR_SEMANTIC_TAG_ENCODED_CBOR);
-
-        baos = new ByteArrayOutputStream();
-        try {
-            new CborEncoder(baos).encode(new CborBuilder()
-                    .addArray()
-                    .add(encodedDeviceEngagementItem)
-                    .add(encodedEReaderKeyItem)
-                    .end()
-                    .build());
-        } catch (CborException e) {
-            e.printStackTrace();
-            return null;
-        }
-        return baos.toByteArray();
-    }
-
-    /*
-     * Helper function to create a CBOR data for requesting data items. The IntentToRetain
-     * value will be set to false for all elements.
-     *
-     * <p>The returned CBOR data conforms to the following CDDL schema:</p>
-     *
-     * <pre>
-     *   ItemsRequest = {
-     *     ? "docType" : DocType,
-     *     "nameSpaces" : NameSpaces,
-     *     ? "RequestInfo" : {* tstr => any} ; Additional info the reader wants to provide
-     *   }
-     *
-     *   NameSpaces = {
-     *     + NameSpace => DataElements     ; Requested data elements for each NameSpace
-     *   }
-     *
-     *   DataElements = {
-     *     + DataElement => IntentToRetain
-     *   }
-     *
-     *   DocType = tstr
-     *
-     *   DataElement = tstr
-     *   IntentToRetain = bool
-     *   NameSpace = tstr
-     * </pre>
-     *
-     * @param entriesToRequest       The entries to request, organized as a map of namespace
-     *                               names with each value being a collection of data elements
-     *                               in the given namespace.
-     * @param docType                  The document type or {@code null} if there is no document
-     *                                 type.
-     * @return CBOR data conforming to the CDDL mentioned above.
-     */
-    static @NonNull byte[] createItemsRequest(
-            @NonNull Map<String, Collection<String>> entriesToRequest,
-            @Nullable String docType) {
-        CborBuilder builder = new CborBuilder();
-        MapBuilder<CborBuilder> mapBuilder = builder.addMap();
-        if (docType != null) {
-            mapBuilder.put("docType", docType);
-        }
-
-        MapBuilder<MapBuilder<CborBuilder>> nsMapBuilder = mapBuilder.putMap("nameSpaces");
-        for (String namespaceName : entriesToRequest.keySet()) {
-            Collection<String> entryNames = entriesToRequest.get(namespaceName);
-            MapBuilder<MapBuilder<MapBuilder<CborBuilder>>> entryNameMapBuilder =
-                    nsMapBuilder.putMap(namespaceName);
-            for (String entryName : entryNames) {
-                entryNameMapBuilder.put(entryName, false);
-            }
-        }
-
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        CborEncoder encoder = new CborEncoder(baos);
-        try {
-            encoder.encode(builder.build());
-        } catch (CborException e) {
-            throw new RuntimeException("Error encoding CBOR", e);
-        }
-        return baos.toByteArray();
-    }
-
-    static KeyPair createEphemeralKeyPair() {
-        try {
-            KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC);
-            ECGenParameterSpec ecSpec = new ECGenParameterSpec("prime256v1");
-            kpg.initialize(ecSpec);
-            KeyPair keyPair = kpg.generateKeyPair();
-            return keyPair;
-        } catch (NoSuchAlgorithmException
-                | InvalidAlgorithmParameterException e) {
-            throw new RuntimeException("Error generating ephemeral key-pair", e);
-        }
-    }
-
-    // Returns true if, and only if, the Identity Credential HAL (and credstore) is implemented
-    // on the device under test.
-    static boolean isHalImplemented() {
-        Context appContext = InstrumentationRegistry.getTargetContext();
-        IdentityCredentialStore store = IdentityCredentialStore.getInstance(appContext);
-        if (store != null) {
-            return true;
-        }
-        return false;
-    }
-
-    // Returns true if, and only if, the Direct Access Identity Credential HAL (and credstore) is
-    // implemented on the device under test.
-    static boolean isDirectAccessHalImplemented() {
-        Context appContext = InstrumentationRegistry.getTargetContext();
-        IdentityCredentialStore store = IdentityCredentialStore.getDirectAccessInstance(appContext);
-        if (store != null) {
-            return true;
-        }
-        return false;
-    }
-
-    static byte[] getPopSha256FromAuthKeyCert(X509Certificate cert) {
-        byte[] octetString = cert.getExtensionValue("1.3.6.1.4.1.11129.2.1.26");
-        if (octetString == null) {
-            return null;
-        }
-        Util.hexdump("octetString", octetString);
-
-        try {
-            ASN1InputStream asn1InputStream = new ASN1InputStream(octetString);
-            byte[] cborBytes = ((ASN1OctetString) asn1InputStream.readObject()).getOctets();
-            Util.hexdump("cborBytes", cborBytes);
-
-            ByteArrayInputStream bais = new ByteArrayInputStream(cborBytes);
-            List<DataItem> dataItems = new CborDecoder(bais).decode();
-            if (dataItems.size() != 1) {
-                throw new RuntimeException("Expected 1 item, found " + dataItems.size());
-            }
-            if (!(dataItems.get(0) instanceof co.nstant.in.cbor.model.Array)) {
-                throw new RuntimeException("Item is not a map");
-            }
-            co.nstant.in.cbor.model.Array array = (co.nstant.in.cbor.model.Array) dataItems.get(0);
-            List<DataItem> items = array.getDataItems();
-            if (items.size() < 2) {
-                throw new RuntimeException("Expected at least 2 array items, found " + items.size());
-            }
-            if (!(items.get(0) instanceof UnicodeString)) {
-                throw new RuntimeException("First array item is not a string");
-            }
-            String id = ((UnicodeString) items.get(0)).getString();
-            if (!id.equals("ProofOfBinding")) {
-                throw new RuntimeException("Expected ProofOfBinding, got " + id);
-            }
-            if (!(items.get(1) instanceof ByteString)) {
-                throw new RuntimeException("Second array item is not a bytestring");
-            }
-            byte[] popSha256 = ((ByteString) items.get(1)).getBytes();
-            if (popSha256.length != 32) {
-                throw new RuntimeException("Expected bstr to be 32 bytes, it is " + popSha256.length);
-            }
-            return popSha256;
-        } catch (IOException e) {
-            throw new RuntimeException("Error decoding extension data", e);
-        } catch (CborException e) {
-            throw new RuntimeException("Error decoding data", e);
-        }
-    }
-
-}
diff --git a/tests/tests/identity/src/android/security/identity/cts/UtilUnitTests.java b/tests/tests/identity/src/android/security/identity/cts/UtilUnitTests.java
deleted file mode 100644
index c77de79..0000000
--- a/tests/tests/identity/src/android/security/identity/cts/UtilUnitTests.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright 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.security.identity.cts;
-
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import android.security.keystore.KeyGenParameterSpec;
-import android.security.keystore.KeyProperties;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-
-import java.security.cert.X509Certificate;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-
-import co.nstant.in.cbor.CborBuilder;
-import co.nstant.in.cbor.CborEncoder;
-import co.nstant.in.cbor.CborException;
-import co.nstant.in.cbor.builder.ArrayBuilder;
-import co.nstant.in.cbor.model.ByteString;
-import co.nstant.in.cbor.model.DoublePrecisionFloat;
-import co.nstant.in.cbor.model.HalfPrecisionFloat;
-import co.nstant.in.cbor.model.NegativeInteger;
-import co.nstant.in.cbor.model.SimpleValue;
-import co.nstant.in.cbor.model.SimpleValueType;
-import co.nstant.in.cbor.model.SinglePrecisionFloat;
-import co.nstant.in.cbor.model.UnicodeString;
-import co.nstant.in.cbor.model.UnsignedInteger;
-
-public class UtilUnitTests {
-    @Test
-    public void prettyPrintMultipleCompleteTypes() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new CborBuilder()
-                .add("text")                // add string
-                .add(1234)                  // add integer
-                .add(new byte[]{0x10})   // add byte array
-                .addArray()                 // add array
-                .add(1)
-                .add("text")
-                .end()
-                .build());
-        assertEquals("'text',\n"
-                + "1234,\n"
-                + "[0x10],\n"
-                + "[1, 'text']", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintString() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new UnicodeString("foobar"));
-        assertEquals("'foobar'", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintBytestring() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new ByteString(new byte[]{1, 2, 33, (byte) 254}));
-        assertEquals("[0x01, 0x02, 0x21, 0xfe]", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintUnsignedInteger() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new UnsignedInteger(42));
-        assertEquals("42", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintNegativeInteger() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new NegativeInteger(-42));
-        assertEquals("-42", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintDouble() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new DoublePrecisionFloat(1.1));
-        assertEquals("1.1", Util.cborPrettyPrint(baos.toByteArray()));
-
-        baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new DoublePrecisionFloat(-42.0000000001));
-        assertEquals("-42.0000000001", Util.cborPrettyPrint(baos.toByteArray()));
-
-        baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new DoublePrecisionFloat(-5));
-        assertEquals("-5", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintFloat() throws CborException {
-        ByteArrayOutputStream baos;
-
-        // TODO: These two tests yield different results on different devices, disable for now
-        /*
-        baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new SinglePrecisionFloat(1.1f));
-        assertEquals("1.100000023841858", Util.cborPrettyPrint(baos.toByteArray()));
-
-        baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new SinglePrecisionFloat(-42.0001f));
-        assertEquals("-42.000099182128906", Util.cborPrettyPrint(baos.toByteArray()));
-        */
-
-        baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new SinglePrecisionFloat(-5f));
-        assertEquals("-5", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintHalfFloat() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new HalfPrecisionFloat(1.1f));
-        assertEquals("1.099609375", Util.cborPrettyPrint(baos.toByteArray()));
-
-        baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new HalfPrecisionFloat(-42.0001f));
-        assertEquals("-42", Util.cborPrettyPrint(baos.toByteArray()));
-
-        baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new HalfPrecisionFloat(-5f));
-        assertEquals("-5", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintFalse() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new SimpleValue(SimpleValueType.FALSE));
-        assertEquals("false", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintTrue() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new SimpleValue(SimpleValueType.TRUE));
-        assertEquals("true", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintNull() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new SimpleValue(SimpleValueType.NULL));
-        assertEquals("null", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintUndefined() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new SimpleValue(SimpleValueType.UNDEFINED));
-        assertEquals("undefined", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintTag() throws CborException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new CborBuilder()
-                        .addTag(0)
-                        .add("ABC")
-                        .build());
-        byte[] data = baos.toByteArray();
-        assertEquals("tag 0 'ABC'", Util.cborPrettyPrint(data));
-    }
-
-    @Test
-    public void prettyPrintArrayNoCompounds() throws CborException {
-        // If an array has no compound elements, no newlines are used.
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new CborBuilder()
-                .addArray()                 // add array
-                .add(1)
-                .add("text")
-                .add(new ByteString(new byte[]{1, 2, 3}))
-                .end()
-                .build());
-        assertEquals("[1, 'text', [0x01, 0x02, 0x03]]", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintArray() throws CborException {
-        // This array contains a compound value so will use newlines
-        CborBuilder array = new CborBuilder();
-        ArrayBuilder<CborBuilder> arrayBuilder = array.addArray();
-        arrayBuilder.add(2);
-        arrayBuilder.add(3);
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new CborBuilder()
-                .addArray()                 // add array
-                .add(1)
-                .add("text")
-                .add(new ByteString(new byte[]{1, 2, 3}))
-                .add(array.build().get(0))
-                .end()
-                .build());
-        assertEquals("[\n"
-                + "  1,\n"
-                + "  'text',\n"
-                + "  [0x01, 0x02, 0x03],\n"
-                + "  [2, 3]\n"
-                + "]", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void prettyPrintMap() throws CborException {
-        // If an array has no compound elements, no newlines are used.
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new CborEncoder(baos).encode(new CborBuilder()
-                .addMap()
-                .put("Foo", 42)
-                .put("Bar", "baz")
-                .put(43, 44)
-                .put(new UnicodeString("bstr"), new ByteString(new byte[]{1, 2, 3}))
-                .put(new ByteString(new byte[]{1, 2, 3}), new UnicodeString("other way"))
-                .end()
-                .build());
-        assertEquals("{\n"
-                + "  43 : 44,\n"
-                + "  [0x01, 0x02, 0x03] : 'other way',\n"
-                + "  'Bar' : 'baz',\n"
-                + "  'Foo' : 42,\n"
-                + "  'bstr' : [0x01, 0x02, 0x03]\n"
-                + "}", Util.cborPrettyPrint(baos.toByteArray()));
-    }
-
-    @Test
-    public void cborEncodeDecode() {
-        // TODO: add better coverage and check specific encoding etc.
-        assertEquals(42, Util.cborDecodeInt(Util.cborEncodeInt(42)));
-        assertEquals(123456, Util.cborDecodeInt(Util.cborEncodeInt(123456)));
-        assertFalse(Util.cborDecodeBoolean(Util.cborEncodeBoolean(false)));
-        assertTrue(Util.cborDecodeBoolean(Util.cborEncodeBoolean(true)));
-    }
-
-    private KeyPair coseGenerateKeyPair() throws Exception {
-        KeyPairGenerator kpg = KeyPairGenerator.getInstance(
-            KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
-        KeyGenParameterSpec.Builder builder =
-                new KeyGenParameterSpec.Builder(
-                    "coseTestKeyPair",
-                    KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
-                        .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512);
-        kpg.initialize(builder.build());
-        return kpg.generateKeyPair();
-    }
-
-    @Test
-    public void coseSignAndVerify() throws Exception {
-        KeyPair keyPair = coseGenerateKeyPair();
-        byte[] data = new byte[] {0x10, 0x11, 0x12, 0x13};
-        byte[] detachedContent = new byte[] {};
-        byte[] sig = Util.coseSign1Sign(keyPair.getPrivate(), data, detachedContent, null);
-        assertTrue(Util.coseSign1CheckSignature(sig, detachedContent, keyPair.getPublic()));
-        assertArrayEquals(data, Util.coseSign1GetData(sig));
-        assertEquals(new ArrayList() {}, Util.coseSign1GetX5Chain(sig));
-    }
-
-    @Test
-    public void coseSignAndVerifyDetachedContent() throws Exception {
-        KeyPair keyPair = coseGenerateKeyPair();
-        byte[] data = new byte[] {};
-        byte[] detachedContent = new byte[] {0x20, 0x21, 0x22, 0x23, 0x24};
-        byte[] sig = Util.coseSign1Sign(keyPair.getPrivate(), data, detachedContent, null);
-        assertTrue(Util.coseSign1CheckSignature(sig, detachedContent, keyPair.getPublic()));
-        assertArrayEquals(data, Util.coseSign1GetData(sig));
-        assertEquals(new ArrayList() {}, Util.coseSign1GetX5Chain(sig));
-    }
-
-    @Test
-    public void coseSignAndVerifySingleCertificate() throws Exception {
-        KeyPair keyPair = coseGenerateKeyPair();
-        byte[] data = new byte[] {};
-        byte[] detachedContent = new byte[] {0x20, 0x21, 0x22, 0x23, 0x24};
-        ArrayList<X509Certificate> certs = new ArrayList() {};
-        certs.add(Util.signPublicKeyWithPrivateKey("coseTestKeyPair", "coseTestKeyPair"));
-        byte[] sig = Util.coseSign1Sign(keyPair.getPrivate(), data, detachedContent, certs);
-        assertTrue(Util.coseSign1CheckSignature(sig, detachedContent, keyPair.getPublic()));
-        assertArrayEquals(data, Util.coseSign1GetData(sig));
-        assertEquals(certs, Util.coseSign1GetX5Chain(sig));
-    }
-
-    @Test
-    public void coseSignAndVerifyMultipleCertificates() throws Exception {
-        KeyPair keyPair = coseGenerateKeyPair();
-        byte[] data = new byte[] {};
-        byte[] detachedContent = new byte[] {0x20, 0x21, 0x22, 0x23, 0x24};
-        ArrayList<X509Certificate> certs = new ArrayList() {};
-        certs.add(Util.signPublicKeyWithPrivateKey("coseTestKeyPair", "coseTestKeyPair"));
-        certs.add(Util.signPublicKeyWithPrivateKey("coseTestKeyPair", "coseTestKeyPair"));
-        certs.add(Util.signPublicKeyWithPrivateKey("coseTestKeyPair", "coseTestKeyPair"));
-        byte[] sig = Util.coseSign1Sign(keyPair.getPrivate(), data, detachedContent, certs);
-        assertTrue(Util.coseSign1CheckSignature(sig, detachedContent, keyPair.getPublic()));
-        assertArrayEquals(data, Util.coseSign1GetData(sig));
-        assertEquals(certs, Util.coseSign1GetX5Chain(sig));
-    }
-
-    @Test
-    public void coseMac0() throws Exception {
-        SecretKey secretKey = new SecretKeySpec(new byte[32], "");
-        byte[] data = new byte[] {0x10, 0x11, 0x12, 0x13};
-        byte[] detachedContent = new byte[] {};
-        byte[] mac = Util.coseMac0(secretKey, data, detachedContent);
-        assertEquals("[\n"
-                + "  [0xa1, 0x01, 0x05],\n"
-                + "  {},\n"
-                + "  [0x10, 0x11, 0x12, 0x13],\n"
-                + "  [0x6c, 0xec, 0xb5, 0x6a, 0xc9, 0x5c, 0xae, 0x3b, 0x41, 0x13, 0xde, 0xa4, "
-                + "0xd8, 0x86, 0x5c, 0x28, 0x2c, 0xd5, 0xa5, 0x13, 0xff, 0x3b, 0xd1, 0xde, 0x70, "
-                + "0x5e, 0xbb, 0xe2, 0x2d, 0x42, 0xbe, 0x53]\n"
-                + "]", Util.cborPrettyPrint(mac));
-    }
-
-    @Test
-    public void coseMac0DetachedContent() throws Exception {
-        SecretKey secretKey = new SecretKeySpec(new byte[32], "");
-        byte[] data = new byte[] {};
-        byte[] detachedContent = new byte[] {0x10, 0x11, 0x12, 0x13};
-        byte[] mac = Util.coseMac0(secretKey, data, detachedContent);
-        // Same HMAC as in coseMac0 test, only difference is that payload is null.
-        assertEquals("[\n"
-                + "  [0xa1, 0x01, 0x05],\n"
-                + "  {},\n"
-                + "  null,\n"
-                + "  [0x6c, 0xec, 0xb5, 0x6a, 0xc9, 0x5c, 0xae, 0x3b, 0x41, 0x13, 0xde, 0xa4, "
-                + "0xd8, 0x86, 0x5c, 0x28, 0x2c, 0xd5, 0xa5, 0x13, 0xff, 0x3b, 0xd1, 0xde, 0x70, "
-                + "0x5e, 0xbb, 0xe2, 0x2d, 0x42, 0xbe, 0x53]\n"
-                + "]", Util.cborPrettyPrint(mac));
-    }
-
-    @Test
-    public void replaceLineTest() {
-        assertEquals("foo",
-                Util.replaceLine("Hello World", 0, "foo"));
-        assertEquals("foo\n",
-                Util.replaceLine("Hello World\n", 0, "foo"));
-        assertEquals("Hello World",
-                Util.replaceLine("Hello World", 1, "foo"));
-        assertEquals("Hello World\n",
-                Util.replaceLine("Hello World\n", 1, "foo"));
-        assertEquals("foo\ntwo\nthree",
-                Util.replaceLine("one\ntwo\nthree", 0, "foo"));
-        assertEquals("one\nfoo\nthree",
-                Util.replaceLine("one\ntwo\nthree", 1, "foo"));
-        assertEquals("one\ntwo\nfoo",
-                Util.replaceLine("one\ntwo\nthree", 2, "foo"));
-        assertEquals("one\ntwo\nfoo",
-                Util.replaceLine("one\ntwo\nthree", -1, "foo"));
-        assertEquals("one\ntwo\nthree\nfoo",
-                Util.replaceLine("one\ntwo\nthree\nfour", -1, "foo"));
-        assertEquals("one\ntwo\nfoo\nfour",
-                Util.replaceLine("one\ntwo\nthree\nfour", -2, "foo"));
-    }
-
-}
diff --git a/tests/tests/identity/src/android/security/identity/cts/X509CertificateSigningTest.java b/tests/tests/identity/src/android/security/identity/cts/X509CertificateSigningTest.java
index 7153982..0fe6e2f 100644
--- a/tests/tests/identity/src/android/security/identity/cts/X509CertificateSigningTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/X509CertificateSigningTest.java
@@ -27,6 +27,7 @@
 import android.security.keystore.KeyProperties;
 import android.util.AtomicFile;
 import android.util.Log;
+import com.android.security.identity.internal.Util;
 
 import androidx.test.InstrumentationRegistry;
 
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index b86302c..e12ee51 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -2859,8 +2859,8 @@
                 if (audioCaps != null) {
                     format = MediaFormat.createAudioFormat(
                             type,
-                            audioCaps.getMaxInputChannelCount(),
-                            audioCaps.getSupportedSampleRateRanges()[0].getLower());
+                            audioCaps.getSupportedSampleRateRanges()[0].getLower(),
+                            audioCaps.getMaxInputChannelCount());
                     if (info.isEncoder()) {
                         format.setInteger(MediaFormat.KEY_BIT_RATE, AUDIO_BIT_RATE);
                     }
diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
deleted file mode 100644
index 582419f..0000000
--- a/tests/tests/os/Android.mk
+++ /dev/null
@@ -1,61 +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.
-
-# platform version check (b/32056228)
-# ============================================================
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := cts-platform-version-check
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts general-tests
-
-cts_platform_version_path := cts/tests/tests/os/assets/platform_versions.txt
-cts_platform_version_string := $(shell cat $(cts_platform_version_path))
-cts_platform_release_path := cts/tests/tests/os/assets/platform_releases.txt
-cts_platform_release_string := $(shell cat $(cts_platform_release_path))
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE) : $(cts_platform_version_path) build/core/version_defaults.mk
-	$(hide) if [ -z "$(findstring $(PLATFORM_VERSION),$(cts_platform_version_string))" ]; then \
-		echo "============================================================" 1>&2; \
-		echo "Could not find version \"$(PLATFORM_VERSION)\" in CTS platform version file:" 1>&2; \
-		echo "" 1>&2; \
-		echo "	$(cts_platform_version_path)" 1>&2; \
-		echo "" 1>&2; \
-		echo "Most likely PLATFORM_VERSION in build/core/version_defaults.mk" 1>&2; \
-		echo "has changed and a new version must be added to this CTS file." 1>&2; \
-		echo "============================================================" 1>&2; \
-		exit 1; \
-	fi
-	$(hide) if [ -z "$(findstring $(PLATFORM_VERSION_LAST_STABLE),$(cts_platform_release_string))" ]; then \
-		echo "============================================================" 1>&2; \
-		echo "Could not find version \"$(PLATFORM_VERSION_LAST_STABLE)\" in CTS platform release file:" 1>&2; \
-		echo "" 1>&2; \
-		echo "	$(cts_platform_release_path)" 1>&2; \
-		echo "" 1>&2; \
-		echo "Most likely PLATFORM_VERSION_LAST_STABLE in build/core/version_defaults.mk" 1>&2; \
-		echo "has changed and a new version must be added to this CTS file." 1>&2; \
-		echo "============================================================" 1>&2; \
-		exit 1; \
-	fi
-	@mkdir -p $(dir $@)
-	echo $(cts_platform_version_string) > $@
diff --git a/tests/tests/os/src/android/os/cts/EnvironmentTest.java b/tests/tests/os/src/android/os/cts/EnvironmentTest.java
index 2ce40fe..9252f6ba 100644
--- a/tests/tests/os/src/android/os/cts/EnvironmentTest.java
+++ b/tests/tests/os/src/android/os/cts/EnvironmentTest.java
@@ -43,14 +43,11 @@
     }
 
     /**
-     * TMPDIR being set prevents apps from asking to have temporary files
-     * placed in their own storage, instead forcing their location to
-     * something OS-defined. If TMPDIR points to a global shared directory,
+     * If TMPDIR points to a global shared directory,
      * this could compromise the security of the files.
      */
     public void testNoTmpDir() {
-        assertNull("environment variable TMPDIR should not be set",
-                System.getenv("TMPDIR"));
+        assertTrue(System.getenv("TMPDIR").endsWith("android.os.cts/cache"));
     }
 
     /**
diff --git a/tests/tests/os/src/android/os/cts/StrictModeTest.java b/tests/tests/os/src/android/os/cts/StrictModeTest.java
index f0358bd..92f5dc4 100644
--- a/tests/tests/os/src/android/os/cts/StrictModeTest.java
+++ b/tests/tests/os/src/android/os/cts/StrictModeTest.java
@@ -37,6 +37,7 @@
 import android.net.Uri;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.strictmode.UnbufferedIoViolation;
 import android.os.StrictMode;
 import android.os.StrictMode.ThreadPolicy.Builder;
 import android.os.StrictMode.ViolationInfo;
@@ -88,6 +89,9 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
+import java.util.Random;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
 
 /** Tests for {@link StrictMode} */
 @RunWith(AndroidJUnit4.class)
@@ -479,6 +483,55 @@
     }
 
     @Test
+    public void testUnbufferedIoGZipInput() throws Exception {
+        StrictMode.setThreadPolicy(
+                new StrictMode.ThreadPolicy.Builder().detectUnbufferedIo().penaltyLog().build());
+
+        inspectViolation(
+                () -> {
+                    File tmp = File.createTempFile("StrictModeTest", "tmp");
+                    try (FileOutputStream fos = new FileOutputStream(tmp);
+                         GZIPOutputStream gzippedOut = new GZIPOutputStream(fos)) {
+                        byte[] data = new byte[10240];
+                        new Random().nextBytes(data);
+                        gzippedOut.write(data);
+                    }
+
+                    try (FileInputStream fileInputStream = new FileInputStream(tmp);
+                        GZIPInputStream in = new GZIPInputStream(fileInputStream)) {
+
+                        byte[] buffer = new byte[1024];
+                        while (in.read(buffer) != -1) {}
+                    }
+                },
+                info -> assertThat(info.getViolationClass())
+                        .isAssignableTo(UnbufferedIoViolation.class));
+    }
+
+    @Test
+    public void testUnbufferedIoGZipOutput() throws Exception {
+        StrictMode.setThreadPolicy(
+                new StrictMode.ThreadPolicy.Builder().detectUnbufferedIo().penaltyLog().build());
+
+        inspectViolation(
+                () -> {
+                    byte[] data = new byte[512];
+                    Random random = new Random(0);
+                    try (FileOutputStream ostream = new FileOutputStream(
+                            File.createTempFile("StrictModeTest","testUnbufferedIo.dat"));
+                        GZIPOutputStream gzippedOut = new GZIPOutputStream(ostream)) {
+                        for (int i = 0; i < 9; i++) {
+                            random.nextBytes(data);
+                            gzippedOut.write(data, 0, data.length);
+                        }
+                    }
+                },
+                info -> assertThat(info.getViolationClass())
+                        .isAssignableTo(UnbufferedIoViolation.class));
+    }
+
+
+    @Test
     public void testViolationAcrossBinder() throws Exception {
         runWithRemoteServiceBound(
                 getContext(),
diff --git a/tests/tests/os/src/android/os/image/cts/DynamicSystemClientTest.java b/tests/tests/os/src/android/os/image/cts/DynamicSystemClientTest.java
index fed6b44..b961efb 100644
--- a/tests/tests/os/src/android/os/image/cts/DynamicSystemClientTest.java
+++ b/tests/tests/os/src/android/os/image/cts/DynamicSystemClientTest.java
@@ -20,6 +20,8 @@
 import static org.junit.Assert.fail;
 
 import android.app.Instrumentation;
+import android.content.ActivityNotFoundException;
+import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.image.DynamicSystemClient;
 import android.platform.test.annotations.AppModeFull;
@@ -29,6 +31,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.After;
+import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -40,6 +43,12 @@
     private boolean mUpdated;
     private Instrumentation mInstrumentation;
 
+    private static final String DSU_PACKAGE_NAME = "com.android.dynsystem";
+
+    private PackageManager getPackageManager() {
+        return mInstrumentation.getContext().getPackageManager();
+    }
+
     public void onStatusChanged(int status, int cause, long progress, Throwable detail) {
         mUpdated = true;
     }
@@ -63,6 +72,13 @@
         mUpdated = false;
         try {
             dSClient.start(uri, 1024L << 10);
+        } catch (ActivityNotFoundException e) {
+            try {
+                getPackageManager().getPackageInfo(DSU_PACKAGE_NAME, 0);
+            } catch (PackageManager.NameNotFoundException ignore) {
+                Assume.assumeNoException(ignore);
+            }
+            throw e;
         } catch (SecurityException e) {
             fail();
         }
@@ -90,6 +106,13 @@
         Uri uri = Uri.parse("https://www.google.com/").buildUpon().build();
         try {
             dSClient.start(uri, 1024L << 10);
+        } catch (ActivityNotFoundException e) {
+            try {
+                getPackageManager().getPackageInfo(DSU_PACKAGE_NAME, 0);
+            } catch (PackageManager.NameNotFoundException ignore) {
+                Assume.assumeNoException(ignore);
+            }
+            throw e;
         } catch (SecurityException e) {
             fail();
         }
diff --git a/tests/tests/permission3/res/values/strings.xml b/tests/tests/permission3/res/values/strings.xml
index d6d368b..194f203 100755
--- a/tests/tests/permission3/res/values/strings.xml
+++ b/tests/tests/permission3/res/values/strings.xml
@@ -18,9 +18,6 @@
 
 <resources>
     <string name="permissions">Permissions</string>
-    <string name="deny">Don\u2019t allow</string>
-    <string name="ask">Ask every time</string>
-    <string name="allow">Allow</string>
     <string name="allow_foreground">Allow only while using the app</string>
     <string name="allow_media_storage">Allow access to media only</string>
     <string name="allow_external_storage">Allow management of all files</string>
diff --git a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
index 70f73b7..867cbf0 100644
--- a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
@@ -72,6 +72,12 @@
                 "com.android.permissioncontroller:" +
                         "id/permission_no_upgrade_and_dont_ask_again_button"
 
+        const val ALLOW_RADIO_BUTTON = "com.android.permissioncontroller:id/allow_radio_button"
+        const val ALLOW_FOREGROUND_RADIO_BUTTON =
+                "com.android.permissioncontroller:id/allow_foreground_only_radio_button"
+        const val ASK_RADIO_BUTTON = "com.android.permissioncontroller:id/ask_radio_button"
+        const val DENY_RADIO_BUTTON = "com.android.permissioncontroller:id/deny_radio_button"
+
         const val ALLOW_BUTTON_TEXT = "grant_dialog_button_allow"
         const val ALLOW_FOREGROUND_BUTTON_TEXT = "grant_dialog_button_allow_foreground"
         const val DENY_BUTTON_TEXT = "grant_dialog_button_deny"
@@ -420,45 +426,45 @@
             val wasGranted = if (isAutomotive) {
                 // Automotive doesn't support one time permissions, and thus
                 // won't show an "Ask every time" message
-                !waitFindObject(byTextRes(R.string.deny)).isChecked
+                !waitFindObject(By.res(DENY_RADIO_BUTTON)).isChecked
             } else {
-                !(waitFindObject(byTextRes(R.string.deny)).isChecked ||
+                !(waitFindObject(By.res(DENY_RADIO_BUTTON)).isChecked ||
                     (!isLegacyApp && hasAskButton(permission) &&
-                        waitFindObject(byTextRes(R.string.ask)).isChecked))
+                        waitFindObject(By.res(ASK_RADIO_BUTTON)).isChecked))
             }
             var alreadyChecked = false
             val button = waitFindObject(
-                byTextRes(
-                    if (isAutomotive) {
-                        // Automotive doesn't support one time permissions, and thus
-                        // won't show an "Ask every time" message
-                        when (state) {
-                            PermissionState.ALLOWED -> R.string.allow
-                            PermissionState.DENIED -> R.string.deny
-                            PermissionState.DENIED_WITH_PREJUDICE -> R.string.deny
-                        }
-                    } else {
-                        when (state) {
-                            PermissionState.ALLOWED ->
-                                if (showsForegroundOnlyButton(permission)) {
-                                    R.string.allow_foreground
-                                } else if (isMediaStorageButton(permission, targetSdk)) {
-                                    R.string.allow_media_storage
-                                } else if (isAllStorageButton(permission, targetSdk)) {
-                                    R.string.allow_external_storage
-                                } else {
-                                    R.string.allow
-                                }
-                            PermissionState.DENIED ->
-                                if (!isLegacyApp && hasAskButton(permission)) {
-                                    R.string.ask
-                                } else {
-                                    R.string.deny
-                                }
-                            PermissionState.DENIED_WITH_PREJUDICE -> R.string.deny
-                        }
+                if (isAutomotive) {
+                    // Automotive doesn't support one time permissions, and thus
+                    // won't show an "Ask every time" message
+                    when (state) {
+                        PermissionState.ALLOWED -> By.res(ALLOW_RADIO_BUTTON)
+                        PermissionState.DENIED -> By.res(DENY_RADIO_BUTTON)
+                        PermissionState.DENIED_WITH_PREJUDICE -> By.res(DENY_RADIO_BUTTON)
                     }
-                )
+                } else {
+                    when (state) {
+                        PermissionState.ALLOWED ->
+                            if (showsForegroundOnlyButton(permission)) {
+                                By.res(ALLOW_FOREGROUND_RADIO_BUTTON)
+                            } else if (isMediaStorageButton(permission, targetSdk)) {
+                                // Uses "allow_foreground_only_radio_button" as id
+                                byTextRes(R.string.allow_media_storage)
+                            } else if (isAllStorageButton(permission, targetSdk)) {
+                                // Uses "allow_always_radio_button" as id
+                                byTextRes(R.string.allow_external_storage)
+                            } else {
+                                By.res(ALLOW_RADIO_BUTTON)
+                            }
+                        PermissionState.DENIED ->
+                            if (!isLegacyApp && hasAskButton(permission)) {
+                                By.res(ASK_RADIO_BUTTON)
+                            } else {
+                                By.res(DENY_RADIO_BUTTON)
+                            }
+                        PermissionState.DENIED_WITH_PREJUDICE -> By.res(DENY_RADIO_BUTTON)
+                    }
+                }
             )
             alreadyChecked = button.isChecked
             if (!alreadyChecked) {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
index 84ebee7..a3a58e5 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
@@ -219,7 +219,10 @@
         Allocation.createFromBitmap(mRS, B).destroy();
         Allocation.createCubemapFromBitmap(mRS, B).destroy();
         for (Allocation.MipmapControl mc : Allocation.MipmapControl.values()) {
-            helperCreateFromBitmap(B, mc);
+            if (mc != Allocation.MipmapControl.MIPMAP_FULL) {
+                // MIPMAP_FULL is not tested because of http://b/184904346
+                helperCreateFromBitmap(B, mc);
+            }
         }
 
         try {
@@ -883,5 +886,3 @@
     a.destroy();
    }
 }
-
-
diff --git a/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp b/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp
index 824cb50..23ae5b0 100644
--- a/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp
+++ b/tests/tests/security/native/encryption/FileBasedEncryptionPolicyTest.cpp
@@ -180,6 +180,7 @@
 // https://source.android.com/security/encryption/file-based.html
 TEST(FileBasedEncryptionPolicyTest, allowedPolicy) {
     int first_api_level = getFirstApiLevel();
+    char crypto_type[PROPERTY_VALUE_MAX];
     struct fscrypt_get_policy_ex_arg arg;
     int res;
     int contents_mode;
@@ -191,6 +192,8 @@
         FAIL() << "Failed to open " DIR_TO_CHECK ": " << strerror(errno);
     }
 
+    property_get("ro.crypto.type", crypto_type, "");
+    GTEST_LOG_(INFO) << "ro.crypto.type is '" << crypto_type << "'";
     GTEST_LOG_(INFO) << "First API level is " << first_api_level;
 
     // Note: SELinux policy allows the shell domain to use these ioctls, but not
@@ -216,6 +219,15 @@
                         << "Exempt from file-based encryption due to old starting API level";
                 return;
             }
+            if (strcmp(crypto_type, "managed") == 0) {
+                // Android is running in a virtualized environment and the file system is encrypted
+                // by the host system.
+                GTEST_LOG_(INFO) << "Exempt from file-based encryption because the file system is "
+                                 << "encrypted by the host system";
+                // Note: All encryption-related CDD requirements still must be met,
+                // but they can't be tested directly in this case.
+                return;
+            }
             FAIL() << "Device isn't using file-based encryption";
         } else {
             FAIL() << "Failed to get encryption policy of " DIR_TO_CHECK ": " << strerror(errno);
diff --git a/tests/tests/selinux/common/jni/android_security_SELinuxTargetSdkTest.cpp b/tests/tests/selinux/common/jni/android_security_SELinuxTargetSdkTest.cpp
index 9dc0d97..4570f46 100644
--- a/tests/tests/selinux/common/jni/android_security_SELinuxTargetSdkTest.cpp
+++ b/tests/tests/selinux/common/jni/android_security_SELinuxTargetSdkTest.cpp
@@ -26,7 +26,7 @@
 #include <memory>
 
 struct SecurityContext_Delete {
-    void operator()(security_context_t p) const {
+    void operator()(char* p) const {
         freecon(p);
     }
 };
@@ -151,7 +151,7 @@
         return NULL;
     }
 
-    security_context_t tmp = NULL;
+    char* tmp = NULL;
     int ret = getfilecon(path.c_str(), &tmp);
     Unique_SecurityContext context(tmp);
 
diff --git a/tests/tests/wrap/Android.bp b/tests/tests/wrap/Android.bp
index 27ffc21..a94a5db0 100644
--- a/tests/tests/wrap/Android.bp
+++ b/tests/tests/wrap/Android.bp
@@ -25,3 +25,11 @@
         "android.test.base.stubs",
     ],
 }
+
+filegroup {
+    name: "wrap.sh",
+    srcs: [
+        "wrap.sh",
+    ],
+    path: ".",
+}
diff --git a/tests/tests/wrap/wrap_debug/Android.bp b/tests/tests/wrap/wrap_debug/Android.bp
new file mode 100644
index 0000000..5f50d5e
--- /dev/null
+++ b/tests/tests/wrap/wrap_debug/Android.bp
@@ -0,0 +1,66 @@
+// 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 {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "CtsWrapWrapDebugTestCases",
+    compile_multilib: "both",
+    dex_preopt: {
+        enabled: false,
+    },
+    optimize: {
+        enabled: false,
+    },
+    static_libs: [
+        "compatibility-device-util-axt",
+        "androidx.test.rules",
+        "wrap_debug_lib"
+    ],
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+    srcs: [":cts_tests_tests_wrap_src"],
+    test_suites: [
+        "cts",
+        "general-tests",
+    ],
+    sdk_version: "current",
+    manifest: "AndroidManifest.xml",
+    // Jarjar to make WrapTest unique.
+    jarjar_rules: "jarjar-rules.txt",
+    use_embedded_native_libs: false,
+}
+
+java_genrule {
+    name: "wrap_debug_lib",
+    srcs: [":wrap.sh"],
+    tools: ["soong_zip"],
+    out: ["wrap_debug_abi.jar"],
+    cmd: "mkdir -p $(genDir)/lib/armeabi-v7a/ && " +
+         "mkdir -p $(genDir)/lib/arm64-v8a/ && " +
+         "mkdir -p $(genDir)/lib/x86/ && " +
+         "mkdir -p $(genDir)/lib/x86_64/ && " +
+         "cp $(in) $(genDir)/lib/armeabi-v7a/ && " +
+         "cp $(in) $(genDir)/lib/arm64-v8a/ && " +
+         "cp $(in) $(genDir)/lib/x86/ && " +
+         "cp $(in) $(genDir)/lib/x86_64/ && " +
+         "$(location soong_zip) -o $(out) -C $(genDir) " +
+         "-D $(genDir)/lib/armeabi-v7a/ -D $(genDir)/lib/arm64-v8a/ " +
+         "-D $(genDir)/lib/x86/ -D $(genDir)/lib/x86_64/",
+}
diff --git a/tests/tests/wrap/wrap_debug/Android.mk b/tests/tests/wrap/wrap_debug/Android.mk
deleted file mode 100644
index 8743cc4..0000000
--- a/tests/tests/wrap/wrap_debug/Android.mk
+++ /dev/null
@@ -1,51 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MULTILIB := both
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_DEX_PREOPT := false
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	compatibility-device-util-axt \
-	androidx.test.rules
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
-LOCAL_COMPATIBILITY_SUITE := cts general-tests
-LOCAL_SDK_VERSION := current
-
-LOCAL_PREBUILT_JNI_LIBS_arm := ../wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_arm64 := ../wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_mips := ../wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_mips64 := ../wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_x86 := ../wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_x86_64 := ../wrap.sh
-
-LOCAL_PACKAGE_NAME := CtsWrapWrapDebugTestCases
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_MANIFEST_FILE := AndroidManifest.xml
-
-# Jarjar to make WrapTest unique.
-LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
-
-LOCAL_USE_EMBEDDED_NATIVE_LIBS := false
-
-include $(BUILD_PACKAGE)
-
-include $(CLEAR_VARS)
diff --git a/tests/tests/wrap/wrap_debug_malloc_debug/Android.bp b/tests/tests/wrap/wrap_debug_malloc_debug/Android.bp
new file mode 100644
index 0000000..9f152f7
--- /dev/null
+++ b/tests/tests/wrap/wrap_debug_malloc_debug/Android.bp
@@ -0,0 +1,68 @@
+// 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 {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "CtsWrapWrapDebugMallocDebugTestCases",
+    compile_multilib: "both",
+    dex_preopt: {
+        enabled: false,
+    },
+    optimize: {
+        enabled: false,
+    },
+    static_libs: [
+        "compatibility-device-util-axt",
+        "androidx.test.rules",
+        // this is for the src files
+        "cts_tests_tests_wrap_src",
+        "wrap_debug_malloc_debug_lib",
+    ],
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+        "android.test.mock.stubs",
+    ],
+    test_suites: [
+        "cts",
+        "general-tests",
+    ],
+    sdk_version: "current",
+    manifest: "AndroidManifest.xml",
+    // Jarjar to make WrapTest unique.
+    jarjar_rules: "jarjar-rules.txt",
+    use_embedded_native_libs: false,
+}
+
+java_genrule {
+    name: "wrap_debug_malloc_debug_lib",
+    srcs: ["wrap.sh"],
+    tools: ["soong_zip"],
+    out: ["wrap_debug_malloc_debug_abi.jar"],
+    cmd: "mkdir -p $(genDir)/lib/armeabi-v7a/ && " +
+         "mkdir -p $(genDir)/lib/arm64-v8a/ && " +
+         "mkdir -p $(genDir)/lib/x86/ && " +
+         "mkdir -p $(genDir)/lib/x86_64/ && " +
+         "cp $(in) $(genDir)/lib/armeabi-v7a/ && " +
+         "cp $(in) $(genDir)/lib/arm64-v8a/ && " +
+         "cp $(in) $(genDir)/lib/x86/ && " +
+         "cp $(in) $(genDir)/lib/x86_64/ && " +
+         "$(location soong_zip) -o $(out) -C $(genDir) " +
+         "-D $(genDir)/lib/armeabi-v7a/ -D $(genDir)/lib/arm64-v8a/ " +
+         "-D $(genDir)/lib/x86/ -D $(genDir)/lib/x86_64/",
+}
diff --git a/tests/tests/wrap/wrap_debug_malloc_debug/Android.mk b/tests/tests/wrap/wrap_debug_malloc_debug/Android.mk
deleted file mode 100644
index 06d1d5c..0000000
--- a/tests/tests/wrap/wrap_debug_malloc_debug/Android.mk
+++ /dev/null
@@ -1,51 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MULTILIB := both
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_DEX_PREOPT := false
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	compatibility-device-util-axt \
-	androidx.test.rules
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
-LOCAL_COMPATIBILITY_SUITE := cts general-tests
-LOCAL_SDK_VERSION := current
-
-LOCAL_PREBUILT_JNI_LIBS_arm := wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_arm64 := wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_mips := wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_mips64 := wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_x86 := wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_x86_64 := wrap.sh
-
-LOCAL_PACKAGE_NAME := CtsWrapWrapDebugMallocDebugTestCases
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_MANIFEST_FILE := AndroidManifest.xml
-
-# Jarjar to make WrapTest unique.
-LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
-
-LOCAL_USE_EMBEDDED_NATIVE_LIBS := false
-
-include $(BUILD_PACKAGE)
-
-include $(CLEAR_VARS)
diff --git a/tests/tests/wrap/wrap_nodebug/Android.bp b/tests/tests/wrap/wrap_nodebug/Android.bp
new file mode 100644
index 0000000..34f0a5c
--- /dev/null
+++ b/tests/tests/wrap/wrap_nodebug/Android.bp
@@ -0,0 +1,48 @@
+// 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 {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "CtsWrapWrapNoDebugTestCases",
+    compile_multilib: "both",
+    dex_preopt: {
+        enabled: false,
+    },
+    optimize: {
+        enabled: false,
+    },
+    static_libs: [
+        "compatibility-device-util-axt",
+        "androidx.test.rules",
+        "wrap_debug_lib"
+    ],
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+    srcs: [":cts_tests_tests_wrap_src"],
+    test_suites: [
+        "cts",
+        "general-tests",
+    ],
+    sdk_version: "current",
+    manifest: "AndroidManifest.xml",
+    // Jarjar to make WrapTest unique.
+    jarjar_rules: "jarjar-rules.txt",
+    use_embedded_native_libs: false,
+}
diff --git a/tests/tests/wrap/wrap_nodebug/Android.mk b/tests/tests/wrap/wrap_nodebug/Android.mk
deleted file mode 100644
index f7823c5..0000000
--- a/tests/tests/wrap/wrap_nodebug/Android.mk
+++ /dev/null
@@ -1,51 +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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MULTILIB := both
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_DEX_PREOPT := false
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_STATIC_JAVA_LIBRARIES := \
-	compatibility-device-util-axt \
-	androidx.test.rules
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
-LOCAL_COMPATIBILITY_SUITE := cts general-tests
-LOCAL_SDK_VERSION := current
-
-LOCAL_PREBUILT_JNI_LIBS_arm := ../wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_arm64 := ../wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_mips := ../wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_mips64 := ../wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_x86 := ../wrap.sh
-LOCAL_PREBUILT_JNI_LIBS_x86_64 := ../wrap.sh
-
-LOCAL_PACKAGE_NAME := CtsWrapWrapNoDebugTestCases
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_MANIFEST_FILE := AndroidManifest.xml
-
-# Jarjar to make WrapTest unique.
-LOCAL_JARJAR_RULES := $(LOCAL_PATH)/jarjar-rules.txt
-
-LOCAL_USE_EMBEDDED_NATIVE_LIBS := false
-
-include $(BUILD_PACKAGE)
-
-include $(CLEAR_VARS)
diff --git a/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java b/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
index 096db55..50e69f4 100644
--- a/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
+++ b/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
@@ -168,15 +168,22 @@
                 List<String> supportedAbiApk = result.getNativeCode();
                 Set<String> buildTarget = AbiUtils.getAbisForArch(
                         TestSuiteInfo.getInstance().getTargetArchs().get(0));
-                // first check, all the abis are supported
-                for (String abi : supportedAbiApk) {
-                    if (!buildTarget.contains(abi)) {
+                // first check, all the abis in the buildTarget are supported
+                for (String abiBT : buildTarget) {
+                    Boolean findMatch = false;
+                    for (String abiApk : supportedAbiApk) {
+                        if (abiApk.equals(abiBT)) {
+                            findMatch = true;
+                            break;
+                        }
+                    }
+                    if (!findMatch) {
                         fail(String.format("apk %s %s does not support our abis [%s]",
                                 testApk.getName(), supportedAbiApk, buildTarget));
                     }
                 }
                 apkToAbi.put(testApk.getName(), supportedAbiApk.size());
-                maxAbi = Math.max(maxAbi, supportedAbiApk.size());
+                maxAbi = Math.max(maxAbi, buildTarget.size());
             }
         }