Merge "Avoid PixelCopy timeout on some devices" into rvc-dev
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 dcca509..e54fdb5 100644
--- a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -1,4 +1,4 @@
-# Copyright 2015 The Android Open Source Project
+# Copyright 2015 The Android Open Source Project (lint as: python2)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -41,6 +41,40 @@
 AR_DIFF_ATOL = 0.01
 
 
+def print_failed_test_results(failed_ar, failed_fov, failed_crop):
+    """Print failed test results."""
+    if failed_ar:
+        print "\nAspect ratio test summary"
+        print "Images failed in the aspect ratio test:"
+        print "Aspect ratio value: width / height"
+        for fa in failed_ar:
+            print "%s with %s %dx%d: %.3f;" % (
+                    fa["fmt_iter"], fa["fmt_cmpr"],
+                    fa["w"], fa["h"], fa["ar"]),
+            print "valid range: %.3f ~ %.3f" % (
+                    fa["valid_range"][0], fa["valid_range"][1])
+
+    if failed_fov:
+        print "\nFoV test summary"
+        print "Images failed in the FoV test:"
+        for fov in failed_fov:
+            print fov
+
+    if failed_crop:
+        print "\nCrop test summary"
+        print "Images failed in the crop test:"
+        print "Circle center position, (horizontal x vertical), listed",
+        print "below is relative to the image center."
+        for fc in failed_crop:
+            print "%s with %s %dx%d: %.3f x %.3f;" % (
+                    fc["fmt_iter"], fc["fmt_cmpr"], fc["w"], fc["h"],
+                    fc["ct_hori"], fc["ct_vert"]),
+            print "valid horizontal range: %.3f ~ %.3f;" % (
+                    fc["valid_range_h"][0], fc["valid_range_h"][1]),
+            print "valid vertical range: %.3f ~ %.3f" % (
+                    fc["valid_range_v"][0], fc["valid_range_v"][1])
+
+
 def is_checked_aspect_ratio(first_api_level, w, h):
     if first_api_level >= 30:
         return True
@@ -182,6 +216,7 @@
 
     Returns:
         ref_fov:    dict with [fmt, % coverage, w, h, circle_w, circle_h]
+        cc_ct_gt:   circle center position relative to the center of image.
     """
     ref_fov = {}
     fmt = its.objects.get_largest_jpeg_format(props)
@@ -193,8 +228,8 @@
     img = its.image.convert_capture_to_rgb_image(cap, props=props)
     print "Captured JPEG %dx%d" % (w, h)
     img_name = "%s_jpeg_w%d_h%d.png" % (NAME, w, h)
-    # Set debug to True to save the debug image
-    _, _, circle_size = measure_aspect_ratio(img, img_name, False, debug=True)
+    # Set debug to True to save the reference image
+    _, cc_ct_gt, circle_size = measure_aspect_ratio(img, img_name, False, debug=True)
     fov_percent = calc_circle_image_ratio(circle_size[0], circle_size[1], w, h)
     ref_fov["fmt"] = "JPEG"
     ref_fov["percent"] = fov_percent
@@ -203,7 +238,7 @@
     ref_fov["circle_w"] = circle_size[0]
     ref_fov["circle_h"] = circle_size[1]
     print "Using JPEG reference:", ref_fov
-    return ref_fov
+    return ref_fov, cc_ct_gt
 
 
 def calc_circle_image_ratio(circle_w, circle_h, image_w, image_h):
@@ -469,7 +504,11 @@
                   # as reference frame; otherwise the highest resolution JPEG is used.
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
+        fls_logical = props['android.lens.info.availableFocalLengths']
+        print 'logical available focal lengths: %s', str(fls_logical)
         props = cam.override_with_hidden_physical_camera_props(props)
+        fls_physical = props['android.lens.info.availableFocalLengths']
+        print 'physical available focal lengths: %s', str(fls_physical)
         # determine skip conditions
         first_api = its.device.get_first_api_level(its.device.get_device_id())
         if first_api < 30:  # original constraint
@@ -491,11 +530,11 @@
         cam.do_3a()
         req = its.objects.auto_capture_request()
 
-        # If raw capture is available, use it as ground truth.
-        if raw_avlb:
+        # If raw is available and main camera, use it as ground truth.
+        if raw_avlb and (fls_physical == fls_logical):
             ref_fov, cc_ct_gt, aspect_ratio_gt = find_raw_fov_reference(cam, req, props, debug)
         else:
-            ref_fov = find_jpeg_fov_reference(cam, req, props)
+            ref_fov, cc_ct_gt = find_jpeg_fov_reference(cam, req, props)
 
         if run_crop_test:
             # Normalize the circle size to 1/4 of the image size, so that
@@ -624,47 +663,12 @@
                                             "valid_range_v": thres_range_v_cp})
                         its.image.write_image(img/255, img_name, True)
 
-        # Print aspect ratio test results
-        failed_image_number_for_aspect_ratio_test = len(failed_ar)
-        if failed_image_number_for_aspect_ratio_test > 0:
-            print "\nAspect ratio test summary"
-            print "Images failed in the aspect ratio test:"
-            print "Aspect ratio value: width / height"
-            for fa in failed_ar:
-                print "%s with %s %dx%d: %.3f;" % (
-                        fa["fmt_iter"], fa["fmt_cmpr"],
-                        fa["w"], fa["h"], fa["ar"]),
-                print "valid range: %.3f ~ %.3f" % (
-                        fa["valid_range"][0], fa["valid_range"][1])
-
-        # Print FoV test results
-        failed_image_number_for_fov_test = len(failed_fov)
-        if failed_image_number_for_fov_test > 0:
-            print "\nFoV test summary"
-            print "Images failed in the FoV test:"
-            for fov in failed_fov:
-                print fov
-
-        # Print crop test results
-        failed_image_number_for_crop_test = len(failed_crop)
-        if failed_image_number_for_crop_test > 0:
-            print "\nCrop test summary"
-            print "Images failed in the crop test:"
-            print "Circle center position, (horizontal x vertical), listed",
-            print "below is relative to the image center."
-            for fc in failed_crop:
-                print "%s with %s %dx%d: %.3f x %.3f;" % (
-                        fc["fmt_iter"], fc["fmt_cmpr"], fc["w"], fc["h"],
-                        fc["ct_hori"], fc["ct_vert"]),
-                print "valid horizontal range: %.3f ~ %.3f;" % (
-                        fc["valid_range_h"][0], fc["valid_range_h"][1]),
-                print "valid vertical range: %.3f ~ %.3f" % (
-                        fc["valid_range_v"][0], fc["valid_range_v"][1])
-
-        assert failed_image_number_for_aspect_ratio_test == 0
-        assert failed_image_number_for_fov_test == 0
+        # Print failed any test results
+        print_failed_test_results(failed_ar, failed_fov, failed_crop)
+        assert not failed_ar
+        assert not failed_fov
         if level3_device:
-            assert failed_image_number_for_crop_test == 0
+            assert not failed_crop
 
 
 if __name__ == "__main__":
diff --git a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
index 94e5c6b..649fc2a 100644
--- a/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
+++ b/apps/CameraITS/tests/scene4/test_multi_camera_alignment.py
@@ -26,8 +26,8 @@
 
 import numpy as np
 
-ALIGN_TOL_MM = 4.0E-3  # mm
-ALIGN_TOL = 0.01  # multiplied by sensor diagonal to convert to pixels
+ALIGN_ATOL_MM = 10E-3  # mm
+ALIGN_RTOL = 0.01  # multiplied by sensor diagonal to convert to pixels
 CIRCLE_RTOL = 0.1
 GYRO_REFERENCE = 1
 LENS_FACING_BACK = 1  # 0: FRONT, 1: BACK, 2: EXTERNAL
@@ -241,7 +241,7 @@
         gray:           numpy grayscale array with pixel values in [0,255].
         name:           string of file name.
     Returns:
-        circle:         (circle_center_x, circle_center_y, radius)
+        circle:         {'x': val, 'y': val, 'r': val}
     """
     size = gray.shape
     # otsu threshold to binarize the image
@@ -315,7 +315,7 @@
         print 'More than one black circle was detected. Background of scene',
         print 'may be too complex.\n'
         assert num_circle == 1
-    return [circle_ctx, circle_cty, (circle_w+circle_h)/4.0]
+    return {'x': circle_ctx, 'y': circle_cty, 'r': (circle_w+circle_h)/4.0}
 
 
 def define_reference_camera(pose_reference, cam_reference):
@@ -335,6 +335,9 @@
         i_2nd = list(cam_reference.keys())[1]
     else:
         print 'pose_reference is CAMERA'
+        num_ref_cameras = len([v for v in cam_reference.itervalues() if v])
+        e_msg = 'Too many/few reference cameras: %s' % str(cam_reference)
+        assert num_ref_cameras == 1, e_msg
         i_ref = (k for (k, v) in cam_reference.iteritems() if v).next()
         i_2nd = (k for (k, v) in cam_reference.iteritems() if not v).next()
     return i_ref, i_2nd
@@ -378,7 +381,6 @@
                              its.caps.logical_multi_camera(props) and
                              its.caps.backward_compatible(props))
         debug = its.caps.debug_mode()
-        avail_fls = props['android.lens.info.availableFocalLengths']
         pose_reference = props['android.lens.poseReference']
 
         # Convert chart_distance for lens facing back
@@ -458,6 +460,7 @@
         circle = {}
         fl = {}
         sensor_diag = {}
+        pixel_sizes = {}
         capture_cam_ids = physical_ids
         if fmt == 'raw':
             capture_cam_ids = physical_raw_ids
@@ -519,7 +522,7 @@
                 print 't:', t[i]
                 print 'r:', r[i]
 
-            # Correct lens distortion to image (if available)
+            # Correct lens distortion to RAW image (if available)
             if its.caps.distortion_correction(physical_props[i]) and fmt == 'raw':
                 distort = np.array(physical_props[i]['android.lens.distortion'])
                 assert len(distort) == 5, 'distortion has wrong # of params.'
@@ -536,26 +539,37 @@
             # Find the circles in grayscale image
             circle[i] = find_circle(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY),
                                     '%s_%s_gray_%s.jpg' % (NAME, fmt, i))
-            print 'Circle radius ', i, ': ', circle[i][2]
+            print 'Circle %s radius: %.3f' % (i, circle[i]['r'])
 
             # Undo zoom to image (if applicable). Assume that the maximum
             # physical YUV image size is close to active array size.
             if fmt == 'yuv':
-                ar = physical_props[i]['android.sensor.info.activeArraySize']
-                arw = ar['right'] - ar['left']
-                arh = ar['bottom'] - ar['top']
+                yuv_w = caps[(fmt, i)]['width']
+                yuv_h = caps[(fmt, i)]['height']
+                print 'cap size: %d x %d' % (yuv_w, yuv_h)
                 cr = caps[(fmt, i)]['metadata']['android.scaler.cropRegion']
                 crw = cr['right'] - cr['left']
                 crh = cr['bottom'] - cr['top']
                 # Assume pixels remain square after zoom, so use same zoom
                 # ratios for x and y.
-                zoom_ratio = min(1.0 * arw / crw, 1.0 * arh / crh)
-                circle[i][0] = cr['left'] + circle[i][0] / zoom_ratio
-                circle[i][1] = cr['top'] + circle[i][1] / zoom_ratio
-                circle[i][2] = circle[i][2] / zoom_ratio
+                zoom_ratio = min(1.0 * yuv_w / crw, 1.0 * yuv_h / crh)
+                circle[i]['x'] = cr['left'] + circle[i]['x'] / zoom_ratio
+                circle[i]['y'] = cr['top'] + circle[i]['y'] / zoom_ratio
+                circle[i]['r'] = circle[i]['r'] / zoom_ratio
+                print ' Calculated zoom_ratio:', zoom_ratio
+                print ' Corrected circle X:', circle[i]['x']
+                print ' Corrected circle Y:', circle[i]['y']
+                print ' Corrected circle radius : %.3f'  % circle[i]['r']
 
-            # Find focal length & sensor size
+            # Find focal length and pixel & sensor size
             fl[i] = physical_props[i]['android.lens.info.availableFocalLengths'][0]
+            ar = physical_props[i]['android.sensor.info.activeArraySize']
+            sensor_size = physical_props[i]['android.sensor.info.physicalSize']
+            pixel_size_w = sensor_size['width'] / (ar['right'] - ar['left'])
+            pixel_size_h = sensor_size['height'] / (ar['bottom'] - ar['top'])
+            print 'pixel size(um): %.2f x %.2f' % (
+                pixel_size_w*1E3, pixel_size_h*1E3)
+            pixel_sizes[i] = (pixel_size_w + pixel_size_h) / 2 * 1E3
             sensor_diag[i] = math.sqrt(size[i][0] ** 2 + size[i][1] ** 2)
 
         i_ref, i_2nd = define_reference_camera(pose_reference, cam_reference)
@@ -566,7 +580,7 @@
         y_w = {}
         for i in [i_ref, i_2nd]:
             x_w[i], y_w[i] = convert_to_world_coordinates(
-                    circle[i][0], circle[i][1], r[i], t[i], k[i],
+                    circle[i]['x'], circle[i]['y'], r[i], t[i], k[i],
                     chart_distance)
 
         # Back convert to image coordinates for sanity check
@@ -582,7 +596,7 @@
         # Summarize results
         for i in [i_ref, i_2nd]:
             print ' Camera: %s' % i
-            print ' x, y (pixels): %.1f, %.1f' % (circle[i][0], circle[i][1])
+            print ' x, y (pixels): %.1f, %.1f' % (circle[i]['x'], circle[i]['y'])
             print ' x_w, y_w (mm): %.2f, %.2f' % (x_w[i]*1.0E3, y_w[i]*1.0E3)
             print ' x_p, y_p (pixels): %.1f, %.1f' % (x_p[i], y_p[i])
 
@@ -591,31 +605,31 @@
                              np.array([x_w[i_2nd], y_w[i_2nd]]))
         print 'Center location err (mm): %.2f' % (err*1E3)
         msg = 'Center locations %s <-> %s too different!' % (i_ref, i_2nd)
-        msg += ' val=%.2fmm, THRESH=%.fmm' % (err*1E3, ALIGN_TOL_MM*1E3)
-        assert err < ALIGN_TOL, msg
+        msg += ' val=%.2fmm, THRESH=%.fmm' % (err*1E3, ALIGN_ATOL_MM*1E3)
+        assert err < ALIGN_ATOL_MM, msg
 
         # Check projections back into pixel space
         for i in [i_ref, i_2nd]:
-            err = np.linalg.norm(np.array([circle[i][0], circle[i][1]]) -
+            err = np.linalg.norm(np.array([circle[i]['x'], circle[i]['y']]) -
                                  np.array([x_p[i], y_p[i]]))
-            print 'Camera %s projection error (pixels): %.1f' % (i, err)
-            tol = ALIGN_TOL * sensor_diag[i]
+            print 'Camera %s projection error (pixels): %.2f' % (i, err)
+            tol = ALIGN_RTOL * sensor_diag[i]
             msg = 'Camera %s project locations too different!' % i
             msg += ' diff=%.2f, TOL=%.2f' % (err, tol)
             assert err < tol, msg
 
         # Check focal length and circle size if more than 1 focal length
-        if len(avail_fls) > 1:
+        if len(fl) > 1:
             print 'Circle radii (pixels); ref: %.1f, 2nd: %.1f' % (
-                    circle[i_ref][2], circle[i_2nd][2])
+                    circle[i_ref]['r'], circle[i_2nd]['r'])
             print 'Focal lengths (diopters); ref: %.2f, 2nd: %.2f' % (
                     fl[i_ref], fl[i_2nd])
-            print 'Sensor diagonals (pixels); ref: %.2f, 2nd: %.2f' % (
-                    sensor_diag[i_ref], sensor_diag[i_2nd])
+            print 'Pixel size (um); ref: %.2f, 2nd: %.2f' % (
+                    pixel_sizes[i_ref], pixel_sizes[i_2nd])
             msg = 'Circle size scales improperly! RTOL=%.1f' % CIRCLE_RTOL
-            msg += '\nMetric: radius/focal_length*sensor_diag should be equal.'
-            assert np.isclose(circle[i_ref][2]/fl[i_ref]*sensor_diag[i_ref],
-                              circle[i_2nd][2]/fl[i_2nd]*sensor_diag[i_2nd],
+            msg += '\nMetric: radius*pixel_size/focal_length should be equal.'
+            assert np.isclose(circle[i_ref]['r']*pixel_sizes[i_ref]/fl[i_ref],
+                              circle[i_2nd]['r']*pixel_sizes[i_2nd]/fl[i_2nd],
                               rtol=CIRCLE_RTOL), msg
 
 if __name__ == '__main__':
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 8b45f84..6cdbb3e 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -169,6 +169,7 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_other" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive" />
         </activity>
 
         <activity android:name=".forcestop.RecentTaskRemovalTestActivity"
@@ -179,6 +180,7 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_required_configs" android:value="config_has_recents"/>
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive" />
         </activity>
 
         <activity android:name=".companion.CompanionDeviceTestActivity"
@@ -2209,6 +2211,8 @@
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
 
             <meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
 
         <activity android:name=".camera.intents.CameraIntentsActivity"
@@ -2220,6 +2224,8 @@
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
 
             <meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
 
         <service android:name=".camera.intents.CameraContentJobService"
@@ -2235,6 +2241,8 @@
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
 
             <meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
 
         <activity
@@ -2248,16 +2256,22 @@
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
             <meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
         <activity
             android:name=".camera.fov.DetermineFovActivity"
             android:label="@string/camera_fov_calibration"
             android:screenOrientation="landscape"
             android:theme="@android:style/Theme.Holo.NoActionBar.Fullscreen" >
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
         <activity
             android:name=".camera.fov.CalibrationPreferenceActivity"
             android:label="@string/camera_fov_label_options" >
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
 
 
@@ -2271,6 +2285,8 @@
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
             <meta-data android:name="test_required_features"
                     android:value="android.hardware.camera.any"/>
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
 
         <activity android:name=".camera.its.ItsTestActivity"
@@ -2284,6 +2300,8 @@
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
             <meta-data android:name="test_required_features" android:value="android.hardware.camera.any" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
 
         <activity android:name=".camera.flashlight.CameraFlashlightActivity"
@@ -2295,6 +2313,8 @@
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
             <meta-data android:name="test_required_features" android:value="android.hardware.camera.flash" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
 
         <activity android:name=".camera.performance.CameraPerformanceActivity"
@@ -2306,6 +2326,8 @@
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
             <meta-data android:name="test_required_features" android:value="android.hardware.camera.any" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
 
         <activity android:name=".camera.bokeh.CameraBokehActivity"
@@ -2318,6 +2340,8 @@
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_camera" />
             <meta-data android:name="test_required_features" android:value="android.hardware.camera.any" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.automotive"/>
         </activity>
 
         <activity android:name=".usb.accessory.UsbAccessoryTestActivity"
@@ -2551,7 +2575,7 @@
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_tiles" />
             <meta-data android:name="test_excluded_features"
-                       android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
+                       android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch:android.hardware.type.automotive" />
         </activity>
 
         <service android:name=".qstiles.MockTileService"
@@ -4318,6 +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" />
         </activity>
         <activity android:name=".instantapps.RecentAppsTestActivity"
                  android:label="@string/ia_recents">
@@ -4326,6 +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" />
         </activity>
         <activity android:name=".instantapps.AppInfoTestActivity"
                  android:label="@string/ia_app_info">
@@ -4335,7 +4361,7 @@
             </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.television:android.software.leanback" />
+                android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.automotive" />
         </activity>
 
         <activity android:name=".displaycutout.DisplayCutoutTestActivity"
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
index 7776d27..c8a667b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
@@ -35,6 +35,8 @@
 import android.view.View.OnClickListener;
 import android.widget.ImageButton;
 import android.widget.Toast;
+import android.app.ActionBar;
+import android.view.MenuItem;
 
 import java.util.List;
 import java.util.stream.Collectors;
@@ -180,6 +182,25 @@
 
         @Override
         public TestResultHistoryCollection getHistoryCollection() { return mHistoryCollection; }
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            ActionBar actBar = getActionBar();
+            if (actBar != null) {
+                actBar.setDisplayHomeAsUpEnabled(true);
+            }
+        }
+
+        @Override
+        public boolean onOptionsItemSelected(MenuItem item) {
+            if (item.getItemId() == android.R.id.home) {
+                onBackPressed();
+                return true;
+            }
+            return super.onOptionsItemSelected(item);
+        }
+
     }
 
     public static class ListActivity extends android.app.ListActivity implements PassFailActivity {
@@ -234,6 +255,25 @@
 
         @Override
         public TestResultHistoryCollection getHistoryCollection() { return mHistoryCollection; }
+
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            ActionBar actBar = getActionBar();
+            if (actBar != null) {
+                actBar.setDisplayHomeAsUpEnabled(true);
+            }
+        }
+
+        @Override
+        public boolean onOptionsItemSelected(MenuItem item) {
+            if (item.getItemId() == android.R.id.home) {
+                onBackPressed();
+                return true;
+            }
+            return super.onOptionsItemSelected(item);
+        }
     }
 
     public static class TestListActivity extends AbstractTestListActivity
@@ -302,6 +342,25 @@
         public void updatePassButton() {
             getPassButton().setEnabled(mAdapter.allTestsPassed());
         }
+
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            ActionBar actBar = getActionBar();
+            if (actBar != null) {
+                actBar.setDisplayHomeAsUpEnabled(true);
+            }
+        }
+
+        @Override
+        public boolean onOptionsItemSelected(MenuItem item) {
+            if (item.getItemId() == android.R.id.home) {
+                onBackPressed();
+                return true;
+            }
+            return super.onOptionsItemSelected(item);
+        }
     }
 
     protected static <T extends android.app.Activity & PassFailActivity>
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
index 7db3682..8fdf859 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
@@ -103,7 +103,7 @@
      * Verify we can write to our own package dirs.
      */
     public void testAllPackageDirsWritable() throws Exception {
-        final long testValue = 12345000;
+        final long testValue = 1234500000000L;
         final List<File> paths = getAllPackageSpecificPaths(getContext());
         for (File path : paths) {
             assertNotNull("Valid media must be inserted during CTS", path);
diff --git a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
index e44d70d..f507d40 100644
--- a/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/StorageTest.java
@@ -45,6 +45,7 @@
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObjectNotFoundException;
 import android.support.test.uiautomator.UiScrollable;
 import android.support.test.uiautomator.UiSelector;
 import android.test.InstrumentationTestCase;
@@ -102,7 +103,11 @@
 
         if (!isTV(getContext())) {
             UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
-            uiScrollable.scrollTextIntoView("internal storage");
+            try {
+                uiScrollable.scrollTextIntoView("internal storage");
+            } catch (UiObjectNotFoundException e) {
+                // Scrolling can fail if the UI is not scrollable
+            }
             device.findObject(new UiSelector().textContains("internal storage")).click();
             device.waitForIdle();
         }
diff --git a/hostsidetests/bootstats/Android.bp b/hostsidetests/bootstats/Android.bp
index fa86bcf..3681c59 100644
--- a/hostsidetests/bootstats/Android.bp
+++ b/hostsidetests/bootstats/Android.bp
@@ -17,6 +17,7 @@
     defaults: ["cts_defaults"],
     // Only compile source java files in this apk.
     srcs: ["src/**/*.java"],
+    static_libs: ["framework-protos"],
     libs: [
         "cts-tradefed",
         "tradefed",
diff --git a/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java b/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
index 47789f1..9bcf2a1 100644
--- a/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
+++ b/hostsidetests/bootstats/src/android/bootstats/cts/BootStatsHostTest.java
@@ -18,11 +18,13 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.os.AtomsProto.Atom;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.IDeviceTest;
 
+import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -53,6 +55,11 @@
                 + " in Android 8.0. Current API Level " + apiLevel,
                 apiLevel < 26 /* Build.VERSION_CODES.O */);
 
+        if (apiLevel <= 29 /* Build.VERSION_CODES.Q */) {
+            testBootStatsForApiLevel29AndBelow();
+            return;
+        }
+
         // Clear buffer to make it easier to find new logs
         getDevice().executeShellCommand("logcat --buffer=events --clear");
 
@@ -109,6 +116,69 @@
         return value;
     }
 
+    /** Need to keep the old version of test for api 27, 28, 29 as new version 
+        of tests can be used on devices with old Android versions */
+    private void testBootStatsForApiLevel29AndBelow() throws Exception {
+        long startTime = System.currentTimeMillis();
+        // Clear buffer to make it easier to find new logs
+        getDevice().executeShellCommand("logcat --buffer=events --clear");
+
+        // reboot device
+        getDevice().rebootUntilOnline();
+        waitForBootCompleted();
+        int upperBoundSeconds = (int) ((System.currentTimeMillis() - startTime) / 1000);
+
+        // wait for logs to post
+        Thread.sleep(10000);
+
+        // find logs and parse them
+        // ex: sysui_multi_action: [757,804,799,ota_boot_complete,801,85,802,1]
+        // ex: 757,804,799,counter_name,801,bucket_value,802,increment_value
+        final String bucketTag = Integer.toString(MetricsEvent.RESERVED_FOR_LOGBUILDER_BUCKET);
+        final String counterNameTag = Integer.toString(MetricsEvent.RESERVED_FOR_LOGBUILDER_NAME);
+        final String counterNamePattern = counterNameTag + ",boot_complete,";
+        final String multiActionPattern = "sysui_multi_action: [";
+
+        final String log = getDevice().executeShellCommand("logcat --buffer=events -d");
+
+        int counterNameIndex = log.indexOf(counterNamePattern);
+        Assert.assertTrue("did not find boot logs", counterNameIndex != -1);
+
+        int multiLogStart = log.lastIndexOf(multiActionPattern, counterNameIndex);
+        multiLogStart += multiActionPattern.length();
+        int multiLogEnd = log.indexOf("]", multiLogStart);
+        String[] multiLogDataStrings = log.substring(multiLogStart, multiLogEnd).split(",");
+
+        boolean foundBucket = false;
+        int bootTime = 0;
+        for (int i = 0; i < multiLogDataStrings.length; i += 2) {
+            if (bucketTag.equals(multiLogDataStrings[i])) {
+                foundBucket = true;
+                Assert.assertTrue("histogram data was truncated",
+                        (i + 1) < multiLogDataStrings.length);
+                bootTime = Integer.valueOf(multiLogDataStrings[i + 1]);
+            }
+        }
+        Assert.assertTrue("log line did not contain a tag " + bucketTag, foundBucket);
+        Assert.assertTrue("reported boot time must be less than observed boot time",
+                bootTime < upperBoundSeconds);
+        Assert.assertTrue("reported boot time must be non-zero", bootTime > 0);
+    }
+
+    private boolean isBootCompleted() throws Exception {
+        return "1".equals(getDevice().executeShellCommand("getprop sys.boot_completed").trim());
+    }
+
+    private void waitForBootCompleted() throws Exception {
+        for (int i = 0; i < 45; i++) {
+            if (isBootCompleted()) {
+                return;
+            }
+            Thread.sleep(1000);
+        }
+        throw new AssertionError("System failed to become ready!");
+    }
+
     @Override
     public void setDevice(ITestDevice device) {
         mDevice = device;
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 4321f38..f6659f3 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,6 +88,12 @@
         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/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java
index f59803b..ed420f1 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java
@@ -16,7 +16,6 @@
 package com.android.cts.deviceandprofileowner;
 
 import android.app.admin.DevicePolicyManager;
-import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 import android.util.Log;
 
 /**
@@ -34,35 +33,32 @@
         super.setUp();
     }
 
-    public void testSetScreenCaptureDisabled_false() throws Exception {
+    public void testSetScreenCaptureDisabled_false() {
         mDevicePolicyManager.setScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT, false);
         assertFalse(mDevicePolicyManager.getScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT));
         assertFalse(mDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
     }
 
-    public void testSetScreenCaptureDisabled_true() throws Exception {
+    public void testSetScreenCaptureDisabled_true() {
         mDevicePolicyManager.setScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT, true);
         assertTrue(mDevicePolicyManager.getScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT));
         assertTrue(mDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
     }
 
-    public void testSetScreenCaptureDisabledOnParent() throws Exception {
+    public void testSetScreenCaptureDisabledOnParent_false() {
         DevicePolicyManager parentDevicePolicyManager =
                 mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
-        boolean initial = parentDevicePolicyManager.getScreenCaptureDisabled(
-                ADMIN_RECEIVER_COMPONENT);
-
-        parentDevicePolicyManager.setScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT, true);
-        assertTrue(parentDevicePolicyManager.getScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT));
-        assertTrue(parentDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
-        testScreenCaptureImpossible();
-
         parentDevicePolicyManager.setScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT, false);
         assertFalse(parentDevicePolicyManager.getScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT));
         assertFalse(parentDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
-        testScreenCapturePossible();
+    }
 
-        parentDevicePolicyManager.setScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT, initial);
+    public void testSetScreenCaptureDisabledOnParent_true() {
+        DevicePolicyManager parentDevicePolicyManager =
+                mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
+        parentDevicePolicyManager.setScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT, true);
+        assertTrue(parentDevicePolicyManager.getScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT));
+        assertTrue(parentDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
     }
 
     public void testScreenCaptureImpossible() throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index d828b86..048468c 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -1223,6 +1223,12 @@
             // Reboot while in kiosk mode and then unlock the device
             rebootAndWaitUntilReady();
 
+            // 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");
 
@@ -2219,13 +2225,9 @@
                 ? "testScreenCaptureImpossible"
                 : "testScreenCapturePossible";
 
-        if (userId == mPrimaryUserId) {
-            // If testing for user-0, also make sure the existing screen can't be captured.
-            executeDeviceTestMethod(".ScreenCaptureDisabledTest", testMethodName);
-        }
-
         startSimpleActivityAsUser(userId);
         executeDeviceTestMethod(".ScreenCaptureDisabledTest", testMethodName);
+        forceStopPackageForUser(TEST_APP_PKG, userId);
     }
 
     protected void setScreenCaptureDisabled_assist(int userId, boolean disabled) throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileContactsTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileContactsTest.java
index 2ed1e30..5492cf2 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileContactsTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileContactsTest.java
@@ -150,6 +150,9 @@
                     "settings put --user " + mProfileUserId
                     + " secure managed_profile_contact_remote_search 1");
 
+            // Wait for updating cache
+            waitForBroadcastIdle();
+
             // Add test account
             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
                     "testAddTestAccount", mParentUserId);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
index f575fc7..875803c 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/OrgOwnedProfileOwnerTest.java
@@ -49,6 +49,8 @@
     private static final String ACTION_WIPE_DATA =
             "com.android.cts.deviceandprofileowner.WIPE_DATA";
 
+    private static final String TEST_APP_APK = "CtsSimpleApp.apk";
+    private static final String TEST_APP_PKG = "com.android.cts.launcherapps.simpleapp";
     private static final String DUMMY_IME_APK = "DummyIme.apk";
     private static final String DUMMY_IME_PKG = "com.android.cts.dummyime";
     private static final String DUMMY_IME_COMPONENT = DUMMY_IME_PKG + "/.DummyIme";
@@ -554,8 +556,41 @@
         if (!mHasFeature) {
             return;
         }
+        installAppAsUser(DEVICE_ADMIN_APK, mPrimaryUserId);
+        setPoAsUser(mPrimaryUserId);
+
+        try {
+            setScreenCaptureDisabled(true);
+        } finally {
+            setScreenCaptureDisabled(false);
+        }
+    }
+
+    private void takeScreenCaptureAsUser(int userId, String testMethodName) throws Exception {
+        installAppAsUser(TEST_APP_APK, /* grantPermissions */ true, /* dontKillApp */ true, userId);
+        startActivityAsUser(userId, TEST_APP_PKG, TEST_APP_PKG + ".SimpleActivity");
         runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".ScreenCaptureDisabledTest",
-                "testSetScreenCaptureDisabledOnParent", mUserId);
+                testMethodName, userId);
+        forceStopPackageForUser(TEST_APP_PKG, userId);
+    }
+
+    private void setScreenCaptureDisabled(boolean disabled) throws Exception {
+        String testMethodName = disabled
+                ? "testSetScreenCaptureDisabledOnParent_true"
+                : "testSetScreenCaptureDisabledOnParent_false";
+        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".ScreenCaptureDisabledTest",
+                testMethodName, mUserId);
+
+        testMethodName = disabled
+                ? "testScreenCaptureImpossible"
+                : "testScreenCapturePossible";
+
+        // Test personal profile
+        takeScreenCaptureAsUser(mPrimaryUserId, testMethodName);
+
+        // Test managed profile. This should not be disabled when screen capture is disabled on
+        // the parent by the profile owner of an organization-owned device.
+        takeScreenCaptureAsUser(mUserId, "testScreenCapturePossible");
     }
 
     private void assertHasNoUser(int userId) throws DeviceNotAvailableException {
diff --git a/hostsidetests/scopedstorage/Android.bp b/hostsidetests/scopedstorage/Android.bp
index 3e5096b..1a1a7f9 100644
--- a/hostsidetests/scopedstorage/Android.bp
+++ b/hostsidetests/scopedstorage/Android.bp
@@ -15,28 +15,28 @@
 android_test_helper_app {
     name: "CtsScopedStorageTestAppA",
     manifest: "ScopedStorageTestHelper/TestAppA.xml",
-    static_libs: ["androidx.test.rules", "cts-scopedstorage-lib"],
+    static_libs: ["cts-scopedstorage-lib"],
     sdk_version: "test_current",
     srcs: ["ScopedStorageTestHelper/src/**/*.java"],
 }
 android_test_helper_app {
     name: "CtsScopedStorageTestAppB",
     manifest: "ScopedStorageTestHelper/TestAppB.xml",
-    static_libs: ["androidx.test.rules", "cts-scopedstorage-lib"],
+    static_libs: ["cts-scopedstorage-lib"],
     sdk_version: "test_current",
     srcs: ["ScopedStorageTestHelper/src/**/*.java"],
 }
 android_test_helper_app {
     name: "CtsScopedStorageTestAppC",
     manifest: "ScopedStorageTestHelper/TestAppC.xml",
-    static_libs: ["androidx.test.rules", "cts-scopedstorage-lib"],
+    static_libs: ["cts-scopedstorage-lib"],
     sdk_version: "test_current",
     srcs: ["ScopedStorageTestHelper/src/**/*.java"],
 }
 android_test_helper_app {
     name: "CtsScopedStorageTestAppCLegacy",
     manifest: "ScopedStorageTestHelper/TestAppCLegacy.xml",
-    static_libs: ["androidx.test.rules", "cts-scopedstorage-lib"],
+    static_libs: ["cts-scopedstorage-lib"],
     sdk_version: "test_current",
     target_sdk_version: "28",
     srcs: ["ScopedStorageTestHelper/src/**/*.java"],
@@ -46,9 +46,9 @@
     name: "ScopedStorageTest",
     manifest: "AndroidManifest.xml",
     srcs: ["src/**/*.java"],
-    static_libs: ["androidx.test.rules", "truth-prebuilt", "cts-scopedstorage-lib"],
+    static_libs: ["truth-prebuilt", "cts-scopedstorage-lib"],
     compile_multilib: "both",
-    test_suites: ["general-tests", "mts"],
+    test_suites: ["general-tests", "mts", "cts"],
     sdk_version: "test_current",
     java_resources: [
         ":CtsScopedStorageTestAppA",
@@ -61,9 +61,9 @@
     name: "LegacyStorageTest",
     manifest: "legacy/AndroidManifest.xml",
     srcs: ["legacy/src/**/*.java"],
-    static_libs: ["androidx.test.rules", "truth-prebuilt",  "cts-scopedstorage-lib"],
+    static_libs: ["truth-prebuilt", "cts-scopedstorage-lib"],
     compile_multilib: "both",
-    test_suites: ["general-tests", "mts"],
+    test_suites: ["general-tests", "mts", "cts"],
     sdk_version: "test_current",
     target_sdk_version: "29",
     java_resources: [
@@ -74,17 +74,15 @@
 java_test_host {
     name: "CtsScopedStorageHostTest",
     srcs: ["host/src/**/*.java"],
-    libs: ["tradefed"],
-    static_libs: ["testng"],
-    test_suites: ["general-tests", "mts"],
+    libs: ["tradefed", "testng"],
+    test_suites: ["general-tests", "mts", "cts"],
     test_config: "AndroidTest.xml",
 }
 
 java_test_host {
     name: "CtsScopedStoragePublicVolumeHostTest",
     srcs: ["host/src/**/*.java"],
-    libs: ["tradefed"],
-    static_libs: ["testng"],
+    libs: ["tradefed", "testng"],
     test_suites: ["general-tests", "mts"],
     test_config: "PublicVolumeTest.xml",
 }
diff --git a/hostsidetests/scopedstorage/AndroidTest.xml b/hostsidetests/scopedstorage/AndroidTest.xml
index 64599d8..43208ac 100644
--- a/hostsidetests/scopedstorage/AndroidTest.xml
+++ b/hostsidetests/scopedstorage/AndroidTest.xml
@@ -15,6 +15,10 @@
 -->
 <configuration description="External storage host test for legacy and scoped storage">
     <option name="test-suite-tag" value="cts" />
+    <option name="config-descriptor:metadata" key="component" value="framework" />
+    <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+    <option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="ScopedStorageTest.apk" />
@@ -23,6 +27,7 @@
     <test class="com.android.tradefed.testtype.HostTest" >
         <option name="class" value="android.scopedstorage.cts.host.LegacyStorageHostTest" />
         <option name="class" value="android.scopedstorage.cts.host.ScopedStorageHostTest" />
+        <option name="class" value="android.scopedstorage.cts.host.ScopedStorageInstantAppHostTest" />
     </test>
 
     <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
diff --git a/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java b/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java
index 2054907..2144def 100644
--- a/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java
+++ b/hostsidetests/scopedstorage/ScopedStorageTestHelper/src/android/scopedstorage/cts/ScopedStorageTestHelper.java
@@ -18,6 +18,7 @@
 import static android.scopedstorage.cts.lib.RedactionTestHelper.EXIF_METADATA_QUERY;
 import static android.scopedstorage.cts.lib.RedactionTestHelper.getExifMetadata;
 import static android.scopedstorage.cts.lib.TestUtils.CAN_READ_WRITE_QUERY;
+import static android.scopedstorage.cts.lib.TestUtils.CREATE_IMAGE_ENTRY_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.CREATE_FILE_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.DELETE_FILE_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.INTENT_EXCEPTION;
@@ -26,11 +27,16 @@
 import static android.scopedstorage.cts.lib.TestUtils.OPEN_FILE_FOR_WRITE_QUERY;
 import static android.scopedstorage.cts.lib.TestUtils.QUERY_TYPE;
 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 android.app.Activity;
 import android.content.Intent;
+import android.content.ContentResolver;
+import android.content.ContentValues;
 import android.os.Bundle;
+import android.provider.MediaStore;
 
 import androidx.annotation.Nullable;
 
@@ -73,11 +79,15 @@
                 case DELETE_FILE_QUERY:
                 case OPEN_FILE_FOR_READ_QUERY:
                 case OPEN_FILE_FOR_WRITE_QUERY:
+                case SETATTR_QUERY:
                     returnIntent = accessFile(queryType);
                     break;
                 case EXIF_METADATA_QUERY:
                     returnIntent = sendMetadata(queryType);
                     break;
+                case CREATE_IMAGE_ENTRY_QUERY:
+                    returnIntent = createImageEntry(queryType);
+                    break;
                 case "null":
                 default:
                     throw new IllegalStateException(
@@ -125,6 +135,28 @@
         }
     }
 
+    private Intent createImageEntry(String queryType) throws Exception {
+        if (getIntent().hasExtra(INTENT_EXTRA_PATH)) {
+            final String path = getIntent().getStringExtra(INTENT_EXTRA_PATH);
+            final String relativePath = path.substring(0, path.lastIndexOf('/'));
+            final String name = path.substring(path.lastIndexOf('/') + 1);
+
+            ContentValues values = new ContentValues();
+            values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
+            values.put(MediaStore.Images.Media.RELATIVE_PATH, relativePath);
+            values.put(MediaStore.Images.Media.DISPLAY_NAME, name);
+
+            getContentResolver().insert(getMediaContentUri(), values);
+
+            final Intent intent = new Intent(queryType);
+            intent.putExtra(queryType, true);
+            return intent;
+        } else {
+            throw new IllegalStateException(
+                    CREATE_IMAGE_ENTRY_QUERY + ": File path not set from launcher app");
+        }
+    }
+
     private Intent accessFile(String queryType) throws IOException {
         if (getIntent().hasExtra(INTENT_EXTRA_PATH)) {
             final String filePath = getIntent().getStringExtra(INTENT_EXTRA_PATH);
@@ -141,6 +173,9 @@
                 returnStatus = canOpen(file, false /* forWrite */);
             } else if (queryType.equals(OPEN_FILE_FOR_WRITE_QUERY)) {
                 returnStatus = canOpen(file, true /* forWrite */);
+            } else if (queryType.equals(SETATTR_QUERY)) {
+                int newTimeMillis = 12345000;
+                returnStatus = file.setLastModified(newTimeMillis);
             }
             final Intent intent = new Intent(queryType);
             intent.putExtra(queryType, returnStatus);
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 ab391c9..cfb30a3 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/LegacyStorageHostTest.java
@@ -20,6 +20,8 @@
 
 import static org.junit.Assert.assertTrue;
 
+import android.platform.test.annotations.AppModeFull;
+
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
@@ -32,6 +34,7 @@
  * Runs the legacy file path access tests.
  */
 @RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
 public class LegacyStorageHostTest extends BaseHostJUnit4Test {
     private boolean isExternalStorageSetup = false;
 
@@ -186,4 +189,9 @@
     public void testCaseInsensitivity() throws Exception {
         runDeviceTest("testAndroidDataObbCannotBeDeleted");
     }
+
+    @Test
+    public void testLegacyAppUpdatingOwnershipOfExistingEntry() throws Exception {
+        runDeviceTest("testLegacyAppUpdatingOwnershipOfExistingEntry");
+    }
 }
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 d34606a..c067a1c 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
@@ -18,6 +18,8 @@
 
 import static org.junit.Assert.assertTrue;
 
+import android.platform.test.annotations.AppModeFull;
+
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
@@ -30,6 +32,7 @@
  * Runs the ScopedStorageTest tests.
  */
 @RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
 public class ScopedStorageHostTest extends BaseHostJUnit4Test {
     private boolean mIsExternalStorageSetup = false;
 
@@ -108,6 +111,11 @@
     }
 
     @Test
+    public void testDeleteAlreadyUnlinkedFile() throws Exception {
+        runDeviceTest("testDeleteAlreadyUnlinkedFile");
+
+    }
+    @Test
     public void testOpendirRestrictions() throws Exception {
         runDeviceTest("testOpendirRestrictions");
     }
@@ -362,6 +370,11 @@
     }
 
     @Test
+    public void testCantSetAttrOtherAppsFile() throws Exception {
+        runDeviceTest("testCantSetAttrOtherAppsFile");
+    }
+
+    @Test
     public void testAccess_file() throws Exception {
         grantPermissions("android.permission.READ_EXTERNAL_STORAGE");
         try {
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageInstantAppHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageInstantAppHostTest.java
new file mode 100644
index 0000000..c97b41f
--- /dev/null
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageInstantAppHostTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.scopedstorage.cts.host;
+
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.AppModeInstant;
+
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Runs the ScopedStorageTest tests for an instant app.
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class ScopedStorageInstantAppHostTest extends BaseHostJUnit4Test {
+    /**
+     * Runs the given phase of Test by calling into the device.
+     * Throws an exception if the test phase fails.
+     */
+    protected void runDeviceTest(String phase) throws Exception {
+        assertTrue(runDeviceTests("android.scopedstorage.cts",
+                "android.scopedstorage.cts.ScopedStorageTest", phase));
+    }
+
+    @Test
+    @AppModeInstant
+    public void testInstantAppsCantAccessExternalStorage() throws Exception {
+        runDeviceTest("testInstantAppsCantAccessExternalStorage");
+    }
+}
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 43c6d20..f700391 100644
--- a/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/LegacyStorageTest.java
+++ b/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/LegacyStorageTest.java
@@ -26,6 +26,7 @@
 import static android.scopedstorage.cts.lib.TestUtils.assertDirectoryContains;
 import static android.scopedstorage.cts.lib.TestUtils.assertFileContent;
 import static android.scopedstorage.cts.lib.TestUtils.createFileAs;
+import static android.scopedstorage.cts.lib.TestUtils.createImageEntryAs;
 import static android.scopedstorage.cts.lib.TestUtils.deleteFileAsNoThrow;
 import static android.scopedstorage.cts.lib.TestUtils.deleteWithMediaProviderNoThrow;
 import static android.scopedstorage.cts.lib.TestUtils.executeShellCommand;
@@ -34,10 +35,12 @@
 import static android.scopedstorage.cts.lib.TestUtils.getFileRowIdFromDatabase;
 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.pollForExternalStorageState;
 import static android.scopedstorage.cts.lib.TestUtils.pollForPermission;
 import static android.scopedstorage.cts.lib.TestUtils.setupDefaultDirectories;
 import static android.scopedstorage.cts.lib.TestUtils.uninstallApp;
+import static android.scopedstorage.cts.lib.TestUtils.uninstallAppNoThrow;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -93,9 +96,16 @@
     private static final String TAG = "LegacyFileAccessTest";
     static final String THIS_PACKAGE_NAME = InstrumentationRegistry.getContext().getPackageName();
 
-    static final String IMAGE_FILE_NAME = "LegacyStorageTest_file.jpg";
-    static final String VIDEO_FILE_NAME = "LegacyStorageTest_file.mp4";
-    static final String NONMEDIA_FILE_NAME = "LegacyStorageTest_file.pdf";
+    /**
+     * To help avoid flaky tests, give ourselves a unique nonce to be used for
+     * all filesystem paths, so that we don't risk conflicting with previous
+     * test runs.
+     */
+    static final String NONCE = String.valueOf(System.nanoTime());
+
+    static final String IMAGE_FILE_NAME = "LegacyStorageTest_file_" + NONCE + ".jpg";
+    static final String VIDEO_FILE_NAME = "LegacyStorageTest_file_" + NONCE + ".mp4";
+    static final String NONMEDIA_FILE_NAME = "LegacyStorageTest_file_" + NONCE + ".pdf";
 
     private static final TestApp TEST_APP_A = new TestApp("TestAppA",
             "android.scopedstorage.cts.testapp.A", 1, false, "CtsScopedStorageTestAppA.apk");
@@ -666,6 +676,30 @@
         assertThat(canDeleteDir.delete()).isTrue();
     }
 
+    @Test
+    public void testLegacyAppUpdatingOwnershipOfExistingEntry() throws Exception {
+        pollForPermission(Manifest.permission.READ_EXTERNAL_STORAGE, /*granted*/ true);
+        pollForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, /*granted*/ true);
+
+        final File fullPath = new File(TestUtils.getDcimDir(),
+                "OwnershipChange_" + IMAGE_FILE_NAME);
+        final String relativePath = "DCIM/OwnershipChange_" + IMAGE_FILE_NAME;
+        try {
+            installApp(TEST_APP_A, false);
+            createImageEntryAs(TEST_APP_A, relativePath);
+            assertThat(fullPath.createNewFile()).isTrue();
+
+            // We have transferred ownership away from TEST_APP_A so reads / writes
+            // should no longer work.
+            assertThat(openFileAs(TEST_APP_A, fullPath, false /* for write */)).isFalse();
+            assertThat(openFileAs(TEST_APP_A, fullPath, false /* for read */)).isFalse();
+        } finally {
+            deleteFileAsNoThrow(TEST_APP_A, fullPath.getAbsolutePath());
+            uninstallAppNoThrow(TEST_APP_A);
+            fullPath.delete();
+        }
+    }
+
     private static void assertCanCreateFile(File file) throws IOException {
         if (file.exists()) {
             file.delete();
diff --git a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/Android.bp b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/Android.bp
index 3a5ba59..be2ae44 100644
--- a/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/Android.bp
+++ b/hostsidetests/scopedstorage/libs/ScopedStorageTestLib/Android.bp
@@ -15,6 +15,6 @@
 java_library {
     name: "cts-scopedstorage-lib",
     srcs: ["src/**/*.java"],
-    static_libs: ["androidx.test.rules", "cts-install-lib"],
+    static_libs: ["androidx.test.rules", "cts-install-lib", "platform-test-annotations",],
     sdk_version: "test_current"
 }
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 3a2caaf..f17cbbe 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
@@ -65,6 +65,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InterruptedIOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -84,13 +85,17 @@
     public static final String INTENT_EXTRA_PATH = "android.scopedstorage.cts.path";
     public static final String INTENT_EXCEPTION = "android.scopedstorage.cts.exception";
     public static final String CREATE_FILE_QUERY = "android.scopedstorage.cts.createfile";
+    public static final String CREATE_IMAGE_ENTRY_QUERY =
+            "android.scopedstorage.cts.createimageentry";
     public static final String DELETE_FILE_QUERY = "android.scopedstorage.cts.deletefile";
-    public static final String OPEN_FILE_FOR_READ_QUERY = "android.scopedstorage.cts.openfile_read";
+    public static final String OPEN_FILE_FOR_READ_QUERY =
+            "android.scopedstorage.cts.openfile_read";
     public static final String OPEN_FILE_FOR_WRITE_QUERY =
             "android.scopedstorage.cts.openfile_write";
     public static final String CAN_READ_WRITE_QUERY =
             "android.scopedstorage.cts.can_read_and_write";
     public static final String READDIR_QUERY = "android.scopedstorage.cts.readdir";
+    public static final String SETATTR_QUERY = "android.scopedstorage.cts.setattr";
 
     public static final String STR_DATA1 = "Just some random text";
     public static final String STR_DATA2 = "More arbitrary stuff";
@@ -102,7 +107,7 @@
     private static File sExternalStorageDirectory = Environment.getExternalStorageDirectory();
     private static String sStorageVolumeName = MediaStore.VOLUME_EXTERNAL;
 
-    private static final long POLLING_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(10);
+    private static final long POLLING_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(20);
     private static final long POLLING_SLEEP_MILLIS = 100;
 
     /**
@@ -165,7 +170,21 @@
     /**
      * Executes a shell command.
      */
-    public static String executeShellCommand(String cmd) throws Exception {
+    public static String executeShellCommand(String command) throws IOException {
+        int attempt = 0;
+        while (attempt++ < 5) {
+            try {
+                return executeShellCommandInternal(command);
+            } catch (InterruptedIOException e) {
+                // Hmm, we had trouble executing the shell command; the best we
+                // can do is try again a few more times
+                Log.v(TAG, "Trouble executing " + command + "; trying again", e);
+            }
+        }
+        throw new IOException("Failed to execute " + command);
+    }
+
+    private static String executeShellCommandInternal(String cmd) throws IOException {
         UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
         try (FileInputStream output = new FileInputStream(
                      uiAutomation.executeShellCommand(cmd).getFileDescriptor())) {
@@ -210,6 +229,17 @@
     }
 
     /**
+     * Makes the given {@code testApp} create a mediastore DB entry under
+     * {@code MediaStore.Media.Images}.
+     *
+     * The {@code path} argument is treated as a relative path and a name separated
+     * by an {@code '/'}.
+     */
+    public static boolean createImageEntryAs(TestApp testApp, String path) throws Exception {
+        return getResultFromTestApp(testApp, path, CREATE_IMAGE_ENTRY_QUERY);
+    }
+
+    /**
      * Makes the given {@code testApp} delete a file.
      *
      * <p>This method drops shell permission identity.
@@ -254,6 +284,16 @@
     }
 
     /**
+     * Makes the given {@code testApp} setattr for given file path.
+     *
+     * <p>This method drops shell permission identity.
+     */
+    public static boolean setAttrAs(TestApp testApp, String path)
+            throws Exception {
+        return getResultFromTestApp(testApp, path, SETATTR_QUERY);
+    }
+
+    /**
      * Installs a {@link TestApp} without storage permissions.
      */
     public static void installApp(TestApp testApp) throws Exception {
@@ -332,6 +372,13 @@
     }
 
     /**
+     * Returns the content URI for images based on the current storage volume.
+     */
+    public static Uri getMediaContentUri() {
+        return MediaStore.Images.Media.getContentUri(sStorageVolumeName);
+    }
+
+    /**
      * Renames the given file using {@link ContentResolver} and {@link MediaStore} and APIs.
      * This method uses the data column, and not all apps can use it.
      * @see MediaStore.MediaColumns#DATA
@@ -884,7 +931,11 @@
         intent.putExtra(INTENT_EXTRA_PATH, dirPath);
         intent.addCategory(Intent.CATEGORY_LAUNCHER);
         getContext().startActivity(intent);
-        latch.await();
+        if (!latch.await(POLLING_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)) {
+            final String errorMessage = "Timed out while waiting to receive " + actionName
+                    + " intent from " + packageName;
+            throw new TimeoutException(errorMessage);
+        }
         getContext().unregisterReceiver(broadcastReceiver);
     }
 
diff --git a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
index 87077bc..4bd2344 100644
--- a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
+++ b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
@@ -85,6 +85,7 @@
 import static android.scopedstorage.cts.lib.TestUtils.queryVideoFile;
 import static android.scopedstorage.cts.lib.TestUtils.readExifMetadataFromTestApp;
 import static android.scopedstorage.cts.lib.TestUtils.revokePermission;
+import static android.scopedstorage.cts.lib.TestUtils.setAttrAs;
 import static android.scopedstorage.cts.lib.TestUtils.setupDefaultDirectories;
 import static android.scopedstorage.cts.lib.TestUtils.uninstallApp;
 import static android.scopedstorage.cts.lib.TestUtils.uninstallAppNoThrow;
@@ -102,6 +103,7 @@
 import static androidx.test.InstrumentationRegistry.getContext;
 
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
 
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
@@ -123,6 +125,7 @@
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
+import android.platform.test.annotations.AppModeInstant;
 import android.provider.MediaStore;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -162,14 +165,21 @@
     static final String TAG = "ScopedStorageTest";
     static final String THIS_PACKAGE_NAME = getContext().getPackageName();
 
-    static final String TEST_DIRECTORY_NAME = "ScopedStorageTestDirectory";
+    /**
+     * To help avoid flaky tests, give ourselves a unique nonce to be used for
+     * all filesystem paths, so that we don't risk conflicting with previous
+     * test runs.
+     */
+    static final String NONCE = String.valueOf(System.nanoTime());
 
-    static final String AUDIO_FILE_NAME = "ScopedStorageTest_file.mp3";
-    static final String PLAYLIST_FILE_NAME = "ScopedStorageTest_file.m3u";
-    static final String SUBTITLE_FILE_NAME = "ScopedStorageTest_file.srt";
-    static final String VIDEO_FILE_NAME = "ScopedStorageTest_file.mp4";
-    static final String IMAGE_FILE_NAME = "ScopedStorageTest_file.jpg";
-    static final String NONMEDIA_FILE_NAME = "ScopedStorageTest_file.pdf";
+    static final String TEST_DIRECTORY_NAME = "ScopedStorageTestDirectory" + NONCE;
+
+    static final String AUDIO_FILE_NAME = "ScopedStorageTest_file_" + NONCE + ".mp3";
+    static final String PLAYLIST_FILE_NAME = "ScopedStorageTest_file_" + NONCE + ".m3u";
+    static final String SUBTITLE_FILE_NAME = "ScopedStorageTest_file_" + NONCE + ".srt";
+    static final String VIDEO_FILE_NAME = "ScopedStorageTest_file_" + NONCE + ".mp4";
+    static final String IMAGE_FILE_NAME = "ScopedStorageTest_file_" + NONCE + ".jpg";
+    static final String NONMEDIA_FILE_NAME = "ScopedStorageTest_file_" + NONCE + ".pdf";
 
     static final String FILE_CREATION_ERROR_MESSAGE = "No such file or directory";
 
@@ -191,8 +201,10 @@
         // skips all test cases if FUSE is not active.
         assumeTrue(getBoolean("persist.sys.fuse", false));
 
-        pollForExternalStorageState();
-        getExternalFilesDir().mkdirs();
+        if (!getContext().getPackageManager().isInstantApp()) {
+            pollForExternalStorageState();
+            getExternalFilesDir().mkdirs();
+        }
     }
 
     /**
@@ -503,6 +515,29 @@
     }
 
     /**
+     * Test that deleting uri corresponding to a file which was already deleted via filePath
+     * doesn't result in a security exception.
+     */
+    @Test
+    public void testDeleteAlreadyUnlinkedFile() throws Exception {
+        final File nonMediaFile = new File(getDownloadDir(), NONMEDIA_FILE_NAME);
+        try {
+            assertTrue(nonMediaFile.createNewFile());
+            final Uri uri = MediaStore.scanFile(getContentResolver(), nonMediaFile);
+            assertNotNull(uri);
+
+            // Delete the file via filePath
+            assertTrue(nonMediaFile.delete());
+
+            // If we delete nonMediaFile with ContentResolver#delete, it shouldn't result in a
+            // security exception.
+            assertThat(getContentResolver().delete(uri, Bundle.EMPTY)).isEqualTo(0);
+        } finally {
+            nonMediaFile.delete();
+        }
+    }
+
+    /**
      * This test relies on the fact that {@link File#list} uses opendir internally, and that it
      * returns {@code null} if opendir fails.
      */
@@ -679,10 +714,8 @@
             // TEST_APP_A should not see other app's external files directory.
             installAppWithStoragePermissions(TEST_APP_A);
 
-            // TODO(b/157650550): we don't have consistent behaviour on both primary and public
-            //  volumes
-//            assertThrows(IOException.class,
-//                    () -> listAs(TEST_APP_A, getAndroidDataDir().getPath()));
+            assertThrows(IOException.class,
+                    () -> listAs(TEST_APP_A, getAndroidDataDir().getPath()));
             assertThrows(IOException.class,
                     () -> listAs(TEST_APP_A, getExternalFilesDir().getPath()));
         } finally {
@@ -1632,8 +1665,7 @@
                     THIS_PACKAGE_NAME, TEST_APP_A.getPackageName()));
             final File otherAppExternalDataFile = new File(otherAppExternalDataDir,
                     NONMEDIA_FILE_NAME);
-            assertThat(createFileAs(TEST_APP_A, otherAppExternalDataFile.getAbsolutePath()))
-                    .isTrue();
+            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
@@ -1653,6 +1685,41 @@
     }
 
     /**
+     * Tests that an instant app can't access external storage.
+     */
+    @Test
+    @AppModeInstant
+    public void testInstantAppsCantAccessExternalStorage() throws Exception {
+        assumeTrue("This test requires that the test runs as an Instant app",
+                getContext().getPackageManager().isInstantApp());
+        assertThat(getContext().getPackageManager().isInstantApp()).isTrue();
+
+        // Can't read ExternalStorageDir
+        assertThat(getExternalStorageDir().list()).isNull();
+
+        // Can't create a top-level direcotry
+        final File topLevelDir = new File(getExternalStorageDir(), TEST_DIRECTORY_NAME);
+        assertThat(topLevelDir.mkdir()).isFalse();
+
+        // Can't create file under root dir
+        final File newTxtFile = new File(getExternalStorageDir(), NONMEDIA_FILE_NAME);
+        assertThrows(IOException.class,
+                () -> { newTxtFile.createNewFile(); });
+
+        // Can't create music file under /MUSIC
+        final File newMusicFile = new File(getMusicDir(), AUDIO_FILE_NAME);
+        assertThrows(IOException.class,
+                () -> { newMusicFile.createNewFile(); });
+
+        // getExternalFilesDir() is not null
+        assertThat(getExternalFilesDir()).isNotNull();
+
+        // Can't read/write app specific dir
+        assertThat(getExternalFilesDir().list()).isNull();
+        assertThat(getExternalFilesDir().exists()).isFalse();
+    }
+
+    /**
      * Test that apps can create and delete hidden file.
      */
     @Test
@@ -2543,6 +2610,34 @@
     }
 
     /**
+     * Test that apps can't set attributes on another app's files.
+     */
+    @Test
+    public void testCantSetAttrOtherAppsFile() throws Exception {
+        // This path's permission is checked in MediaProvider (directory/external media dir)
+        final File externalMediaPath = new File(getExternalMediaDir(), VIDEO_FILE_NAME);
+
+        try {
+            // Create the files
+            if (!externalMediaPath.exists()) {
+                assertThat(externalMediaPath.createNewFile()).isTrue();
+            }
+
+            // Install TEST_APP_A with READ_EXTERNAL_STORAGE permission.
+            installAppWithStoragePermissions(TEST_APP_A);
+
+            // TEST_APP_A should not be able to setattr to other app's files.
+            assertWithMessage(
+                "setattr on directory/external media path [%s]", externalMediaPath.getPath())
+                .that(setAttrAs(TEST_APP_A, externalMediaPath.getPath()))
+                .isFalse();
+        } finally {
+            externalMediaPath.delete();
+            uninstallAppNoThrow(TEST_APP_A);
+        }
+    }
+
+    /**
      * 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
      * method doesn't uninstall given {@code testApp} at the end.
diff --git a/hostsidetests/securitybulletin/Android.bp b/hostsidetests/securitybulletin/Android.bp
index 6a574c9..f17395e 100644
--- a/hostsidetests/securitybulletin/Android.bp
+++ b/hostsidetests/securitybulletin/Android.bp
@@ -53,4 +53,8 @@
         "vts10",
         "sts",
     ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
 }
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/Android.bp b/hostsidetests/securitybulletin/securityPatch/includes/Android.bp
index 3f4087f..c20e845 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/Android.bp
+++ b/hostsidetests/securitybulletin/securityPatch/includes/Android.bp
@@ -13,15 +13,22 @@
 // limitations under the License.
 
 filegroup {
-    name: "cts_securitybulletin_memutils",
+    name: "cts_hostsidetests_securitybulletin_memutils",
     srcs: [
         "memutils.c",
     ],
 }
 
 filegroup {
-    name: "cts_securitybulletin_omxutils",
+    name: "cts_hostsidetests_securitybulletin_omxutils",
     srcs: [
         "omxUtils.cpp",
     ],
 }
+
+filegroup {
+    name: "cts_hostsidetests_securitybulletin_memutils_track",
+    srcs: [
+        "memutils_track.c",
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.c b/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.c
new file mode 100644
index 0000000..80e125f
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.c
@@ -0,0 +1,205 @@
+/**
+ * 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.
+ */
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <unistd.h>
+#include "common.h"
+#include "memutils_track.h"
+
+void memutils_init(void) {
+    real_memalign = dlsym(RTLD_NEXT, "memalign");
+    if (!real_memalign) {
+        return;
+    }
+    real_malloc = dlsym(RTLD_NEXT, "malloc");
+    if (!real_malloc) {
+        return;
+    }
+    real_free = dlsym(RTLD_NEXT, "free");
+    if (!real_free) {
+        return;
+    }
+
+#ifdef CHECK_MEMORY_LEAK
+    real_calloc = dlsym(RTLD_NEXT, "calloc");
+    if (!real_calloc) {
+        return;
+    }
+    atexit(exit_vulnerable_if_memory_leak_detected);
+#endif /* CHECK_MEMORY_LEAK */
+
+    s_memutils_initialized = true;
+}
+
+void *memalign(size_t alignment, size_t size) {
+    if (!s_memutils_initialized) {
+        memutils_init();
+    }
+    void* mem_ptr = real_memalign(alignment, size);
+
+#ifdef CHECK_UNINITIALIZED_MEMORY
+    if(mem_ptr) {
+        memset(mem_ptr, INITIAL_VAL, size);
+    }
+#endif /* CHECK_UNINITIALIZED_MEMORY */
+
+#ifdef ENABLE_SELECTIVE_OVERLOADING
+    if ((enable_selective_overload & ENABLE_MEMALIGN_CHECK) != ENABLE_MEMALIGN_CHECK) {
+        return mem_ptr;
+    }
+#endif /* ENABLE_SELECTIVE_OVERLOADING */
+
+    if (!is_tracking_required(size)) {
+        return mem_ptr;
+    }
+    if (s_allocation_index >= MAX_ENTRIES) {
+        return mem_ptr;
+    }
+    s_allocation_list[s_allocation_index].mem_ptr = mem_ptr;
+    s_allocation_list[s_allocation_index].mem_size = size;
+    ++s_allocation_index;
+    return mem_ptr;
+}
+
+void *malloc(size_t size) {
+    if (!s_memutils_initialized) {
+        memutils_init();
+    }
+    void* mem_ptr = real_malloc(size);
+
+#ifdef CHECK_UNINITIALIZED_MEMORY
+    if(mem_ptr) {
+        memset(mem_ptr, INITIAL_VAL, size);
+    }
+#endif /* CHECK_UNINITIALIZED_MEMORY */
+
+#ifdef ENABLE_SELECTIVE_OVERLOADING
+    if ((enable_selective_overload & ENABLE_MALLOC_CHECK) != ENABLE_MALLOC_CHECK) {
+        return mem_ptr;
+    }
+#endif /* ENABLE_SELECTIVE_OVERLOADING */
+
+    if (!is_tracking_required(size)) {
+        return mem_ptr;
+    }
+    if (s_allocation_index >= MAX_ENTRIES) {
+        return mem_ptr;
+    }
+    s_allocation_list[s_allocation_index].mem_ptr = mem_ptr;
+    s_allocation_list[s_allocation_index].mem_size = size;
+    ++s_allocation_index;
+    return mem_ptr;
+}
+
+void free(void *ptr) {
+    if (!s_memutils_initialized) {
+        memutils_init();
+    }
+    if (ptr) {
+        for (int i = 0; i < s_allocation_index; ++i) {
+            if (ptr == s_allocation_list[i].mem_ptr) {
+                real_free(ptr);
+                memset(&s_allocation_list[i], 0,
+                       sizeof(allocated_memory_struct));
+                return;
+            }
+        }
+    }
+    return real_free(ptr);
+}
+
+#ifdef CHECK_MEMORY_LEAK
+void *calloc(size_t nitems, size_t size) {
+    if (!s_memutils_initialized) {
+        memutils_init();
+    }
+    void* mem_ptr = real_calloc(nitems, size);
+
+#ifdef ENABLE_SELECTIVE_OVERLOADING
+    if ((enable_selective_overload & ENABLE_CALLOC_CHECK) != ENABLE_CALLOC_CHECK) {
+        return mem_ptr;
+    }
+#endif /* ENABLE_SELECTIVE_OVERLOADING */
+
+    if (!is_tracking_required((nitems *size))) {
+        return mem_ptr;
+    }
+    if (s_allocation_index >= MAX_ENTRIES) {
+        return mem_ptr;
+    }
+    s_allocation_list[s_allocation_index].mem_ptr = mem_ptr;
+    s_allocation_list[s_allocation_index].mem_size = nitems * size;
+    ++s_allocation_index;
+    return mem_ptr;
+}
+
+void exit_vulnerable_if_memory_leak_detected(void) {
+    bool memory_leak_detected = false;
+    for (int i = 0; i < s_allocation_index; ++i) {
+        if (s_allocation_list[i].mem_ptr) {
+            real_free(s_allocation_list[i].mem_ptr);
+            memset(&s_allocation_list[i], 0,
+                    sizeof(allocated_memory_struct));
+            memory_leak_detected = true;
+        }
+    }
+    if(memory_leak_detected) {
+        exit(EXIT_VULNERABLE);
+    }
+    return;
+}
+#endif /* CHECK_MEMORY_LEAK */
+
+#ifdef CHECK_UNINITIALIZED_MEMORY
+bool is_memory_uninitialized() {
+    for (int i = 0; i < s_allocation_index; ++i) {
+        char *mem_ptr = s_allocation_list[i].mem_ptr;
+        size_t mem_size = s_allocation_list[i].mem_size;
+        if (mem_ptr) {
+
+#ifdef CHECK_FOUR_BYTES
+            if(mem_size > (2 * sizeof(uint32_t))) {
+                char *mem_ptr_start = (char *)s_allocation_list[i].mem_ptr;
+                char *mem_ptr_end = (char *)s_allocation_list[i].mem_ptr + mem_size - 1;
+                for (size_t j = 0; j < sizeof(uint32_t); ++j) {
+                    if (*mem_ptr_start++ == INITIAL_VAL) {
+                        return true;
+                    }
+                    if (*mem_ptr_end-- == INITIAL_VAL) {
+                        return true;
+                    }
+                }
+                continue;
+            }
+#endif /* CHECK_FOUR_BYTES */
+
+            for (size_t j = 0; j < mem_size; ++j) {
+                if (*mem_ptr++ == INITIAL_VAL) {
+                    return true;
+                }
+            }
+        }
+    }
+    return false;
+}
+
+#endif /* CHECK_UNINITIALIZED_MEMORY */
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.h b/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.h
new file mode 100644
index 0000000..dff76e2
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/includes/memutils_track.h
@@ -0,0 +1,59 @@
+/**
+ * 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.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#define MAX_ENTRIES               (32 * 1024)
+#define INITIAL_VAL               0xBE
+
+#define ENABLE_NONE               0x00
+#define ENABLE_MEMALIGN_CHECK     0x01
+#define ENABLE_MALLOC_CHECK       0x02
+#define ENABLE_CALLOC_CHECK       0x04
+#define ENABLE_ALL                ENABLE_MEMALIGN_CHECK | ENABLE_MALLOC_CHECK |\
+    ENABLE_CALLOC_CHECK
+
+typedef struct {
+    void *mem_ptr;
+    size_t mem_size;
+} allocated_memory_struct;
+
+static bool s_memutils_initialized = false;
+static int s_allocation_index = 0;
+static allocated_memory_struct s_allocation_list[MAX_ENTRIES] = { { 0, 0 } };
+
+extern bool is_tracking_required(size_t size);
+static void* (*real_memalign)(size_t, size_t) = NULL;
+static void* (*real_malloc)(size_t) = NULL;
+static void (*real_free)(void *) = NULL;
+
+#ifdef ENABLE_SELECTIVE_OVERLOADING
+extern char enable_selective_overload;
+#endif /* ENABLE_SELECTIVE_OVERLOADING */
+
+#ifdef CHECK_MEMORY_LEAK
+static void* (*real_calloc)(size_t, size_t) = NULL;
+void exit_vulnerable_if_memory_leak_detected(void);
+#endif
+
+#ifdef CHECK_UNINITIALIZED_MEMORY
+extern bool is_memory_uninitialized();
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
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/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/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
index 5aa76c0..c478bf2 100644
--- a/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
+++ b/tests/BlobStore/src/com/android/cts/blob/BlobStoreManagerTest.java
@@ -62,10 +62,14 @@
 import org.junit.runner.RunWith;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Random;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
@@ -598,14 +602,14 @@
 
         try {
             commitBlob(blobData);
-            // Verify that blob can be access after committing.
+            // Verify that blob can be accessed after committing.
             try (ParcelFileDescriptor pfd = mBlobStoreManager.openBlob(blobData.getBlobHandle())) {
                 assertThat(pfd).isNotNull();
                 blobData.verifyBlob(pfd);
             }
 
             commitBlob(blobData);
-            // Verify that blob can be access after re-committing.
+            // Verify that blob can be accessed after re-committing.
             try (ParcelFileDescriptor pfd = mBlobStoreManager.openBlob(blobData.getBlobHandle())) {
                 assertThat(pfd).isNotNull();
                 blobData.verifyBlob(pfd);
@@ -622,14 +626,14 @@
         final TestServiceConnection connection = bindToHelperService(HELPER_PKG);
         try {
             commitBlob(blobData);
-            // Verify that blob can be access after committing.
+            // Verify that blob can be accessed after committing.
             try (ParcelFileDescriptor pfd = mBlobStoreManager.openBlob(blobData.getBlobHandle())) {
                 assertThat(pfd).isNotNull();
                 blobData.verifyBlob(pfd);
             }
 
             commitBlobFromPkg(blobData, connection);
-            // Verify that blob can be access after re-committing.
+            // Verify that blob can be accessed after re-committing.
             try (ParcelFileDescriptor pfd = mBlobStoreManager.openBlob(blobData.getBlobHandle())) {
                 assertThat(pfd).isNotNull();
                 blobData.verifyBlob(pfd);
@@ -642,6 +646,130 @@
     }
 
     @Test
+    public void testSessionCommit_largeBlob() throws Exception {
+        final long fileSizeBytes = Math.min(mBlobStoreManager.getRemainingLeaseQuotaBytes(),
+                150 * 1024L * 1024L);
+        final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+                .setFileSize(fileSizeBytes)
+                .build();
+        blobData.prepare();
+        final long commitTimeoutSec = TIMEOUT_COMMIT_CALLBACK_SEC * 2;
+        try {
+            final long sessionId = mBlobStoreManager.createSession(blobData.getBlobHandle());
+            assertThat(sessionId).isGreaterThan(0L);
+            try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
+                blobData.writeToSession(session);
+
+                final CompletableFuture<Integer> callback = new CompletableFuture<>();
+                session.commit(mContext.getMainExecutor(), callback::complete);
+                assertThat(callback.get(commitTimeoutSec, TimeUnit.SECONDS))
+                        .isEqualTo(0);
+            }
+
+            // Verify that blob can be accessed after committing.
+            try (ParcelFileDescriptor pfd = mBlobStoreManager.openBlob(blobData.getBlobHandle())) {
+                assertThat(pfd).isNotNull();
+                blobData.verifyBlob(pfd);
+            }
+        } finally {
+            blobData.delete();
+        }
+    }
+
+    @Test
+    public void testCommitSession_multipleWrites() throws Exception {
+        final int numThreads = 2;
+        final Random random = new Random(0);
+        final ExecutorService executorService = Executors.newFixedThreadPool(numThreads);
+        final CompletableFuture<Throwable>[] completableFutures = new CompletableFuture[numThreads];
+        for (int i = 0; i < numThreads; ++i) {
+            completableFutures[i] = CompletableFuture.supplyAsync(() -> {
+                final int minSizeMb = 30;
+                final long fileSizeBytes = (minSizeMb + random.nextInt(minSizeMb)) * 1024L * 1024L;
+                final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+                        .setFileSize(fileSizeBytes)
+                        .build();
+                try {
+                    blobData.prepare();
+                    commitAndVerifyBlob(blobData);
+                } catch (Throwable t) {
+                    return t;
+                } finally {
+                    blobData.delete();
+                }
+                return null;
+            }, executorService);
+        }
+        final ArrayList<Throwable> invalidResults = new ArrayList<>();
+        for (int i = 0; i < numThreads; ++i) {
+             final Throwable result = completableFutures[i].get();
+             if (result != null) {
+                 invalidResults.add(result);
+             }
+        }
+        assertThat(invalidResults).isEmpty();
+    }
+
+    @Test
+    public void testCommitSession_multipleReadWrites() throws Exception {
+        final int numThreads = 2;
+        final Random random = new Random(0);
+        final ExecutorService executorService = Executors.newFixedThreadPool(numThreads);
+        final CompletableFuture<Throwable>[] completableFutures = new CompletableFuture[numThreads];
+        for (int i = 0; i < numThreads; ++i) {
+            completableFutures[i] = CompletableFuture.supplyAsync(() -> {
+                final int minSizeMb = 30;
+                final long fileSizeBytes = (minSizeMb + random.nextInt(minSizeMb)) * 1024L * 1024L;
+                final DummyBlobData blobData = new DummyBlobData.Builder(mContext)
+                        .setFileSize(fileSizeBytes)
+                        .build();
+                try {
+                    blobData.prepare();
+                    final long sessionId = mBlobStoreManager.createSession(
+                            blobData.getBlobHandle());
+                    assertThat(sessionId).isGreaterThan(0L);
+                    try (BlobStoreManager.Session session = mBlobStoreManager.openSession(
+                            sessionId)) {
+                        final long partialFileSizeBytes = minSizeMb * 1024L * 1024L;
+                        blobData.writeToSession(session, 0L, partialFileSizeBytes);
+                        blobData.readFromSessionAndVerifyBytes(session, 0L,
+                                (int) partialFileSizeBytes);
+                        blobData.writeToSession(session, partialFileSizeBytes,
+                                blobData.getFileSize() - partialFileSizeBytes);
+                        blobData.readFromSessionAndVerifyBytes(session, partialFileSizeBytes,
+                                (int) (blobData.getFileSize() - partialFileSizeBytes));
+
+                        final CompletableFuture<Integer> callback = new CompletableFuture<>();
+                        session.commit(mContext.getMainExecutor(), callback::complete);
+                        assertThat(callback.get(TIMEOUT_COMMIT_CALLBACK_SEC, TimeUnit.SECONDS))
+                                .isEqualTo(0);
+                    }
+
+                    // Verify that blob can be accessed after committing.
+                    try (ParcelFileDescriptor pfd = mBlobStoreManager.openBlob(
+                            blobData.getBlobHandle())) {
+                        assertThat(pfd).isNotNull();
+                        blobData.verifyBlob(pfd);
+                    }
+                } catch (Throwable t) {
+                    return t;
+                } finally {
+                    blobData.delete();
+                }
+                return null;
+            }, executorService);
+        }
+        final ArrayList<Throwable> invalidResults = new ArrayList<>();
+        for (int i = 0; i < numThreads; ++i) {
+            final Throwable result = completableFutures[i].get();
+            if (result != null) {
+                invalidResults.add(result);
+            }
+        }
+        assertThat(invalidResults).isEmpty();
+    }
+
+    @Test
     public void testOpenBlob() throws Exception {
         final DummyBlobData blobData = new DummyBlobData.Builder(mContext).build();
         blobData.prepare();
@@ -652,7 +780,7 @@
             try (BlobStoreManager.Session session = mBlobStoreManager.openSession(sessionId)) {
                 blobData.writeToSession(session);
 
-                // Verify that trying to access the blob before commit throws
+                // Verify that trying to accessed the blob before commit throws
                 assertThrows(SecurityException.class,
                         () -> mBlobStoreManager.openBlob(blobData.getBlobHandle()));
 
@@ -662,7 +790,7 @@
                         .isEqualTo(0);
             }
 
-            // Verify that blob can be access after committing.
+            // Verify that blob can be accessed after committing.
             try (ParcelFileDescriptor pfd = mBlobStoreManager.openBlob(blobData.getBlobHandle())) {
                 assertThat(pfd).isNotNull();
 
@@ -1196,6 +1324,16 @@
         }
     }
 
+    private void commitAndVerifyBlob(DummyBlobData blobData) throws Exception {
+        commitBlob(blobData);
+
+        // Verify that blob can be accessed after committing.
+        try (ParcelFileDescriptor pfd = mBlobStoreManager.openBlob(blobData.getBlobHandle())) {
+            assertThat(pfd).isNotNull();
+            blobData.verifyBlob(pfd);
+        }
+    }
+
     private long commitBlob(DummyBlobData blobData) throws Exception {
         return commitBlob(blobData, null);
     }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
index b37358f..252fbcb 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
@@ -150,11 +150,13 @@
     }
 
     private final AccessibilityEventFilter mDividerPresentFilter = (event) ->
-            (event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED)
+            (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
+                    || event.getEventType() == TYPE_WINDOWS_CHANGED)
                     && isDividerWindowPresent();
 
     private final AccessibilityEventFilter mDividerAbsentFilter = (event) ->
-            (event.getEventType() == AccessibilityEvent.TYPE_WINDOWS_CHANGED)
+            (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
+                    || event.getEventType() == TYPE_WINDOWS_CHANGED)
                     && !isDividerWindowPresent();
 
     @MediumTest
@@ -700,11 +702,14 @@
     }
 
     private boolean isDividerWindowPresent() {
-        List<AccessibilityWindowInfo> windows = sUiAutomation.getWindows();
+        final List<AccessibilityWindowInfo> windows = sUiAutomation.getWindows();
         final int windowCount = windows.size();
         for (int i = 0; i < windowCount; i++) {
-            AccessibilityWindowInfo window = windows.get(i);
-            if (window.getType() == AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER) {
+            final AccessibilityWindowInfo window = windows.get(i);
+            final AccessibilityNodeInfo rootNode = window.getRoot();
+            if (window.getType() == AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER &&
+                    rootNode != null &&
+                    rootNode.isVisibleToUser()) {
                 return true;
             }
         }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
index 860295f..9224739 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/TouchExplorerTest.java
@@ -17,20 +17,14 @@
 package android.accessibilityservice.cts;
 
 import static android.accessibilityservice.cts.utils.AsyncUtils.await;
-import static android.accessibilityservice.cts.utils.GestureUtils.IS_ACTION_DOWN;
-import static android.accessibilityservice.cts.utils.GestureUtils.IS_ACTION_UP;
 import static android.accessibilityservice.cts.utils.GestureUtils.add;
-import static android.accessibilityservice.cts.utils.GestureUtils.ceil;
 import static android.accessibilityservice.cts.utils.GestureUtils.click;
-import static android.accessibilityservice.cts.utils.GestureUtils.diff;
 import static android.accessibilityservice.cts.utils.GestureUtils.dispatchGesture;
 import static android.accessibilityservice.cts.utils.GestureUtils.doubleTap;
 import static android.accessibilityservice.cts.utils.GestureUtils.doubleTapAndHold;
-import static android.accessibilityservice.cts.utils.GestureUtils.isRawAtPoint;
 import static android.accessibilityservice.cts.utils.GestureUtils.multiTap;
 import static android.accessibilityservice.cts.utils.GestureUtils.secondFingerMultiTap;
 import static android.accessibilityservice.cts.utils.GestureUtils.swipe;
-import static android.accessibilityservice.cts.utils.GestureUtils.times;
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_HOVER_ENTER;
 import static android.view.MotionEvent.ACTION_HOVER_EXIT;
@@ -49,9 +43,6 @@
 import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_CLICKED;
 import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_LONG_CLICKED;
 
-import static org.hamcrest.CoreMatchers.both;
-import static org.hamcrest.MatcherAssert.assertThat;
-
 import android.accessibility.cts.common.AccessibilityDumpOnFailureRule;
 import android.accessibility.cts.common.InstrumentedAccessibilityServiceTestRule;
 import android.accessibilityservice.GestureDescription;
@@ -71,7 +62,6 @@
 import android.platform.test.annotations.AppModeFull;
 import android.util.DisplayMetrics;
 import android.view.Display;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
@@ -87,8 +77,6 @@
 import org.junit.rules.RuleChain;
 import org.junit.runner.RunWith;
 
-import java.util.List;
-
 /**
  * A set of tests for testing touch exploration. Each test dispatches a gesture and checks for the
  * appropriate hover and/or touch events followed by the appropriate accessibility events. Some
@@ -221,27 +209,7 @@
         dispatch(
                 swipe(finger1Start, finger1End, mSwipeTimeMillis),
                 swipe(finger2Start, finger2End, mSwipeTimeMillis));
-        List<MotionEvent> twoFingerPoints = mTouchListener.getRawEvents();
-
-        // Check the drag events performed by a two finger drag. The moving locations would be
-        // adjusted to the middle of two fingers.
-        final int numEvents = twoFingerPoints.size();
-        final int upEventIndex = numEvents - 1;
-        final float stepDuration =
-                (float)
-                        (twoFingerPoints.get(1).getEventTime()
-                                - twoFingerPoints.get(0).getEventTime());
-        final float gestureDuration =
-                (float)
-                        (twoFingerPoints.get(upEventIndex).getEventTime()
-                                - twoFingerPoints.get(0).getEventTime());
-        final float intervalFraction =
-                stepDuration * (mSwipeDistance / gestureDuration) / gestureDuration;
-        PointF downPoint = add(dragStart, ceil(times(intervalFraction, diff(dragEnd, dragStart))));
-        assertThat(twoFingerPoints.get(0), both(IS_ACTION_DOWN).and(isRawAtPoint(downPoint, 1.0f)));
-        assertThat(
-                twoFingerPoints.get(upEventIndex),
-                both(IS_ACTION_UP).and(isRawAtPoint(finger2End, 1.0f)));
+        mTouchListener.assertPropagated(ACTION_DOWN, ACTION_MOVE, ACTION_UP);
     }
 
     /** Test a basic single tap which should initiate touch exploration. */
diff --git a/tests/app/src/android/app/cts/ActionBarTest.java b/tests/app/src/android/app/cts/ActionBarTest.java
index ee28c27..f3d2846 100644
--- a/tests/app/src/android/app/cts/ActionBarTest.java
+++ b/tests/app/src/android/app/cts/ActionBarTest.java
@@ -124,6 +124,21 @@
         assertFalse(menuIsVisible[0]);
     }
 
+    @UiThreadTest
+    public void testElevation() {
+        if (mBar == null) {
+            return;
+        }
+        final float oldElevation = mBar.getElevation();
+        try {
+            final float newElevation = 42;
+            mBar.setElevation(newElevation);
+            assertEquals(newElevation, mBar.getElevation());
+        } finally {
+            mBar.setElevation(oldElevation);
+        }
+    }
+
     private Tab createTab(String name) {
         return mBar.newTab().setText("Tab 1").setTabListener(new TestTabListener());
     }
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java b/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
index 55253db..6893090 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DatasetFilteringTest.java
@@ -38,9 +38,9 @@
 import com.android.cts.mockime.ImeEventStream;
 import com.android.cts.mockime.MockImeSession;
 
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
 
 import java.util.regex.Pattern;
 
@@ -53,15 +53,12 @@
         super(inlineUiBot);
     }
 
-    @BeforeClass
-    public static void setMaxDatasets() throws Exception {
-        Helper.setMaxVisibleDatasets(4);
+    @Override
+    protected TestRule getMainTestRule() {
+        return RuleChain.outerRule(new MaxVisibleDatasetsRule(4))
+                        .around(super.getMainTestRule());
     }
 
-    @AfterClass
-    public static void restoreMaxDatasets() throws Exception {
-        Helper.setMaxVisibleDatasets(0);
-    }
 
     private void changeUsername(CharSequence username) {
         mActivity.onUsername((v) -> v.setText(username));
@@ -111,10 +108,7 @@
         // No dataset start with 'aaa'
         final MyAutofillCallback callback = mActivity.registerCallback();
         changeUsername("aaa");
-        // TODO(b/157762527): Fix this for the inline case.
-        if (!isInlineMode()) {
-            callback.assertUiHiddenEvent(mActivity.getUsername());
-        }
+        callback.assertUiHiddenEvent(mActivity.getUsername());
         mUiBot.assertNoDatasets();
 
         // Delete some text to bring back 2 datasets
@@ -179,10 +173,7 @@
         sendKeyEvent("KEYCODE_A");
         sendKeyEvent("KEYCODE_A");
         sendKeyEvent("KEYCODE_A");
-        // TODO(b/157762527): Fix this for the inline case.
-        if (!isInlineMode()) {
-            callback.assertUiHiddenEvent(mActivity.getUsername());
-        }
+        callback.assertUiHiddenEvent(mActivity.getUsername());
         mUiBot.assertNoDatasets();
     }
 
@@ -253,10 +244,7 @@
         final MyAutofillCallback callback = mActivity.registerCallback();
         final ImeCommand cmd5 = mockImeSession.callCommitText("aaa", 1);
         expectCommand(stream, cmd5, MOCK_IME_TIMEOUT_MS);
-        // TODO(b/157762527): Fix this for the inline case.
-        if (!isInlineMode()) {
-            callback.assertUiHiddenEvent(mActivity.getUsername());
-        }
+        callback.assertUiHiddenEvent(mActivity.getUsername());
         mUiBot.assertNoDatasets();
     }
 
@@ -413,10 +401,7 @@
         // No dataset start with 'aaa'
         final MyAutofillCallback callback = mActivity.registerCallback();
         changeUsername("aaa");
-        // TODO(b/157762527): Fix this for the inline case.
-        if (!isInlineMode()) {
-            callback.assertUiHiddenEvent(mActivity.getUsername());
-        }
+        callback.assertUiHiddenEvent(mActivity.getUsername());
         mUiBot.assertNoDatasets();
     }
 
@@ -483,10 +468,7 @@
         // No dataset start with 'aaa'
         final MyAutofillCallback callback = mActivity.registerCallback();
         changeUsername("aaa");
-        // TODO(b/157762527): Fix this for the inline case.
-        if (!isInlineMode()) {
-            callback.assertUiHiddenEvent(mActivity.getUsername());
-        }
+        callback.assertUiHiddenEvent(mActivity.getUsername());
         mUiBot.assertNoDatasets();
     }
 
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityCommonTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityCommonTestCase.java
index 1ef42c5..1bad60a 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityCommonTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityCommonTestCase.java
@@ -117,6 +117,10 @@
         // Set service.
         enableService();
 
+        final MyAutofillCallback callback = mActivity.registerCallback();
+        final View username = mActivity.getUsername();
+        final View password = mActivity.getPassword();
+
         String[] expectedDatasets = new String[numDatasets];
         final CannedFillResponse.Builder builder = new CannedFillResponse.Builder();
         for (int i = 0; i < numDatasets; i++) {
@@ -136,11 +140,13 @@
         mUiBot.waitForIdle();
 
         mUiBot.assertDatasets(expectedDatasets);
+        callback.assertUiShownEvent(username);
 
         mUiBot.selectDataset(expectedDatasets[selectedDatasetIndex]);
 
         // Check the results.
         mActivity.assertAutoFilled();
+        callback.assertUiHiddenEvent(username);
 
         // Make sure input was sanitized.
         final InstrumentedAutoFillService.FillRequest request = sReplier.getNextFillRequest();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/MaxVisibleDatasetsRule.java b/tests/autofillservice/src/android/autofillservice/cts/MaxVisibleDatasetsRule.java
new file mode 100644
index 0000000..8a397d9
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/MaxVisibleDatasetsRule.java
@@ -0,0 +1,63 @@
+/*
+ * 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.autofillservice.cts;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Custom JUnit4 rule that improves autofill-related environment by:
+ *
+ * <ol>
+ *   <li>Setting max_visible_datasets before and after test.
+ * </ol>
+ */
+public final class MaxVisibleDatasetsRule implements TestRule {
+
+    private static final String TAG = MaxVisibleDatasetsRule.class.getSimpleName();
+
+    private final int mMaxNumber;
+
+    /**
+     * Creates a MaxVisibleDatasetsRule with given datasets values.
+     *
+     * @param maxNumber The desired max_visible_datasets value for a test,
+     * after the test it will be replaced by the original value
+     */
+    public MaxVisibleDatasetsRule(int maxNumber) {
+        mMaxNumber = maxNumber;
+    }
+
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return new Statement() {
+
+            @Override
+            public void evaluate() throws Throwable {
+                final int original = Helper.getMaxVisibleDatasets();
+                Helper.setMaxVisibleDatasets(mMaxNumber);
+                try {
+                    base.evaluate();
+                } finally {
+                    Helper.setMaxVisibleDatasets(original);
+                }
+            }
+        };
+    }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedLoginActivityTest.java
index 75c1042..d645834 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedLoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/inline/InlineAugmentedLoginActivityTest.java
@@ -29,6 +29,7 @@
 
 import android.autofillservice.cts.AutofillActivityTestRule;
 import android.autofillservice.cts.Helper;
+import android.autofillservice.cts.MyAutofillCallback;
 import android.autofillservice.cts.augmented.AugmentedAutofillAutoActivityLaunchTestCase;
 import android.autofillservice.cts.augmented.AugmentedLoginActivity;
 import android.autofillservice.cts.augmented.CannedAugmentedFillResponse;
@@ -175,6 +176,8 @@
     }
 
     private void testBasicLoginAutofill() throws Exception {
+
+        final MyAutofillCallback callback = mActivity.registerCallback();
         // Set expectations
         final EditText username = mActivity.getUsername();
         final EditText password = mActivity.getPassword();
@@ -202,6 +205,7 @@
 
         // Confirm two suggestion
         mUiBot.assertDatasets("dude");
+        callback.assertUiShownEvent(username);
 
         mActivity.expectAutoFill("dude", "sweet");
 
@@ -210,6 +214,8 @@
         mUiBot.waitForIdle();
 
         mActivity.assertAutoFilled();
+        mUiBot.assertNoDatasetsEver();
+        callback.assertUiHiddenEvent(username);
     }
 
     @Test
@@ -315,6 +321,8 @@
         Helper.mockSwitchInputMethod(sContext);
         mUiBot.waitForIdleSync();
 
+        // Set new expectations
+        sReplier.addResponse(NO_RESPONSE);
         sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
                 .addInlineSuggestion(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me 2")
                         .setField(usernameId, "dude2", createInlinePresentation("dude2"))
@@ -326,8 +334,7 @@
         // Trigger auto-fill
         mUiBot.selectByRelativeId(ID_USERNAME);
         mUiBot.waitForIdle();
-
-        // Confirm new fill request
+        sReplier.getNextFillRequest();
         sAugmentedReplier.getNextFillRequest();
 
         // Confirm new suggestion
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/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
index 192d7ad..e7b36f0 100644
--- a/tests/camera/src/android/hardware/cts/CameraTest.java
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -152,31 +152,50 @@
      * receive the callback messages.
      */
     private void initializeMessageLooper(final int cameraId) throws IOException {
+        LooperInfo looperInfo = new LooperInfo();
+        initializeMessageLooper(cameraId, mErrorCallback, looperInfo);
+        mIsExternalCamera = looperInfo.isExternalCamera;
+        mCamera = looperInfo.camera;
+        mLooper = looperInfo.looper;
+    }
+
+    private final class LooperInfo {
+        Camera camera = null;
+        Looper looper = null;
+        boolean isExternalCamera = false;
+    };
+
+    /*
+     * Initializes the message looper so that the Camera object can
+     * receive the callback messages.
+     */
+    private void initializeMessageLooper(final int cameraId, final ErrorCallback errorCallback,
+            LooperInfo looperInfo) throws IOException {
         final ConditionVariable startDone = new ConditionVariable();
         final CameraCtsActivity activity = mActivityRule.getActivity();
         new Thread() {
             @Override
             public void run() {
-                Log.v(TAG, "start loopRun");
+                Log.v(TAG, "start loopRun for cameraId " + cameraId);
                 // Set up a looper to be used by camera.
                 Looper.prepare();
                 // Save the looper so that we can terminate this thread
                 // after we are done with it.
-                mLooper = Looper.myLooper();
+                looperInfo.looper = Looper.myLooper();
                 try {
-                    mIsExternalCamera = CameraUtils.isExternal(
+                    looperInfo.isExternalCamera = CameraUtils.isExternal(
                             activity.getApplicationContext(), cameraId);
                 } catch (Exception e) {
                     Log.e(TAG, "Unable to query external camera!" + e);
                 }
 
                 try {
-                    mCamera = Camera.open(cameraId);
-                    mCamera.setErrorCallback(mErrorCallback);
+                    looperInfo.camera = Camera.open(cameraId);
+                    looperInfo.camera.setErrorCallback(errorCallback);
                 } catch (RuntimeException e) {
-                    Log.e(TAG, "Fail to open camera." + e);
+                    Log.e(TAG, "Fail to open camera id " + cameraId + ": " + e);
                 }
-                Log.v(TAG, "camera is opened");
+                Log.v(TAG, "camera" + cameraId + " is opened");
                 startDone.open();
                 Looper.loop(); // Blocks forever until Looper.quit() is called.
                 if (VERBOSE) Log.v(TAG, "initializeMessageLooper: quit.");
@@ -188,9 +207,8 @@
             Log.v(TAG, "initializeMessageLooper: start timeout");
             fail("initializeMessageLooper: start timeout");
         }
-        assertNotNull("Fail to open camera.", mCamera);
-        mCamera.setPreviewDisplay(activity.getSurfaceView().getHolder());
-
+        assertNotNull("Fail to open camera " + cameraId, looperInfo.camera);
+        looperInfo.camera.setPreviewDisplay(activity.getSurfaceView().getHolder());
         File parent = activity.getPackageManager().isInstantApp()
                 ? activity.getFilesDir()
                 : activity.getExternalFilesDir(null);
@@ -210,21 +228,33 @@
      * Terminates the message looper thread, optionally allowing evict error
      */
     private void terminateMessageLooper(boolean allowEvict) throws Exception {
-        mLooper.quit();
+        LooperInfo looperInfo = new LooperInfo();
+        looperInfo.camera = mCamera;
+        looperInfo.looper = mLooper;
+        terminateMessageLooper(allowEvict, mCameraErrorCode, looperInfo);
+        mCamera = null;
+    }
+
+    /*
+     * Terminates the message looper thread, optionally allowing evict error
+     */
+    private void terminateMessageLooper(final boolean allowEvict, final int errorCode,
+            final LooperInfo looperInfo) throws Exception {
+        looperInfo.looper.quit();
         // Looper.quit() is asynchronous. The looper may still has some
         // preview callbacks in the queue after quit is called. The preview
         // callback still uses the camera object (setHasPreviewCallback).
         // After camera is released, RuntimeException will be thrown from
         // the method. So we need to join the looper thread here.
-        mLooper.getThread().join();
-        mCamera.release();
-        mCamera = null;
+        looperInfo.looper.getThread().join();
+        looperInfo.camera.release();
+        looperInfo.camera = null;
         if (allowEvict) {
             assertTrue("Got unexpected camera error callback.",
-                    (NO_ERROR == mCameraErrorCode ||
-                    Camera.CAMERA_ERROR_EVICTED == mCameraErrorCode));
+                    (NO_ERROR == errorCode ||
+                    Camera.CAMERA_ERROR_EVICTED == errorCode));
         } else {
-            assertEquals("Got camera error callback.", NO_ERROR, mCameraErrorCode);
+            assertEquals("Got camera error callback.", NO_ERROR, errorCode);
         }
     }
 
@@ -344,6 +374,15 @@
         }
     }
 
+    // parent independent version of TestErrorCallback
+    private static final class TestErrorCallbackI implements ErrorCallback {
+        private int mCameraErrorCode = NO_ERROR;
+        public void onError(int error, Camera camera) {
+            Log.e(TAG, "Got camera error=" + error);
+            mCameraErrorCode = error;
+        }
+    }
+
     private final class AutoFocusCallback
             implements android.hardware.Camera.AutoFocusCallback {
         public void onAutoFocus(boolean success, Camera camera) {
@@ -2554,54 +2593,53 @@
         testCamera0.release();
         testCamera1.release();
 
-        // Start first camera
-        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Opening camera 0");
-        initializeMessageLooper(0);
-        SimplePreviewStreamCb callback0 = new SimplePreviewStreamCb(0);
-        mCamera.setPreviewCallback(callback0);
+        LooperInfo looperInfo0 = new LooperInfo();
+        LooperInfo looperInfo1 = new LooperInfo();
+
+        ConditionVariable previewDone0 = new ConditionVariable();
+        ConditionVariable previewDone1 = new ConditionVariable();
+        // Open both cameras camera
+        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Opening cameras 0 and 1");
+        TestErrorCallbackI errorCallback0 = new TestErrorCallbackI();
+        TestErrorCallbackI errorCallback1 = new TestErrorCallbackI();
+        initializeMessageLooper(0, errorCallback0, looperInfo0);
+        initializeMessageLooper(1, errorCallback1, looperInfo1);
+
+        SimplePreviewStreamCbI callback0 = new SimplePreviewStreamCbI(0, previewDone0);
+        looperInfo0.camera.setPreviewCallback(callback0);
         if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Starting preview on camera 0");
-        mCamera.startPreview();
+        looperInfo0.camera.startPreview();
         // Run preview for a bit
         for (int f = 0; f < 100; f++) {
-            mPreviewDone.close();
+            previewDone0.close();
             assertTrue("testMultiCameraRelease: First camera preview timed out on frame " + f + "!",
-                       mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE));
+                       previewDone0.block( WAIT_FOR_COMMAND_TO_COMPLETE));
         }
         if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Stopping preview on camera 0");
-        mCamera.stopPreview();
-        // Save message looper and camera to deterministically release them, instead
-        // of letting GC do it at some point.
-        Camera firstCamera = mCamera;
-        Looper firstLooper = mLooper;
-        //terminateMessageLooper(); // Intentionally not calling this
-        // Preview surface should be released though!
-        mCamera.setPreviewDisplay(null);
+        looperInfo0.camera.stopPreview();
 
-        // Start second camera without releasing the first one (will
-        // set mCamera and mLooper to new objects)
-        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Opening camera 1");
-        initializeMessageLooper(1);
-        SimplePreviewStreamCb callback1 = new SimplePreviewStreamCb(1);
-        mCamera.setPreviewCallback(callback1);
+        // Preview surface should be released though!
+        looperInfo0.camera.setPreviewDisplay(null);
+
+        SimplePreviewStreamCbI callback1 = new SimplePreviewStreamCbI(1, previewDone1);
+        looperInfo1.camera.setPreviewCallback(callback1);
         if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Starting preview on camera 1");
-        mCamera.startPreview();
-        // Run preview for a bit - GC of first camera instance should not impact the second's
-        // operation.
+        looperInfo1.camera.startPreview();
         for (int f = 0; f < 100; f++) {
-            mPreviewDone.close();
+            previewDone1.close();
             assertTrue("testMultiCameraRelease: Second camera preview timed out on frame " + f + "!",
-                       mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE));
+                       previewDone1.block( WAIT_FOR_COMMAND_TO_COMPLETE));
             if (f == 50) {
                 // Release first camera mid-preview, should cause no problems
                 if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Releasing camera 0");
-                firstCamera.release();
+                looperInfo0.camera.release();
             }
         }
-        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Stopping preview on camera 0");
-        mCamera.stopPreview();
+        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Stopping preview on camera 1");
+        looperInfo1.camera.stopPreview();
 
-        firstLooper.quit();
-        terminateMessageLooper(true/*allowEvict*/);
+        looperInfo0.looper.quit();
+        terminateMessageLooper(true, errorCallback1.mCameraErrorCode, looperInfo1);
     }
 
     // This callback just signals on the condition variable, making it useful for checking that
@@ -2618,6 +2656,21 @@
         }
     }
 
+    // Parent independent version of SimplePreviewStreamCb
+    private static final class SimplePreviewStreamCbI
+            implements android.hardware.Camera.PreviewCallback {
+        private int mId;
+        private ConditionVariable mPreviewDone = null;
+        public SimplePreviewStreamCbI(int id, ConditionVariable previewDone) {
+            mId = id;
+            mPreviewDone = previewDone;
+        }
+        public void onPreviewFrame(byte[] data, android.hardware.Camera camera) {
+            if (VERBOSE) Log.v(TAG, "Preview frame callback, id " + mId + ".");
+            mPreviewDone.open();
+        }
+    }
+
     @UiThreadTest
     @Test
     public void testFocusAreas() throws Exception {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
index 856b4fa..5b3a250 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/DialogFrameTests.java
@@ -36,10 +36,12 @@
 import static org.junit.Assert.assertEquals;
 
 import android.content.ComponentName;
+import android.graphics.Insets;
 import android.graphics.Rect;
 import android.platform.test.annotations.AppModeFull;
 import android.platform.test.annotations.Presubmit;
 import android.server.wm.WindowManagerState.WindowState;
+import android.view.WindowInsets;
 
 import androidx.test.rule.ActivityTestRule;
 
@@ -97,9 +99,9 @@
     // the same content frame as the main activity window
     @Test
     public void testMatchParentDialog() throws Exception {
-        doParentChildTest(TEST_MATCH_PARENT, (parent, dialog) ->
-                assertEquals(parent.getContentFrame(), dialog.getFrame())
-        );
+        doParentChildTest(TEST_MATCH_PARENT, (parent, dialog) -> { ;
+            assertEquals(getParentFrameWithInsets(parent), dialog.getFrame());
+        });
     }
 
     private static final int explicitDimension = 200;
@@ -108,12 +110,12 @@
     @Test
     public void testExplicitSizeDefaultGravity() throws Exception {
         doParentChildTest(TEST_EXPLICIT_SIZE, (parent, dialog) -> {
-            Rect contentFrame = parent.getContentFrame();
+            Rect parentFrame = getParentFrameWithInsets(parent);
             Rect expectedFrame = new Rect(
-                    contentFrame.left + (contentFrame.width() - explicitDimension) / 2,
-                    contentFrame.top + (contentFrame.height() - explicitDimension) / 2,
-                    contentFrame.left + (contentFrame.width() + explicitDimension) / 2,
-                    contentFrame.top + (contentFrame.height() + explicitDimension) / 2);
+                    parentFrame.left + (parentFrame.width() - explicitDimension) / 2,
+                    parentFrame.top + (parentFrame.height() - explicitDimension) / 2,
+                    parentFrame.left + (parentFrame.width() + explicitDimension) / 2,
+                    parentFrame.top + (parentFrame.height() + explicitDimension) / 2);
             assertEquals(expectedFrame, dialog.getFrame());
         });
     }
@@ -121,12 +123,12 @@
     @Test
     public void testExplicitSizeTopLeftGravity() throws Exception {
         doParentChildTest(TEST_EXPLICIT_SIZE_TOP_LEFT_GRAVITY, (parent, dialog) -> {
-            Rect contentFrame = parent.getContentFrame();
+            Rect parentFrame = getParentFrameWithInsets(parent);
             Rect expectedFrame = new Rect(
-                    contentFrame.left,
-                    contentFrame.top,
-                    contentFrame.left + explicitDimension,
-                    contentFrame.top + explicitDimension);
+                    parentFrame.left,
+                    parentFrame.top,
+                    parentFrame.left + explicitDimension,
+                    parentFrame.top + explicitDimension);
             assertEquals(expectedFrame, dialog.getFrame());
         });
     }
@@ -134,12 +136,12 @@
     @Test
     public void testExplicitSizeBottomRightGravity() throws Exception {
         doParentChildTest(TEST_EXPLICIT_SIZE_BOTTOM_RIGHT_GRAVITY, (parent, dialog) -> {
-            Rect contentFrame = parent.getContentFrame();
+            Rect parentFrame = getParentFrameWithInsets(parent);
             Rect expectedFrame = new Rect(
-                    contentFrame.left + contentFrame.width() - explicitDimension,
-                    contentFrame.top + contentFrame.height() - explicitDimension,
-                    contentFrame.left + contentFrame.width(),
-                    contentFrame.top + contentFrame.height());
+                    parentFrame.left + parentFrame.width() - explicitDimension,
+                    parentFrame.top + parentFrame.height() - explicitDimension,
+                    parentFrame.left + parentFrame.width(),
+                    parentFrame.top + parentFrame.height());
             assertEquals(expectedFrame, dialog.getFrame());
         });
     }
@@ -152,7 +154,7 @@
         doParentChildTest(TEST_OVER_SIZED_DIMENSIONS, (parent, dialog) ->
                 // With the default flags oversize should result in clipping to
                 // parent frame.
-                assertEquals(parent.getContentFrame(), dialog.getFrame())
+                assertEquals(getParentFrameWithInsets(parent), dialog.getFrame())
         );
     }
 
@@ -166,10 +168,10 @@
         // TODO(b/36890978): We only run this in fullscreen because of the
         // unclear status of NO_LIMITS for non-child surfaces in MW modes
         doFullscreenTest(TEST_OVER_SIZED_DIMENSIONS_NO_LIMITS, (parent, dialog) -> {
-            Rect contentFrame = parent.getContentFrame();
-            Rect expectedFrame = new Rect(contentFrame.left, contentFrame.top,
-                    contentFrame.left + oversizedDimension,
-                    contentFrame.top + oversizedDimension);
+            Rect parentFrame = getParentFrameWithInsets(parent);
+            Rect expectedFrame = new Rect(parentFrame.left, parentFrame.top,
+                    parentFrame.left + oversizedDimension,
+                    parentFrame.top + oversizedDimension);
             assertEquals(expectedFrame, dialog.getFrame());
         });
     }
@@ -180,7 +182,7 @@
     @Test
     public void testExplicitPositionMatchParent() throws Exception {
         doParentChildTest(TEST_EXPLICIT_POSITION_MATCH_PARENT, (parent, dialog) ->
-                assertEquals(parent.getContentFrame(), dialog.getFrame())
+                assertEquals(getParentFrameWithInsets(parent), dialog.getFrame())
         );
     }
 
@@ -190,8 +192,8 @@
     public void testExplicitPositionMatchParentNoLimits() throws Exception {
         final int explicitPosition = 100;
         doParentChildTest(TEST_EXPLICIT_POSITION_MATCH_PARENT_NO_LIMITS, (parent, dialog) -> {
-            Rect contentFrame = parent.getContentFrame();
-            Rect expectedFrame = new Rect(contentFrame);
+            Rect parentFrame = getParentFrameWithInsets(parent);
+            Rect expectedFrame = new Rect(parentFrame);
             expectedFrame.offset(explicitPosition, explicitPosition);
             assertEquals(expectedFrame, dialog.getFrame());
         });
@@ -218,7 +220,7 @@
         float horizontalMargin = .10f;
         float verticalMargin = .15f;
         doParentChildTest(TEST_WITH_MARGINS, (parent, dialog) -> {
-            Rect frame = parent.getContentFrame();
+            Rect frame = getParentFrameWithInsets(parent);
             Rect expectedFrame = new Rect(
                     (int) (horizontalMargin * frame.width() + frame.left),
                     (int) (verticalMargin * frame.height() + frame.top),
@@ -237,4 +239,26 @@
                 assertThat(wmState.getZOrder(dialog), greaterThan(wmState.getZOrder(parent)))
         );
     }
+
+    private Rect getParentFrameWithInsets(WindowState parent) {
+        Rect parentFrame = parent.getFrame();
+        return inset(parentFrame, getActivitySystemInsets());
+    }
+
+    private Insets getActivitySystemInsets() {
+        return mDialogTestActivity
+                .getActivity()
+                .getWindow()
+                .getDecorView()
+                .getRootWindowInsets()
+                .getInsets(WindowInsets.Type.systemBars());
+    }
+
+    private static Rect inset(Rect original, Insets insets) {
+        final int left = original.left + insets.left;
+        final int top = original.top + insets.top;
+        final int right = original.right - insets.right;
+        final int bottom = original.bottom - insets.bottom;
+        return new Rect(left, top, right, bottom);
+    }
 }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/PresentationTest.java b/tests/framework/base/windowmanager/src/android/server/wm/PresentationTest.java
index dfc42c3..4b34c9b 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/PresentationTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/PresentationTest.java
@@ -72,6 +72,7 @@
         WindowManagerState.DisplayContent display = virtualDisplaySession
                         .setPresentationDisplay(true)
                         .setPublicDisplay(true)
+                        .setResizeDisplay(false) // resize only through resizeDisplay call
                         .createDisplay();
 
         assertThat(display.getFlags() & Display.FLAG_PRESENTATION)
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
index 1863487..0fc4bc8 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
@@ -16,6 +16,7 @@
 
 package android.server.wm;
 
+import static android.server.wm.WindowManagerState.STATE_RESUMED;
 import static android.server.wm.app.Components.SPLASHSCREEN_ACTIVITY;
 import static android.view.Display.DEFAULT_DISPLAY;
 
@@ -53,6 +54,8 @@
     @Test
     public void testSplashscreenContent() {
         launchActivityNoWait(SPLASHSCREEN_ACTIVITY);
+        // Activity may not be launched yet even if app transition is in idle state.
+        mWmState.waitForActivityState(SPLASHSCREEN_ACTIVITY, STATE_RESUMED);
         mWmState.waitForAppTransitionIdleOnDisplay(DEFAULT_DISPLAY);
         mWmState.getStableBounds();
         final Bitmap image = takeScreenshot();
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 da69b92..3494c7c 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java
@@ -22,6 +22,7 @@
 import static android.view.WindowInsets.Type.statusBars;
 import static android.view.WindowInsets.Type.systemBars;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -333,6 +334,7 @@
             getWindow().setDecorFitsSystemWindows(false);
             getWindow().getAttributes().layoutInDisplayCutoutMode =
                     LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+            getWindow().setSoftInputMode(SOFT_INPUT_STATE_HIDDEN);
             setContentView(mView);
             mEditor.requestFocus();
         }
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java
index 84a868e..23fabe7 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTests.java
@@ -52,8 +52,6 @@
 
 import java.util.List;
 
-import androidx.test.filters.FlakyTest;
-
 /**
  * Test whether {@link WindowInsetsAnimation.Callback} are properly dispatched to views.
  *
@@ -106,7 +104,6 @@
     }
 
     @Test
-    @FlakyTest(detail = "Promote once confirmed non-flaky")
     public void testAnimationCallbacks_overlapping() {
         WindowInsets before = mActivity.mLastWindowInsets;
 
@@ -238,7 +235,6 @@
     }
 
     @Test
-    @FlakyTest(detail = "b/159038873")
     public void testAnimationCallbacks_withLegacyFlags() {
         getInstrumentation().runOnMainSync(() -> {
             mActivity.getWindow().setDecorFitsSystemWindows(true);
@@ -251,10 +247,9 @@
             });
         });
 
-        getWmState().waitFor(state -> !state.isWindowVisible("StatusBar"),
-                "Waiting for status bar to be hidden");
-        assertFalse(getWmState().isWindowVisible("StatusBar"));
+        waitForOrFail("Waiting until animation done", () -> mActivity.mCallback.animationDone);
 
+        assertFalse(getWmState().isWindowVisible("StatusBar"));
         verify(mActivity.mCallback).onPrepare(any());
         verify(mActivity.mCallback).onStart(any(), any());
         verify(mActivity.mCallback, atLeastOnce()).onProgress(any(), any());
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 de2ddd9..55fa3d2 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
@@ -30,6 +30,7 @@
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
 import static androidx.test.InstrumentationRegistry.getInstrumentation;
@@ -74,7 +75,7 @@
  * Build/Install/Run:
  *     atest CtsWindowManagerDeviceTestCases:WindowInsetsControllerTests
  */
-//TODO(b/159038873) @Presubmit
+@Presubmit
 public class WindowInsetsControllerTests extends WindowManagerTestBase {
 
     private final static long TIMEOUT = 1000; // milliseconds
@@ -180,6 +181,7 @@
     }
 
     @Test
+    @FlakyTest(detail = "b/159038873")
     public void testImeShowAndHide() {
         showImeWithHardKeyboardSetting(mObjectTracker);
 
@@ -461,6 +463,7 @@
     }
 
     @Test
+    @FlakyTest(detail = "b/159038873")
     public void testShowImeOnCreate() throws Exception {
         showImeWithHardKeyboardSetting(mObjectTracker);
 
@@ -633,6 +636,7 @@
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setViews(this);
+            getWindow().setSoftInputMode(SOFT_INPUT_STATE_HIDDEN);
         }
     }
 
diff --git a/tests/media/jni/NativeCodecTestBase.cpp b/tests/media/jni/NativeCodecTestBase.cpp
index 750abe6..b07c1c3 100644
--- a/tests/media/jni/NativeCodecTestBase.cpp
+++ b/tests/media/jni/NativeCodecTestBase.cpp
@@ -528,10 +528,11 @@
 
 int CodecTestBase::getWidth(AMediaFormat* format) {
     int width = -1;
-    int cropLeft, cropRight;
+    int cropLeft, cropRight, cropTop, cropBottom;
     AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &width);
-    if (AMediaFormat_getInt32(format, "crop-left", &cropLeft) &&
-        AMediaFormat_getInt32(format, "crop-right", &cropRight)) {
+    if (AMediaFormat_getRect(format, "crop", &cropLeft, &cropTop, &cropRight, &cropBottom) ||
+        (AMediaFormat_getInt32(format, "crop-left", &cropLeft) &&
+        AMediaFormat_getInt32(format, "crop-right", &cropRight))) {
         width = cropRight + 1 - cropLeft;
     }
     return width;
@@ -539,10 +540,11 @@
 
 int CodecTestBase::getHeight(AMediaFormat* format) {
     int height = -1;
-    int cropTop, cropBottom;
+    int cropLeft, cropRight, cropTop, cropBottom;
     AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &height);
-    if (AMediaFormat_getInt32(format, "crop-top", &cropTop) &&
-        AMediaFormat_getInt32(format, "crop-bottom", &cropBottom)) {
+    if (AMediaFormat_getRect(format, "crop", &cropLeft, &cropTop, &cropRight, &cropBottom) ||
+        (AMediaFormat_getInt32(format, "crop-top", &cropTop) &&
+        AMediaFormat_getInt32(format, "crop-bottom", &cropBottom))) {
         height = cropBottom + 1 - cropTop;
     }
     return height;
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/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/car/src/android/car/cts/CarAppFocusManagerTest.java b/tests/tests/car/src/android/car/cts/CarAppFocusManagerTest.java
index 8e6adcc..9383460 100644
--- a/tests/tests/car/src/android/car/cts/CarAppFocusManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarAppFocusManagerTest.java
@@ -47,6 +47,9 @@
 @RunWith(AndroidJUnit4.class)
 public class CarAppFocusManagerTest extends CarApiTestBase {
     private static final String TAG = CarAppFocusManagerTest.class.getSimpleName();
+
+    private static final long NO_EVENT_WAIT_TIME_MS = 50;
+
     private final Context mContext =
             InstrumentationRegistry.getInstrumentation().getTargetContext();
     private CarAppFocusManager mManager;
@@ -150,6 +153,7 @@
         Assert.assertArrayEquals(expectedFocuses, manager2.getActiveAppTypes());
         assertTrue(mManager.isOwningFocus(owner, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION));
         assertFalse(manager2.isOwningFocus(owner2, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION));
+        // should update as it became active
         assertTrue(change2.waitForFocusChangedAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
                 CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, true));
         assertTrue(change.waitForFocusChangedAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
@@ -163,34 +167,38 @@
         Assert.assertArrayEquals(expectedFocuses, mManager.getActiveAppTypes());
         Assert.assertArrayEquals(expectedFocuses, manager2.getActiveAppTypes());
 
-        // this should be no-op
         change.reset();
         change2.reset();
         assertEquals(CarAppFocusManager.APP_FOCUS_REQUEST_SUCCEEDED,
                 mManager.requestAppFocus(CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, owner));
         assertTrue(owner.waitForOwnershipGrantAndAssert(
                 DEFAULT_WAIT_TIMEOUT_MS, APP_FOCUS_TYPE_NAVIGATION));
-
         Assert.assertArrayEquals(expectedFocuses, mManager.getActiveAppTypes());
         Assert.assertArrayEquals(expectedFocuses, manager2.getActiveAppTypes());
+        // The same owner requesting again triggers update
         assertTrue(change2.waitForFocusChangedAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
                 CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, true));
         assertTrue(change.waitForFocusChangedAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
                 CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, true));
 
+        change.reset();
+        change2.reset();
         assertEquals(CarAppFocusManager.APP_FOCUS_REQUEST_SUCCEEDED,
                 manager2.requestAppFocus(CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, owner2));
         assertTrue(owner2.waitForOwnershipGrantAndAssert(
                 DEFAULT_WAIT_TIMEOUT_MS, APP_FOCUS_TYPE_NAVIGATION));
-
         assertFalse(mManager.isOwningFocus(owner, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION));
         assertTrue(manager2.isOwningFocus(owner2, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION));
         Assert.assertArrayEquals(expectedFocuses, mManager.getActiveAppTypes());
         Assert.assertArrayEquals(expectedFocuses, manager2.getActiveAppTypes());
         assertTrue(owner.waitForOwnershipLossAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
                 CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION));
+        // ownership change should send update
+        assertTrue(change2.waitForFocusChangedAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
+                CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, true));
+        assertTrue(change.waitForFocusChangedAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
+                CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, true));
 
-        // no-op as it is not owning it
         change.reset();
         change2.reset();
         mManager.abandonAppFocus(owner, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);
@@ -198,15 +206,19 @@
         assertTrue(manager2.isOwningFocus(owner2, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION));
         Assert.assertArrayEquals(expectedFocuses, mManager.getActiveAppTypes());
         Assert.assertArrayEquals(expectedFocuses, manager2.getActiveAppTypes());
+        // abandoning from non-owner should not trigger update
+        assertFalse(change2.waitForFocusChangedAndAssert(NO_EVENT_WAIT_TIME_MS,
+                CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, true));
+        assertFalse(change.waitForFocusChangedAndAssert(NO_EVENT_WAIT_TIME_MS,
+                CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, true));
 
-        change.reset();
-        change2.reset();
         assertFalse(mManager.isOwningFocus(owner, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION));
         assertTrue(manager2.isOwningFocus(owner2, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION));
         expectedFocuses = new int[] {CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION};
         Assert.assertArrayEquals(expectedFocuses, mManager.getActiveAppTypes());
         Assert.assertArrayEquals(expectedFocuses, manager2.getActiveAppTypes());
 
+        manager2.removeFocusListener(change2);
         change.reset();
         change2.reset();
         manager2.abandonAppFocus(owner2, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);
@@ -215,10 +227,14 @@
         expectedFocuses = emptyFocus;
         Assert.assertArrayEquals(expectedFocuses, mManager.getActiveAppTypes());
         Assert.assertArrayEquals(expectedFocuses, manager2.getActiveAppTypes());
+        // abandoning from owner should trigger update
         assertTrue(change.waitForFocusChangedAndAssert(DEFAULT_WAIT_TIMEOUT_MS,
                 CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, false));
+        // removed focus listener should not get events
+        assertFalse(change2.waitForFocusChangedAndAssert(NO_EVENT_WAIT_TIME_MS,
+                CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION, true));
         mManager.removeFocusListener(change);
-        manager2.removeFocusListener(change2);
+
     }
 
     @Test
@@ -304,6 +320,7 @@
         public void reset() {
             mLastChangeAppType = 0;
             mLastChangeAppActive = false;
+            mChangeWait.drainPermits();
         }
 
         @Override
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 ba6a589..ec02cd3 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java
@@ -38,6 +38,7 @@
 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;
 
@@ -233,6 +234,7 @@
 
     @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.
diff --git a/tests/tests/deviceconfig/AndroidManifest.xml b/tests/tests/deviceconfig/AndroidManifest.xml
index ee3a34c..eafb00a 100755
--- a/tests/tests/deviceconfig/AndroidManifest.xml
+++ b/tests/tests/deviceconfig/AndroidManifest.xml
@@ -22,6 +22,12 @@
         <uses-library android:name="android.test.runner" />
     </application>
 
+    <!--
+       - Must set INTERACT_ACROSS_USERS because DeviceConfig always run as user 0, and the CTS tests
+       - might be running as a secondary user
+      -->
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                      android:targetPackage="android.deviceconfig.cts"
                      android:label="CTS tests for DeviceConfig API">
diff --git a/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java b/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java
index 15fb469..6d77ebb 100644
--- a/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java
+++ b/tests/tests/deviceconfig/src/android/deviceconfig/cts/DeviceConfigApiPermissionTests.java
@@ -189,8 +189,8 @@
             violations.append("DeviceConfig.setProperties() for public namespaces must not be "
                     + " accessible without WRITE_DEVICE_CONFIG permission\n");
         } catch (DeviceConfig.BadConfigException e) {
-            violations.append("DeviceConfig.setProperties() should not throw BadConfigException "
-                    + "without a known bad configuration.");
+            addExceptionToViolations(violations, "DeviceConfig.setProperties() should not throw "
+                    + "BadConfigException without a known bad configuration", e);
         } catch (SecurityException e) {
         }
 
@@ -200,8 +200,8 @@
         try {
             DeviceConfig.setProperty(PUBLIC_NAMESPACE, KEY, VALUE, /*makeDefault=*/ false);
         } catch (SecurityException e) {
-            violations.append("DeviceConfig.setProperty() must be accessible with"
-                    + " WRITE_DEVICE_CONFIG permission\n");
+            addExceptionToViolations(violations, "DeviceConfig.setProperty() must be accessible "
+                    + "with WRITE_DEVICE_CONFIG permission", e);
         }
 
         try {
@@ -209,11 +209,11 @@
                     new Properties.Builder(PUBLIC_NAMESPACE).setString(KEY, VALUE).build();
             DeviceConfig.setProperties(properties);
         } catch (DeviceConfig.BadConfigException e) {
-            violations.append("DeviceConfig.setProperties() should not throw BadConfigException"
-                    + " without a known bad configuration.");
+            addExceptionToViolations(violations, "DeviceConfig.setProperties() should not throw "
+                    + "BadConfigException without a known bad configuration", e);
         } catch (SecurityException e) {
-            violations.append("DeviceConfig.setProperties() must be accessible with"
-                    + " WRITE_DEVICE_CONFIG permission.\n");
+            addExceptionToViolations(violations, "DeviceConfig.setProperties() must be accessible "
+                    + "with WRITE_DEVICE_CONFIG permission", e);
         }
 
         try {
@@ -221,8 +221,8 @@
             assertEquals("Value read from DeviceConfig API public namespace does not match written"
                     + " value.", VALUE, property);
         } catch (SecurityException e) {
-            violations.append("DeviceConfig.getProperty() for public namespaces must be accessible "
-                    + "without READ_DEVICE_CONFIG permission\n");
+            addExceptionToViolations(violations, "DeviceConfig.getProperty() for public namespaces "
+                    + "must be accessible without READ_DEVICE_CONFIG permission", e);
         }
 
         try {
@@ -230,16 +230,17 @@
             assertEquals("Value read from DeviceConfig API public namespace does not match written"
                     + " value.", VALUE, properties.getString(KEY, "default_value"));
         } catch (SecurityException e) {
-            violations.append("DeviceConfig.getProperties() for public namespaces must be "
-                    + "accessible without READ_DEVICE_CONFIG permission\n");
+            addExceptionToViolations(violations, "DeviceConfig.getProperties() for public "
+                    + "namespaces must be accessible without READ_DEVICE_CONFIG permission", e);
         }
 
         try {
             DeviceConfig.addOnPropertiesChangedListener(
                     PUBLIC_NAMESPACE, EXECUTOR, new TestOnPropertiesListener());
         } catch (SecurityException e) {
-            violations.append("DeviceConfig.addOnPropertiesChangeListener() for public namespaces "
-                    + "must be accessible without READ_DEVICE_CONFIG permission\n");
+            addExceptionToViolations(violations, "DeviceConfig.addOnPropertiesChangeListener() for "
+                    + "public namespaces must be accessible without READ_DEVICE_CONFIG permission",
+                    e);
         }
 
         // Bail if we found any violations
@@ -271,8 +272,8 @@
             violations.append("DeviceConfig.setProperties() must not be accessible without "
                     + "WRITE_DEVICE_CONFIG permission.\n");
         } catch (DeviceConfig.BadConfigException e) {
-            violations.append("DeviceConfig.setProperties() should not throw BadConfigException "
-                    + "without a known bad configuration.");
+            addExceptionToViolations(violations, "DeviceConfig.setProperties() should not throw "
+                    + "BadConfigException without a known bad configuration.", e);
         } catch (SecurityException e) {
         }
     }
@@ -309,8 +310,8 @@
         try {
             DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, /*makeDefault=*/ false);
         } catch (SecurityException e) {
-            violations.append("DeviceConfig.setProperty() must be accessible with"
-                    + " WRITE_DEVICE_CONFIG permission\n");
+            addExceptionToViolations(violations, "DeviceConfig.setProperty() must be accessible "
+                    + "with WRITE_DEVICE_CONFIG permission", e);
         }
     }
 
@@ -323,8 +324,8 @@
             violations.append("DeviceConfig.setProperties() should not throw BadConfigException"
                     + " without a known bad configuration.");
         } catch (SecurityException e) {
-            violations.append("DeviceConfig.setProperties() must be accessible with"
-                    + " WRITE_DEVICE_CONFIG permission.\n");
+            addExceptionToViolations(violations, "DeviceConfig.setProperties() must be accessible "
+                    + "with WRITE DEVICE_CONFIG permission", e);
         }
     }
 
@@ -333,8 +334,8 @@
         try {
             property = DeviceConfig.getProperty(NAMESPACE, KEY);
         } catch (SecurityException e) {
-            violations.append("DeviceConfig.getProperty() must be accessible with"
-                    + " READ_DEVICE_CONFIG permission\n");
+            addExceptionToViolations(violations, "DeviceConfig.getProperty() must be accessible "
+                    + "with READ_DEVICE_CONFIG permission", e);
         }
         return property;
     }
@@ -344,8 +345,8 @@
         try {
             properties = DeviceConfig.getProperties(NAMESPACE2);
         } catch (SecurityException e) {
-            violations.append("DeviceConfig.getProperties() must be accessible with"
-                    + " READ_DEVICE_CONFIG permission\n");
+            addExceptionToViolations(violations, "DeviceConfig.getProperties() must be accessible "
+                    + "with READ_DEVICE_CONFIG permission", e);
         }
         return properties;
     }
@@ -355,8 +356,13 @@
             DeviceConfig.addOnPropertiesChangedListener(
                     NAMESPACE, EXECUTOR, new TestOnPropertiesListener());
         } catch (SecurityException e) {
-            violations.append("DeviceConfig.addOnPropertiesChangeListener() must be accessible with"
-                    + " READ_DEVICE_CONFIG permission\n");
+            addExceptionToViolations(violations, "DeviceConfig.addOnPropertiesChangeListener() must"
+                    + " be accessible with READ_DEVICE_CONFIG permission", e);
         }
     }
+
+    private static void addExceptionToViolations(StringBuilder violations, String message,
+            Exception e) {
+        violations.append(message).append(": ").append(e).append("\n");
+    }
 }
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/keystore/src/android/keystore/cts/CipherTest.java b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
index 2eef41d..e3fbad5 100644
--- a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
@@ -430,6 +430,59 @@
         }
     }
 
+    /*
+     * This test performs a round trip en/decryption. It does so while the current thread
+     * is in interrupted state which cannot be signaled to the user of the Java Crypto
+     * API.
+     */
+    public void testEncryptsAndDecryptsInterrupted()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        final byte[] originalPlaintext = EmptyArray.BYTE;
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            for (ImportedKey key : importKatKeys(
+                    algorithm,
+                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                    false)) {
+                try {
+                    Key encryptionKey = key.getKeystoreBackedEncryptionKey();
+                    byte[] plaintext = truncatePlaintextIfNecessary(
+                            algorithm, encryptionKey, originalPlaintext);
+                    if (plaintext == null) {
+                        // Key is too short to encrypt anything using this transformation
+                        continue;
+                    }
+                    Cipher cipher = Cipher.getInstance(algorithm, provider);
+                    Thread.currentThread().interrupt();
+                    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
+                    AlgorithmParameters params = cipher.getParameters();
+                    byte[] ciphertext = cipher.doFinal(plaintext);
+                    byte[] expectedPlaintext = plaintext;
+                    if ("RSA/ECB/NoPadding".equalsIgnoreCase(algorithm)) {
+                        // RSA decryption without padding left-pads resulting plaintext with NUL
+                        // bytes to the length of RSA modulus.
+                        int modulusLengthBytes = (TestUtils.getKeySizeBits(encryptionKey) + 7) / 8;
+                        expectedPlaintext = TestUtils.leftPadWithZeroBytes(
+                                expectedPlaintext, modulusLengthBytes);
+                    }
+
+                    cipher = Cipher.getInstance(algorithm, provider);
+                    Key decryptionKey = key.getKeystoreBackedDecryptionKey();
+                    cipher.init(Cipher.DECRYPT_MODE, decryptionKey, params);
+                    byte[] actualPlaintext = cipher.doFinal(ciphertext);
+                    assertTrue(Thread.currentThread().interrupted());
+                    MoreAsserts.assertEquals(expectedPlaintext, actualPlaintext);
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + algorithm + " with key " + key.getAlias(),
+                            e);
+                }
+            }
+        }
+    }
+
+
     private boolean isDecryptValid(byte[] expectedPlaintext, byte[] ciphertext, Cipher cipher,
             AlgorithmParameters params, ImportedKey key) {
         try {
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/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 3541454..62c6012 100644
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -1691,8 +1691,12 @@
     }
 
     private List<String> codecsFor(int resource) throws IOException {
+        return codecsFor(resource, mResources);
+    }
+
+    protected static List<String> codecsFor(int resource, Resources resources) throws IOException {
         MediaExtractor ex = new MediaExtractor();
-        AssetFileDescriptor fd = mResources.openRawResourceFd(resource);
+        AssetFileDescriptor fd = resources.openRawResourceFd(resource);
         try {
             ex.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
         } finally {
diff --git a/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java b/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java
index 8032988..0263601 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTestAacDrc.java
@@ -586,10 +586,8 @@
                 if (drcParams.mDecoderTargetLevel != 0) {
                     final int targetLevelFromCodec = codec.getOutputFormat()
                             .getInteger(MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL);
-                    if (false) { // TODO disabled until b/157773721 fixed
-                        if (targetLevelFromCodec != drcParams.mDecoderTargetLevel) {
-                            fail("Drc Target Reference Level received from MediaCodec is not the Target Reference Level set");
-                        }
+                    if (targetLevelFromCodec != drcParams.mDecoderTargetLevel) {
+                        fail("DRC Target Ref Level received from MediaCodec is not the level set");
                     }
                 }
             }
@@ -711,12 +709,20 @@
             if (drcParams.mDecoderTargetLevel != 0) {
                 final int targetLevelFromCodec = codec.getOutputFormat()
                         .getInteger(MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL);
-                if (false) { // TODO disabled until b/157773721 fixed
-                    if (targetLevelFromCodec != drcParams.mDecoderTargetLevel) {
-                        fail("Drc Target Reference Level received from MediaCodec is not the Target Reference Level set");
-                    }
+                if (targetLevelFromCodec != drcParams.mDecoderTargetLevel) {
+                    fail("DRC Target Ref Level received from MediaCodec is not the level set");
                 }
             }
+
+            final MediaFormat outputFormat = codec.getOutputFormat();
+            final int cutFromCodec = outputFormat.getInteger(
+                    MediaFormat.KEY_AAC_DRC_ATTENUATION_FACTOR);
+            assertEquals("Attenuation factor received from MediaCodec differs from set:",
+                    drcParams.mCut, cutFromCodec);
+            final int boostFromCodec = outputFormat.getInteger(
+                    MediaFormat.KEY_AAC_DRC_BOOST_FACTOR);
+            assertEquals("Boost factor received from MediaCodec differs from set:",
+                    drcParams.mBoost, boostFromCodec);
         }
 
         // expectedOutputLoudness == -2 indicates that output loudness is not tested
diff --git a/tests/tests/media/src/android/media/cts/DecoderTestAacFormat.java b/tests/tests/media/src/android/media/cts/DecoderTestAacFormat.java
new file mode 100755
index 0000000..4e9c43e
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/DecoderTestAacFormat.java
@@ -0,0 +1,232 @@
+/*
+ * 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.media.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.app.Instrumentation;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources;
+import android.media.MediaCodec;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.media.cts.DecoderTest.AudioParameter;
+import android.media.cts.R;
+import android.os.Build;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.ApiLevelUtil;
+import com.android.compatibility.common.util.MediaUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+public class DecoderTestAacFormat {
+    private static final String TAG = "DecoderTestAacFormat";
+
+    private static final boolean sIsAndroidRAndAbove =
+            ApiLevelUtil.isAtLeast(Build.VERSION_CODES.R);
+
+    private Resources mResources;
+
+    @Before
+    public void setUp() throws Exception {
+        final Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+        assertNotNull(inst);
+        mResources = inst.getContext().getResources();
+    }
+
+    /**
+     * Verify downmixing to stereo at decoding of MPEG-4 HE-AAC 5.0 and 5.1 channel streams
+     */
+    @Test
+    public void testHeAacM4aMultichannelDownmix() throws Exception {
+        Log.i(TAG, "START testDecodeHeAacMcM4a");
+
+        if (!MediaUtils.check(sIsAndroidRAndAbove, "M-chan downmix fixed in Android R"))
+            return;
+
+        // array of multichannel resources with their expected number of channels without downmixing
+        int[][] samples = {
+                //  {resourceId, numChannels},
+                {R.raw.noise_5ch_48khz_aot5_dr_sbr_sig1_mp4, 5},
+                {R.raw.noise_6ch_44khz_aot5_dr_sbr_sig2_mp4, 6},
+        };
+        for (int[] sample: samples) {
+            for (String codecName : DecoderTest.codecsFor(sample[0] /* resource */, mResources)) {
+                // verify correct number of channels is observed without downmixing
+                AudioParameter chanParams = new AudioParameter();
+                decodeUpdateFormat(codecName, sample[0] /*resource*/, chanParams, 0 /*no downmix*/);
+                assertEquals("Number of channels differs for codec:" + codecName,
+                        sample[1], chanParams.getNumChannels());
+
+                // verify correct number of channels is observed when downmixing to stereo
+                AudioParameter downmixParams = new AudioParameter();
+                decodeUpdateFormat(codecName, sample[0] /* resource */, downmixParams,
+                        2 /*stereo downmix*/);
+                assertEquals("Number of channels differs for codec:" + codecName,
+                        2, downmixParams.getNumChannels());
+
+            }
+        }
+    }
+
+    /**
+     *
+     * @param decoderName
+     * @param testInput
+     * @param audioParams
+     * @param downmixChannelCount 0 if no downmix requested,
+     *                           positive number for number of channels in requested downmix
+     * @throws IOException
+     */
+    private void decodeUpdateFormat(String decoderName, int testInput, AudioParameter audioParams,
+            int downmixChannelCount)
+            throws IOException
+    {
+        AssetFileDescriptor testFd = mResources.openRawResourceFd(testInput);
+
+        MediaExtractor extractor = new MediaExtractor();
+        extractor.setDataSource(testFd.getFileDescriptor(), testFd.getStartOffset(),
+                testFd.getLength());
+        testFd.close();
+
+        assertEquals("wrong number of tracks", 1, extractor.getTrackCount());
+        MediaFormat format = extractor.getTrackFormat(0);
+        String mime = format.getString(MediaFormat.KEY_MIME);
+        assertTrue("not an audio file", mime.startsWith("audio/"));
+
+        MediaCodec decoder;
+        if (decoderName == null) {
+            decoder = MediaCodec.createDecoderByType(mime);
+        } else {
+            decoder = MediaCodec.createByCodecName(decoderName);
+        }
+
+        MediaFormat configFormat = format;
+        if (downmixChannelCount > 0) {
+            configFormat.setInteger(
+                    MediaFormat.KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT, downmixChannelCount);
+        }
+
+        Log.v(TAG, "configuring with " + configFormat);
+        decoder.configure(configFormat, null /* surface */, null /* crypto */, 0 /* flags */);
+
+        decoder.start();
+        ByteBuffer[] codecInputBuffers = decoder.getInputBuffers();
+        ByteBuffer[] codecOutputBuffers = decoder.getOutputBuffers();
+
+        extractor.selectTrack(0);
+
+        // start decoding
+        final long kTimeOutUs = 5000;
+        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+        boolean sawInputEOS = false;
+        boolean sawOutputEOS = false;
+        int noOutputCounter = 0;
+        int samplecounter = 0;
+        short[] decoded = new short[0];
+        int decodedIdx = 0;
+        while (!sawOutputEOS && noOutputCounter < 50) {
+            noOutputCounter++;
+            if (!sawInputEOS) {
+                int inputBufIndex = decoder.dequeueInputBuffer(kTimeOutUs);
+
+                if (inputBufIndex >= 0) {
+                    ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
+
+                    int sampleSize =
+                            extractor.readSampleData(dstBuf, 0 /* offset */);
+
+                    long presentationTimeUs = 0;
+
+                    if (sampleSize < 0) {
+                        Log.d(TAG, "saw input EOS.");
+                        sawInputEOS = true;
+                        sampleSize = 0;
+                    } else {
+                        samplecounter++;
+                        presentationTimeUs = extractor.getSampleTime();
+                    }
+                    decoder.queueInputBuffer(
+                            inputBufIndex,
+                            0 /* offset */,
+                            sampleSize,
+                            presentationTimeUs,
+                            sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+
+                    if (!sawInputEOS) {
+                        extractor.advance();
+                    }
+                }
+            }
+
+            int res = decoder.dequeueOutputBuffer(info, kTimeOutUs);
+
+            if (res >= 0) {
+                if (info.size > 0) {
+                    noOutputCounter = 0;
+                }
+
+                int outputBufIndex = res;
+                ByteBuffer buf = codecOutputBuffers[outputBufIndex];
+
+                if (decodedIdx + (info.size / 2) >= decoded.length) {
+                    decoded = Arrays.copyOf(decoded, decodedIdx + (info.size / 2));
+                }
+
+                buf.position(info.offset);
+                for (int i = 0; i < info.size; i += 2) {
+                    decoded[decodedIdx++] = buf.getShort();
+                }
+
+                decoder.releaseOutputBuffer(outputBufIndex, false /* render */);
+
+                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                    Log.d(TAG, "saw output EOS.");
+                    sawOutputEOS = true;
+                }
+            } else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                codecOutputBuffers = decoder.getOutputBuffers();
+                Log.d(TAG, "output buffers have changed.");
+            } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                MediaFormat outputFormat = decoder.getOutputFormat();
+                audioParams.setNumChannels(outputFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
+                audioParams.setSamplingRate(outputFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
+                Log.i(TAG, "output format has changed to " + outputFormat);
+            } else {
+                Log.d(TAG, "dequeueOutputBuffer returned " + res);
+            }
+        }
+        if (noOutputCounter >= 50) {
+            fail("decoder stopped outputing data");
+        }
+        decoder.stop();
+        decoder.release();
+        extractor.release();
+    }
+}
+
diff --git a/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java b/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java
index 3d8891c..0b4dee5 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTestXheAac.java
@@ -1168,7 +1168,8 @@
      * @param drcParams the MPEG-D DRC decoder parameter configuration
      * @param decoderName if non null, the name of the decoder to use for the decoding, otherwise
      *     the default decoder for the format will be used
-     * @param runtimeChange defines whether the decoder is configured at runtime or not
+     * @param runtimeChange defines whether the decoder is configured at runtime or configured
+     *                      before starting to decode
      * @param expectedOutputLoudness value to check if the correct output loudness is returned
      *     by the decoder
      * @throws RuntimeException
@@ -1388,30 +1389,32 @@
             if (drcParams.mAlbumMode != 0) {
                 final int albumModeFromCodec = codec.getOutputFormat()
                         .getInteger(MediaFormat.KEY_AAC_DRC_ALBUM_MODE);
-                if (false) { // TODO disabled until b/157773721 fixed
-                    if (albumModeFromCodec != drcParams.mAlbumMode) {
-                        fail("Drc AlbumMode received from MediaCodec is not the Album Mode set");
-                    }
-                }
+                assertEquals("DRC AlbumMode received from MediaCodec is not the Album Mode set"
+                        + " runtime:" + runtimeChange, drcParams.mAlbumMode, albumModeFromCodec);
             }
             if (drcParams.mEffectType != 0) {
                 final int effectTypeFromCodec = codec.getOutputFormat()
                         .getInteger(MediaFormat.KEY_AAC_DRC_EFFECT_TYPE);
-                if (false) { // TODO disabled until b/157773721 fixed
-                    if (effectTypeFromCodec != drcParams.mEffectType) {
-                        fail("Drc Effect Type received from MediaCodec is not the Effect Type set");
-                    }
-                }
+                assertEquals("DRC Effect Type received from MediaCodec is not the Effect Type set"
+                        + " runtime:" + runtimeChange, drcParams.mEffectType, effectTypeFromCodec);
             }
             if (drcParams.mDecoderTargetLevel != 0) {
                 final int targetLevelFromCodec = codec.getOutputFormat()
                         .getInteger(MediaFormat.KEY_AAC_DRC_TARGET_REFERENCE_LEVEL);
-                if (false) { // TODO disabled until b/157773721 fixed
-                    if (targetLevelFromCodec != drcParams.mDecoderTargetLevel) {
-                        fail("Drc Target Reference Level received from MediaCodec is not the Target Reference Level set");
-                    }
-                }
+                assertEquals("DRC Target Ref Level received from MediaCodec is not the level set"
+                        + " runtime:" + runtimeChange,
+                        drcParams.mDecoderTargetLevel, targetLevelFromCodec);
             }
+
+            final MediaFormat outputFormat = codec.getOutputFormat();
+            final int cutFromCodec = outputFormat.getInteger(
+                    MediaFormat.KEY_AAC_DRC_ATTENUATION_FACTOR);
+            assertEquals("Attenuation factor received from MediaCodec differs from set:",
+                    drcParams.mCut, cutFromCodec);
+            final int boostFromCodec = outputFormat.getInteger(
+                    MediaFormat.KEY_AAC_DRC_BOOST_FACTOR);
+            assertEquals("Boost factor received from MediaCodec differs from set:",
+                    drcParams.mBoost, boostFromCodec);
         }
 
         // expectedOutputLoudness == -2 indicates that output loudness is not tested
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
index f648a3c..6438cd0 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
@@ -27,6 +27,9 @@
 import android.platform.test.annotations.Presubmit;
 import android.util.Base64;
 import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+
 import android.view.Surface;
 
 import com.android.compatibility.common.util.ApiLevelUtil;
@@ -115,6 +118,10 @@
         if (false == deviceHasMediaDrm()) {
             tearDown();
         }
+        // Need MANAGE_USERS or CREATE_USERS permission to access ActivityManager#getCurrentUse in
+        // MediaCas, then adopt it from shell.
+        InstrumentationRegistry
+            .getInstrumentation().getUiAutomation().adoptShellPermissionIdentity();
     }
 
     @Override
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index 42c9f29..48208d9 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -599,14 +599,20 @@
     }
 
     public void testThumbnailVP9Hdr() {
+        if (!MediaUtils.check(mIsAtLeastR, "test needs Android 11")) return;
+
         testThumbnail(R.raw.video_1280x720_vp9_hdr_static_3mbps, 1280, 720);
     }
 
     public void testThumbnailAV1Hdr() {
+        if (!MediaUtils.check(mIsAtLeastR, "test needs Android 11")) return;
+
         testThumbnail(R.raw.video_1280x720_av1_hdr_static_3mbps, 1280, 720);
     }
 
     public void testThumbnailHDR10() {
+        if (!MediaUtils.check(mIsAtLeastR, "test needs Android 11")) return;
+
         testThumbnail(R.raw.video_1280x720_hevc_hdr10_static_3mbps, 1280, 720);
     }
 
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/media/src/android/media/cts/VideoCodecTestBase.java b/tests/tests/media/src/android/media/cts/VideoCodecTestBase.java
index 82c8b18..7ba3541 100644
--- a/tests/tests/media/src/android/media/cts/VideoCodecTestBase.java
+++ b/tests/tests/media/src/android/media/cts/VideoCodecTestBase.java
@@ -832,8 +832,9 @@
             if (out.outputGenerated) {
                 if ((out.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
                     Log.d(TAG, "Storing codec config separately");
-                    mCodecConfigs.add(
-                            ByteBuffer.allocate(out.buffer.length).put(out.buffer));
+                    ByteBuffer csdBuffer = ByteBuffer.allocate(out.buffer.length).put(out.buffer);
+                    csdBuffer.rewind();
+                    mCodecConfigs.add(csdBuffer);
                     out.buffer = new byte[0];
                 }
                 if (out.buffer.length > 0) {
@@ -1480,8 +1481,9 @@
                 }
                 if ((out.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
                     Log.d(TAG, "Storing codec config separately");
-                    codecConfigs.add(
-                            ByteBuffer.allocate(out.buffer.length).put(out.buffer));
+                    ByteBuffer csdBuffer = ByteBuffer.allocate(out.buffer.length).put(out.buffer);
+                    csdBuffer.rewind();
+                    codecConfigs.add(csdBuffer);
                     out.buffer = new byte[0];
                 }
 
@@ -1786,8 +1788,9 @@
                     }
                     if ((out.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
                         Log.d(TAG, "----Enc" + i + ". Storing codec config separately");
-                        codecConfigs.get(i).add(
-                                ByteBuffer.allocate(out.buffer.length).put(out.buffer));
+                        ByteBuffer csdBuffer = ByteBuffer.allocate(out.buffer.length).put(out.buffer);
+                        csdBuffer.rewind();
+                        codecConfigs.get(i).add(csdBuffer);
                         out.buffer = new byte[0];
                     }
 
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/src/android/net/cts/CaptivePortalApiTest.kt b/tests/tests/net/src/android/net/cts/CaptivePortalApiTest.kt
index 68d5281..ef2b0ce 100644
--- a/tests/tests/net/src/android/net/cts/CaptivePortalApiTest.kt
+++ b/tests/tests/net/src/android/net/cts/CaptivePortalApiTest.kt
@@ -35,8 +35,6 @@
 import android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE_DISCOVER
 import android.net.dhcp.DhcpPacket.DHCP_MESSAGE_TYPE_REQUEST
 import android.net.dhcp.DhcpRequestPacket
-import android.net.shared.Inet4AddressUtils.getBroadcastAddress
-import android.net.shared.Inet4AddressUtils.getPrefixMaskAsInet4Address
 import android.os.Build
 import android.os.HandlerThread
 import android.platform.test.annotations.AppModeFull
@@ -44,6 +42,8 @@
 import androidx.test.runner.AndroidJUnit4
 import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
 import com.android.compatibility.common.util.ThrowingRunnable
+import com.android.net.module.util.Inet4AddressUtils.getBroadcastAddress
+import com.android.net.module.util.Inet4AddressUtils.getPrefixMaskAsInet4Address
 import com.android.server.util.NetworkStackConstants.IPV4_ADDR_ANY
 import com.android.testutils.DevSdkIgnoreRule
 import com.android.testutils.DhcpClientPacketFilter
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
index 0248f97..d17d8e5 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityDiagnosticsManagerTest.java
@@ -57,6 +57,7 @@
 import android.os.IBinder;
 import android.os.PersistableBundle;
 import android.os.Process;
+import android.platform.test.annotations.AppModeFull;
 import android.util.Pair;
 
 import androidx.test.InstrumentationRegistry;
@@ -74,6 +75,7 @@
 
 @RunWith(DevSdkIgnoreRunner.class)
 @IgnoreUpTo(Build.VERSION_CODES.Q) // ConnectivityDiagnosticsManager did not exist in Q
+@AppModeFull(reason = "CHANGE_NETWORK_STATE, MANAGE_TEST_NETWORKS not grantable to instant apps")
 public class ConnectivityDiagnosticsManagerTest {
     private static final int CALLBACK_TIMEOUT_MILLIS = 5000;
     private static final int NO_CALLBACK_INVOKED_TIMEOUT = 500;
diff --git a/tests/tests/net/src/android/net/cts/DnsResolverTest.java b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
index 28753ff..e6f75c3 100644
--- a/tests/tests/net/src/android/net/cts/DnsResolverTest.java
+++ b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
@@ -30,7 +30,6 @@
 import android.content.ContentResolver;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
-import android.net.DnsPacket;
 import android.net.DnsResolver;
 import android.net.LinkProperties;
 import android.net.Network;
@@ -47,6 +46,8 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import com.android.net.module.util.DnsPacket;
+
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
diff --git a/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java b/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java
index 81dfed5..9eab024 100644
--- a/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java
+++ b/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java
@@ -16,6 +16,7 @@
 
 package android.net.cts;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.cts.util.CtsNetUtils.TestNetworkCallback;
 
@@ -40,6 +41,7 @@
 import android.net.IpSecAlgorithm;
 import android.net.LinkAddress;
 import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.ProxyInfo;
 import android.net.TestNetworkInterface;
@@ -47,6 +49,7 @@
 import android.net.VpnManager;
 import android.net.cts.util.CtsNetUtils;
 import android.os.Build;
+import android.os.Process;
 import android.platform.test.annotations.AppModeFull;
 
 import androidx.test.InstrumentationRegistry;
@@ -426,6 +429,11 @@
         final Network vpnNetwork = cb.currentNetwork;
         assertNotNull(vpnNetwork);
 
+        final NetworkCapabilities caps = sCM.getNetworkCapabilities(vpnNetwork);
+        assertTrue(caps.hasTransport(TRANSPORT_VPN));
+        assertTrue(caps.hasCapability(NET_CAPABILITY_INTERNET));
+        assertEquals(Process.myUid(), caps.getOwnerUid());
+
         sVpnMgr.stopProvisionedVpnProfile();
         cb.waitForLost();
         assertEquals(vpnNetwork, cb.lastLostNetwork);
diff --git a/tests/tests/os/AndroidManifest.xml b/tests/tests/os/AndroidManifest.xml
index 07de155..5a53fa5 100644
--- a/tests/tests/os/AndroidManifest.xml
+++ b/tests/tests/os/AndroidManifest.xml
@@ -48,6 +48,7 @@
     <uses-permission android:name="android.permission.POWER_SAVER" />
     <uses-permission android:name="android.permission.INSTALL_DYNAMIC_SYSTEM" />
     <uses-permission android:name="android.permission.MANAGE_COMPANION_DEVICES" />
+    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
     <uses-permission android:name="android.os.cts.permission.TEST_GRANTED" />
 
diff --git a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
index db5550c..2c74ac8 100644
--- a/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
+++ b/tests/tests/os/src/android/os/cts/AutoRevokeTest.kt
@@ -46,6 +46,7 @@
 
 private const val APK_PATH = "/data/local/tmp/cts/os/CtsAutoRevokeDummyApp.apk"
 private const val APK_PACKAGE_NAME = "android.os.cts.autorevokedummyapp"
+private const val READ_CALENDAR = "android.permission.READ_CALENDAR"
 
 /**
  * Test for auto revoke
@@ -278,39 +279,10 @@
     }
 
     private fun assertPermission(state: Int, packageName: String = APK_PACKAGE_NAME) {
-        // For some reason this incorrectly always returns PERMISSION_DENIED
-//        runWithShellPermissionIdentity {
-//            assertEquals(
-//                permissionStateToString(state),
-//                permissionStateToString(context.packageManager.checkPermission(READ_CALENDAR, APK_PACKAGE_NAME)))
-//        }
-
-        try {
-            goToPermissions(packageName)
-
-            waitForIdle()
-            val ui = instrumentation.uiAutomation.rootInActiveWindow
-            val permStateSection = ui.lowestCommonAncestor(
-                    { node -> node.textAsString.equals("Allowed", ignoreCase = true) },
-                    { node -> node.textAsString.equals("Denied", ignoreCase = true) }
-            ).assertNotNull {
-                "Cannot find permissions state section in\n${uiDump(ui)}"
-            }
-            val sectionHeaderIndex = permStateSection.children.indexOfFirst {
-                it?.depthFirstSearch { node ->
-                    node.textAsString.equals(
-                            if (state == PERMISSION_GRANTED) "Allowed" else "Denied",
-                            ignoreCase = true)
-                } != null
-            }
-            permStateSection.getChild(sectionHeaderIndex + 1).depthFirstSearch { node ->
-                node.textAsString.equals("Calendar", ignoreCase = true)
-            }.assertNotNull {
-                "Permission must be ${permissionStateToString(state)}\n${uiDump(ui)}"
-            }
-        } finally {
-            goBack()
-            goBack()
+        runWithShellPermissionIdentity {
+            assertEquals(
+                permissionStateToString(state),
+                permissionStateToString(context.packageManager.checkPermission(READ_CALENDAR, APK_PACKAGE_NAME)))
         }
     }
 
diff --git a/tests/tests/os/src/android/os/cts/FileObserverTest.java b/tests/tests/os/src/android/os/cts/FileObserverTest.java
index 9e61066..4c183e2 100644
--- a/tests/tests/os/src/android/os/cts/FileObserverTest.java
+++ b/tests/tests/os/src/android/os/cts/FileObserverTest.java
@@ -146,9 +146,9 @@
             expected = new int[] {UNDEFINED};
             moveEvents = waitForEvent(fileObserver);
             if (isEmulated)
-                assertEventsContains(expected, moveEvents);
+                assertEventsContains(testFile, expected, moveEvents);
             else
-                assertEventsEquals(expected, moveEvents);
+                assertEventsEquals(testFile, expected, moveEvents);
         } finally {
             fileObserver.stopWatching();
             if (out != null)
@@ -185,9 +185,9 @@
             };
             moveEvents = waitForEvent(movedFileObserver);
             if (isEmulated) {
-                assertEventsContains(expected, moveEvents);
+                assertEventsContains(testFile, expected, moveEvents);
             } else {
-                assertEventsEquals(expected, moveEvents);
+                assertEventsEquals(testFile, expected, moveEvents);
             }
         } finally {
             movedFileObserver.stopWatching();
@@ -213,9 +213,9 @@
 
         final FileEvent[] moveEvents = waitForEvent(fileObserver);
         if (isEmulated) {
-            assertEventsContains(expected, moveEvents);
+            assertEventsContains(testFile, expected, moveEvents);
         } else {
-            assertEventsEquals(expected, moveEvents);
+            assertEventsEquals(testFile, expected, moveEvents);
         }
     }
 
@@ -238,9 +238,9 @@
 
         final FileEvent[] moveEvents = waitForEvent(fileObserver);
         if (isEmulated) {
-            assertEventsContains(expected, moveEvents);
+            assertEventsContains(testFile, expected, moveEvents);
         } else {
-            assertEventsEquals(expected, moveEvents);
+            assertEventsEquals(testFile, expected, moveEvents);
         }
     }
 
@@ -311,26 +311,30 @@
         }
     }
 
-    private void assertEventsEquals(final int[] expected, final FileEvent[] moveEvents) {
+    private void assertEventsEquals(
+            File testFile, final int[] expected, final FileEvent[] moveEvents) {
         List<Integer> expectedEvents = new ArrayList<Integer>();
         for (int i = 0; i < expected.length; i++) {
             expectedEvents.add(expected[i]);
         }
         List<FileEvent> actualEvents = Arrays.asList(moveEvents);
-        String message = "Expected: " + expectedEvents + " Actual: " + actualEvents;
+        String message = "For test file [" + testFile.getAbsolutePath()
+                + "] expected: " + expectedEvents + " Actual: " + actualEvents;
         assertEquals(message, expected.length, moveEvents.length);
         for (int i = 0; i < expected.length; i++) {
             assertEquals(message, expected[i], moveEvents[i].event);
         }
     }
 
-    private void assertEventsContains(final int[] expected, final FileEvent[] moveEvents) {
+    private void assertEventsContains(
+            File testFile, final int[] expected, final FileEvent[] moveEvents) {
         List<Integer> expectedEvents = new ArrayList<Integer>();
         for (int i = 0; i < expected.length; i++) {
             expectedEvents.add(expected[i]);
         }
         List<FileEvent> actualEvents = Arrays.asList(moveEvents);
-        String message = "Expected to contain: " + expectedEvents + " Actual: " + actualEvents;
+        String message = "For test file [" + testFile.getAbsolutePath()
+                + "] expected: " + expectedEvents + " Actual: " + actualEvents;
         int j = 0;
         for (int i = 0; i < expected.length; i++) {
             while (expected[i] != moveEvents[j].event) {
diff --git a/tests/tests/permission/src/android/permission/cts/ActivityPermissionRationaleTest.java b/tests/tests/permission/src/android/permission/cts/ActivityPermissionRationaleTest.java
index 947e59a..1837b32 100644
--- a/tests/tests/permission/src/android/permission/cts/ActivityPermissionRationaleTest.java
+++ b/tests/tests/permission/src/android/permission/cts/ActivityPermissionRationaleTest.java
@@ -84,7 +84,8 @@
 
     @Before
     public void clearData() {
-        runShellCommand("pm clear android.permission.cts.appthatrunsrationaletests");
+        runShellCommand("pm clear --user " + sContext.getUserId()
+                + " android.permission.cts.appthatrunsrationaletests");
         PermissionUtils.setPermissionFlags(PACKAGE_NAME, PERMISSION_NAME,
                 PackageManager.FLAG_PERMISSION_POLICY_FIXED, 0);
     }
diff --git a/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java b/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
index fac3aab..8609e33 100644
--- a/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
+++ b/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
@@ -25,18 +25,14 @@
 import static android.content.Context.WIFI_P2P_SERVICE;
 import static android.content.Context.WIFI_SERVICE;
 
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 
-import android.app.WallpaperManager;
 import android.content.Context;
 import android.platform.test.annotations.AppModeInstant;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.compatibility.common.util.RequiredServiceRule;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -72,14 +68,8 @@
 
     @Test
     public void cannotGetWallpaperManager() {
-        WallpaperManager mgr  = (WallpaperManager) InstrumentationRegistry.getTargetContext()
-                .getSystemService(WALLPAPER_SERVICE);
-        boolean supported = RequiredServiceRule.hasService("wallpaper");
-        if (supported) {
-            assertNull(mgr);
-        } else {
-            assertFalse(mgr.isWallpaperSupported());
-        }
+        assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
+                WALLPAPER_SERVICE));
     }
 
     @Test
diff --git a/tests/tests/preference/src/android/preference/cts/PreferenceActivityFlowLandscapeTest.java b/tests/tests/preference/src/android/preference/cts/PreferenceActivityFlowLandscapeTest.java
index 4f0bc3e..0c9a60c 100644
--- a/tests/tests/preference/src/android/preference/cts/PreferenceActivityFlowLandscapeTest.java
+++ b/tests/tests/preference/src/android/preference/cts/PreferenceActivityFlowLandscapeTest.java
@@ -42,7 +42,9 @@
     @Before
     public void setup() {
         requireLandscapeModeSupport();
-        mTestUtils = new TestUtils();
+        mActivity = launchActivity(null);
+        mTestUtils = new TestUtils(mActivityRule);
+        mActivity.finish();
     }
 
     /**
diff --git a/tests/tests/preference/src/android/preference/cts/PreferenceActivityFlowPortraitTest.java b/tests/tests/preference/src/android/preference/cts/PreferenceActivityFlowPortraitTest.java
index 155b799..8500425 100644
--- a/tests/tests/preference/src/android/preference/cts/PreferenceActivityFlowPortraitTest.java
+++ b/tests/tests/preference/src/android/preference/cts/PreferenceActivityFlowPortraitTest.java
@@ -41,7 +41,9 @@
     @Before
     public void setup() {
         requirePortraitModeSupport();
-        mTestUtils = new TestUtils();
+        mActivity = launchActivity(null);
+        mTestUtils = new TestUtils(mActivityRule);
+        mActivity.finish();
     }
 
     /**
diff --git a/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java b/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java
index e70a34b..ba6182a 100644
--- a/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java
+++ b/tests/tests/preference/src/android/preference/cts/PreferenceActivityLegacyFlowTest.java
@@ -52,7 +52,7 @@
 
     @Before
     public void setup() {
-        mTestUtils = new TestUtils();
+        mTestUtils = new TestUtils(mActivityRule);
         mActivity = mActivityRule.getActivity();
     }
 
diff --git a/tests/tests/preference/src/android/preference/cts/TestUtils.java b/tests/tests/preference/src/android/preference/cts/TestUtils.java
index d15d99f..30bd9fc 100644
--- a/tests/tests/preference/src/android/preference/cts/TestUtils.java
+++ b/tests/tests/preference/src/android/preference/cts/TestUtils.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.Rect;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject2;
@@ -29,8 +30,12 @@
 import android.support.test.uiautomator.UiScrollable;
 import android.support.test.uiautomator.UiSelector;
 import android.support.test.uiautomator.Until;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.Window;
 
 import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.rule.ActivityTestRule;
 
 /**
  * Collection of helper utils for testing preferences.
@@ -45,13 +50,17 @@
     private final UiAutomation mAutomation;
     private int mStatusBarHeight = -1;
     private int mNavigationBarHeight = -1;
+    private Display mDisplay;
+    private Window mWindow;
 
-    TestUtils() {
+    TestUtils(ActivityTestRule<?> rule) {
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mContext = mInstrumentation.getTargetContext();
         mPackageName = mContext.getPackageName();
         mDevice = UiDevice.getInstance(mInstrumentation);
         mAutomation = mInstrumentation.getUiAutomation();
+        mDisplay = rule.getActivity().getDisplay();
+        mWindow = rule.getActivity().getWindow();
     }
 
     void waitForIdle() {
@@ -75,7 +84,7 @@
         int xToCut = isOnWatchUiMode() ? bt.getWidth() / 5 : bt.getWidth() / 20;
         int yToCut = statusBarHeight;
 
-        if (isLandscape()) {
+        if (hasVerticalNavBar()) {
             xToCut += navigationBarHeight;
         } else {
             yToCut += navigationBarHeight;
@@ -154,9 +163,12 @@
         return mNavigationBarHeight;
     }
 
-    private boolean isLandscape() {
-        return mInstrumentation.getTargetContext().getResources().getConfiguration().orientation
-            == Configuration.ORIENTATION_LANDSCAPE;
+    private boolean hasVerticalNavBar() {
+        Rect displayFrame = new Rect();
+        mWindow.getDecorView().getWindowVisibleDisplayFrame(displayFrame);
+        DisplayMetrics dm = new DisplayMetrics();
+        mDisplay.getRealMetrics(dm);
+        return dm.heightPixels == displayFrame.bottom;
     }
 
     private UiObject2 getTextObject(String text) {
diff --git a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
index feeb87cb..942d4f4 100644
--- a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
+++ b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
@@ -22,8 +22,10 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.app.AppOpsManager;
 import android.app.UiAutomation;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.graphics.Bitmap;
@@ -35,6 +37,7 @@
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 import android.os.UserManager;
 import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
@@ -252,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()));
 
@@ -471,4 +484,31 @@
             throw new IllegalArgumentException();
         }
     }
+
+    /** Revokes ACCESS_MEDIA_LOCATION from the test app */
+    public static void revokeMediaLocationPermission(Context context) throws Exception {
+        try {
+            InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                    .adoptShellPermissionIdentity("android.permission.MANAGE_APP_OPS_MODES",
+                            "android.permission.REVOKE_RUNTIME_PERMISSIONS");
+
+            // Revoking ACCESS_MEDIA_LOCATION permission will kill the test app.
+            // Deny access_media_permission App op to revoke this permission.
+            PackageManager packageManager = context.getPackageManager();
+            String packageName = context.getPackageName();
+            if (packageManager.checkPermission(android.Manifest.permission.ACCESS_MEDIA_LOCATION,
+                    packageName) == PackageManager.PERMISSION_GRANTED) {
+                context.getPackageManager().updatePermissionFlags(
+                        android.Manifest.permission.ACCESS_MEDIA_LOCATION, packageName,
+                        PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
+                        PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, context.getUser());
+                context.getSystemService(AppOpsManager.class).setUidMode(
+                        "android:access_media_location", Process.myUid(),
+                        AppOpsManager.MODE_IGNORED);
+            }
+        } finally {
+            InstrumentationRegistry.getInstrumentation().getUiAutomation().
+                    dropShellPermissionIdentity();
+        }
+    }
 }
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 df47fac..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
@@ -25,12 +25,10 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.app.AppOpsManager;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -40,7 +38,6 @@
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
-import android.os.Process;
 import android.os.storage.StorageManager;
 import android.provider.BaseColumns;
 import android.provider.MediaStore;
@@ -300,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);
@@ -339,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);
@@ -395,30 +388,12 @@
         assertNotNull(mContentResolver.loadThumbnail(uri, new Size(96, 96), null));
     }
 
-    /**
-     * This test doesn't hold
-     * {@link android.Manifest.permission#ACCESS_MEDIA_LOCATION}, so Exif
-     * location information should be redacted.
-     */
     @Test
     public void testLocationRedaction() throws Exception {
         // STOPSHIP: remove this once isolated storage is always enabled
         Assume.assumeTrue(StorageManager.hasIsolatedStorage());
-
-        final String displayName = "cts" + System.nanoTime();
-        final PendingParams params = new PendingParams(
-                mExternalImages, displayName, "image/jpeg");
-
-        final Uri pendingUri = MediaStoreUtils.createPending(mContext, params);
-        final Uri publishUri;
-        try (PendingSession session = MediaStoreUtils.openPending(mContext, pendingUri)) {
-            try (InputStream in = mContext.getResources().openRawResource(R.raw.lg_g4_iso_800_jpg);
-                 OutputStream out = session.openOutputStream()) {
-                android.os.FileUtils.copy(in, out);
-            }
-            publishUri = session.publish();
-        }
-
+        final Uri publishUri = ProviderTestUtils.stageMedia(R.raw.lg_g4_iso_800_jpg, mExternalImages,
+                "image/jpeg");
         final Uri originalUri = MediaStore.setRequireOriginal(publishUri);
 
         // Since we own the image, we should be able to see the Exif data that
@@ -439,32 +414,8 @@
         try (ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(originalUri, "r")) {
         }
 
-        // Remove ACCESS_MEDIA_LOCATION permission
-        try {
-            InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                    .adoptShellPermissionIdentity("android.permission.MANAGE_APP_OPS_MODES",
-                            "android.permission.REVOKE_RUNTIME_PERMISSIONS");
-
-            // Revoking ACCESS_MEDIA_LOCATION permission will kill the test app.
-            // Deny access_media_permission App op to revoke this permission.
-            PackageManager packageManager = mContext.getPackageManager();
-            String packageName = mContext.getPackageName();
-            if (packageManager.checkPermission(android.Manifest.permission.ACCESS_MEDIA_LOCATION,
-                    packageName) == PackageManager.PERMISSION_GRANTED) {
-                mContext.getPackageManager().updatePermissionFlags(
-                        android.Manifest.permission.ACCESS_MEDIA_LOCATION, packageName,
-                        PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
-                        PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, mContext.getUser());
-                mContext.getSystemService(AppOpsManager.class).setUidMode(
-                        "android:access_media_location", Process.myUid(),
-                        AppOpsManager.MODE_IGNORED);
-            }
-        } finally {
-            InstrumentationRegistry.getInstrumentation().getUiAutomation().
-                    dropShellPermissionIdentity();
-        }
-
-        // Now remove ownership, which means that Exif/XMP location data should be redacted
+        // Revoke location access and remove ownership, which means that location should be redacted
+        ProviderTestUtils.revokeMediaLocationPermission(mContext);
         ProviderTestUtils.clearOwner(publishUri);
         try (InputStream is = mContentResolver.openInputStream(publishUri)) {
             final ExifInterface exif = new ExifInterface(is);
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 dca7382..0fa99ca 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
@@ -27,19 +27,16 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.app.AppOpsManager;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.media.MediaMetadataRetriever;
 import android.net.Uri;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
-import android.os.Process;
 import android.os.storage.StorageManager;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Files.FileColumns;
@@ -203,41 +200,32 @@
         return context.getContentResolver().insert(mExternalVideo, values);
     }
 
-    /**
-     * This test doesn't hold
-     * {@link android.Manifest.permission#ACCESS_MEDIA_LOCATION}, so Exif and XMP
-     * location information should be redacted.
-     */
     @Test
-    public void testLocationRedaction() throws Exception {
-        // STOPSHIP: remove this once isolated storage is always enabled
-        Assume.assumeTrue(StorageManager.hasIsolatedStorage());
-
-        final String displayName = "cts" + System.nanoTime();
-        final PendingParams params = new PendingParams(
-                mExternalVideo, displayName, "video/mp4");
-
-        final Uri pendingUri = MediaStoreUtils.createPending(mContext, params);
-        final Uri publishUri;
-        try (PendingSession session = MediaStoreUtils.openPending(mContext, pendingUri)) {
-            try (InputStream in = mContext.getResources().openRawResource(R.raw.testvideo_meta);
-                 OutputStream out = session.openOutputStream()) {
-                FileUtils.copy(in, out);
-            }
-            publishUri = session.publish();
-        }
-
+    public void testOriginalAccess() throws Exception {
+        final Uri publishUri = ProviderTestUtils.stageMedia(R.raw.testvideo_meta, mExternalVideo,
+                "video/mp4");
         final Uri originalUri = MediaStore.setRequireOriginal(publishUri);
 
-        // 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));
+        // As owner, we should be able to request the original bytes
+        try (ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(originalUri, "r")) {
         }
+
+        // Revoke location access and remove ownership, which means that location should be redacted
+        ProviderTestUtils.revokeMediaLocationPermission(mContext);
+        ProviderTestUtils.clearOwner(publishUri);
+
+        // We can't request original bytes unless we have permission
+        try (ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(originalUri, "r")) {
+            fail("Able to read original content without ACCESS_MEDIA_LOCATION");
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
+    @Test
+    public void testXmpLocationRedaction() throws Exception {
+        final Uri publishUri = ProviderTestUtils.stageMedia(R.raw.testvideo_meta, mExternalVideo,
+                "video/mp4");
+
         try (InputStream in = mContentResolver.openInputStream(publishUri);
                 ByteArrayOutputStream out = new ByteArrayOutputStream()) {
             FileUtils.copy(in, out);
@@ -248,44 +236,11 @@
             assertTrue("Failed to read XMP latitude", xmp.contains("53,50.070500N"));
             assertTrue("Failed to read non-location XMP", xmp.contains("13166/7763"));
         }
-        // As owner, we should be able to request the original bytes
-        try (ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(originalUri, "r")) {
-        }
 
-        // Remove ACCESS_MEDIA_LOCATION permission
-        try {
-            InstrumentationRegistry.getInstrumentation().getUiAutomation()
-                    .adoptShellPermissionIdentity("android.permission.MANAGE_APP_OPS_MODES",
-                            "android.permission.REVOKE_RUNTIME_PERMISSIONS");
-
-            // Revoking ACCESS_MEDIA_LOCATION permission will kill the test app.
-            // Deny access_media_permission App op to revoke this permission.
-            PackageManager packageManager = mContext.getPackageManager();
-            String packageName = mContext.getPackageName();
-            if (packageManager.checkPermission(android.Manifest.permission.ACCESS_MEDIA_LOCATION,
-                    packageName) == PackageManager.PERMISSION_GRANTED) {
-                mContext.getPackageManager().updatePermissionFlags(
-                        android.Manifest.permission.ACCESS_MEDIA_LOCATION, packageName,
-                        PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
-                        PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, mContext.getUser());
-                mContext.getSystemService(AppOpsManager.class).setUidMode(
-                        "android:access_media_location", Process.myUid(),
-                        AppOpsManager.MODE_IGNORED);
-            }
-        } finally {
-                InstrumentationRegistry.getInstrumentation().getUiAutomation().
-                        dropShellPermissionIdentity();
-        }
-
-        // Now remove ownership, which means that location should be redacted
+        // 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));
-        }
+
         try (InputStream in = mContentResolver.openInputStream(publishUri);
                 ByteArrayOutputStream out = new ByteArrayOutputStream()) {
             FileUtils.copy(in, out);
@@ -296,10 +251,36 @@
             assertFalse("Failed to redact XMP latitude", xmp.contains("53,50.070500N"));
             assertTrue("Redacted non-location XMP", xmp.contains("13166/7763"));
         }
-        // We can't request original bytes unless we have permission
-        try (ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(originalUri, "r")) {
-            fail("Able to read original content without ACCESS_MEDIA_LOCATION");
-        } catch (UnsupportedOperationException expected) {
+    }
+
+    @Test
+    public void testIsoLocationRedaction() throws Exception {
+        // 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");
+
+        // 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));
+        }
+
+        // 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));
         }
     }
 
diff --git a/tests/tests/secure_element/omapi/apk/signed-CtsOmapiTestCases.apk b/tests/tests/secure_element/omapi/apk/signed-CtsOmapiTestCases.apk
index a6cbfd8..53275fd 100644
--- a/tests/tests/secure_element/omapi/apk/signed-CtsOmapiTestCases.apk
+++ b/tests/tests/secure_element/omapi/apk/signed-CtsOmapiTestCases.apk
Binary files differ
diff --git a/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java b/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
index da99ff0..5d56ded 100644
--- a/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
+++ b/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
@@ -24,6 +24,7 @@
 
 import android.content.pm.PackageManager;
 import android.os.Build;
+import android.os.SystemProperties;
 import android.se.omapi.Channel;
 import android.se.omapi.Reader;
 import android.se.omapi.SEService;
@@ -154,7 +155,7 @@
 
     private boolean supportsHardware() {
         final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
-        boolean lowRamDevice = PropertyUtil.propertyEquals("ro.config.low_ram", "true");
+        boolean lowRamDevice = SystemProperties.getBoolean("ro.config.low_ram", false);
         return !lowRamDevice || pm.hasSystemFeature("android.hardware.type.watch")
                 || hasSecureElementPackage(pm);
     }
diff --git a/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetDeviceTest.java b/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetDeviceTest.java
index 8c2f870..f5ddc7c 100644
--- a/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetDeviceTest.java
+++ b/tests/tests/sharesheet/src/android/sharesheet/cts/CtsSharesheetDeviceTest.java
@@ -314,7 +314,12 @@
      */
     public void showsExtraChooserTargets() {
         // Should show chooser targets but must limit them, can't test limit here
-        waitAndAssertTextContains(mExtraChooserTargetsLabelBase);
+        if (mActivityManager.isLowRamDevice()) {
+            // The direct share row and EXTRA_CHOOSER_TARGETS should be hidden on low-ram devices
+            waitAndAssertNoTextContains(mExtraChooserTargetsLabelBase);
+        } else {
+            waitAndAssertTextContains(mExtraChooserTargetsLabelBase);
+        }
     }
 
     /**
diff --git a/tests/tests/systemintents/src/android/systemintents/cts/TestSystemIntents.java b/tests/tests/systemintents/src/android/systemintents/cts/TestSystemIntents.java
index 9f2fbb8..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;
 
@@ -68,7 +73,6 @@
     private final IntentEntry[] mTestIntents = {
             /* Settings-namespace intent actions */
             new IntentEntry(0, new Intent(Settings.ACTION_SETTINGS)),
-            new IntentEntry(0, new Intent(Settings.ACTION_WEBVIEW_SETTINGS)),
             new IntentEntry(0, new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS)),
             new IntentEntry(0, new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)),
             new IntentEntry(0, new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
@@ -115,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/wifi/src/android/net/wifi/rtt/cts/TestBase.java b/tests/tests/wifi/src/android/net/wifi/rtt/cts/TestBase.java
index 07d5718..a721326 100644
--- a/tests/tests/wifi/src/android/net/wifi/rtt/cts/TestBase.java
+++ b/tests/tests/wifi/src/android/net/wifi/rtt/cts/TestBase.java
@@ -52,6 +52,9 @@
     // wait for Wi-Fi scan results to become available
     private static final int WAIT_FOR_SCAN_RESULTS_SECS = 20;
 
+    // wait for network selection and connection finish
+    private static final int WAIT_FOR_CONNECTION_FINISH_MS = 30_000;
+
     protected WifiRttManager mWifiRttManager;
     protected WifiManager mWifiManager;
     private LocationManager mLocationManager;
@@ -96,8 +99,10 @@
         mWifiLock.acquire();
         if (!mWifiManager.isWifiEnabled()) {
             SystemUtil.runShellCommand("svc wifi enable");
+            // Turn on Wi-Fi may trigger connection. Wait connection state stable.
+            scanAps();
+            Thread.sleep(WAIT_FOR_CONNECTION_FINISH_MS);
         }
-
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED);
         WifiRttBroadcastReceiver receiver = new WifiRttBroadcastReceiver();
diff --git a/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
index fad4230..458917d 100644
--- a/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
@@ -49,7 +49,7 @@
     private static final int MAX_FAILURE_RATE_PERCENT = 10;
 
     // Maximum variation from the average measurement (measures consistency)
-    private static final int MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM = 1000;
+    private static final int MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM = 2000;
 
     // Minimum valid RSSI value
     private static final int MIN_VALID_RSSI = -100;
@@ -176,10 +176,12 @@
                         + ", AP SSID=" + testAp.SSID,
                 numFailures <= NUM_OF_RTT_ITERATIONS * MAX_FAILURE_RATE_PERCENT / 100);
         if (numFailures != NUM_OF_RTT_ITERATIONS) {
-            double distanceAvg = distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures);
-            assertTrue("Wi-Fi RTT: Variation (max direction) exceeds threshold",
+            double distanceAvg = (double) distanceSum / (NUM_OF_RTT_ITERATIONS - numFailures);
+            assertTrue("Wi-Fi RTT: Variation (max direction) exceeds threshold, Variation ="
+                            + (distanceMax - distanceAvg),
                     (distanceMax - distanceAvg) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM);
-            assertTrue("Wi-Fi RTT: Variation (min direction) exceeds threshold",
+            assertTrue("Wi-Fi RTT: Variation (min direction) exceeds threshold, Variation ="
+                            + (distanceAvg - distanceMin),
                     (distanceAvg - distanceMin) <= MAX_VARIATION_FROM_AVERAGE_DISTANCE_MM);
             for (int i = 0; i < numGoodResults; ++i) {
                 assertNotSame("Number of attempted measurements is 0", 0, numAttempted[i]);